Solved

Excel:Find MAX of Last 3 Non-Empty Rows of Sub-Range

Posted on 2010-11-28
12
459 Views
Last Modified: 2012-05-10
Column A contains company names and column B contains sales data. How do I find the MAX value of the last three non-empty rows per company?

Best wishes,

John
0
Comment
Question by:jfdinneen
  • 5
  • 4
  • 2
  • +1
12 Comments
 
LVL 58

Expert Comment

by:cyberkiwi
ID: 34226707
Does this have to be a formula or VBA?
Which version of Excel please?
Also, can we assume it looks something like this?

Company, Sales
A,12.23
B,51.22
B,11.22 *
B,
B,1.22 *
B,9.87 *
C,1.23

Where the * rows are the last 3 non-empty for B
Note also the assumption that the company records are contiguous.
0
 
LVL 50

Expert Comment

by:teylyn
ID: 34226708
Hello jfdinneen,

a data sample would be helpful. "last three non-empty rows per company?" seems to imply that there are several rows per company. Is that correct?

Could you upload a spreadsheet with some dummy sample data and your expected result?

cheers, teylyn
0
 

Author Comment

by:jfdinneen
ID: 34226782
cyberwiki / teylyn,

Thanks for the prompt replies.
The data sample cyberwiki outlined above looks correct.

Best wishes,

John
0
 

Author Comment

by:jfdinneen
ID: 34226790
cyberwiki / teylyn,

The solution must be a function but either formula of VBA is acceptable.

Best wishes,

John
0
 
LVL 58

Expert Comment

by:cyberkiwi
ID: 34226875
A single function/formula won't be able to give you
"MAX value of the last three non-empty rows per company?"
can it?
Unless you mean one single value overall, from the last 3 sales per company.
So in the sample I gave above, it would return a single value "12.23" from A, since the largest value "51.22" from B is out of consideration.

I have also assumed that "last three" refers to row order, and there are no other date/id/time columns.

Can you please confirm?
0
 

Author Comment

by:jfdinneen
ID: 34226957
cyberwiki,

As per your example, the function should return 12.23, 11.22, and 1.23 for A, B, and C respectively.

Best wishes,

John
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 58

Assisted Solution

by:cyberkiwi
cyberkiwi earned 100 total points
ID: 34226979
So how would you use this function... I imagine one formula per cell, per company?
Like
H2: =MaxFromLast3(A:B, "A")
H3: =MaxFromLast3(A:B, "B")
etc

But that would require each company be manually inserted into the formula.
"The solution must be a function but either formula of VBA is acceptable."
I assumed by the bold part that you mean a function that can be used in the formula bar, but those won't return results into multiple cells (one per company).

Such a function for MaxFromLast3 (range, company as string) is certainly possible, where range is implied to be 2 columns (any number of rows), company on the left.

If you are after a Macro that can be run to fill some area of a sheet with the data, automatically putting one row out per company
company,max
that is also possible.

Please advice
0
 

Author Comment

by:jfdinneen
ID: 34227011
cyberwiki,

Thanks for your patience and the benefit of your expertise.

Ideally, the function MaxFromLast3 would work as follows (array formula):
={ If(A1:A100=A1,MaxFromLast3(B1:B100)) }
={ If(A1:A100=A2,MaxFromLast3(B1:B100)) }
...

Company, Sales, Max (Last 3)
A,12.23, 12.33
B,51.22
B,11.22 *
B,
B,1.22 *
B,9.87 *,11.22
C,1.23,1.23

Best wishes,

John
0
 
LVL 50

Accepted Solution

by:
barry houdini earned 400 total points
ID: 34227100
You could use this array formula

=MAX(IF(ROW(B1:B100)>=LARGE(IF(A1:A100=A1,IF(B1:B100<>"",ROW(B1:B100))),3),IF(A1:A100=A1,B1:B100)))

confirmed with CTRL+SHIFT+ENTER

That assumes that there will be at least 3 entries where the criteria match, if not then change to

=MAX(IF(ROW(B1:B100)>=LARGE(IF(A1:A100=A1,IF(B1:B100<>"",ROW(B1:B100))),MIN(3,SUM((A1:A100=A1)*(B1:B100<>"")))),IF(A1:A100=A1,B1:B100)))

regards, barry
0
 
LVL 50

Expert Comment

by:barry houdini
ID: 34227127
See example attached with some random values (press F9 to re-generate)

Formulas in C2:C6 should give the same results as D2:D6.......unless there are fewer than 3 qualifying rows....in which case column C will have an error

regards, barry
26642825.xls
0
 

Author Closing Comment

by:jfdinneen
ID: 34227232
Thanks Barry for the ideal solution.

Best wishes,

John
0
 
LVL 58

Expert Comment

by:cyberkiwi
ID: 34227254
Hi John,

Please find attached a sheet with the function below, and an example of using it.
It returns an array of 2 values:
1- the value
2- the row on which it was found (not relative terms like Match, just absolute)

The formula in C uses the 2nd value returned to inspect whether it is the max row, and only then shows the value from B (no need to run the function again).

If the function were to return [only] the max value [without the row reference], then a more complicated formula on the Excel side would be needed to tiebreak between multiple rows with the same value.

Hope this helps

Regards
Function MaxLast3(ByRef R As Range, ByVal company As String)

    If IsEmpty(R) Then

        Func MaxLast3(ByRef R As Range, ByVal company As String)

    If IsEmpty(R) Then

        Exit Function

    End If

    Set R = Intersect(R, R.Worksheet.UsedRange)

    If R Is Nothing Then

        Exit Function

    End If



    Dim which As Integer, test As Range, where As Range, maxVal

    which = 1

    maxVal = ""

    Set where = Nothing

    Set test = R.Cells(1)

    

    Set test = R.Columns(1).Find(What:=company, After:=test, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlPrevious)

    While Not test Is Nothing

        If test.Offset(, 1) > "" Then

            If which = 1 Or Val(test.Offset(, 1)) > maxVal Then

                Set where = test.Offset(, 1)

                maxVal = Val(test.Offset(, 1))

            End If

            which = which + 1

        End If

        If which <= 3 And Not where Is Nothing Then

            Set test = R.Columns(1).Find(What:=company, After:=test, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlPrevious)

        Else

            Set test

Open in new window

Book1.xls
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Excel VBA - Get files in a folder 5 78
consolidate from multiple folders 5 39
Office 2016 Excel Issue 4 25
Easy Excel formula needed 4 23
INDEX and MATCH can be used to great effect to replace HLOOKUP and VLOOKUP as it does not have the limitation of needing the data to be sorted so that the reference value is in the first column or row. It also has the ability to perform a bi-directi…
Some code to ensure data integrity when using macros within Excel. Also included code that helps secure your data within an Excel workbook.
This Micro Tutorial will demonstrate in Microsoft Excel how to add style and sexy appeal to horizontal bar charts.
This Micro Tutorial will demonstrate the scrolling table in Microsoft Excel using the INDEX function.

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now