Excel: find location of Max value across multiple worksheets - excel

I have a workbook containing 8 worksheets which are all of the same format. I have built a formula to calculate the Max value in a particular cell across all the worksheets:
=MAX(MAX('Equipment - A:Equipment - H'!C17))
This works great. It finds me the Max value out of the 8 instances of cell C17.
What I now want to know is which sheet that Max value is found on. I tried to use the MATCH function, but it doesn't seem to work:
=MATCH(MAX('Equipment - A:Equipment - H'!C17),'Equipment - A:Equipment - H'!C17)
returns #N/A.
All my Google searches tend to point to using VLOOKUP but this seems like a bit of a sledgehammer tactic.
Any ideas?

How about this...
I'll psuedo code this since there are too many unknown details, but essentially, as you said each of the sheets is the same format, so you can use Excel Power Query (builtin 2016, add-in to 2010/2013), to open and reformat ONE of the sheets to:
1) INCLUDE the name of the sheet, and;
2) exclude all of the other rows you don't don't need (eg only the max row).
This can be applied as a function call in PQ (see this link) to open AND process all of the other tabs. At the end of each process, the resulting output can be merged to a seperate work table, and when completed will require a vlookup() to that temp/helper sheet/table to return the needed value (remember, I said PQ can incoprorate the sheet name as one of the data attributes from the 'imported' sheet.)

Related

SUMIF in multiple sheets without using INDIRECT

Here is simplified EXCEL file I am working on.
Data sheet 1 called "first":
Data sheet 2 called "second":
Data structure and range (C2:E8) is same. I need to sum those sheets based on criteria in column B (Option).
Outcome I expect:
option1_sum sheet:
option2_sum sheet:
I can achieve this by putting either this formula in sum sheet C2 and dragging to E8:
=SUMIF(first!$B2,$B$2,first!C2)+SUMIF(second!$B2,$B$2,second!C2)
or this:
=IF(first!$B2=$B$2,first!C2,0)+IF(second!$B$2=$B2,second!C2,0)
These works as expected. Calculations are fast. The problem is that in original file there are ~100 data sheets to sum and area is more than 30000 cells in each sheet.
Formulas are getting very long and file is getting too heavy, takes ages to open.
If there wouldn't be IF condition I would calculate like this:
=sum(first:second!C2)
I expected SUMIF to work like this:
=SUMIF(first:second!$B2,$B$2,first:second!C2)
Unfortunately it doesn't. Every solution I've found uses INDIRECT formula like this:
=SUMPRODUCT(SUMIF(INDIRECT("'"&Sheetlist&"'!B2"),$B$2,INDIRECT("'"&Sheetlist&"'!C2"))) where Sheetlist is named list:
It does work, it is much shorter and makes file lighter more than 3 times, but because INDIRECT is volatile formula, it freezes excel for 5 seconds every time change is made in data sheets. And changes are made often.
Are there any other ways to make file lighter without losing speed?
Limitations:
Can't use VBA because it is stored in Sharepoint and accessed via both Excel 365 and browser Excel
Can't use manual recalculation as it is constantly monitored by several people and changes need to be seen on the spot
UPDATE: #JvdV suggested formula works, but after adding 10+ sheets every recalculations takes more than 5 seconds.
Updated said formula to include blank cells:
=LET(x,WRAPROWS(TOCOL(first:last!A1:E8,0),5),IFERROR(DROP(REDUCE(0,A2:A8,LAMBDA(a,b,VSTACK(a,BYCOL(FILTER(DROP(x,,2),(TAKE(x,,1)=b)*(INDEX(x,,2)=B2),0),LAMBDA(c,SUM(c)))))),1),0))
Using a custom function from the name manager comes to mind. Something like =TOCOL(GET.WORKBOOK(1)) would spill all sheetnames but it requires to save your workbook as .xlsm. So I came up with another idea. If your sheets are always in order you could do something like:
=WRAPROWS(TOCOL(first:last!A:E,1),5)
Now let's incorporate this into a REDUCE() to fill all cells in each sum-sheet:
Formula in C2:
=LET(x,WRAPROWS(TOCOL(first:last!A:E,1),5),IFERROR(DROP(REDUCE(0,A2:A8,LAMBDA(a,b,VSTACK(a,BYCOL(FILTER(DROP(x,,2),(TAKE(x,,1)=b)*(INDEX(x,,2)=B2),0),LAMBDA(c,SUM(c)))))),1),0))
Note that 'last' is just a placeholder for whatever is the last sheet in the sequence of sheets to sum from. I hope that below visual will help cover the basics of the theory implemented:

How to identify and name different ranges in one column in Excel?

I have a recorded drive cycle of a truck which includes speed and coordinates over time. The file looks like this (simplified version)
I want to know the number of times the truck is stopped (when speed = 0) and number them. Therefore, I would like to group the intervals with '0' values (vehicle stopped) in the Speed column and name them in order (Stop 1, Stop 2, etc). Ultimately, my goal would be to somehow be able to calculate the number of stops and duration like this:
Is there any function in Excel which would allow me to do something like that? Thank you.
You can do it using Pivot Tables and a helper column. Also if you have Excel365 with functions like FILTER,UNIQUE and SUMIFS
Formula helper column is just to enumerate properly each group of stops. Notice data need to be sorted properly as your exampel or it won't work:
=IF(D2="STOP";IF(D1="STOP";E1;MAX($E$1:E1)+1);"")
Then pivot table can be inserted:
Helper Column and Vehicle Stop into rows section
Time-step seconds into values section, formated as Time and operation=Sum
Filter field Helper Column to exclude blanks
If you have Excel 365, you can get this output with advanced formulas. In cell J14 formula is:
=UNIQUE(FILTER(D2:D19&E2:E19;D2:D19="STOP"))
And K14 is (and drag down) is:
=SUMIFS($B$2:$B$19;$D$2:$D$19;"STOP";$E$2:$E$19;MID(J14;5;99))
Anyways, I've uploaded the workbook to Gdrive so you can see the Pivot Table and the formulas by yourself. If you don't jave Excel 365, the formulation part may give some errors when you open it:
https://docs.google.com/spreadsheets/d/1t1INxGKJRHFexWnSC5LlIi37JrThjajs/edit?usp=sharing&ouid=114417674018837700466&rtpof=true&sd=true
Just as a postscript to this, you could do the same thing without using helper columns by comparing offset ranges to see where the transitions in speed occurred from 0 to 10 (go) or 10 to 0 (stop). The problem is that normally you would have to go outside the data range (a2:a16 and c2:c16) which gets you either a header cell (a1 or c1) or a blank cell (a17 or c17). In the case of time, there is also a special case where the first time-step is taken to be zero.
All this can be avoided in Excel 365 by using vstack to add appropriate dummy values to the beginning or end of the two ranges:
=LET(timeRange,A2:A16,
speedRange,C2:C16,
timeRange1,VSTACK(A2,timeRange),
speedRange1,VSTACK(1,speedRange),
speedRange2,VSTACK(speedRange,1),
startTime,FILTER(timeRange1,(speedRange1>0)*(speedRange2=0)),
endTime,FILTER(timeRange1,(speedRange1=0)*(speedRange2>0)),
stopTime,endTime-startTime,
label,"STOP "&SEQUENCE(ROWS(stopTime)),
HSTACK(label,stopTime))

Microsoft Excel LOOKUP function just... doesn't work?

So, I have a fairly involved workbook.
Sheet 1: A database where the user enters a list of instruments as well as some data about the instruments in a vertical column.
Sheet 2: A sheet that contains the exact same information as sheet 1 but displays it in a different format. Automatically populates based on entries from Sheet 1. (Not useful in this question)
There exists a macro on Sheet 1 that is executed by clicking a button. This macro takes every column from Sheet 1 and creates a new Sheet for each column. Each new sheet, Sheet 3, is renamed to the first value in the column of Sheet 1 that it represents.
i.e., There are 4 columns in Sheet 1 with the first value in each column being: LS-ALPHA, LS-BRAVO, LS-CHARLIE, LS-DELTA. My macro will create 4 new sheets called LS-ALPHA, LS-BRAVO, LS-CHARLIE, LS-DELTA.
The first cell (technically H2) on each of the new sheets contains a formula to reference the sheet name.
=MID(CELL("filename",A1),FIND("]",CELL("filename",A1))+1,255)
i.e., H2 on the LS-ALPHA sheet will actually say "LS-ALPHA", H2 on the LS-BRAVO sheet will say LS-BRAVO, etc.
Every other data cell on the new sheet will automatically look up that value on the main sheet (Sheet 1) to determine what column it is from. Then, it will go below that value and get the contents from some cell x rows below.
=LOOKUP(H2,'Database (Cols)'!D2:AN2,'Database (Cols)'!D3:AN3)
This works absolutely perfectly. It does everything well.
Except, not always.
If I rename the columns to "LS-A, LS-B, LS-C, LS-D", it works. If I rename the columns to "LS-AA, LS-AB, LS-AC, LS-AD", it works. If I rename the columns to "LS-AAA, LS-AAB, LS-AAC, LS-AAD", it works.
However, if I rename the columns to something like "LS-TTF, LS-TTD,LS-TSD, LS-TSF" they are all broken somehow.... None of the links on the sheets work any more. Some of them point to the incorrect column if they even do show something. This issue I'm having is incredibly peculiar. I don't know why these names break it in particular, nor do I know what other names would also break it.
What happens when it 'breaks': All of the references seem to find the last available column in the LOOKUP. Three of the four sheets all use values from the fourth column when they aren't supposed to. Then, one sheet just gives me errors (#N/A). When I step through the calculation, it is looking for the correct value in the LOOKUP function, it's just not returning the right thing....
I can't really give much more information without showing you what's happening so I've included a working spreadsheet and a broken spreadsheet. The sheets have been generated from the macro so you don't have to mess with it. The working and broken files are below:
Working: https://drive.google.com/file/d/0B9zbU-BeMQNfSmRrWVhKVW9RN3M/view?usp=drivesdk
Broken: https://drive.google.com/file/d/0B9zbU-BeMQNfd1FUemwxQjQwMEE/view?usp=drivesdk
Note, the echo column is for debugging purposes. I was trying to see if they would all show echo instead of delta. Apparently, they don't.
From the help for the LOOKUP function:
IMPORTANT: The values in lookup_vector must be placed in ascending
order: ..., -2, -1, 0, 1, 2, ..., A-Z, FALSE, TRUE; otherwise, LOOKUP
might not return the correct value. Uppercase and lowercase text are
equivalent.
The set of values which work correctly - "LS-A, LS-B, LS-C, LS-D" - are in alphabetical order. The set of values which don't work correctly - "LS-TTF, LS-TTD, LS-TSD, LS-TSF" - are not in alphabetical order. Also, LOOKUP doesn't necessarily find an exact match - as specified in the help:
If the LOOKUP function can't find the lookup_value, the function
matches the largest value in lookup_vector that is less than or equal
to lookup_value.
To fix, either:
reorder the non-working set of values to be in alphabetical order (although you still won't guarantee an exact match), or
switch to using the HLOOKUP function instead. Ensure that the Range_lookup parameter is false to require an exact match. Sample usage: =HLOOKUP(H2,'Database (Cols)'!D2:AN3,2,FALSE)
I had a similar problem because I was wrongly using lookup. To find a value in a vector, I had to use
=MATCH("KEY";F5:F48;0)
instead of
=LOOKUP("KEY";F5:F48)
LOOKUP just didn't work for my objectives.

Combine INDIRECT with IF AND COUNTIF

I'm working on a Google Sheets based database for work, which shows availability on the dive boats, which instructors are available etc.
I need to copy some some similar formulas to the rows below. There are 365 rows for each day of the year, and several columns with different formulas I need to copy. Sound's straight-forward enough right, but, there's a couple of things that makes this harder.
Here's one of the formulas...
=IF(AND(COUNTIF(MER!$T4:$T23,AE3)=0,COUNTIF(CHO!$T4:$T23,AE3)=0, COUNTIF(KEP!$T4:$T23,AE3)=0,COUNTIF(SUP!$T4:$T23,AE3)=0),AE3,"")
I am working from Sheet 'AVL'. It basically references ranges in
five different sheets in the same workbook to look for a match
against a list of dive instructors we employ who are available to
work on a daily basis.
I need to copy the formula to the rows directly below, so close to
200 rows for the remainder of this year, and on a new sheet for
2017, a further 365 rows.
If I copy as normal on google sheets, > Paste special > Paste formula, the formula increases the row number on the formula by one row. EG:
=IF(AND(COUNTIF(MER!$T4:$T23,AE3)=0,COUNTIF(CHO!$T4:$T23,AE3)=0, COUNTIF(KEP!$T4:$T23,AE3)=0,COUNTIF(SUP!$T4:$T23,AE3)=0),AE3,"")
=IF(AND(COUNTIF(MER!$T5:$T24,AE4)=0,COUNTIF(CHO!$T5:$T24,AE4)=0, COUNTIF(KEP!$T5:$T24,AE4)=0,COUNTIF(SUP!$T5:$T24,AE4)=0),AE4,"")
That's no good to me, because the ranges I need to reference from the other sheets are completely different, but, the cell referenced with the staff name on, on the sheet I'm working on 'AVL' moves down by one row which is correct.
The ranges from the five other sheets needs to move down by 26 rows each time. EG:
=IF(AND(COUNTIF(MER!$T4:$T23,AE3)=0,COUNTIF(CHO!$T4:$T23,AE3)=0, COUNTIF(KEP!$T4:$T23,AE3)=0,COUNTIF(SUP!$T4:$T23,AE3)=0),AE3,"")
=IF(AND(COUNTIF(MER!$T30:$T49,AE4)=0,COUNTIF(CHO!$T30:$T49,AE4)=0, COUNTIF(KEP!$T30:$T49,AE4)=0, COUNTIF(SUP!$T30:$T49,AE4)=0, COUNTIF(OTH!$T30:$T49,AE4)=0),AE4,"")
=IF(AND(COUNTIF(MER!$U56:$U75,AE5)=0,COUNTIF(CHO!$U56:$U75,AE5)=0, COUNTIF(KEP!$U56:$U75,AE5)=0,COUNTIF(SUP!$U56:$U75,AF5)=0, COUNTIF(OTH!$U56:$U75,AE5)=0),AE5,"")
Etc etc.
I've used the INDIRECT function previously for something else, and was wondering if I should be looking at combining the formula I used for something else, with the formula I need to copy 1,000's of times. EG...
=INDIRECT("CHO!B" & (3 + 26*(ROW()-3)))
adjusted and modified and combined with...
=IF(AND(COUNTIF(MER!$T4:$T23,AE3)=0,COUNTIF(CHO!$T4:$T23,AE3)=0, COUNTIF(KEP!$T4:$T23,AE3)=0,COUNTIF(SUP!$T4:$T23,AE3)=0),AE3,"")
to somehow increase the ranges by 26 rows every time I copy the formula, while leaving the cell I'm matching against AE3 etc, to just increase by one row.
Build your cell ranges with a pair of non-volatile¹ INDEX functions.
For example, these two cell ranges are exactly the same.
=T4:T23
=INDEX(T:T, 4):INDEX(T:T, 23)
The rest is just simple maths and a ROW function. Put this in the top row.
=IF(AND(COUNTIF(INDEX(MER!$T:$T, (ROW(1:1)-1)*26+4):INDEX(MER!$T:$T, (ROW(1:1)-1)*26+23), AE3)=0,
COUNTIF(INDEX(CHO!$T:$T, (ROW(1:1)-1)*26+4):INDEX(CHO!$T:$T, (ROW(1:1)-1)*26+23), AE3)=0,
COUNTIF(INDEX(KEP!$T:$T, (ROW(1:1)-1)*26+4):INDEX(KEP!$T:$T, (ROW(1:1)-1)*26+23), AE3)=0,
COUNTIF(INDEX(SUP!$T:$T, (ROW(1:1)-1)*26+4):INDEX(SUP!$T:$T, (ROW(1:1)-1)*26+23), AE3)=0), AE3, "")
Fill down as necessary.
¹ Volatile functions recalculate whenever anything in the entire workbook changes, not just when something that affects their outcome changes. Examples of volatile functions are INDIRECT, OFFSET, TODAY, NOW, RAND and RANDBETWEEN. Some sub-functions of the CELL and INFO worksheet functions will make them volatile as well.

Optimization of vlookup with multiple criteria (index + match)

I have a 12x18 Excel range which draws data from a 823x20 sheet (Results!$A:$T) according to the 12x18 range's page, row and column headers (criterion1, criterion2 and criterion3, respectively)
={INDEX(Results!$A:$T,
MATCH(1, (criterion1 = Results!$A:$A) * (criterion2 = Results!$B:$B), 0),
MATCH(criterion3, Results!$A$1:$T$1, 0))}
As you can see, it's not that much data, but still, when I change the page header, my computer (2 GHz Intel Xeon with 24 GB of RAM) takes about a minute to update the 216 (12x18) index searches and I'm not even half way done with creating searches.
Earlier on my project, these searches only had one criterion, so I used VLOOKUP() and the results came very quickly. However, now I need to find values according to three criteria, and the function above is the best way I've managed to accomplish this. However, it seems to be the responsible for the long computation times I'm getting. So my question is: how can I optimize a VLOOKUP() of multiple criteria? Should I tweak INDEX(1, MATCH()*MATCH(), MATCH()) or is there a faster way to do this?
Here's a sample of the 12x18 index searches (branch name is the only variable that the end-user will be able to change):
And of the 823x20 sheet it searches (column A has no merges, actually):
For a summary and options for Lookup with multiple criteria you may check this.
I use a lot Method 2 here (it is non-array formula) and method here.
I guess you should try them to check their speed.
First of all, can't this be accomplished simply by filtering on column A in sheet 'Results'? I think that is the most straightforward solution.
However, I have created an example workbook based on the criteria you described. It can be found here
First I created a list of the unique branches by using Advanced Filter for unique values on sheet 'Results' column A and put them on sheet 'Lists' where I created a named range listUnqBranches. I used that named range to create a data validation drop-down list on sheet 'Sheet1' cell A1 so that users can select which branch they'd like to see. I named that cell Branch.
Next I created two named ranges. rngDate is defined with this dynamic named range formula:
=INDEX(Results!$B:$B,MATCH(Branch,Results!$A:$A,0)):INDEX(Results!$B:$B,MATCH(Branch,Results!$A:$A,0)+COUNTIF(Results!$A:$A,Branch)-1)
rngLookup is defined with this dynamic named range formula:
=INDEX(Results!$C:$C,MATCH(Branch,Results!$A:$A,0)):INDEX(Results!$T:$T,MATCH(Branch,Results!$A:$A,0)+COUNTIF(Results!$A:$A,Branch)-1)
Lastly, in sheet 'Sheet1' cell B2 and copied over and down is this formula:
=IF(Branch="","",INDEX(rngLookup,MATCH($A2,rngDate,0),MATCH(B$1,Results!$C$1:$T$1,0)))
Note that the formula solution with named ranges is dependent on the data in sheet 'Results' being sorted by Branch. Does that work for you?

Resources