Excel, Match lookup array to ignore hidden rows - excel

NOTE: I'm using Excel 2016, don't have access to the good stuff in 365 :(
I'm trying to build a summary sheet at the moment. The idea is to filter a table, then have the summary formulas pick out the top 5 values in a given column.
To do this I'm trying to use the Large function in Aggregate which will help me ignore hidden rows while also allowing me to extract the nth largest value.
From there I had thought to use match to find the row number of that value within the column so that I could also get text based values from the same row by assigning a column letter via Indirect.
^This is the crux of what I'm trying to do^
The code looks like this at the moment... (Sales is column "R")
=MATCH(AGGREGATE(14,5,Table1[Sales],1),Table1[Sales],0)+62
Would then go be
=INDIRECT("N"&MATCH(AGGREGATE(14,5,Table1[Sales],1),Table1[Sales],0)+62)
Aggregate(14 = Large*
Aggregate(,5 = Ignore hidden rows*
The 62 there at the end is there as the data in the table starts on row 63 (making it more robust with row() is on my list but not there yet).
The issue I'm having is it seems the lookup array in the Match function Table1[Sales] isn't being filtered as the table is being filtered.
At least that's what the results I'm seeing are indicating to me as the row number I'm getting back isn't within the filtered table (I.e. Match is returning a hidden row number).
My question is if anyone has an idea about how make this so that only visible rows are considered within the array.
(If I've completely missed the mark with this and someone has a better idea about how to accomplish this goal (without having to resort to array functions) I'd be very grateful).
Thanks!
Expected results
row
A
B
1
Company A
425
2
Company B
1500
4
Company A
1200
7
Company C
750
15
Company B
100
19
Company A
100
I'd be looking for the nth largest value in column B, say 1200 (second largest) in this example.
=MATCH(AGGREGATE(14,5,B:B,2),B:B,0)
=MATCH((1200),C:C,0))
=3
The expected result is Row 4, but because (again, it seems) the look-up array isn't excluding filtered/hidden rows, it is returning Row 3 instead.
I hope this is a bit clearer!

Related

Get last 5 values ignoring blanks excel

So I have data consisting of the following:
there are multiple more rows.
Im trying to retrieve the last 5 values in a row, for further use.
I can do this with a simple INDEX(MATCH()) setup, however that doesn't ignore the blank cells, which I would like it to do. It does successfully detect the first nonblank cell and returns that, however when it's blank in the middle of the 5 most recent, it doesn't remove that.
something like this is what it does now:
however i want it to come back in this format:
and so on. A blank could occur at any position, and there may not always be 5 scores available to retrieve.
TIA
You could use the following array-formula (entered with ctrl+shift+enter in older Excel versions):
=INDEX(1:1,AGGREGATE(14,6,COLUMN(A:G)/(A1:G1<>""),{5,4,3,2,1})) copied down.
Aggregate creates an array of the column numbers divided by 1 or 0 (TRUE or FALSE). Divided by 0 results in an error and gets ignored. It then takes the 5th largest to the largest column number without error and returns that as an array on the indexed row.
Where 1:1 represents the first row and A:G represents the first to last column used.
If you would want it on row 2 and column A:Z you'd have to amend it like this:
=INDEX(2:2,AGGREGATE(14,6,COLUMN(A:Z)/(A2:Z2<>""),{5,4,3,2,1}))
Different approach - using the new Excel 365 formulas:
This will return the values of the last five non-empty cells of row 2
=LET(
data,FILTER(B2:H2,B2:H2<>""),
cntData,COUNT(data),
matrix,SEQUENCE(1,MIN(cntData,5),IF(cntData>5,cntData-4,1)),
INDEX(data,1,matrix)
)
data returns all values except empty cells using the FILTER- formula
cntData holds the number of cells
using SEQUENCE a matrix is build that will return the column-indices to be returned. In case less then 5 values are available, the matrix returns 1 to cntData.
finally this "index-matrix" is used to return the values from the filtered data
This could be enhanced, by storing the number of cells to be returned within a named cell - and referencing this name in the formula. By that you could easily alter the number without altering the formula.

Sum every 11 rows excel

I have a table with 2600+ rows, related to towns in my region and their population; each town has 11 rows, one for each age class (0-9, 10-19, and so on).
I need to get the sum of the population of each town; of course I can do it manually but it's a never ending job; I wonder if there's some kind of command that tells excel to do the sum every 11 rows and do it for all the towns.
I think it's a kind of loop but I have no idea about how to do it.
The problem can be reduced by using the SUMIF function. The question then becomes how to apply this to your dataset.
Assuming one of the columns in your 2600+ rows contains the town name (or another unique identifier), and you have a list of towns (or other unique identifier), the below method can be used.
The formula in E2 is =SUMIF(A:A,D2,C:C), and in E3 =SUMIF(A:A,D3,C:C). A to C is the list of all data, D is a list of towns.
For a VBA solution, you should be able to use a step in the loop.
So if you wish to step by 11 rows at a time.
Public Sub IterateRows()
Dim rData As Range, rPtr As Range
Dim dSum As Double
Dim i As long
Set rData = Sheet1.Range("A1:A1000")
For i = 1 To rData.Rows.Count Step 11
Set rPtr = rData(1).Resize(11).Offset(i - 1)
dSum = Application.WorksheetFunction.Sum(rPtr)
Next
End Sub
If you want a worksheet function solution, you will probably have to use the MOD operator and check for when the value is zero..
You can also try this manual method which is not a never ending job; i.e.:
in E11 put your formula as =SUM(C1:C11)
copy range E1:E11
select range E12:E2600 and paste special function
Do you have any reference columns? As in...say for example Column A has the Town Name, and Column B has the Age Class, and Column C has the values.
Going down the rows Column A will have repeating town names, yes?
Like this:
Town - Age Class - Pop
Wherever - 0-9 - 1000
Wherever - 10-19 - 2000
Wheverer - 20-29 - 2500
Assuming you have maintained the data structure (NO GAPS) a possible solution in Column D (or whatever column just make sure you change the references) could be (putting this in D2 and dragging it down the length of your sheet):
=IF(A1<>A2,SUM(INDIRECT("C"&ROW(A2)&":C"&SUMPRODUCT(MAX((A:A=A2)*(ROW(A:A)))))),D1)
This works if you have any amount of rows per town, so long as you SORT by town name so the same names are next to each other in the list and there are no gaps.
In the above test data set I subtracted 250 from each Values count per Town going down (each class has 250 less than the previous city) just to show some variation in the output...you can see each city has 2750 (250 * 11) less pop than the previous.
Basically it builds an array with a starting position of "not the town above" in the first row it encounters a new town name to an ending position of "last (max) position of new town in same list" so that is how it doesn't matter how many rows you have per town. From 1 to memory limit basically, I think. :)
ALTHOUGH, this also works:
=SUMIF(A:A,A2,C:C)
Yep. Not kidding just drag that down Column D...
Assuming the following structure
This is a very easy task using a pivot table.
For LibreOffice Calc:
Just select the complete data area including the column headers (in my example: A1:C13);
Menu Data -> Pivot Table;
Current selection;
Following settings for Pivot table:
(drag the Town field into the Row Fiels area, and the Count field into the Data fields area. LO Calc will offer to calculate the Sum of the count entries by default).
Hit OK - the resulting pivot table will look like this:
This solution has the advantage that the source data area hasn't to be sorted by town, and it doesn't matter if some towns don't have nine value rows each. Additionally, you don't need any formulas.
EDIT:
You can work with the contents of the pivot table the same way as with calculated results. For example, you could use the pivot table values to calculate the sum for some of the towns (in my example, calculate the sum for town B and C based on the pivot table values B3 and B4 respectively):
You could do this with the MOD function, which gives the remainder of division. You could look at each row number and if its MOD of 11 equals zero, then it's the row you're looking for.
I am counting 10 items in each section in your example so I'm not sure I completely understand. Let's assume you need to sum every row that ends in a 9 (A9, A19, A29, etc.). You can replace the 9's below with an 11.
=ROW(A9) gets you the row number.
=MOD(ROW(A9),9) gets you a TRUE or false on weather that number is divisible by 9. If it is a multiple of 9, it will return the number 0.
Now use the SUM function and hit CONTROL+SHIFT+ENTER to complete it. Note that the formula bar indicates that this is an array function by using curly braces. You don't need to type those in yourself.
{=SUM(A1:A9*(MOD(ROW(A1:A9),9)=0))}

Need to find a value that matches two columns of criteria. Possible VLOOKUP

Update Below -- 6/4
I have two worksheets in excel. One is a list of donors with their check#/amount/ Donor ID ( "donations" worksheet) and the other is a copy of the accounting info with Donor ID/check#/amounts (quickbooks worksheet). Quickbooks does not have the DonorID's filled in yet.
The issue I have is that i need match up Donor ID's with their checks. To get this i need to match the check# and amount in "Quickbooks" to the same in "Donations", when they match, it will give me the Donor ID that corresponds with that check.
Here is how it is laid out:
Donations Worksheet:
A B C
DonationID Check# Amount
1 179 106 $200
2 210 106 $500
3 220 106 $600
Quickbooks Worksheet:
A B C
DonationID Check# Amount
1 n/a 106 200
2 N/a 1074 500
3 N/a 300 1000
When I ask to find "check# 106 is for $200" it should tell me that it is from Donor 179.
Some checks don't match and are not from donors. The list has close to 50000 names.
Please ask me any questions so i can clarify this more. I am also somewhat new to all this and apologize if I am not to clear.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Thanks everyone for your help. We are not there yet but you were all steering me in the right direction.
I have added a screen shot of the page for reference because the team was having issues making the given formula's work. I also combined the two sheets onto one page so there is less cross worksheet referencing and will be easier to read.
Cknum = Check#
Two column matches typically come in one of two typical configurations; one being an array formula and the other being a standard formula. Both use variations of an INDEX/MATCH function pair.
        
The standard formula for Quickbooks!A2 would be,
=IFERROR(INDEX(Donations!A$1:A$999, MIN(INDEX(ROW($1:$999)+((Donations!B$1:B$999<>B2)+(Donations!C$1:C$999<>C2))*1E+99, , ))), "No match")
The array formula version for Quickbooks!A2 would be,
=IFERROR(INDEX(Donations!A$1:A$999, MATCH(1, (Donations!B$1:B$999=B2)*(Donations!C$1:C$999=C2), 0)), "no match")
Array formulas need to be finalized with Ctrl+Shift+Enter↵ rather than simply Enter↵.
Once one of the formulas has been put in Quickbooks!A2 correctly, fill down as necessary to catch the values from other rows. Note that I have changed the third line of your sample data to demonstrate a second DonationID lookup for Check# 106.
With ~50K records, there is the distinct possibility that multiple matches could be made on both columns B and C. To capture the subsequent second, third, etc matches from the Donations worksheet, change the MIN function to a SMALL function and use a progressive COUNTIFS function to adjust the k ordinal.
=IFERROR(INDEX(Donations!A$1:A$50000, SMALL(INDEX(ROW($1:$50000)+((Donations!B$1:B$50000<>B2)+(Donations!C$1:C$50000<>C2))*1E+99, , ), COUNTIFS(B$2:B2, B2, C$2:C2, C2))), "No match")
After setting up some intentional duplicates in the Donations worksheet like this,
DonationID Check# Amount
179 106 $200
210 106 $500
220 106 $600
979 106 $200
910 106 $500
920 106 $600
You should receive results like the following.
        
The IFERROR function has been used to catch non-matches and show no match rather than the #N/A error.
I have modified the values in your single worksheet sample data to show a variety of matches as well as one case where the chknum and amount were duplicated by two different donationID entries.
    
The matching records are color-coded for quick reference. I've made this sample workbook publically available at my Docs.com-Preview site.
 VLOOKUP_w_Multiple_Criteria_and_Duplicates.xlsx
There is an existing command, DGET, that can be used for multiple criteria.
In your QB worksheet, I added another few rows, starting at A7.
ID CheckNo Amount
106 200
The ID is 179
Note that I changed Check# to CheckNo. I also added a definition of donationDB, from A1 to D4.
The DGet statement is where the 179 is. I used =DGET(donationDB,Donations!B1,Quickbooks!A7:C8)
What the DGET does is to look up the database, tell it you're looking for the Donor ID in B1, using the criteria in the fields A7 to C8.
One quick way out of this problem is to create a Pivot Table on the Donations data and then use GETPIVOTDATA to pull values out of it to get the donation id on the Quickbooks table.
This is easily done if the donation ID is always numeric. You set up a Pivot Table with row fields including check number and amount. You then set the values to be equal to MIN or MAX of the donation ID. If there is only one result you will get it immediately. If there is a clash, you can determine this by switching over to COUNT and flag any of those >1.
Once you have the table set up with MAX you can then quickly use GETPIVOTDATA to pull in the matching value.
This assumes that your amount values are close enough (in the floating point decimal sense) to match. Nearly all will be. Some may not. If you can get 50k records down to 100 though to double check, then life is good.
Picture of sample data and Pivot set up, shows the Pivot Table built on the left data (with the donation ID). The lookup data is on the right.
Formula for the lookup is a simple GETPIVOTDATA, this is in cell F3 and copied down.
=GETPIVOTDATA("Donation",$B$10,"Check",G3,"Amount",H3)
You will get the #REF! error if a match is not made. See the last row for an example.
To compare two sets of data by matching several fields and obtain another field as a result of the match, I suggest to add a new field to each database to create a concatenated value of the Fields to match, then use a VLOOKUP and COUNTIF formulas combined.
Let’s use the sample data provided by Jeeped, in which we have:
Data A: Quickbooks - range D1:M24 and Data B: Donations – range R1:W23, to be extended to C1:M24 and Q1:W23 respectively
Add Field “Key” to concatenate the Fields to match (2 fields in this case, but also works for more), use | as separator.
Data A: Add Field “Key” in Column C and enter this formula
=CONCATENATE($E2,"|",$M2)
Data B: Add Field “Key” in Column Q and enter this formula
=CONCATENATE($V2,"|",$W2)
Enter formulas to match concatenated fields and retrieve required information (also indicates items duplicated)
Data A: Add this formula in column N
=IF(COUNTIF($Q$1:$Q$23,$C2)>1,
"Duplicated: "&COUNTIF($Q$1:$Q$23,$C2),
IFERROR(VLOOKUP($C2,$Q$1:$W$23,2,0),""))
Data B: Add this formula in column X
=IF(COUNTIF($C$1:$M$24,$Q5)>1,
"Duplicated: "&COUNTIF($C$1:$M$24,$Q5),
IFERROR(VLOOKUP($Q5,$C$1:$M$24,2,0),""))
I use the AVERAGEIFS function for getting a numeric value based on multiple criteria. If you are not confident that the criteria would only return one value, then you can wrap in a COUNTIFS statement.
=IF(COUNTIFS($A$1:$A$10, crit1, $B$1:$B$10, crit2) = 1, AVERAGEIFS($C$1:C$10, $A$1:$A$10, crit1, $B$1:$B$10, crit2), #N/A)
This only works for numeric values though.

Return Value in a column based on value in a subset in another column

I'm working on taking information from a table like so:
A 1
2
B 3
1
4
C 2
5
Essentially, a series of sets (A,B,C) with their elements arranged vertically beside them.
What I'm trying to do is retrieve the list of column 1 values that have a certain value in column 2. For instance, if the lookup value for column 2 was 1, I would want A and B to match, but not C. Best case scenario, I could generate a new column containing the matches. Is there a way to do this without resorting to VBA?
EDIT:
The data I am working with is not so clean, here's a doctored version of it
1 2 3 4
83 Fun Edit ZZZZZZ*AAAAAA 210
365,400 176
210
85 Fun Edit 600,500 205
MEDICARE[705] 176
200
The extracted data does not like to preserve relationships between data beyond the column 1 identifier. In this case, the information in column 3 "###, ###" comes from item 176 in column 4. So filling down and taking the row will result in issues downstream.
In the long run, the data in column 4 is just a key for matching the information in this extract with another one.
I appreciate everyone's help thus far, and apologize for my insufficient original example.
Here's a short workflow that will do it:
Select the entire range
Press Ctrl+G (Goto)
Click Special
Tick Blanks and OK
Type = and arrow up. You should have a formula that looks like =A1
Press Ctrl+Enter. At this point all the missing alpha values should be filled in.
Apply Autofilter and filter the numbers to show only 1
If you want to use the filtered alpha list elsewhere, copy the values showing, and paste elsewhere.

Subtracting columns in a Vlookup

I have a Excel spreadsheet that has two tabs, I have data on the DATA tab and the results of the data on the RESULTS tab. On the RESULTS tab I need to create a vlookup that will look for data on the DATA tab and subtract Column A from Column B. Is this possible with vlookup?
I have a before and after with the same clientID but data being copied/pasted will change.
Before
A B C
1021 102 125.00
1022 102 150.00
1023 105 100.00
After
A B C
1021 102 125.00
1022 102
1023 105 100.00
So each day I take the AFTER number and paste them over the before number, and get my new AFTER numbers from another tab.But if the pasted AFTER number does not have data for that specific account (in this case 1022), and the new AFTER number I get from another tab does not have data for 1022, my comparision will be off an account and will not notify me that this account is missing. I'm sorry, i know that is probably confusing.
I don't actually get why you need to use VLOOKUP to substract two columns...
In the results tab, you could just type
=IF(AND(DATA!B1<>"",DATA!A1<>""),DATA!B1-DATA!A1,"")
And copy the formula down the whole column.
The IF condition checks if both DATA!B1 and DATA!A1 are not empty, in which case it means they both have data and it will substract it. If one of the two columns is empty, it won't do anything, which is what you want.
If I didn't understand your question correctly, feel free to comment and clarify and I will propose something else.
Edit for VLOOKUP solution: I'm assuming that the client IDs are in column A in both tabs and you have to substract B from C in the same row as the ID in the DATA tab.
In RESULTS, use the following formula (put this one in row number 1 and copy it down):
=VLOOKUP(A1,DATA!A:C,3,FALSE)-VLOOKUP(A1,DATA!A:C,2,FALSE)
This will return 0 if both fields are empty, C if only B is empty and -B if only C is empty.
I can modify this if you need a different behavior depending on which columns are empty.
Hope this helps!
Yes it is possible with Vloopup.
=VLOOKUP(ResultsRefID,DATAarray,col1,FALSE)-VLOOKUP(ResultsRefID,DATAarray,col2,FALSE)
you could use that formula where ResultsRefID is the unique row identifier you are trying to get data for, DATAarray is all of the data in the DATA worksheet, and col1/col2 are the columns of data you want to have subtracted.
You can get the same results a little easier (I think) with an IF statement as an array.
=IF(ResultsRefID=DATAarrayUniqueIDrow1:DATAarrayUniqueIDrow1lastRow,col1FirstRow:col1LastRow-col2Firstrow:col2LastRow,"match not found.")
The IF statement has to be entered as an array (ctrl+shift+return)

Resources