Countif/Sumif should show empty value instead of 0 in arrayformula - filter

I have a lot of arrayformulas wrapped around countif and sumifs functions. I want the countifs/sumifs to return an empty value ("") instead of 0.
My workaround is very expensive and long:
=ARRAYFORMULA(IF(SUMIFS(Sheet!$C$1:$C; 'Sheet!$A$1:$A; ">="&$A3; Sheet!$A$1:$A; "<="&$B3)=0; ""; SUMIFS(Sheet!$C$1:$C; Sheet!$A$1:$A; ">="&$A3; Sheet!$A$1:$A; "<="&$B3)))
Here is an example sheet: https://docs.google.com/spreadsheets/d/1xyS0Y4gnG3zLyOGtycWytvTlA1NmqjEAy8H7QJatdSg/edit?usp=sharing
Is there a different way for this?

=IFERROR(SUM(QUERY(Sheet2!A:C;
"select C
where month(A)+1="&MONTH(A3)&"
and year(A)="&YEAR(A3); 0)))
=IFERROR(SUM(FILTER(Sheet2!C:C;
YEAR(Sheet2!A:A)=YEAR(A3); MONTH(Sheet2!A:A)=MONTH(A3))))

Related

Array of value from multiple conditions

I wanna return an array of value from multiple conditions.
Currently formula is set to accept one condition.
https://docs.google.com/spreadsheets/d/1pgVlBWYKWtT6AEPyRtZmAYdOXBCjYG_B7pdlvCqYq0A/edit?usp=sharing
The desired result is showed in the ad hoc worksheet
Edit : initial problem solved by player0. Thanks !
Previous post
I'm using curly brace to return an array of value with the IF formula. This works well. I wanted to use IFS function because i wanted to use more conditions.
With a similar table, only the 1st number is returned form the array.
I don't understand why.
https://docs.google.com/spreadsheets/d/1pgVlBWYKWtT6AEPyRtZmAYdOXBCjYG_B7pdlvCqYq0A/edit?usp=sharing
Thanks !
delete range E2:L and use this in E2:
=ARRAYFORMULA(TRANSPOSE(SPLIT(TRANSPOSE(QUERY(
IF((E1:L1=B2:B11)+(E1:L1=C2:C11)+(E1:L1=D2:D11);
"1;2;3;4;5;6;7"; ";");;9^9)); ";"; 1; 0)))

How evaluate concatenated string as indexed XPath expression in VB6

I've built an Xpath expression by concatenating strings in VB6:
strXPath = "xDOC.selectNodes(" & """/GroupType1""" & ").item(" & CStr(i) & ").selectNodes(" & """/OperationStageCollection/OperationStage""" & ").length"
"i" is an integer used to index into
I want to evaluate strXPath to get a loop counter, for example:
n = CInt(strXPath)
n is declared as Integer; strXPath is declared as string. VB6 throws a Type Mismatch error on the above evaluation expression. I must be missing something obvious. How can I evaluate strXPath?
I realize that there may be errors in the XPath expression itself, but I'd like to get the evaluation working in order to debug such possible errors.
Try removing some of the double-quotes:
iLength = xDOC.selectNodes("/GroupType1").item(i).selectNodes("/OperationStageCollection/OperationStage").length
This should return the length property you want, as an Integer.
Then you can use iLength in your loop.
#BRW: both of your questions are very specific, i.e. how to achieve certain results using XPath. But I have the suspicion that if you would explain what (data) you try to retrieve form the XML, commenters might show you ways you didn't think of, e.g. say you want to iterate through all <OperationEvent>s within a <OperationEventCollection>, a single <OperationEvent> can be retrieved by //GroupType1/OperationStageCollection/OperationStage/OperationEventCollection/OperationEvent[1-based-index], e.g. //GroupType1/OperationStageCollection/OperationStage/OperationEventCollection/OperationEvent[1], which results in a single XML node:
<OperationEvent>
<OperationEventDate1>2018-12-16</OperationEventDate1>
<OperationEventCode>5</OperationEventCode>
<OperationEventDate2>2018-05-16</OperationEventDate2>
</OperationEvent>
So instead multiple selectNodes methods, one proper XPath query might yield the desired outcome right away.

Use cell text to define vlookup datatable range

In the image above, how do I replace the portion "Tom.A:C" in the vlookup function with the text in cell B2 + .A:C ?
Where "Tom" is the name of a sheet in my workbook and I want to lookup a value in the second column of that sheet.
The formula
=VLOOKUP(lookup,sheet!range,column,match)
Then, in your example, you must write it like this:
=VLOOKUP(A2, TOM ! [Range of the sheet], 2, FALSE)
Edit:
I did not understand the first time exactly what was the question, so here it is the answer:
The formula
=VLOOKUP(lookup,indirect(concat(<cell with sheetname>,<"!"|".">,"<CELL RANGE IN ALL LOOKING SHEETS>")), column, match)
Then in your example:
=VLOOKUP(A2, indirect(concat(A2,".","A:C")), 2, 0)
First you need to concatenate the value of the sheet and range that you want, then with indirect, you take that string value and use it as a valid reference.

VBScript: Finding the number of non-null elements in an array

What is the "best" way to determine the number of elements in an array in VBScript?
UBound() tells you how many slots have been allocated for the array, but not how many are filled--depending on the situation, those may or may not be the same numbers.
First off there is no predefined identifier called vbUndefined as the currently accepted answer appears to imply. That code only works when there is not an Option Explicit at the top of the script. If you are not yet using Option Explicit then start doing so, it will save you all manner of grief.
The value you could use in place of vbUndefined is Empty, e.g.,:-
If arr(x) = Empty Then ...
Empty is a predefined identify and is the default value of a variable or array element that has not yet had a value assigned to it.
However there is Gotcha to watch out for. The following statements all display true:-
MsgBox 0 = Empty
MsgBox "" = Empty
MsgBox CDate("30 Dec 1899") = True
Hence if you expect any of these values to be a valid defined value of an array element then comparing to Empty doesn't cut it.
If you really want to be sure that the element is truely "undefined" that is "empty" use the IsEmpty function:-
If IsEmpty(arr(x)) Then
IsEmpty will only return true if the parameter it actually properly Empty.
There is also another issue, Null is a possible value that can be held in an array or variable. However:-
MsgBox Null = Empty
Is a runtime error, "invalid use of null" and :-
MsgBox IsEmpty(Null)
is false. So you need to decide if Null means undefined or is a valid value. If Null also means undefined you need your If statement to look like:-
If IsEmpty(arr(x)) Or IsNull(arr(x)) Then ....
You might be able to waive this if you know a Null will never be assigned into the array.
I'm not aware of a non-iterative method to do this, so here's the iterative method:
Function countEmptySlots(arr)
Dim x, c
c = 0
For x = 0 To ubound(arr)
If arr(x) = vbUndefined Then c = c + 1
Next
countEmptySlots = c
End Function
As Spencer Ruport says, it's probably better to keep track yourself to begin with.
There's nothing built in to tell you what elements are filled. The best way is to keep track of this yourself using a count variable as you add/remove elements from the array.

Is it better to use NOT or <> when comparing values?

Is it better to use NOT or to use <> when comparing values in VBScript?
is this:
If NOT value1 = value2 Then
or this:
If value1 <> value2 Then
better?
EDIT:
Here is my counterargument.
When looking to logically negate a Boolean value you would use the NOT operator, so this is correct:
If NOT boolValue1 Then
and when a comparison is made in the case of the first example a Boolean value is returned. either the values are equal True, or they are not False. So using the NOT operator would be appropriate, because you are logically negating a Boolean value.
For readability placing the comparison in parenthesis would probably help.
The latter (<>), because the meaning of the former isn't clear unless you have a perfect understanding of the order of operations as it applies to the Not and = operators: a subtlety which is easy to miss.
Because "not ... =" is two operations and "<>" is only one, it is faster to use "<>".Here is a quick experiment to prove it:
StartTime = Timer
For x = 1 to 100000000
If 4 <> 3 Then
End if
Next
WScript.echo Timer-StartTime
StartTime = Timer
For x = 1 to 100000000
If Not (4 = 3) Then
End if
Next
WScript.echo Timer-StartTime
The results I get on my machine:
4.783203
5.552734
Agreed, code readability is very important for others, but more importantly yourself. Imagine how difficult it would be to understand the first example in comparison to the second.
If code takes more than a few seconds to read (understand), perhaps there is a better way to write it. In this case, the second way.
The second example would be the one to go with, not just for readability, but because of the fact that in the first example, If NOT value1 would return a boolean value to be compared against value2. IOW, you need to rewrite that example as
If NOT (value1 = value2)
which just makes the use of the NOT keyword pointless.

Resources