Changing a cell formula based on for loop iteration - vba

I am trying to insert and change a counta formula based on the iteration of the for loop. The problem I am facing is that even though the code runs without error, nothing happens. The totalrow variable is consistently 0. I'm not sure where I am going wrong here. All the variable have been initialized outside the loop. CurrentColname is string, countUsedCols is long, totalRows is long.
For i = 2 To countUsedCols
ActiveSheet.Cells(3, i).Select
currentColName = ActiveSheet.Cells(3, i).Value
If currentColName = "Valid From" Then
totalrow = ActiveWorkbook.Sheets("Customer_Facing_View").Range("AR1").Formula = "=COUNTA($" & i & ":$" & i & ")"
totalrow = ActiveWorkbook.Sheets("Customer_Facing_View").Range("AR1").Value

A couple of things.
In vba when you put X=Y=Z X becomes a Boolean value based on whether y = z or not.
So when you write:
totalrow = ActiveWorkbook.Sheets("Customer_Facing_View").Range("AR1").Formula = "=COUNTA($" & i & ":$" & i & ")"
Totalrow is returning false because the formula in that cell is not the same as the string you have provided.
Second your COUNT A will resolve to a row not a column. i is a number and not a letter.
So remove the totalrow = from the first expression and change the range reference.
ActiveWorkbook.Sheets("Customer_Facing_View").Range("AR1").Formula = "=COUNTA(" & Columns(i).Address &")"

I guess you would like to write a formula into Cell AR1 to calculate the number of rows (with the first totalrow statement); and get that value back (with the second totalrow statement). But I believe the first totalrow statement is wrong as Scott indicated. You need change it.
Also for the Counta formula you need to include your original worksheet name otherwise it just count the column in the Customer_Facing_View worksheet.

Related

Writing a formula with concatenated parts into a cell

Scenario: I have a code that should write a formula to a worksheet cells. This formula is for an API to retrieve some value. My formula is inside a loop (this is done for multiple columns) and references the first row for an identifier.
The original formula:
=FS(B1;"FI(DATE,,DATE)")
The modified formula with the floating reference (inside the loop):
For i = 1 To lColumn
If wb.Worksheets("Dates").Cells(i, 1).Value <> "" Then
wb.Worksheets("Dates").Cells(i,2).value = "=FS(" & i & "1;"FI(DATE,,DATE)")"
End If
Next i
Where lColumn is some pre-defined number.
Issue: I keep getting the "Unexpected end of statement" error in the formula part of the loop.
What I already tried: I tried different variations, repositioning the "s and 's, for example:
wb.Worksheets("Dates").Cells(i,2).value = "'"=FS(" & i & "1;"FI(DATE,,DATE)")""
or
wb.Worksheets("Dates").Cells(i,2).value = "'=FS(" & i & "1;"FI(DATE,,DATE)")"
or
wb.Worksheets("Dates").Cells(i,2).value = "'""=FS(" & i & "1;"FI(DATE,,DATE)")"
and so on. But the error still persists.
Question: What is the proper way to do this operation?
Working with formulas in VBA is a little bit tricky:
To write a formula, use the range.formula property, not the .value.
You have to write the formula as if you are using an english Excel. Parameter-separator is comma (not semicolon).
If a formula needs a quote, double it so that the VBA compiler understands that you want a quote within a string.
I find it helpfull to write a formula into a variable before assigning it - you can check in the debugger if it is exactly how it should before assigning it.
To check how the formula should look like, write it into a cell, change to the VBA-editor, open the immediate window and write ? activecell.formula
Try (untested as the formula you need is not valid to us):
with wb.Worksheets("Dates")
dim f as string, adr as string
adr = cells(i, 1).address(false, false) ' get rid of Dollar signs
f = "=FS(" & adr & ",""FI(DATE,,DATE)"")"
.Cells(i, 2).formula = f
end with
wb.Worksheets("Dates").Cells(i,2).formula = "=FS(" & Cells(1, i).Address(0,0) & ";""FI(DATE,,DATE)"")"
There may be a better way to convert the column number to a letter (which is the problem you are having, along with the double quotes)!

Application.VLookup function always returns #N/A

I am trying to use the Application.VLookup function in Visual Basic to find a value in a different workbook. However, whenever I use it, it always returns #N/A.
This is the layout of my function. LastRow() just returns the row number of the last row. SHORTAGE_SBT is a variable containing the source workbook name. SBT_Last is the last row of SHORTAGE_SBT. The ID that I'm searching with in in the B column, hence why I use "B" & ind to refer to it.
For ind = 4 To LastRow()
Range("H" & ind).Select
ActiveCell.Value = Application.VLookup("B" & ind, Workbooks(SHORTAGE_SBT).Sheets(1).Range("A14:DZ" & SBT_Last), Range("DZ1").Column, False)
Next
I have tried recording a macro for VLookup to see if it would help me understand the problem. The macro gave me this function, which worked but could not be used because it contains the hardcoded file name instead of using the variable.
Range("H" & ind).FormulaR1C1 = "=VLOOKUP(RC[-6],'[filename.xls]Sheet1'!R14C1:R2382C130, COLUMN(R[-3]C[122]), FALSE)"
I cannot see any significant difference between the way the macro lays out the arguments of the function as opposed to mine, other than using more direct references. I have tried using direct numbers in my code but doing so hasn't helped either.
Application.VLookup("B" & ind, Workbooks(SHORTAGE_SBT).Sheets(1).Range("A14:DZ" & SBT_Last), Range("DZ1").Column, False)
"B" & ind will be searched for "literally"; it will not be transformed into a range address because it is interpreted here by VBA, not by Excel. Try:
Application.VLookup(Range("B" & ind), Workbooks(SHORTAGE_SBT).Sheets(1).Range("A14:DZ" & SBT_Last), Range("DZ1").Column, False)
' ^^^^^^^^^^^^^^^^
Combine the two approaches:
Range("H" & ind).FormulaR1C1 = _
& "=VLOOKUP(RC[-6],'[" & Workbooks(SHORTAGE_SBT) _
& "]Sheet1'!R14C1:R2382C130, COLUMN(R[-3]C[122]), FALSE)"

iteration of loop in formula vba

I'm trying to sum a variable range of data starting at row 3. sortedRow is the row # of the end of the data. lColumn is the last column used as a number.
I'm trying to sum the data in row 1, column H - lColumn.
I need to have the formula calculate the sum of column G, then iterating on referenced column by the current iteration (which will be columns h through x)
I've taken Scott Craner's advice and edited my code as
Dim lColumn As Long
lColumn = ActiveSheet.Cells(3, Columns.Count).End(xlToLeft).Column
sortedRow = Cells(Rows.Count, "D").End(xlUp).Row
Dim i As Integer 'iterated column sum cell
For i = 8 To lColumn
Cells(1, i).Value =Application.WorksheetFunction.SumIfs(Range(Cells(3,7),
Cells(sortedRow, 7)), Range(Cells(3, i), Cells(sortedRow, i)), 1)
Next i
The cells are not being updated with their values though.
It feels like I'm missing something really obvious with actually applying the number to the cell. I thought the above would do it.
added lColumn declaration because of issue with the formula being applied
added sortedRow declaration.
basically this. But with variable column lengths and number of columns.
It didn't matter for Column H that there was "#VALUE" in the volume column. So I assume it doesn't matter for the other columns.
Any help would be appreciated!
You have problems here.
("$G3:$G" & sortedRow, i & "3:" & i & sortedRow, 1)
("$G3:$G" & sortedRow & "," & i & "3:" & i & sortedRow, 1)
But you still have issues in there. If i=4 and sortedRow=12 let's say, this is what you would have.
(G3:G12,43:412, 1)
So you need to fix your Criteria_range1. I'm not clear from your question what you want the criteria to be.
Here is info on the arguments. https://msdn.microsoft.com/en-us/library/office/ff193011.aspx
The issue was resolved after fixing #VALUE cells in the sumifs columns I was trying to add. I made a conditional statement that set all errors to equal zero. This allowed the loop to function.

VBA 1004 error : Application defined or object defined error

I am a novice at Excel VBA and am running into an error 1004 while compiling a portion of the code:
Cells(i, j).Formula = _"=vlookup(Cells(i,1).Value,SKULifeCycle_Table_Temp!R1C1:R5000C500,match(Cells(1,j).Value,'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
i and j have been defined previously as integers and are part of a for loop. Could anyone please help me out on this?
A few things wrong there:
First, you're using the literal text "Cells(i, 1).Value" and "Cells(1, j).Value" in the formula string. You would need to concatenate the values into the string like this:
Cells(i, j).FormulaR1C1 = "=vlookup(" & Cells(i,1).Value & ",SKULifeCycle_Table_Temp!R1C1:R5000C500,match(" & Cells(1,j).Value & ",'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
Second, you used the .Formula property but passed R1C1 style references, so you should use the .FormulaR1C1 property (as I did above).
Third, if the values in the cells that you are using for the lookup values are text, you need to enclose them in quotes:
Cells(i, j).FormulaR1C1 = "=vlookup(""" & Cells(i,1).Value & """,SKULifeCycle_Table_Temp!R1C1:R5000C500,match(""" & Cells(1,j).Value & """,'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
or use the addresses (in R1C1 format) instead:
Cells(i, j).FormulaR1C1 = "=vlookup(RC1,SKULifeCycle_Table_Temp!R1C1:R5000C500,match(R1C,'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
One issue that is clear (maybe the cause of the whole error), is that variables are being used within a string. So, what does that mean? I'll simplify using the code below as a template:
Sub Test1()
Dim i as Integer
Dim j as Integer
i = 2
j = 3
Cells(i, j).Value = "The row number is i and the column number is j"
End Sub
In the Cells line, it correctly refers to cell C2, which is the second row and third column. But what value is inserted into the cell? It's literally "The row number is i and the column number is j" using the letters, and not their corresponding numbers. Similarly, in your case, the formula will read: VLOOKUP(CELLS(i,1)... using the letter i, which is incorrect.
Additionally, a cell's formula doesn't use the CELLS syntax. You instead need to build a string using the variables. It would look a lot like:
"=VLOOKUP(" & Cells(i, 1).Address & "SKULifeCycle_Table_Temp!R1C1:R5000C500, Match(" & Cells(i, 1)Address ... "
Try to build out your formula string and refer back to this post with any specific questions.

Convert Excel array formula VBA

I'm trying to do "vlookup" with 2 different criteria(Column A and G values) using "Index" and "Match" functions.
and here is the line i used for the Excel command.
=INDEX(Database!A:KG,MATCH(1,(Database!A:A='TempSheet'!A2)*(Database!G:G='TempSheet'!G2),0),10)
How would I do it with VBA? It's keep giving me the error message "Compile error: Expected end of statement".
Selection= _
"=Index(DB.Range("A:KG"), Match(1, (DB.Range("A" = Temp.Range("A" & i).Value)) * (DB.Range("G" = Temp.Range("G" & i).Value)), 0), 10)"
Thanks
Every time you use a spreadsheet formula inside a VBA code, you need to precede it with <Excel.WorksheetFunction.> or <Application.WorksheetFunction.>.
For example:
Application.WorksheetFunction.Match
instead of Match only.
I have had little luck getting array formulas to work correctly via VBA, and use the 'IFERROR' as a workaround like so:
=IFERROR(VLOOKUP(A1, Database!A:Z,1,FALSE),VLOOKUP(B1, Database!A:Z,1,FALSE))
This function will attempt to match A1, and in case of a #VALUE error, it will match B1.
To get this kind of formula populated on a sheet in VBA, you can loop down your sheet using the '.formula' approach.
' get length of source data
Dim RowCount As Long
RowCount = ThisWorkbook.Sheets("Database").Cells(Rows.Count, 1).End(xlUp).Row
' now starting from row 2 to preserve headings
For i = 2 To RowCount
ThisWorkbook.Sheets("Summary").Cells(i, 1).Formula = "=IF(ISERROR(SEARCH(""ISO"",V" & i & ")),""Order type not supported"",""Transit"")"
ThisWorkbook.Sheets("Summary").Cells(i, 6).Formula = "=IFERROR(TEXT(VLOOKUP(B" & i & ",Database!A:N,7,FALSE),""dd-mmm-yyyy HH:MM AM/PM""),"""")"
Next
Not exactly what you were after, but hope it helps!