Array Formula to Ignore Rows Where Value Exists - excel

This array formula works beautifully for what I need:
=IF(S12="","","Fastest Loop Completed in "&TEXT(MIN(IF((S12:S1048576<>"")*(R12:R1048576<>""),S12:S1048576-R12:R1048576)),"[m]:ss"))
I've since added Column U that will either be blank or have a text string of "A" or "B". I want to update the above formula to perform the same function and continue to include rows where Column U is either blank or "A", but ignore rows where Column U contains "B". I've fiddled with AND(...,U<>"B"), but am not making any progress. This formula is just giving me "Fastest Loop Completed in 0:00":
=IF(S12="","","Fastest Loop Completed in "&TEXT(MIN(IF(AND((S12:S1048576<>"")*(R12:R1048576<>""),U12:U1048576<>"B"),S12:S1048576-R12:R1048576)),"[m]:ss"))
On a side note, is there a cleaner/lighter way to do (S12:S1048576<>"")*(R12:R1048576<>"") to accomplish the same result and have it only check where Column A isn't blank, without having it mindlessly looking at all rows? I.e., "where Column A isn't blank, Column U is not equal to "B" and there is a value in both R and S, then find the fastest time." The sheet could possibly be run with just a few rows or, I anticipate, up to tens of thousands of rows, so it needs to be flexible. I don't expect anyone to ever run 1 million rows (ha, I say that now...).

I was able to get the formula to work by converting the strings to numbers within an IF() statement:
=IF(S12="","","Fastest Loop Completed in "&TEXT(MIN(IF((S12:S1048576<>"")*(R12:R1048576<>"")*(IF(U12:U1048576="B","",1)<>""),S12:S1048576-R12:R1048576)),"[m]:ss"))
Still interested to know if there is a better way than using an IF() to accomplish this as well as a cleaner/lighter way to only check rows that have data.

Related

how to group same values into Excel array

I have a duplicate value in column A with different value in column B and column C.
For example:
There are 3 column which is A, B and C.
- A has duplicate value which is serial number
- B is whether it fail the test or not
- C is the time for testing.
Is it possible with Excel to find time difference between time for first fail and pass?
I want to delete the data that have less than 12 hour so that I know the things don't need rework, just retest. I want to know the exact number of modules that need rework.
=IF(AND(B7 = "pass",B6 = "fail", A7 = A6),TEXT(C7-C6, "h:mm"), "")
To get the difference between last fail and pass use this formula in cell D7. If the cell in column B is pass and previous cell was a fail, it will work out the time difference between the previous cell that was a fail. It will also check that the cell in column A matches previous cell in column A. Can also try using Index / Match or Vlookup to get the first fail by formula. As Tim Williams said a pivot table will also help. I don't use them much, so I'm not sure how to get the time difference with a pivot table, but it'll make viewing the data easier.
You could also try adapting this formula, by nesting conditions to get the previous cell that is the first fail. Work out the maximum number of cells between a pass and a first fail, and nest it that many times. If there are cases where the fail time is later than the pass it will throw an error. If you have multiple consecutive pass cells, for the same element you'd need to add more conditions to account for that, but if there's only 1 pass per element this should work.
=IF(AND(B7="pass",B5="fail",A7=A5),TEXT(C7-C5,"h:mm"),IF(AND(B7="pass",B6="fail",A7=A6),TEXT(C7-C6,"h:mm"),""))

Transpose multiple occurrences

EDIT: I have revived the source data source to remove the ambiguity of my last screen shots
I am trying to transpose spreadsheet data where there are many rows where the customer name may be duplicated but each row contains a different product.
For instance
revised original data source
to
revised proposed data format
I would like to do it with formulae if possible as I struggle with VB
Thank you for any help
I realise this is a huge answer, apologies but I wanted to be clear. If you need anything from me, drop me a comment and I'll help out.
Here's the output from my formula:
EDITED ANSWER - Named ranges used for ease of understanding:
These are just an example of a few of the named ranges I have used, you can reference the ranges directly or name them yourself (simplest way is to highlight the data then put the name in the drop down next to the formula bar [top left])
Be wary that as we will be using Array formulas for AccNum and AccType, you will not want to select the entire column and instead opt for either the exact data length or overshoot it by 100 or so. Large array formulas tend to slow down calculation and will calculate every cell individually regardless of it being empty.
First formula
=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Account Number ",LEFT((COLUMN(A:A)+1)/2,1)),"")
This formula is identical to the one in the original answer apart form the adjusted heading title.
=IF(Condition,True,False) - There are so many uses for the IF logic, it is the best formula in Excel in my opinion. I have used to IF with COUNTIF to check whether there is more than 0 cells that are more than BLANK (or ""). This is just a trick around using ISBLANK() or other blank identifiers that get confused when formula is present.
If the result is TRUE, I use CONCATENATE(Text1,Text2,etc.) to build a text string for the column header. ROW(1:1) or COLUMN(A:A) is commonly used to initiate an automatically increasing integer for formulas to use based on whether the count increase is required horizontally or vertically. I add 1 to this increasing integer and divide it by 2 so that the increase for each column is 0.5 (1 > 1.5 > 2 > 2.5) I then use LEFT formula to just take the first digit to the left of this decimal answer so the number increases only once every 2 columns.
If the result is FALSE then leave the cell blank ,""). Standard stuff here, no explanation needed.
Second Formula
=CONCATENATE(INDEX(Forename,MATCH(Sheet4!$A2,Reference,0)))
=CONCATENATE(INDEX(Surname,MATCH(Sheet4!$A2,Reference,0)))
CONCATENATE has only been used here to force blank cells to remain blank when pulled by INDEX. INDEX will read blank cells as values and therefore 0's whereas CONCATENATE will read them as text and therefore "".
INDEX(Range,Row,Column): This is a lookup formula that is much more advanced than VLOOKUP or HLOOKUP and not limited in the way that they are.
The range i have used is the expected output range - Forename or Surname
The row is then calculated using MATCH(Criteria,Range,Match Type). Match will look through a range and return the position as an integer where a match occurs. For this I have set the criteria to the unique reference number in column A for that row, the range to the named range Reference and the match type as 0 (1 Less than, 0 Exact Match, -1 Greater than).
I did not define a column number for INDEX as it defaults to the first column and I am only giving it one column of data to output from anyway.
Third Formula
Remember these need to be entered as an array (when in the formula bar hit Ctrl+Shift+Enter)
=IFERROR(INDEX(AccNum,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0))),"")
=IFERROR(INDEX(AccType,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))),"")
As you can see, one of these is used for AccNum and the other for AccType.
IFERROR(Value): The reason that this has been used is that we are not expecting the formula to always return something. When the formula cannot return something or SMALL has run out of matches to go through then an error will occur (usually #VALUE or #NUM!) so i use ,"") to force a blank result instead (again standard stuff).
I have already explained the INDEX formula above so let's just dive in to how I have worked out the rows that match what we are looking for:
SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))
The IF statement here is fairly self explanatory but as we have used it as an array formula, it will perform =Sheet4!$A2 which is the unique reference on every cell in the named range Reference individually. In your mock data this returns a result of: {FALSE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE} for the first entry (I included titles in the range, hence the initial FALSE). IF will do my row calculation* for every true but leave the FALSEs as they are.
This leaves a result of {FALSE;2;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE} that SMALL(array,k) will use. SMALL will only work on numeric values and will display the 'k'th result. Again the column trick has been used but to cover more ground, I used another method: ROUNDDOWN(Number,digits) as opposed to using LEFT() Digits here means decimal places so I used 0 to round down to a whole integer for the same result. As this copies across the columns like so: 1, 1, 2, 2, 3, 3, SMALL will alternatively (as the formulas alternate) grab the 1st smallest AccNum then the 1st Smallest AccType before grabbing the 2nd AccNum and Acctype and so forth.
*(Row number of the match minus the first row number of the range then plus 1, again fairly common as a foolproof way to always get the correct row regardless of where the data starts; actually as your data starts on row 1 we could just do ROW(Reference) but I left it as is incase you had data in a different format)
ORIGINAL ANSWER - Same logic as above
Here's your solution in 3 parts
Part 1 being a trick for the auto completion of the titles so that they will hide when not used (in case you will just copay and paste values the whole lot to speed up use again).
=IF(COUNTIF(C2:C11,">""")>0,CONCATENATE("Product ",LEFT((COLUMN(A:A)+1)/2,1)),"") in C
=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Prod code ",LEFT((COLUMN(B:B)+1)/2,1)),"") in D
Highlight both of the cells and drag across to stagger the outputs "Product " and "Prod code "
Part 2 would be inputting the unique IDs to the new sheet, I would suggest copying your entire column A across to a new sheet and using DATA > REMOVE DUPLICATES > Continue with current selection to trim out the multiple occurrences of unique IDs.
In column B use =INDEX(Sheet2!$B$1:$B$7,MATCH(Sheet4!$A2,Sheet2!$A$1:$A$7,0)) to get the names pulled across.
Part 3, the INDEX
Once again, we are doing a staggered input here before copying the formula across the page to cover the entirety of the data.
=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0)),1),"") in C
=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0)),2),"") in D
The formulas of Part 3 will need to be entered as an array (when in the formula bar hit Ctrl+Shift+Enter) . This will need to be done before copying the formulas across.
These formulas can now be dragged / copied in all directions and will feed off of the unique ID in column A.
My Answer is already rather long so I haven't gone on to break the formula down. If you have any trouble understanding how this works, let me know and I will be happy to write up a quick guide, breaking it down chunk by chunk for you.

I have multiple IDs for items, how can I use VLOOKUP to scan next column if it doesnt find it in the first?

Imagine my dataset has multiple IDs in columns, for the same item. How can I use VLOOKUP to scan the next column in the order up until it finds the same ID in another dataset? Or if it does not exist just stop searching after 6 columns? Thanks!
You could do this with 6 nested IFERROR statements; that would look like this: (Assuming your ID columns are A->F, your results column is G, and your search term is in J1):
=IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(VLOOKUP(J1,A:G,7,0),VLOOKUP(J1,B:G,6,0)),VLOOKUP(J1,C:G,5,0)),VLOOKUP(J1,D:G,4,0)),VLOOKUP(J1,E:G,3,0)),VLOOKUP(J1,F:G,2,0))
This looks at each column (starting with F and working outwards), and if it can't find a match, it creates an error, so goes to the next column. It is not very clean to read. A better way using this same methodology could be to use a combination of INDEX & MATCH, like so:
=INDEX(G:G,IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(MATCH(J1,A:A,0),MATCH(J1,B:B,0)),MATCH(J1,C:C,0)),MATCH(J1,D:D,0)),MATCH(J1,E:E,0)),MATCH(J1,F:F,0))
Though this is a little shorter [because we don't need to specify the entire block of data, or which column to pull from, as it always pulls from column G], it is still not very readable.
Let's try this instead using an Array Formula which runs the same function multiple times over many cells, gets the result for each cell, and provides an array of results. Then we just need to collapse that array into a single value, like so:
=INDEX(G1:G14,MIN(IFERROR(IF(SEARCH(J1,A1:A14&B1:B14&C1:C14&D1:D14&E1:E14&F1:F14)>0,ROW(A1:A14),""),"")))
Confirm this formula with CTRL + SHIFT + ENTER instead of just ENTER. This adds all strings of all search columns together, basically making a single column of values. It then takes that column, and searches each cell for the word found in J1. If it finds it, it returns that row number, otherwise it returns "". The function then uses MIN to take the lowest row number found (to tie-break to the earliest row, if there is a duplicate), and then uses that with INDEX to return the value from that row in column G.
Note that the logic here is a little different from the options I gave above, as it defaults to the earliest row #, rather than the earliest column #, of a match.

Count max value (text+number) occurrences with filtering a specific part of text in excel

I'm having an excel column range (including blank cells) something like:
00EGB00-GE001
00EGB00-GE001
00EGB00-GE001
00EGB00-GE001
00EGB00-GE002
00EGB00-GE002
00EGB00-GE002
00EGB00-GE002
00EGD20-GD101
What I need is to Count total number of similar values and I'm stuck with the logic for counting total unique "similar" values... example "GE" & "GD" separately.
How to count total number of unique "GE" values in the list?
I thought =COUNTIF(B:B,"*GE*") should work but it does not. It gives total count of "GE" but I need to find unique count. Example GE001 & GE002 should be considered as 2 values in total.
Kindly help
EDIT AGAIN: Given further clarification below, and assuming that the data always has the same number of digits, one way to do it is by putting this in Column B:
=RIGHT(A1,5)
Then, if you have Excel 2007 or up, Copy and Paste Values and use Remove Duplicates to leave you with the unique values. Then remove the items with GD, either manually or using a formula.
In this case, the output is:
GE001
GE002
In this case, you can easily see that it's 2. If you have lots of values, you can use COUNTA. Is that what you want?
YET ANOTHER EDIT BASED ON LAST COMMENT: this is probably getting closer:
=SUMPRODUCT(--(MID(A1:A9,9,2)="GE"),1/COUNTIF(A1:A9,A1:A9))
Where the "GE" is hard-coded in the formula above you could also substitute a cell reference where you can alter the value.
Or, if you don't know where the text you want will be exactly because the number of characters change, this will work (but you'd need to be careful with what you were searching on because it might repeat somewhere else in the string):
=SUMPRODUCT(--(ISERR(SEARCH("GE",A1:A9))<>TRUE),1/COUNTIF(A1:A9,A1:A9))
Again, you can replace the "GE" with a cell reference.
As discovered below, though -- blank cells will cause this to fail. There IS almost definitely a way to cater for them (maybe using a FREQUENCY based Array Formula), but if you can live with cleaning out the blank cells then that would be one way of doing it.
LAST EDIT: this will account for blank cells. It is an Array Formula, and CAN be used on whole columns, but that will be quite slow as it takes up a fair bit of calculation effort:
{=SUMPRODUCT(--(MID(A1:A9,9,2)="GE"),IF(ISBLANK(A1:A9),1,1/COUNTIF(A1:A9,A1:A9)))}
As it's an Array Formula, use Ctrl + Shift + Enter to input it.

excel 2007 duplicate row

How can I compare records in a table, to make sure these records are not duplicates? Using excel 2007 I don't won’t them to delete after comparison.
Duplicates rows should be colored. I have a table columns are from A to P and I have 500 rows. I want to put condition on A, B, E, F, G, I.
If you don't want to sort your column, you can try with a matrix formula (http://www.stanford.edu/~wfsharpe/mia/mat/mia_mat4.htm).
Practically, you can compare your current row to every row above. Somtething like :
=MIN(LINE(B1)*(IF(A2=A1;1;0))*(IF(B2=B1;1;0)))*(...)
validated with CTRL-SHIFT-ENTER will check if all the conditions are true, else, will return 0.
Please send a file (with anonymous data) if you want a practical example.
Hope that helps
Edit : here is the good solution (provided you want to compare data in the Q column) :
=MIN(LIGNE($Q$5:Q6)*EQUIV(Q6;$Q$5:Q6;0))
If you want to have the first line where the value appear
=MIN(LIGNE($Q$5:Q5)*EQUIV(Q6;$Q$5:Q5;0))
If you'd rather have #N/A if there are no duplicate before that line
Still validate with CTRL-SHIFT-ENTER
Sort by the columns you are interested in then use a formula to compare each row with the one above. You can then use conditional formatting to colour the results.
I may sound stupid here, but usually the simple answers are usually the best.
I did this recently, by literally using the CONCATENATE() function with the TEXT() function to combine all the columns I wanted to compare into a single cell. So in effect I am creating a cell with a unique "key" that holds all the data I want to be unique.
I then sort that column and create another empty column next to it.
Then us this formula to compare the row with the row above it: =IF(A2=A1,0,1)
This simply puts a 0 where it's the same row and a 1 where it's different.
I then filter on the '1's and there are my duplicates!
It'a also usefull as an alternative way of doing a unique COUNT(DISTINCT ...) where I want to count how many unique references of my data exists. SUBTOTAL(3...) is not enough.

Resources