IF AND Formula in VBA Code - vba

Recently you guys helped me solve looping through a pivot table by inserting a dynamic formula next to a pivot table and auto filling down.
'formula
frml = "=if(" & myrange.Address(0, 0) & ">0.3%," & myrange2.Address(0, 0) & ","""")"
'where i want the formula to go
pt.ColumnRange.End(xlToRight).Offset(1, 0).End(xlToLeft).Offset(1, 1).formula = frml
ActiveSheet.range("P7:P36588").FillDown
I've tried updating this formula by adding
"=if(and("
and then also adding in another range. Problem is the additional ( never shows up. I've also tried just adding "(" as it's own part but then the next part (the 'where the formula goes) stops working which makes no sense to me.
Can someone help me convert this formula into an ifand statement and also explain why the 'where the formula should go' part all of the sudden stops working?
Edit:
In total, the new addition would look like this:
"if(and(" & myrange.address(0,0) & ">0.3%," & myrange3.address(0,0) & ">$100," & myrange2.address(0,0) & ","""")
to output this formula in the corresponding cell by the pivot table
=if(and(c3>.3%,d3>$100),a3,""
the problem right now is adding that and part to the formula which would be d3. If those 2 statements work, then it should bring out a3, if not it will return nothing.

A couple of notes:
#Jeeped already answered the reason to your error - you need to add closing bracket ) to your AND.
I like to use Chr(34) to write down " inside formula strings.
I like to avoid comparing the formats inside the cell, just the values. So instead of myrange.address(0,0) & ">0.3%" I like using myrange.address(0,0) & ">0.003".
Code
frml = "=IF(AND(" & myrange.Address(0, 0) & ">0.003," & myrange3.Address(0, 0) & ">100)," & myrange2.Address(0, 0) & "," & Chr(34) & Chr(34) & ")"

You aren't closing off the AND clause with a ).
'formula
frml = "=if(and(" & myrange.address(0,0) & ">0.3%, " & myrange3.address(0,0) & ">$100), " & myrange2.address(0,0) & ", text(,))
text(,) is a good substitute for """" in a quoted string formula.

Related

Why does my SQL statement not find a match with the WHERE statement below?

I'm attempting to pull data from my MS Access database via an Excel SQL statement. It does NOT give me any errors, however it also does not pull the data I'm searching for.
If items(u, 1) is text (ex. 308-203BL), then it works perfectly.
I've tried both comparing them as text and as numerical, but neither way find any matches when items(u, 1) is 19310.
This compares it as text...
LEFT(Item," & Len(items(u, 1)) & ") = '" & items(u, 1) & "'"
this compares it as numerical...
VAL(LEFT(Item," & Len(items(u, 1))) & ") = " & items(u, 1)
I have verified that there are records in the DB that match the given criteria.
items() is an array populated from a 1 column table on the sheet by items = Range("Items").Value.
Using these two SKU's as examples, the first working, the second not, the array would be as follows. .
SKU by SKU, they're fed into the SQL as below.
With the input in the example, the output I receive is an array populated only the sales for the second item. The order I put the SKU's in the table doesn't change that result. I have tested it with multiple SKU's, and no matter how many I use, it returns the proper information, with the exception of not returning any results for any numerical SKU's.
The field for Item in the DB is a short text, which is why I used '" & items(u, 1) & "'" to convert the SKU to text when I was trying to match it as text, and Val() to convert the field to a value when trying to match it as a number. Both gave me 0 record counts in the function, but did not give me a data type error.
Below is the portion of my code which determines the SQL string, and a bit afterwords which basically stuffs it into a UDF which pulls the info from the DB and puts it into an array for me. Aside from not finding a match when items(u,1) is numerical, it works perfectly.
DBString = "SELECT Invoice, Line, Inv_Date, Sales_Order, SOLine, SO_Date, CustID, Item, Part_Description, Ship_Qty, Price, Ext_Sales FROM `" & Year(tabledate) & "-" & Format(tabledate, "mm") & "` WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# AND LEFT(Item," & Len(items(u, 1)) & ") = '" & items(u, 1) & "'"
SalesHolder = PullFromDB(DBString, SGMDB)
I've also tried the below code instead, to force it to compare as a number instead of text, which also doesn't give me any errors, but doesn't find a match.
DBString = "SELECT Invoice, Line, Inv_Date, Sales_Order, SOLine, SO_Date, CustID, Item, Part_Description, Ship_Qty, Price, Ext_Sales FROM `" & Year(tabledate) & "-" & Format(tabledate, "mm") & "` WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# AND VAL(LEFT(Item," & Len(items(u, 1))) & ") = " & items(u, 1)
SalesHolder = PullFromDB(DBString, SGMDB)
Below is the UDF itself which pulls the info from the DB. It works quite nicely.
Function PullFromDB(DBStr As String, DBLoc As String) As Variant
Dim TheDB As Recordset, DBHolder() As Variant
Set TheDB = OpenDatabase(DBLoc).OpenRecordset(DBStr)
If TheDB.RecordCount = 0 Then GoTo theexit
TheDB.MoveLast
TheDB.MoveFirst
ReDim DBHolder(0 To TheDB.RecordCount, 1 To TheDB.Fields.Count) As Variant
For k = 1 To UBound(DBHolder, 2)
TheDB.MoveFirst
For j = 0 To UBound(DBHolder)
If j = 0 Then
DBHolder(j, k) = TheDB.Fields(k - 1).Name
Else
DBHolder(j, k) = TheDB.Fields(k - 1).Value
TheDB.MoveNext
End If
Next j
Next k
theexit:
TheDB.Close
Set TheDB = Nothing
PullFromDB = DBHolder
On Error GoTo -1
End Function
The expected result is to populate the array SalesHolder with the information that matches the criteria.
What am I missing? I'm going blind trying to find it.
Thank you all for your responses to this, it turns out I was completely hunting for the wrong problem. The code I posted was actually correct, the issue was with the format of Inv_Date field in the DB. I had mistakenly entered the last couple of months as text instead of date, so the WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# portion of my SQL didn't match anything.
I hadn't identified that this was the issue earlier due to the timing of the sales of the SKU's themselves, which was purely coincidence. When I expanded the dates range, I found that it did return results for the numerical SKU, but both numerical and text SKU's cut off two months ago.
Thank you again!

Summing in VBA with a variable column and range

I know this question gets asked a lot but I haven't been able to find the answer I'm looking for. I'm trying to write a code that will be able to find a key term and then sum that column for a certain amount of rows.
I've tried simply replacing "G" in this code with my variable for the correct column (col) and I've made sure that my column variable is matching to the correct column.
Cells(subRow, col).Formula = "=SUM(G" & row & ":G" & subRow & ")"
The above, for example, works; but I would like it to look like this:
Cells(subRow, col).Formula = "=SUM(col" & row & ":col" & subRow & ")"
I've tried moving the col variable around in and outside of the quotes, and I can't seem to find a way to do it.
Thanks in advance.
Based on the case you have described, you would have to use R1C1 Reference Style:
Cells(subRow, col).FormulaR1C1 = _
"=SUM(R" & row & "C" & col & ":R" & subRow & "C" & col")"
There is also a Cells(row, column).Resize(number of rows, number of columns) option :
Cells(subRow, col).Formula = "=SUM(" & Cells(row, col).Resize(subRow - row, 1).Address(0, 0) & ")"

Writing a formula as Syntax in VBA

I want to run a rank formula across a range of cells. I am scratching my head as to why it's not working. Lastrow is just the formula that counts the number of rows.
Range("B1:B" & Lastrow).Formula = "=RANK(A1,Offset(" & Chr$(36) & "A1" & Chr$(36) & "," & Lastrow & ",0))"
I feel like it's something wrong with Chr$(36), but when I try Chr(36) it doesn't work either. (removing these chr(36)'s and just having Offset(A1... etc) works fine).
Thanks in Advance!
It's hard to see what you want to do. The line of VBA code below will, at least, work.
Range("B1:B" & LastRow).Formula = "=RANK(ROW(),$A1:$A$" & LastRow & ",0)"
Your issue seems to be with the RANK() function. It has 3 arguments, (1) the rank, (2) the range in which to find the rank and (3) Ascending/Descending. In your formula the first argument is missing and your "Offset(" & Chr$(36) & "A1" & Chr$(36) & "," & LastRow" doesn't describe a range, read as Offset($A1$,300 with closing bracket missing.
My above formula suggests the Row number as rank, meaning 1 for Row 1, 2 for Row 2 etc. but descending, as indicated by the 3rd argument (taken from your formula) and, as second argument a range in column A between A1 and the LastRow. It probably isn't what you wanted but I hope you will be able to tweak it.

Writing formula in cell gives error although formula is correct

I am using VBA to write formulas in an MS Excel sheet. When I copy the formula to the cell manually it works but when I use the line below it gives me a run-time error:
'1004': Application-defined or object-defined error.
ActiveSheet.Cells(Row + 3, Column + i).Formula = "=SUMPRODUCT(--(OFFSET(endResourceNaam;2;0):OFFSET(endResourceNaam;1000;0)=$A" & Row + 1 & ");--(OFFSET(endResourceNaam;2;4):OFFSET(endResourceNaam;1000;4)=$E" & Row + 1 & ");OFFSET(endResourceWeek;2;" & ColumnLetter(Column - 1) & "$1):OFFSET(endResourceWeek;1000;" & ColumnLetter(Column - 1) & "$1))"
The (first in loop) string generated is:
=SUMPRODUCT(--(OFFSET(endResourceNaam;2;0):OFFSET(endResourceNaam;1000;0)=$A6);--(OFFSET(endResourceNaam;2;4):OFFSET(endResourceNaam;1000;4)=$E6);OFFSET(endResourceWeek;2;O$1):OFFSET(endResourceWeek;1000;O$1))
I tested the formula by printing it from the VBA code and than copy/pasta that to the cell. That way I know for certain that the generated string is actually correct. From what I have learned there is some kind of protection build into VBA that makes sure that when I try to write a formula the formula is correct and working. There might be something in that protection that is keeping me from writing the formula to a cell.
Is there any solution for me to write the desired formula to a cell using VBA?
My bet is because it's an array formula, you should use the FormulaArray property.
ActiveSheet.Cells(Row + 3, Column + i).FormulaArray =
Jeeped gave the correct answer to my problem, replace the semi-colon list seperators with EN-US commas. Below actually works without a problem:
ActiveSheet.Cells(Row + 3, Column + i).Formula = "=SUMPRODUCT(--(OFFSET(endResourceNaam,2,0):OFFSET(endResourceNaam,1000,0)=$A" & Row + 1 & "),--(OFFSET(endResourceNaam,2,4):OFFSET(endResourceNaam,1000,4)=$E" & Row + 1 & "),OFFSET(endResourceWeek,2," & ColumnLetter(Column - 1) & "$1):OFFSET(endResourceWeek,1000," & ColumnLetter(Column - 1) & "$1))"
I have not tried the FormulaArray method since this already solved my problem.

Specifying cells and sheets in formula using VBA

I need my macro to input the following formula:
Worksheets("U_NEDC_COLD_online_0").Cells(3, A).formula = "=IF(" & Worksheets (U_NEDC_COLD_online_0).Cells(3, AA).Value & "=" & Worksheets(U_NEDC_COLD_online).Cells(3, AA).Value & ";" & Worksheets(U_NEDC_COLD_online).Cells(3, A).Value & ";" & Worksheets(U_NEDC_COLD_online_0).Cells(3, A).Value & ")"
I've also tried the same formula with the ".Address" property and it doesn't work. What am I doing wrong?
The final formula should look like this:
=IF($AA3 = U_NEDC_COLD_online!$AA3; U_NEDC_COLD_online!A3; U_NEDC_COLD_online_0!A3)
PS: Worksheets("U_NEDC_COLD_online_0") is not the same as Worksheets(U_NEDC_COLD_online_0). (its not a typo)
Thanks.
Use commas instead of semicolons to separate the arguments of the IF statement.
Your formula appears to have a circular relationship; the formula is going into cell A3 and references cell A3... I'll leave that to you to work out.
Always use Option Explicit. Once you put that line at the top of your module, you'll get the error: Variable not defined for the variables: A, AA, and possibly U_NEDC_COLD_online and U_NEDC_COLD_online_0 that you probably intended to use as string literals. (see next bullet for a workaround)
If U_NEDC_COLD_online_0 is truly a variable/constant name and is not equal to the string literal that you use elsewhere (e.g. U_NEDC_COLD_online_0), you should really change the variable name to something else!
If the only reason you are dynamically building the formula is to accommodate variable row indexes, use this where the 3 can be replaced by a variable:
Worksheets("U_NEDC_COLD_online_0").Cells(3, 1).Formula = "=IF($AA" & 3 & "=" & "U_NEDC_COLD_online!AA" & 3 & ", U_NEDC_COLD_online!A" & 3 & ", A" & 3 & ")"
If you don't even need variable row indexes, just use this:
Worksheets("U_NEDC_COLD_online_0").Range(A3).Formula = "=IF($AA3=U_NEDC_COLD_online!AA3, U_NEDC_COLD_online!A3, A3)"