Excel VBA: Using .Cells() to dynamically reference cell in cell formula - excel

I want to create a cell formula which references cells like B1, e.g. ActiveSheet.Cells(1,x).Formula = "=B1*" & x. However, I want to use the .Cells function rather than a Range reference to reference cells.
Given:
Dim x As Integer
Dim y As Integer
x = 5
y = 10
I want this:
ActiveSheet.Cells(1,x).Formula = "=" & ActiveSheet.Cells(y,1) & "*" & x
To provide the same output as:
ActiveSheet.Cells(1,x).Formula = "=B" & y & "*" & x
Ideally, I want to be able to dynamically change both the row and column of the cell I am referencing in the formula. However, I still want the cell to show up as a cell in the formula and not simply the value of the referenced cell.

If I see that correctly then your problem is that you want map the cell numbers to their cell names; similar to this:
ActiveSheet.Cells(1,x).Formula = "=" & Chr(Ord("A") + 1) & y & "*" & x
Keep in mind that this will only work for the first 26 columns, after that you'll need to find a better solution.

Related

formula for array max if Excel VBA

So this is my formula:
ws8.Range("Y2:Y" & lrowWFS).FormulaArray = "=Max(if(x2='New Stock Data'!H:H,'New Stock Data'!G:G))"
Problem is it's returning to {=Max(if(x2='New Stock Data'!H:H,'New Stock Data'!G:G))} in Y3 onwards.
Any idea how to solve?
It should be as simple as to change FormulaArray to Formula. (I haven't tested this), try:
ws8.Range("Y2:Y" & lrowWFS).Formula = "=Max(if(x2='New Stock Data'!H:H,'New Stock Data'!G:G))"
Couple of things. The generic formula looks like this: {=MAX(IF(criteria_range=criteria,value_range))}. So, instead of x2='New Stock Data'!H:H, you want to use: 'New Stock Data'!H:H=x2. Other than that, unlike regular formulas, array formulas assigned to a range do not adjust relative cell references.
E.g. Range("A1:A2").Formula = "=B1" will successively lead to =B1 and =B2, while Range("A1:A2").FormulaArray = "=B1" will lead to 2x =B1.
One solution is to loop through your range and assign the array formulas to each cell individually. E.g.
Dim rng As Range
Dim lrowWFS As Long
lrowWFS = 3
Set rng = ws8.Range("Y2:Y" & lrowWFS)
For Each cell In rng
cell.FormulaArray = "=MAX(IF('New Stock Data'!H:H=" & Cells(cell.Row, "X").Address(False, False) & ",'New Stock Data'!G:G))"
Next cell
A better solution would be to use SUMPRODUCT instead. This avoids the use of an array formula, and thus also the need for a loop.
E.g.:
With rng
.Formula = "=SUMPRODUCT(MAX(('New Stock Data'!H:H=X2)*('New Stock Data'!G:G)))"
End With
More in general, I would advise proper specification of the ranges in the formula. Define first_row and last_row and use something like this:
"=SUMPRODUCT(MAX(('New Stock Data'!H$" & first_row & ":H$" & last_row & "=X2)*('New Stock Data'!G$" & first_row & ":G$" & last_row & ")))"

Excel VBA Trying to write a "MAX" formula to Cells with different Ranges with For-Loop

I am trying to make VBA write a formula into different cells that will find the maximum value for a Range decided by some variables. My variables I and J are (numbers/Integers).
Here is my code.
Sub AddMAX()
Dim I As Integer
Dim J As Integer
Dim L As Integer
I = InputBox("Number of columns to check max value")
J = InputBox("Number of Rows to add formula inn and find max value of that row")
For L = 5 To 4 + J
Worksheets(1).Cells(L, 4 + I).Formula = "=" & Max(Range(Cells(L, 4), Cells(L, 3 + I)))
Next L
End Sub
Have tried to re-write the second part (part behind the equal sign) several times. Usually I get the message Compile error: Sub or Function not defined and it marks the "Max". I thought Max (also tried with big letters) was an in-built function like SUM and so on.
I'm trying to make it write an Excel formula like this into the cells:
For I=2 and J=3:
Cell F5: =MAX(D5:E5)
Cell F6: =MAX(D6:E6)
Cell F7: =MAX(D7:E7)
i.e. I want a formula in the cells like I had wrote it in the cells manually to calculate max value, so that if the value in Cells D5, to D7 and E5 to E7 change, the new max value will be found without any scripts having to run.
Let me know if something is unclear.
You should not be putting Range and Cells in a formula string, they mean nothing to the Excel formula engine. You need the Address of the cells:
Dim I As Long
Dim J As Long
Dim L As Long
I = InputBox("Number of columns to check max value")
J = InputBox("Number of Rows to add formula inn and find max value of that row")
L = 5
With Worksheets(1)
.Range(.Cells(L, 4 + I), .Cells(4 + J, 4 + I)).Formula = "=MAX(" & .Cells(L, 4).Address(False, False) & ":" & .Cells(L, I + 3).Address(False, False) & ")"
End With
The formula is actually the same for all cells, which is why it is possible to assign it in one assignment for the entire range. It looks different in the A1 reference notation, but if you switch to R1C1 in the Excel settings, you will see they are the same. Which also means it is easier to create that formula using the R1C1 notation in the first place:
Dim I As Long
Dim J As Long
Dim L As Long
I = InputBox("Number of columns to check max value")
J = InputBox("Number of Rows to add formula inn and find max value of that row")
L = 5
With Worksheets(1)
.Range(.Cells(L, 4 + I), .Cells(4 + J, 4 + I)).FormulaR1C1 = "=MAX(RC[-" & I & "]:RC[-1])"
End With
But it would appear to me that you should instead use the Excel interface the intended way. Select the cells in which the MAX formula should be. Keeping the entire range selected, put the MAX formula into any of its cells as if you were creating it for just that cell, but instead of pressing Enter, press Ctrl+Enter.
You have to be careful to distinct between the part that is seen by VBA and the final formula.
If you write
Worksheets(1).Cells(L, 4 + I).Formula = "=" & Max(Range(Cells(L, 4), Cells(L, 3 + I)))
Max (and all the following stuff) is seen by the VBA-interpreter, not Excel. But there is no Max-function, and you get an (compiler)-error.
If you write
Worksheets(1).Cells(L, 4 + I).Formula = "=Max(Range(Cells(L, 4), Cells(L, 3 + I)))"
the VBA-interpreter sees the whole stuff as a string. It cannot take care about variables like L or I because is doesn't see them. So you end up with a formula that is exactly like you write it - and Excel (not VBA) will show you an error because it doesn't understand L or I.
What you need is a statement (in VBA) that creates a string that contains the actual values of your variables, and assign it to the cell.formula. I strongly advice that you first assign this to a string variable - it makes debugging much easier:
Dim formula As String
formula = "=Max(Range(Cells(" & L & ", 4), Cells(" & L & ", 3 + " & I & ")))"
Debug.Print formula
Worksheets(1).Cells(L, 4 + I).Formula = formula
Update: Sorry, I haven't looked to the content of the formula at all, of course the Range and Cells-objects are VBA objects. What you need in your formula is the address of the range, so change the line to
formula = "=MAX(" & Range(Cells(L, 4), Cells(L, 3 + i)).Address & ")"
Now VBA will create a Range and put the address into the formula string.

VBA: Using VLOOKUP formula with a dynamic lookup_value

I am trying to embed a VLOOKUP formula into my last column after performing formatting on a sheet. My lookup value is for a column that has the following column header: "Company State".
This is my current flow:
Find the Column number with the Column Header: "Company State":
CompanyStateColumnNumber = WorksheetFunction.Match("Company State", ws.Range("1:1"), 0)
Declare the range for lookup. In this case, it exists in a worksheet/workbook that is not the active workbook/worksheet. Hence, I am referencing it using ( I have already declared TZsrcRange as a Range type):
Set TZsrchRange = TemplateWS.Range("A:C")
Now, I am trying to embed the vlookup into my last column (I found my last column in the sheet and it is stored in the variable " NewestLCol". I want to embed it into the column until the very last row (stored in variable "LastRow") :
For x = 2 To LastRow
Set dynamic_lookup_value = Cells(x, CompanyStateColumnNumber)
Cells(x, NewestLCol).Formula = " =VLOOKUP(" & _
dynamic_lookup_value.Address(0, 0) & _
", Templatews.Range(A:C).Address(0,0),3, FALSE)"
Next x
Now, when I run it, it doesn't embed the formula and doesn't give me a value. What could my issue be?
Try replacing your formula assignment with this one
Cells(x, NewestLCol).Formula = "=VLOOKUP(" & _
dynamic_lookup_value.Address(0, 0) & _
"," & _
TZsrchRange.Address(External:=True) & _
",3, FALSE)"

Excel: Find value across multiple columns and return header column

I am trying to find a way to look for "Unknown" value across multiple columns. When it is present, I would like to return all of the header columns that the value appears in into one cell for each row in column B.
For example for row 2 (the first row below my header row), I want it to return every column name that "Unknown" appears from Column F to Column Y for row 2 only and put the column name in B2. I want to repeat that process for all of my 9064 rows.
I am using Excel 2010. I looked up Match Index but was not able to find a way to do what I wanted to do. Is there a way to look for a value across multiple columns and return every column header that values appears in for that row and put all of the column headers into one cell?
Data View
Here's a custom function. First place the following code in a regular module (Alt+F11 >> Insert >> Module >> Copy/paste >> Alt+Q)...
Function AConcat(a As Variant, Optional Sep As String = "") As String
' Harlan Grove, Mar 2002
Dim Y As Variant
If TypeOf a Is Range Then
For Each Y In a.Cells
AConcat = AConcat & Y.Value & Sep
Next Y
ElseIf IsArray(a) Then
For Each Y In a
AConcat = AConcat & Y & Sep
Next Y
Else
AConcat = AConcat & a & Sep
End If
AConcat = Left(AConcat, Len(AConcat) - Len(Sep))
End Function
Then enter the following formula in AA2, confirm with CONTROL+SHIFT+ENTER, and copy down:
=SUBSTITUTE(AConcat(IF(LEFT(F2:Y2,3)="Unk",", "&$F$1:$Y$1,"")),", ","",1)

vba auto increment a number?

i am trying to insert a reference number into a cell in excel using vba. I want a prefix text of 'V0000' followed by an auto incremented number starting from 836.
so for each row that gets inserted I will have V0000836
Then V0000837
etc
A large portion of my code creates a new row and inserts data into it automatically one after the other, but instead of posting my whole code I am just wanting to focus on this one line of code which inserts value into column AA of my spreadsheet. I am using the following but it just gives me V00001 each time. can someone show me how I can get my code to do what I want it to.
ws2.Range("AA" & DestRow).Value = "V0000836" & Value + 1
Consider an alternative that does not remove numerical (mathematical) functionality from the cell's value.
ws2.Range("AA" & DestRow).numberformat = "\V0000000"
ws2.Range("AA" & DestRow).Value = 836 + 1
If you require the formatted (displayed) alphanumeric designation you can retrieve it like this.
Dim str as string, num as long
str = ws2.Range("AA" & DestRow).text '◄ V0000837
num = ws2.Range("AA" & DestRow).value '◄ 837
Using VBA, you can do this by incrementing the number each time the loop goes round and then prefixing the V0000 to the front like so:
Dim i As Integer
Dim cell As Range, rng As Range
Set rng = Range("A1:A10")
i = 836
For Each cell In rng
cell.Value = "V000" & i
i = i + 1
Next cell

Resources