I am trying to adapt the following formula (counting instances of values between 0 and 24):
=COUNTIFS(cancellations!AG2:AG408,">0",cancellations!AG2:AG408,"<24")
(formula evaluates to 75), to something like:
=COUNTIFS(cancellations!AG2:AG408,">0",cancellations!AG2:AG408,INDIRECT("" & "<" & B1*24 & ""))
but this evaluates to zero. (B1 = 1 in the above example.)
When I view the INDIRECT function inside the fx box it evaluates correctly. Not sure of what I am doing wrong.
When applied in a cell like so:
=INDIRECT("" & "<" & B1*24 & "")
It shows #REF!.
The INDIRECT function returns a reference to a range. You can use this function to create a reference that won't change if row or columns are inserted in the worksheet. Or, use it to create a reference from letters and numbers in other cells.
=COUNTIFS(cancellations!AG2:AG408,">0",cancellations!AG2:AG408,B1)
should work where B1 contains <24.
So, I read up the COUNTIFS() function in more detail and I found that the following works
=COUNTIFS(cancellations!AG2:AG408,">0",cancellations!AG2:AG408,"<"&B1*24)
Where:
B1=1
Related
I'm trying to do Vlookup for target data in different rows.
But unfortunately, I can't find the way to do it.
Vlookup, Hlookup can't get the target data correctly.
Can you advise?
Resource Data Sheet
Result Output (expectation)
Matching ID number consist of these target data.
Dim A As String
Dim B As String
Dim C As String
Dim D As String
Dim E As String
Dim F As String
A = Application.WorksheetFunction.Index(iSheet.Range("G1"), Application.WorksheetFunction.Match(iSheet.Range("A11"), iSheet.Range("A3:A5"), 0))
B = Application.WorksheetFunction.Index(iSheet.Range("I1"), Application.WorksheetFunction.Match(iSheet.Range("A11"), iSheet.Range("A3:A5"), 0))
C = Application.WorksheetFunction.Index(iSheet.Range("K1"), Application.WorksheetFunction.Match(iSheet.Range("A11"), iSheet.Range("A3:A5"), 0))
'*** Error Thrown On Next Line (unable to get the index property of the worksheetfunction class)
D = Application.WorksheetFunction.Index(iSheet.Range("G1"), Application.WorksheetFunction.Match(iSheet.Range("A12"), iSheet.Range("A3:A5"), 0))
E = Application.WorksheetFunction.Index(iSheet.Range("I1"), Application.WorksheetFunction.Match(iSheet.Range("A12"), iSheet.Range("A3:A5"), 0))
F = Application.WorksheetFunction.Index(iSheet.Range("K1"), Application.WorksheetFunction.Match(iSheet.Range("A12"), iSheet.Range("A3:A5"), 0))
iSheet.Range("C7").Value = A & ", " & B & ", " & C
iSheet.Range("C8").Value = D & ", " & E & ", " & F
You're on the wrong track with VLookup() and HLookup().
Try using this: (on multiple lines for readability purposes)
=TEXTJOIN(",",
TRUE,
IF(NOT(ISBLANK(I3)),"POWER", ""),
IF(NOT(ISBLANK(K3)),"MB", ""),
IF(NOT(ISBLANK(M3)),"ANT", "")
)
Let me explain:
TextJoin() concatenates information, based on:
"," : the delimiter to be used
TRUE: how to handle empty cells
the arguments to be concatenated
IF(NOT(ISBLANK(I3)),"POWER", ""): if I3 is filled in, you need to put the word "POWER". If not, put an empty string.
Are you looking for something like this?
Right... so, this will technically do what you have asked for. But I suspect that it may not be exactly what you actually want. I am afraid your original question was quite unclear and I have had to make some guesses/assumptions.
=CONCAT(
IF(INDEX($H$3:$H$5,MATCH($A11,$A$3:$A$5,0))<>"",$G$1 & ", ",""),
IF(INDEX($J$3:$J$5,MATCH($A11,$A$3:$A$5,0))<>"",$I$1 & ", ",""),
IF(INDEX($L$3:$L$5,MATCH($A11,$A$3:$A$5,0))<>"",$K$1 & ", ","")
)
The CONCAT function just adds strings together, one after the other.
Within it, we have one formula for each of your merged column headers.
Please note: If you have lots of column headers, this probably won't be a viable solution. However, making a formula to handle a dynamic number of headers would be far more complex and I would advise re-organising your data to allow use of a simpler formula instead.
So, the inner formula:
IF(INDEX($H$3:$H$5,MATCH($A11,$A$3:$A$5,0))<>"",$G$1 & ", ",""),
Similar to how VLOOKUP would, the INDEX/MATCH is returning the POWER reference number for the specific ID Num. If there is no Ref No., it returns an empty string. If there is a Ref No., this is returned along with a trailing comma and space.
This is repeated for each of your Ref columns, and then CONCAT sticks all the results together. This does leave a trailing comma, however, that is relatively simple to remove if required, and I will leave that for you to work out.
As for returning the Ref No.'s themselves this can be done in the same way, but instead of returning the header, you repeat the INDEX/MATCH formula:
=CONCAT(
IF(INDEX($H$3:$H$5,MATCH($A11,$A$3:$A$5,0))<>"",INDEX($H$3:$H$5,MATCH($A11,$A$3:$A$5,0)) & ", ",""),
IF(INDEX($J$3:$J$5,MATCH($A11,$A$3:$A$5,0))<>"",INDEX($J$3:$J$5,MATCH($A11,$A$3:$A$5,0)) & ", ",""),
IF(INDEX($L$3:$L$5,MATCH($A11,$A$3:$A$5,0))<>"",INDEX($L$3:$L$5,MATCH($A11,$A$3:$A$5,0)) & ", ","")
)
Why Not VLOOKUP?
You may wonder why I used an INDEX/MATCH formula, rather than a VLOOKUP formula.
VLOOKUP would work, however, INDEX/MATCH is better in literally every way. To my knowledge, there is NEVER a situation where VLOOKUP would be a better option.
INDEX/MATCH is faster. When you have hundreds or thousands of formulas, you can often speed up a workbook drastically simply by swapping out all of the VLOOKUPs.
INDEX/MATCH is more versatile. It can work on rows or columns and your lookup range can be anywhere. You can even lookup a value in a 2D table using INDEX/MATCH/MATCH.
INDEX/MATCH is more stable. Moving or re-ordering columns doesn't break your formulas.
INDEX/MATCH is easier to use. It may look confusing if you are used to VLOOKUP, but once you understand it, it is actually easier to use because you can directly reference the ranges, rather than counting the number of columns accross.
Cannot get SUM(SUMIF to work with VBA, yields “Run-time error 1004”. SUM(SUMIF is typically used in Excel to sum using multiple criteria.
This is my formula.
Worksheets("units").Cells(i, j).FormulaR1C1 = "=pws!R[0]C[0]+SUM(SUMIF(pws!R1C3:R1C" & (2 + numlxp) & ",central!C[1]R3:C[1]R" & (2 + numatt) & ",pws!R[0]C3:R[0]C" & (2 + numlxp) & "))"
I also tried a version using OFFSETS instead of R1C1. The OFFSETS versions works within Excel itself, but not in VBA.
I then tried simplifying to the below, to see if there was an issue with SUM(SUMIF specifically within VBA, but it returns a formula with # for implicit intersectionality and gives the wrong result ‘0’:
Worksheets("units").Cells(2, 2).Formula = "=SUM(SUMIF(pws!C1:L1,central!C3:C6,pws!C2:L2))"
Try using SUMPRODUCT combined with unary operator:
Yellow cells would be the criteria (in your case, central!C3:C6).
Formula in cell C6 is:
=SUMPRODUCT(--(COUNTIF($A$6:$A$7,$C$1:$L$1)>0)*$C$2:$L$2)
Formula in cell C7 is:
=SUMPRODUCT(--($C$1:$L$1=$A$6:$A$7)*$C$2:$L$2)
First formula ignore duplicates in criteria and second one does not. Second one is easier to implement but if your criteria has duplicate values, it will duplicate result, so watch out and choose wisely. Just as example, notice if both of my criterias are the same, each formula returns a different output:
Anyways, when you are done choosing, you should be able to implement this in VBA code like this (or kind of):
Worksheets("units").Cells(2, 2).Formula = "=SUMPRODUCT(--(COUNTIF(central!$C$3:$C$6,pws!$C$1:$L$1)>0)*pws!$C$2:$L$2)"
SUMPRODUCT and Double Unary
Operators
How can I substitute a cell reference for the formula it contains, in other words, "expand" or "derivate" cell references?
An example, and I know I could calculate it using PV(): Suppose I want to calculate the present value of a given amount, reductor, number of periods and discount rate and in a spreadsheet I have:
A2: 1 (number of periods)
B2: 5000 (amount)
C2: 0,8 (reductor)
G1: 6% (discount rate)
If I want to calculate the final result on D2, I would have to enter:
=(B2*C2)*(1+$G$1)^(-A2)
(I intentionally used some unnecessary parentheses above)
But if I wanted, for debugging, or for building a more complex formula with more nested calculations write on cells:
D2: =E2*F2^G2
E2: =B2*C2
F2: =1+$G$1
G2: =-A2
So that I could check every part of the calculation is working ok and that the final formula is well "assembled" (or to easily correct what might be wrong or change it to calculate something else, like future value, for which I would remove the minus sign on G2).
And after doing those steps use some function/shortcut/feature on cell D2 that would replace
"=E2*F2^G2"
for
"=(B2*C2)*(1+$G$1)^(-A2)"
(i.e. do E2 → (B2*C2) F2 → (1+$G$1) and G2 → (-A2)) so that the desired formula is built on the right place and I can get rid of the temporary cells.
The closest to this behaviour I could find was formulatext() function, but it works just for a single reference and always include the "=" if I do, for instance
=CONCAT(FORMULATEXT(E2);"*";FORMULATEXT(F2);"^";FORMULATEXT(G2))
results in
=B2*C2*=1+$G$1^=-A2
which is not the desired result.
What I was expecting to find was something like when one select a part of a formula and presses F9 and it substitutes it for the value, but applied for functions or intermediate steps.
As it really does not seem to exist a built-in funcion on Excel, I came out with a script for doing this based on the answer on Parsing and extracting cell references from Excel formulas?
Works on Excel 365 (may work on other versions as well), replaces references on active cell only, does not work on cells that contain intervals (for instance, it will fail on a cell that contains =sum(A1:A5) ) and the contents of the precedent cells will end up enclosed in parentheses. It also does not replace "locked" cells (=$B$2 won't be replaced as well).
In summa, it is not perfect, maybe it's not ellegant too, but it seems to be as good as I needed and works on the proposed scope.
Sub ReplacePrecedents()
Dim r As Range, rr As Range
With ActiveCell.Range("A1")
' store the contents of the cell
parsedcontents = .Formula
Set r = .DirectPrecedents
' iterate throughout all precedents
For Each rr In r
' store each one between parentheses
appendstr = "("
' check whether first character is a "=" or a value
If StrComp(Left(rr.Range("A1").Formula, 1), "=") = 0 Then
appendstr = appendstr & Right(rr.Range("A1").Formula, Len(rr.Range("A1").Formula) - 1)
Else
appendstr = appendstr & rr.Range("A1").Formula
End If
appendstr = appendstr & ")"
' do the magic
parsedcontents = Replace(parsedcontents, rr.Address(0, 0), appendstr)
Next rr
' write the parsed string to the cell
.Formula = parsedcontents
End With
End Sub
Thank you for everyone that replied, I guess I still do not have privileges enough to upvote a comment, as soon as I do, I will.
I'm trying to use Application.Evaluate method for evaluating a Sumif formula in which the criteria is ">="
Following is the line of code I'm trying to get an evaluation of
So I have Order Numbers 1 to 15 in Cell E1 to E15, and their Respective Amounts in Cell F1 to F15.
In J1 the user inputs his Order Number. Amount over and above that order number will be totaled and displayed using Sumif Function.
Now I want to find this answer using Application.Evaluate
MsgBox( Application.Evaluate("=SUMIF(E1:E15, ">=" & J1, F1:F15)"))
I get greeted with True or False Message Box.
Now I am guessing the inverted commas in Sumif Function ie. ">=" is causing this problem. Hence to fix this, I amended the function to
MsgBox( Application.Evaluate("=SUMIF(E1:E15, """">="""" & J1, F1:F15)"))
However now it returns 0, although there are values in it.
I would really appreciate if someone could help me understand a way around it
*Note: Please do not suggest to use any other function. I want to know it purely from Application.Evaluate perspective, as my further line of code depends on it. *
Thanks.
All quotes inside the string must be doubled:
">="
Should be
"">=""
Also:
Application.Evaluate
will work on the active sheet, thus if the wrong sheet is active the sumifs will be done on the wrong sheet since no sheet names are provided in the formula itself.
Use
Worksheets("Sheet1").Evaluate
Changing "Sheet1" to your sheet.
So in total:
MsgBox Worksheets("Sheet1").Evaluate("=SUMIF(E1:E15, "">="" & J1, F1:F15)")
I am trying to create a reference to a separate sheet using INDIRECT. I also want to check this for errors, so I preface the thing by using ISERROR.
H1 is a date value, formatted as "nn m.d". In this case, 42574 returns Sat 7.23
'Sat 7.23'.D2 equals 100
Let's say there's a tab named "Sat 7.23", and I would like to access cell D2. Using INDIRECT and converting the formatted date to text, I create this formula:
=INDIRECT("'" & TEXT(H1, "nn m.d") & "'.D2")
In other words, INDIRECT tells me to make the following reference:
='Sat 7.23'.D2
When the tab exists, this functions perfectly (it returns 100). But... what if the tab doesn't exist? INDIRECT returns #REF!, which is to be expected. So, I throw an ISERROR in front of it:
=ISERROR(INDIRECT("'" & TEXT(H1, "nn m.d") & "'.D2")
This returns nothing (or I guess FALSE), even though INDIRECT is generating a #REF! error and therefore should be TRUE. Should it not?
To go further:
=IF(ISERROR(INDIRECT("'" & TEXT(H1, "nn m.d") & "'.D2")),0,INDIRECT("'" & TEXT(H1, "nn m.d") & "'.D2"))
In this case, ISERROR is always true, so this IF always goes to it's "else" statement. Since the reference is invalid, the whole IF statement returns #REF!
I'm not sure what regional language uses nn to represent Sun - Sat in a format mask but ddd is used in an EN-US system and there is an exclamation mark between the worksheet and the cell address.
=IFERROR(INDIRECT("'"&TEXT(H1,"ddd m.d")&"'!D2"), 0)
This will return zero when copied to one cell above (#REF! on H0 as a cell address).
Some amends as proposed below should help you see through the issues:
Change the custom format of cell H1 which has the date value to "ddd m.dd" without the quotes. I see you have used "nn m.d" and it did not work for me.
Now, in cell I1 (adjacent to H1), let's try and pull the value of D2 from the sheet named 'Sat 7.23' by using the formula below:
=IF(ISERROR(INDIRECT("'" & TEXT(H1, "ddd m.d") & "'!D2")),"sheet doesn't exist, put your appropriate text message here",INDIRECT("'" & TEXT(H1, "ddd m.d") & "'!D2"))
To do a negative check, I recommend putting another date 'Sun 7.24" in H2 and use the same formula in I2 with a reference to the date in H2:
=IF(ISERROR(INDIRECT("'" & TEXT(H2, "ddd m.d") & "'!D2")),"sheet doesn't exist, put your appropriate text message here",INDIRECT("'" & TEXT(H2, "ddd m.d") & "'!D2"))
This is what it will look like in a completed worksheet:
I fixed similar problem by generating error
=IFERROR(QUERY(INDIRECT("'"&I2&"'!B3:E", TRUE), "select E where B = '"&I5&"'),"-")
Gives #REF!
=IFERROR(QUERY(INDIRECT("'"&I2&"'!B3:E", TRUE), "select E where B = '"&I5&"')*1,"-")
Works because multiplication of REF! with 1 gives an error
If you expect a number go with *1
If you expect string go with &''