Determining an empty cell - scripting

I need help finding how to determining if a cell is empty.
At the moment i would use If(sheet.getRange("A2").getValue() == 0) {
But this is now causing issues if the cell actually contains the value 0 and is not empty. therefore my question is how do i make my script see if the cell is empty.
PS i'm new to all this.

use If(sheet.getRange("A2").getValue() == NULL)

Related

How to iterate over an Excel file and ID colored cell values

I have an excel workbook that has cells of a column colored with specific colors to keep or exclude certain users that will then be used to filter another excel workbook.
I want to loop through this column and identify cells with red background and add a functional column stating 0 and identify cells with yellow background and add 1 to this same functional column so as to work as the filter for the other workbook.
I'm hoping to use OpenPyXL to complete this task.
column_pi = ws["A"]
for cell in column_pi:
f cell.fill.fgColor == "00FF0000": # Red Hex
# add column stating 0 as value
Have also tried this but no luck, returning nothing
red_fill = PatternFill(fill_type=None, start_color='00FF0000', end_color='00FF0000')
yellow_fill = PatternFill(fill_type=None, start_color='00FFFF00', end_color='00FFFF00')
for cell in column_pi:
if cell.fill == yellow_fill:
print(cell)
Works with no hex codes provided for no_fill
no_fill = PatternFill(fill_type=None)
for cell in column_pi:
if cell.fill == no_fill:
print(cell)
Any thoughts on the best way to iterate over the values and check the fill/background color are of a specific color and then add a functional column like this?
fill is a set of more complicated variables, so looking for it to be exactly equal only to red_fill or yellow_fill here isn't going to work. The complication is mostly due to being able to set a colour either as a static rgba value, or as one that will automatically update when the theme is changed. Styles in openpyxl, with parameters like PatternFill, are easy ways to set multiple of these values at once.
If you look up cell.fill for a particular cell, it returns something like:
<openpyxl.styles.fills.PatternFill object>
Parameters:
patternType='solid', fgColor=<openpyxl.styles.colors.Color object>
Parameters:
rgb='FFD9D9D9', indexed=None, auto=None, theme=None, tint=0.0, type='rgb', bgColor=<openpyxl.styles.colors.Color object>
Parameters:
rgb='00000000', indexed=None, auto=None, theme=None, tint=0.0, type='rgb'
You can specify these values directly as part of cell.fill.fill_type (synonym for cell.fill.patternType), cell.fill.fgColor, and cell.fill.bgColor. Plus sub-attributes like cell.fill.fgColor.rgb.
You could also make it quicker by picking knowncell.fill.fgColor of a cell you know to have red_fill, if one exists. That way, you could check any of fill_type, fgColor and/or bgColor match. Try:
red_fill = knowncell.fill
for cell in column_pi:
if cell.fill.fgColor == red_fill.fgColor and cell.fill.fill_type == red_fill.fill_type:
print(cell)
However, you can't match knowncell.fill directly with cell.fill, I think because a new openpyxl style object is created each time you define a new one.

Excel IF formula to validate another formula

I want to run below formula on all cells, where current value is zero.
Formula on C3
=SUMIFS(raw!$D:$D,raw!$A:$A,$A3,raw!$C:$C,C$2)
I have tried to put this in another IF statement to validate the cell value first and if that matches condition execute above formula
=IF(C3=0,SUMIFS(raw!$D:$D,raw!$A:$A,$A3,raw!$C:$C,C$2))
But here I am getting circular reference warning, because the second formula is depends upon same cell value. Is there any other way I can do it ?. mean running the formula if the value is equal to zero on specific cell
You can't reference the cell you are working in without creating a circular reference. I usually just add an intermediate column to avoid this. If you want it all in one cell for some reason:
=IF(SUMIFS(raw!$D:$D,raw!$A:$A,$A3,raw!$C:$C,C$2)) = 0, "Sums are zero", SUMIFS(raw!$D:$D,raw!$A:$A,$A3,raw!$C:$C,C$2)))
Its probably takes twice as long to compute, is ugly, and you gotta keep both formulas the identical if you ever edit it, but it does fit in one cell.
Is this all one worksheet, or multiple? I think the below would work, but can't know without the workbook.
=SUMPRODUCT((C3=0) * (raw!$A:$A = A3) * (raw!$C:$C = C2) * (raw!$D:$D))

While loop not working as intended. Google script

I am very new at programming in Google Script, and need some guidance here.
I have a loop that is supposed to check the value of a range, then move down to the next row and set the new range's value as "next", which is then compared to "team".
If the condition is met then "team" is given the same value from the range that "next" was given, and "next" is given the value of the range below the current one.
The purpose is to find how many entries there are that meet conditions in a column, then my other parts of the code manipulate that data.
When the "team" value isn't the same as "next" (the value of the range below the current one), then the loop is supposed to stop, but doesn't. Code:
while (team = next) {
team = orange.getValue();
row ++;
range = col + row.toString();
orange = ordered.getRange(range);
next = orange.getValue();
entries ++;
};
I'm not familiar with Google Script either, but most languages require double equal sign for equality tests. From a cursory view I think Google Script uses the same syntax. Try doing this instead:
while (team == next)
Notice the double == to check for equality instead of single = to assign a variable.

Check if cell if empty

I am trying to check if the cell (A5) in sheet tstDash is empty. Currently the cell contains a formula but sometimes it the result is blank and sometimes is a number.
If it is blank, I want a message box. Otherwise perform other function.
I have this code but it is completely ignoring the line and giving me fits.
If chk25thPercentile.Checked = True And Globals.tsdDash.Range("A5").Value Is DBNull.Value
Try this ..
If chk25thPercentile.Checked And IsDBNull(Globals.tsdDash.Range("A5").Value)
What language are you writing in ? VBA or VB.Net ? VBA won't accept IsDBNull. If you are in VBA you want to be testing for the blank result of the formula, which is probably just an empty string ""
I expect you need something like
If chk25thPercentile.Checked And Globals.tsdDash.Range("A5").Value = ""
That is assuming that the result of your formula is an empty string, if the cell is actually blank, ie, without a formula you might want to look at ISBLANK

For each cell in a range, if a value in a seperate range is found in the next cell do stuff

This Macro I have built works but I am hoping for a faster version or a Formula that will do the same in less time.
What I Have:
For Each cell In Range("Table_Query_1[[#Data],[Reason2]]")
For Each PossibleValue In Range("F2", Range("F2").End(xlDown))
If Len(cell) = 0 Then
If (InStr(UCase(cell.Offset(0, 1)), UCase(PossibleValue)) <> 0) Then
cell.Value = PossibleValue.Value
End If
Else
Exit For
End If
Next
If Len(cell) = 0 Then
cell.Value = cell.Offset(0, -1)
End If
Next
The only other way I could get anything to work way with the following Array Formula
=IF(ISNA(MATCH($F$3:$F$10,[#Extra Info],0)),[#Reason],$F$3:$F$10)
but this doesn't work for Partial matches as in the case of Row 4 and 9. I also have my doubts that this array formula would be that much faster then a vba macro along with the fact it would also require more upkeep with the test values range (F2:f3) in this case as I would have to constantly update that formula OR I wouild have to make the original range like F2:F100 witch would cause it to take that much longer.
So, what i'd like is if ANY value in my range of values (F2:F3 in this case), Is found inside of the Extra Info Column on the current Row , Then Reason2 of that row (Offset(0, -1)) equals the Value that was matched. But if nothing is found then just use the Reason in that row(Offset(0,1)).
And the second Issue is that I need the Macro to Run After the QueryTable refreshes but if I set it as a Cell Change Event on a cell the is in the query that will change, the macro runs and finishes before the Final querytable is imported and sorted.
Solved!
This is post the comment that I posted above which had the initial formula.
=IF(COUNT(FIND($F$2:$F$3,C1)),"What Will Go Here",A1)
The below tells you what has to go in place of "What Will Go Here"
Put this formula in cell B2. Note that this is an Array Formula. You will have to press CTRL + SHIFT + ENTER after you enter the formula.
=IF(COUNT(FIND($F$2:$F$4,C2)),INDEX($F$2:$F$4,MATCH(SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1))),FIND($F$2:$F$4,C2,1),0),0),A2)
Screenshot
Explanation:
FIND($F$2:$F$4,C2,1) when used with an array returns an array. To check the values you can highlight it and press F9 and it will tell you the position at which the match is found. See this screenshot
So it tells us that it found the match at the 3rd position in 4532. It yet doesn't tell us with what did it find a match.
Now the next step is to retrieve the position of that number from the array. So in the above example it will be position 2 and to find that position we will use MATCH() and to use MATCH we will need that 3
So to retrieve 3 from the array we use this formula
=SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1)))
Now we have that 3 so we will use it in Match to find the position in the Possible Value
=MATCH(SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1))),FIND($F$2:$F$4,C2,1),0)
This will give us 2
Now we know the position of the number in the Possible Value. To find that number we will use INDEX
=INDEX($F$2:$F$4,MATCH(SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1))),FIND($F$2:$F$4,C2,1),0),0)
SAMPLE Workbook
http://wikisend.com/download/280280/Sample.xlsx
This is a solution I came across that does not have to be Array Entered and seems to run faster then Siddharth Rout's solution. I am using the formula
=IFERROR(LOOKUP(1E+100,SEARCH($F$2:$F$4,C2),$F$2:$F$4),A2)
Where I am looking for any word in C2 that is in the range F2:F4. If none found it will throw an ERROR and in that situation I know nothing was found and simply return the original reason.
Not shown in the picture I also turn F2:F4 into a named range called Reasons and change the formula too:
=IFERROR(LOOKUP(1E+100,SEARCH(Reasons,C2),Reasons),A2)