On Sheet 1, I have a master list of data, with corresponding attributes. Some data has more than one attribute, some has only one, and there is a possibility of blanks. Attributes can be repeated when assigned to a different name.
I've posted some example data below, so we can all talk about the same cells/names etc.
On Sheet 2, there is much more freeform data input/analysis going on. Users are able to select a 'Name' from a dropdown menu using Data Validation, and are then able to select from the available attributes corresponding to that name, again using a dropdown menu. Names and attributes can appear in any order on Sheet 2.
It is important that all pairings are considered in the second worksheet.
Is it possible to use conditional formatting to highlight the 'Name' field (on Sheet 2) until at least one row exists with all possible pairings? In the example below, you can see that we have forgotten to put any info relating to the fact that Sally is Happy, and consequently 'Sally' has been highlighted to draw attention to the fact that there is some missing information.
Current thoughts:
I already have a list of the attributes that match the corresponding name- this is what drives the dropdown menu on Sheet 2, and is generated in a background sheet when a name is picked on Sheet 2. I can count the non-blank cells in this range to find out the total number of pairs that are required.
I would like to then count the number of non-duplicate attributes that are on rows that have the same Name as the current row, and compare this value.
I'm expecting this to get into the realms of array formulae, but may be wrong...
I'm also expecting array formulae to not work directly with conditional formatting, and to require the use of a 'helper column' to drive the formatting. Let me know if this is incorrect?
Something along the lines of the below (formatted as pseudo-code for readability, but this should be read as a high level description, not actual code)
{Count the 1s in the array(AND(
'Check if it's a name match'
If($D$1:$D$10=[$ACurrent],[set flag to 1],[set flag to 0])
'Check if it's a unique value'
[somehow check array values set at 1 to see if there is a duplicate value in column E, and then set the array value to zero if so])
}
Does this approach make sense, and how would I go about constructing this actual formula?
I don't mind using VBA if required, but would prefer to avoid it if possible (company policy, sorry).
Well, you want to highlight value Sally, Happy if that value does not appear in Sheet2, so you just need a COUNTIFS
COUNTIFS function
I've got this:
I've used a Conditional Formatin Rule based on my own formula. The formula I've used is:
=IF($B2="";IF(COUNTIFS($F$2:$F$12;$A2;$G$2:$G$12;"")=0;TRUE;FALSE);IF(COUNTIFS($F$2:$F$12;$A2;$G$2:$G$12;$B2)=0;TRUE;FALSE))
There are 2 COUNTIFS, because blank values are possible:
IF(COUNTIFS($F$2:$F$12;$A2;$G$2:$G$12;"")=0;TRUE;FALSE) will count how many rows got same name and non blank attributes in Sheet2. If 0, then it will return True and highlight row.
IF(COUNTIFS($F$2:$F$12;$A2;$G$2:$G$12;$B2)=0;TRUE;FALSE) will count how many rows got same name and blank attributes. If 0, then it will return True and will highlight
With the initial IF you can blanks or non blanks attributes, just to make sure you count all posibilities of values.
I've uploaded a sample to mi Gdrive in case you want to download and get the formulas autotranslated opening at your PC.
https://drive.google.com/open?id=1Im4LoaK4EIvINBj7tfyEcYk9juWUp7zr
Hope you can adapt this to your needs.
#Foxfire And Burns And Burns helped me to solve my problem - I have modified his formulae slightly, to remove the double COUNTIFS, and to account for rows in the master data where both cells are blank - below is what I used.
=IF (OR($A2<>"",$B2<>""),
(IF(COUNTIFS($D$2:$D$12,$A2,$E$2:$E$12,IF($B2="","",$B2))=0,TRUE,FALSE)
)
)
This works by returning TRUE or FALSE from the following logical checks - if the final result is TRUE, then the formatting appears.
OR($A2<>"",$B2<>"") - Checks is either of the cells in the master are not blank. - If both cells are blank, this returns FALSE, and does not format anything (see A10:B10).
IF(COUNTIFS($D$2:$D$12,$A2,$E$2:$E$12,[see point 3])<1,TRUE,FALSE) - This counts the number of times that both the range $D$2:$D$12 contains the value of cell $A2, AND the range $E$2:$E$12 contains the value of cell $B2. If that number is <1, (zero matches), then the statement returns TRUE and implements the formatting.
IF($B2="","",$B2) - This nested IF statement checks if Cell $B2 is blank, and returns "" if it is blank, or keeps the value of $B2 otherwise. This is because COUNTIFS would see the cell as a 'zero' when blank otherwise (see A9:B9).
I have not used a similar nested if to check if $A2 is blank, because it should not be blank, so it's useful to highlight that the user has made an error in data entry here, too (see A2:B2 - this will remain red once the user inputs a name, as it will no longer match D2:E2.)
Reference image below:
Related
How to write a formula in excel that based on critria it can check if list of multiple result cells have same value.
I attached example:
Look for all cell with the number 100
Verify that the list of these cells contain same date value of one cell.
I try to use formula such as: COUNTIF + INDEX and MATCH but didn't work as expacted.
I'm guessing you can use =ROWS(FILTER(....)) but what I would do is create a hidden column that evaluates it per row, maybe with something like
=IF(A2="","",XLOOKUP(A2,A$2:A,B$2:B)=B2)
and copy that formula down the column.
This way, you can not only see if there are any bad values (by COUNTIFS for false values where the A-column's value matches the "find these cells" value) but apply conditional formatting as well to highlight the bad values.
I am trying to figure out a formula to find the first non blank cell with data on a separate tab from where I need the value returned. I've tried the following formula but no luck: =INDEX(Sheet2!H:H,MATCH(1,Sheet2!A:A=Sheet1!A3)*Sheet2!H:H<>"",0)
On Sheet 1 under column "Value from Sheet 2" I need the value from Sheet 2 under column H that is not blank using Sheet 1's "Name" column as the reference, in this case value "123" is the first non blank cell for name "ABC" on Sheet 2.
Thank you
In your data above, =sheet2!A$3:A$6=A3 is going to return {true;false;false;true}.
Further, =NOT(ISBLANK(sheet2!H$3:H$6)) is going to return {false;true;true;true}.
Thus, =(sheet2!A$3:A$6=A3) * (NOT(ISBLANK(sheet2!H$3:H$6))) should get you the array {0;0;0;1}, which is what you want to lead you to desired cell.
=MATCH(1, (sheet2!A$3:A$6=A3) * (NOT(ISBLANK(sheet2!H$3:H$6)))) gets you the index to the first hit, which is 4, and using that as in index into H$3:H$6 gets you all the way home.
But I’d exploit the more useful features of XLOOKUP instead and I resort to index/match only when required—which is pretty rare now that XLOOKUP exists:
=XLOOKUP( 1, (sheet2!A$3:A$6=A3) *
(NOT(ISBLANK(sheet2!H$3:H$6)))), sheet2!H$3:H$6)
One fewer functions, AND it adds the ability to handle a not-found condition.
This all should still work if you just decided to use A:A and H:H as in your previous formula.
I'm trying to do something similar in vba which I have an idea of only in python for loops. Can someone teach me how to do this in vba, either in function or module macro please :
For each distinct values in column A4:A30, there should be no more than 9 distinct values in column C4:C30. If true, return 'OK' in cell A1. if false, return 'Error' in cell A1'
e.g As in the picture, Sam should not have more than 9 distinct fruits. Same goes to Mary
Update :
I have tried the filterxml method and unfortunately didn't seem work for me : [1] https://i.stack.imgur.com/cbmTs.png
Solution for excel with filter/unique formulas
Easiest way to achieve it in Excel365 is: add extra column which counts unique values (Fruits) for each Key (Names) and find maximum value in this column
Start with formula that find each non-blank which fits the key.
=FILTER($C$4:$C$30,($A$4:$A$30=A4)*($C$4:$C$30<>""))
Then delete duplicates:
=UNIQUE(FILTER($C$4:$C$30,($A$4:$A$30=A4)*($C$4:$C$30<>"")))
Then check how many cells we have in filtered data without blanks and duplicates:
=COUNTA(UNIQUE(FILTER($C$4:$C$30,($A$4:$A$30=A4)*($C$4:$C$30<>""))))
Then expand our new-column (column B in my case) formula to each row in our Keys.
And finally add formula to A1 which checks maximum counter:
=IF(MAX($B$4:$B$30)<10,"OK","Error - to many velues")
*There is a little typo, it should be "Error - to many values" =)
Below how the worksheet looks in my testfile
Solution for older versions of excel
I've checked if i am able to make it works without these formulas and it is possible:
We need to start with counting if there is for key-value above current row
=COUNTIFS($A$4:A4,A4,$C$4:C4,C4)
In case we have duplicates above, they should be already counted so we skip them:
=IF(COUNTIFS($A$4:A4,A4,$C$4:C4,C4)>1,"",1)
Now we have colum with "1" or blanks. In that case we need to count each non-empty cell above which correct key (name) and add 1 so instead "" and "1" we will have "" or 1, 2, 3, 4, ...
=IF(COUNTIFS($A$4:A4,A4,$C$4:C4,C4)>1,"",COUNTIFS($A$3:A3,A4,$F$3:F3,">0")+1)
Edit
I have added one extra IF to skip keys if value is blank:
=IF(C4="","",IF(COUNTIFS($A$4:A4,A4,$C$4:C4,C4)>1,"",COUNTIFS($A$3:A3,A4,$B$3:B3,">0")+1))
Cells Formula in A1 is the same
=IF(MAX($B$4:$B$30)<10,"OK","Error - to many values")
Quick Note:
Some formulas have range which starts on 3rd row instead of 4th; Its intended because we are counting cells above and at first row of data we need to have choose something above. This code assumes that you don't have numbers (on column B) or names (on column A) in row 3;
Below I am attaching screen with example; This screen have additional columns (D-F) which isn't required, its only do display how final formula was created.
I have the following formula to make a unique list from column plant in table 15:
{=IFERROR(INDEX(Tabel15[Plant];MATCH(0;COUNTIF(Analyses!$Q$2:$Q2;Tabel15[Plant]);0));"")}
This formula is working, but when there is just 1 value in column plant the formula gives a value of 0. This is wrong because it should return the value.
Does anyone know how I can adapt this formula to make it work?
I wanted to change it to this:
{=IF(COUNTA(Tabel15[plant])>0;INDEX(Tabel15[Plant];MATCH(0;COUNTIF(Analyses!$Q$2:$Q2;Tabel15[Plant]);0));Kopie - datablad$G$2)}
But it doesn't work either.
Good mock example. Try and see if this works:
The formula counts the unique cells against another list. The unique list expects to take the first row, no matter what. It also expects you to have more than one value in your duplicate list. If it doesn't you can't compare since it expect duplicates and it throws an error, #N/A. This is mask as blank cell since it's wrapped in IFERROR:
"Unique formula" = IFERROR(INDEX(Tabel15[Plant],MATCH(0,COUNTIF($Q$1:Q2,Tabel15[Plant]), 0)),"")
To solve this we check how many values it exist in our duplicate list:
=IF(COUNTA(Tabel15[Plant])>1,... "Unique formula" ... ,Tabel15[Plant]) //***//
This will give us this result.
Then you probably don't want duplicates...
So we need to check if previous rows contain any of the values the formula would return.
The VLOOKUP formula do that for us, and as lookup value we use the formula above //***// and lookup range will be our current column: $Q$1:Q2. NOTICE this is a dynamic range so Q2 is relative reference (no $).
=IF(ISERROR(VLOOKUP(IF(COUNTA(Tabel15[Plant])>1,IFERROR(INDEX(Tabel15[Plant],MATCH(0,COUNTIF($Q$1:Q2,Tabel15[Plant]), 0)),""),Tabel15[Plant]),$Q$1:Q2,1,FALSE))
So the Final result we need to apply is this in Cell Q3:
=IF(ISERROR(VLOOKUP(IF(COUNTA(Tabel15[Plant])>1,IFERROR(INDEX(Tabel15[Plant],MATCH(0,COUNTIF(Analyses!$Q$1:Q2,Tabel15[Plant]), 0)),""),Tabel15[Plant]),Analyses!$Q$1:Q2,1,FALSE)),IF(COUNTA(Tabel15[Plant])>1,IFERROR(INDEX(Tabel15[Plant],MATCH(0,COUNTIF(Analyses!$Q$1:Q2,Tabel15[Plant]), 0)),""),Tabel15[Plant]),"")
The macro error can be ignored by:
If Not IsError(Sheets("Hulpblad").Range("B6").Value) Then
t = Sheets("Hulpblad").Range("B6").Value
'Code...
End If
there is no problem in your formula, it is just telling that there are blanks in the range, 0 means blank. the formula is treating the blank as a value and also considering it in the unique value calculations.
If you want to remove 0 you can just insert an if over your formula to remove it. like
=if(formula = 0, "", formula)
or in orignal form
=IF( (IFERROR(INDEX(Tabel15[Plant],MATCH(0,COUNTIF(Analyses!$Q$2:$Q2,Tabel15[Plant]),0)),""))=0,"",IFERROR(INDEX(Tabel15[Plant],MATCH(0,COUNTIF(Analyses!$Q$2:$Q2,Tabel15[Plant]),0)),""))
or go in the cell formatting and change the format to display 0 as a dash.
sometimes blank is also used as error checking, you can apply such formulae as well to check how many are blank, maybe that would someday be used to check any data entry problems.
I am trying to get some code working but when I change a target cell into a range of cells I get an error #VALUE!
this code works
=IF(AND(A1=Sheet2!A2,B1=Sheet2!B2),"TRUE","FALSE")
but if I add a range I get #VALUE! Error
=IF(AND(A1=Sheet2!A2:A10,B1=Sheet2!B2:B10),"TRUE","FALSE")
Update : Here is an example of what I am trying to achieve
Any help would be much appreciated
Many Thanks,
And
Different approach from your logic statement. Instead it looks through your table and match the name with the row and the column with the date selected and the pulls the value at that location.
=INDEX($B$7:$G$8,MATCH($B3,$A$7:$A$8,0),MATCH(C$1,$B$6:$G$6,0))
IMPORTANT: The names in you B3:B4 area have to be unique and spelled identical to your A7:A8 area. That included trailing or leading spaces that you may accidentally drop in.
Adjust reference ranges to match your need if tables are on different sheets of your workbook.
THIS IS AN ARRAY FORMULA - Hit Ctrl+Shift+Enter While still in the formula bar
=INDEX(B2:B10,SMALL(IF(A2:A10=A1,IF(B2:B10="ONCALL",ROW(A2:A10)-1)),1))
=INDEX(B2:B10, - Look through B2:B10 and return the row number calulcaulated by:
SMALL(IF(A2:A10=A1,
IF(B2:B10="ONCALL",
ROW(A2:A10)-1)),1))
This is building an array of row numbers minus 1 where both IF statements are true (Date matches and "ONCALL" present), SMALL then returns the nth value in ascending order - I have asked for the 1st match (or the smallest row number) which INDEX then uses to return the result.