I have a formula that uses the below SUMPRODUCT:
=SUMPRODUCT((Data!X:X = 0)* ((Data!H:H =A1)+IF(IFERROR(SEARCH(A1, Data!J:J), 0), 1, 0))* (Data!U:U = A14)(Data!M:M >= C2)(Data!N:N
<=B3))
The issue I'm having is the with the OR part:
((Data!H:H =A1)+IF(IFERROR(SEARCH(A1, Data!J:J), 0), 1, 0)).
The issue is it not working and I'm really not sure I'm going about this right. The logic I'm shooting for:
if the value in A1 equals any data in cells Data!H:H use it,
or
if not, check Data!J:J.
any help would be great.
As follow up from comments, this one work:
=SUMPRODUCT(
(Data!X:X = 0)*
(Data!U:U = A14)*
(Data!M:M >= C2)*
(Data!N:N <=B3)*
IF((Data!H:H=A1)+ISNUMBER(SEARCH(A1,Data!J:J)),1,0)
)
evaluates with CTRL+SHIFT+ENTER
SEARCH(...) reutns either number either #VALUE!, so ISNUMBER(SEARCH(...)) gives you TRUE if value found and FALSE if value not found
Related
I am having an issue with VLookup in my VBA code. When I didn't have the range as a dynamic size using CurrentRegion it worked flawlessly, now for whatever reason, it only works for a single loop over and fails at the first VLookup. I have tried with and without the with block. I have a variable that will replace the 5 in the for loop and works but have kept it as its original so that isn't affecting it.
I apologize if this is a duplicate but I could not find an answer. Any help would be appreciated.
Set jobTypeData = Worksheets("JobType").Range("A1").CurrentRegion
For i = 1 To 5
jobTypeTemp = Worksheets("Employees2").Cells(i + 1, 16).Value
jobRoleTemp = Worksheets("Employees2").Cells(i + 1, 17).Value
'Creates variables relevant to the job type
With Worksheets("JobType")
minHours = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 2))
maxHours = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 3))
minShift = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 5))
maxShift = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 6))
shiftGap = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 7))
End With
There is more code under this but it all works a-okay and worked fine before using the dynamic data size.
The code that works does not change the contents or size of jobTypeData.
I have also checked the values VLookup returns and they are all correct. The only thing I can think of is that it can't find the second jobType however I have checked and they are identical (no hidden spaces).
The answer appears to be related to the way VLookup uses 'approximate match'.
I always thought VLookup would still provide the exact match if it was an option and because I had strict data validation I never thought using approximate match would be a problem. However, turns out, it's not just mildly unpredictable, but actually unreliable.
After checking it was assuming "Role Name" was a closer match to "Team Manager" than "Team Manager". Upon changing it to using 'exact match', everything worked fine. No changes to the code which worked before either.
Well, lesson learned...
When you have an exact match ALWAYS use (no matter how confident you are, use me as an example):
VLOOKUP(arg1, arg2, arg3, FALSE)
Not:
VLOOKUP(arg1, arg2, arg3)
I'm testing an Excel formula that returns Boolean (True or False)
This one works fine:
=OR(ISBLANK(B2),AND(LEN(B2)=12,ISNUMBER(SUMPRODUCT(FIND(MID(B2,ROW(INDIRECT("1:12")),1),"0123456789abcdefABCDEF")))))
Now I want to reverse the result. So I wrap a NOT() around it. But Excel won't take it. Why? Thanks!
=NOT(OR(ISBLANK(B2),AND(LEN(B2)=12,ISNUMBER(SUMPRODUCT(FIND(MID(B2,ROW(INDIRECT("1:12")),1),"0123456789abcdefABCDEF"))))))
To validate a MAC address (or find non-valid ones) split the address into 2 hexadecimals of 6 each and attempt a HEX2DEC conversion.
'validate
=OR(LEN(B2)=0, AND(LEN(B2)=12, IFERROR(HEX2DEC(LEFT(B2, 6))*HEX2DEC(RIGHT(B2, 6)), FALSE)))
=OR(LEN(B2)=0, AND(LEN(B2)=12, ISNUMBER(SUMPRODUCT(HEX2DEC(LEFT(B2, 6)), HEX2DEC(RIGHT(B2, 6))))))
'find non-valid
=NOT(OR(LEN(B2)=0, AND(LEN(B2)=12, IFERROR(HEX2DEC(LEFT(B2, 6))*HEX2DEC(RIGHT(B2, 6)), FALSE))))
=NOT(OR(LEN(B2)=0, AND(LEN(B2)=12, ISNUMBER(SUMPRODUCT(HEX2DEC(LEFT(B2, 6)), HEX2DEC(RIGHT(B2, 6)))))))
This is essentially what your original formula does but with less calculation load. tbh, I'm not sure why your NOT wrapper didn't work; it did for me.
Document: https://docs.google.com/spreadsheets/d/1N4cGw5eUq_3gCJh1w39qVatX9KV1_Hr-AqRHj_nbckA/edit#gid=1770960621
Question
How can I convert the following simple formulas at Schedule!C20:I29 into a single, simple ARRAYFORMULA at Schedule!C20?
=Count(Filter(Students!$B$5:$B, Find(C6, Filter(Students!$J$5:$O,Students!$J$4:$O$4 = 'Current Class'!$B$3))))
.
NOTE:
The above code is only a partial solution. I will substitute the ARRAYFORMULA version of the code into the correct part of the code at Current Class!L6
The C6 reference above can take on any cell between Schedule!C6:I15. I have named that range Timetable_Code. I thought I could do the following, but I was wrong...
=Arrayformula(Count(Filter(Students!$B$5:$B, Find(Timetable_Code, Filter(Students!$J$5:$O,Students!$J$4:$O$4 = 'Current Class'!$B$3)))))
Background
Originally, I created a table that now resides at 1st Version - Current Class!L6. This tab is only for your reference and will be deleted soon. Each cell has a formula with a slight modification. This formula works correctly; however, it is a behemoth and would be hard to modify...
=if(COUNTIF(Meta!$B$5:$B, CONCATENATE("=",if(L$5 = "THURSDAY", "TH", if(L$5 = "SUNDAY", "SU", left(L$5,1))), if(left($K6, 2) = "12", 0, left($K6, 1)))), CONCATENATE(if(L$5 = "THURSDAY", "TH", if(L$5 = "SUNDAY", "SU", left(L$5,1))), if(left($K6, 2) = "12", 0, left($K6, 1)), " ( ", Count(Filter(Students!$B$5:$B, Find(CONCATENATE(if(L$5 = "THURSDAY", "TH", if(L$5 = "SUNDAY", "SU", left(L$5,1))), if(left($K6, 2) = "12", 0, left($K6, 1))), Filter(Students!$J$5:$O,Students!$J$4:$O$4 = $B$3)))), " )") ,"")
.
Pros
I don't have to create any helper data.
All calculations are "in-memory"
Cons
Too large
Hard to modify
I like the output, but I don't like the cons, so I started to create a more edit-friendly version of the code that I am mostly OK with. This code is located at Current Class!L6 (and a secondary copy at Schedule!C33 - it will be deleted.) It has a single formula at Current Class!L6...
=arrayformula(if(COUNTIF(Meta!$B$5:$B, ("=" & Timetable_Code)), (Timetable_Code & " ( " & Timetable_StudentCount & " )") ,""))
.
Pros
Very easy to understand
Very easy to modify
No need to copy formula over to other cells
Cons
Two ( 2 ) helper tables were created ( one of which I think is unneeded)
Again, I like the output, but I really don't like the second helper table (Schedule!C20). I feel like this table can be eliminated, but I have not been able to figure out how.
If you really want to use arrayformula, here it is. For Schedule!C20.
=arrayformula((len(concatenate(index(Students!J5:O, , match('Current Class'!$B$3, Students!J4:O4, 0))))-len(substitute(concatenate(index(Students!J5:O, , match('Current Class'!$B$3, Students!J4:O4, 0))),C6:I15,"")))/len(C6:I15))
Probably you can use filter(as you did before) instead of index & match part, but I prefer index & match and don't want to dig more. Also you can use one help cell to store filter or index & match result to shorten the formula.
The core idea is from counting occurrences of given character in a string, ie len(a1) - len(substitute(a1, .... You can find many documents about it in the net.
Anyway, if I were you, I'd be satified with the current state. Just lock and hide the help tables or sheets. Nobody cares hidden sheets and if something bad happens, you can revert any change.
After getting a good answer from #Sangbok Lee, I decided to break apart each part of the function he gave to me. While doing that I found a highly unlikely connection to some work I did in the Google Sheets last week. A helper column I had in another tab kind of did what Sangbok Lee was trying to do. All I had to do was split that helper column into two columns (1 for the previous final calculation, 1 for) and calculate an additional count column
After reworking both of our formulas, and testing the result, I found a solution that I am even more satisfied with!
=arrayformula(if(countif(Meta!$B$5:$B, (Timetable_Code)), (Timetable_Code & " ( " & vlookup(Timetable_Code, StudentCount_Lookup, 2, false) & " )") ,""))
.
Check out the differences in the Google Sheet
Look at 1st Version - Current Class!L6 tab for the 1st version
Look at Current Class!L6 for the 2nd version
Look at Current Class!U6 for the 3rd and final version
Also look at tab Meta and Schedule for the differences.
Note: Green is old data, Red is new data
My code is this:
=IF(AND(C53=D53,C53="STI",D53="STI"),"No OR, Straight to IM",IF(AND(C53=D53,ISBLANK(C53),ISBLANK(D53)),"No Date Input",IF(AND(C53 = "Still Pending",D53>=DATEVALUE("1/1/2013")),"Error, Check Again",IF(AND(C53>=DATEVALUE("1/1/2013"),D53 = "Still Pending"),TODAY()-C53,D53-C53))))
When C53 is a date (ex:1/8/2016), and D53 is "Still pending", I believe it should return TODAY()-C53. Instead it returns D53-C53.
Can anyone help me with this logic?
I'm not sure why your formula wasn't working for you. I changed a few methods and functions for others but kept your logic intact.
=IF(AND(C53=D53, C53="STI"), "No OR, Straight to IM",
IF(COUNTBLANK(C53:D53)=2, "No Date Input",
IF(AND(C53 = "Still Pending", D53>=DATE(2013, 1, 1)), "Error, Check Again",
IF(AND(C53>=DATE(2013, 1, 1), D53 = "Still Pending"), TODAY()-C53,
IF(COUNT(C53:D53)=2, D53-C53, "not covered")))))
You can keep linefeeds in a formula to help organize it. Results as follows:
I am attempting to combine the if and mid functions in excel. If a value in a specific cell is true, then return the first six characters from another cell; otherwise return nothing. The following are the options I have tried:
=if(AA2=TRUE), MID(Y2,1,5), "")
=if(AA2=TRUE), MID(Y2,1,5), ""))
=if(mid(AA2=True), (Y2, 1, 5), "")
Could someone point out the errors in this syntax? I am new to programming and any help would be appreciated.
Thanks.
You close the parentheses too soon. Instead of
=if(AA2=TRUE), MID(Y2,1,5), "")
Try
=if((AA2=TRUE), MID(Y2,1,5), "")