I want to plug a range object into a formula. An example should look roughly like this:
Dim x As Range
Set x = Range(Cells(1, 1), Cells(2, 1))
Range("C1").Formula = "=SUM(" & x & ")"
The result should be "=SUM(A1:A2)" in cell C1.
The point is to plug the the range object into a formula. I used SUM as an example, the real formula is more complicated.
I guess there is an easy answer to this, e.g. some method for a range object, but I have't found it after some pondering ...
Thanks in advance,
Dainis
You need
Range("C1").Formula = "=SUM(" & x.Address(False, False) & ")"
See also
http://www.dailydoseofexcel.com/archives/2004/04/16/worksheet-formulas-in-vba-part-i/
http://www.dailydoseofexcel.com/archives/2004/04/16/worksheet-formula-in-vba-part-ii/
Use x.address, that should do the trick
Related
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 & ")))"
ws2.Cells(87, col - 2).FormulaR1C1 = "=R[-5]C[0]-'Another Sheet'!F89"
When I run the above code, the result would be, "=AW83- 'Another Sheet'!'F89", which returns an error because the ' between ! and F89. I tried to use " & " but it does not work this way. Does anyone know how to solve this? Thanks in advance!!
You cannot mix R1C1 and A1-notation in a formula. If you use FormulaR1C1, you have to provide all addressen in R1C1-notation. You can use Application.ConvertFormula to convert your F89:
dim r as range
set r = ws2.Cells(87, col - 2)
r.FormulaR1C1 = "=R[-5]C[0]-" & _
Application.ConvertFormula("'Another Sheet'!F89", xlA1, xlR1C1, , r)
I have to calculate the difference between the values of 2 columns(firstCol and lastCol) and set those differences in a different column(NextColumn). The row count keeps changing, so I have to calculate the rowCount before calculating the difference. I'm trying to write a loop using Range so that the difference can be calculated but it doesn't seem to work.
For i = 3 To lastRow
Range(Cells(3, NextColumn), Cells(lastRow, NextColumn)).FormulaR1C1 = "=Range(Cells(i, firstCol),Cells(i,firstCol)).Value - Range(Cells(i, lastCol),Cells(i,lastCol)).Value"
Next i
Any help would be greatly appreciated!
Thank you
Nick
For any input of "i" into the formula, you need to use " & i & " when using using a formula="", such as:
"=A" & i & "+B" & i
When you change to just a formula that doesn't input a formula to the cell (math happens in VBA), you can ignore the Excel formatting and "" blocking, such as:
= Cells(i,"A").Value + Cells(i,"B").Value
Make sure to use your loop variable where appropriate, so that you would have an outcome in a loop like:
Dim i as Long
For i = 1 to 10
Cells(i,"C").Formula = Cells(i,"A").Value + Cells(i,"B").Value
Next i
Why looping ? Unless I misunderstood the question, something like this should do the trick:
Range("X3:X"& lastrow).Formula = "=C3-D3"
The formula will adjust.
vba needs to be outside the quotes and you do not need the loop:
Range(Cells(3, NextColumn), Cells(lastRow, NextColumn)).Formula = "=" & Cells(3, firstCol).Address(0, 0) & "-" & Cells(3, lastCol).Address(0, 0)
No loop needed. Excel will change the relative references as needed.
I would like to know how may i convert this code into dynamic range autofill for the column I to enable the freedom of editing the excel sheet at a later time without the need to adjust the vba code.
Sub Rowcount()
'Charles, M
Dim H As Long
Set sh = Worksheets("Report-Charles, M")
H = sh.UsedRange.Rows.Count
Range("I2:I" & H).Formula = "=IF((AND(OR(E2=""Unrated"",E2=""""),OR(G2<>""Unrated"",G2<>""""))),G2,IF(E2>=""4,25"",""High Performance"",IF(E2<""3,35"",""Low Performance"",IF(AND(E2>=""3,35"",E2<""4,25""),""Medium Performance"",""Unrated""))))"
MsgBox (H) & "Rows have been Autofilled with 3 scale Rating Results"
End Sub
Have a look into the AutoFill function:
Range("I2:I" & H).AutoFill Destination:=Range("I2:I2000"), Type:=xlFillDefault
First off, you are only implicitly referencing the Report-Charles, M as the ActiveSheet property to put the .Formula into; not explicitly with direct reference.
Second, To assign the formula, use a direct .Formula write, the Range.AutoFill method or the Range.FillDown method.
Lastly, writing a formula .Formula through VBA should be done with EN-US syntax and regional settings. If you want to use non-EN-US regional settings like 3,35 or 4,25 then use the Range.FormulaLocal property.
Above all else, treat numbers as numbers; not as text-that-look-like-numbers.
with Worksheets("Report-Charles, M")
h = .UsedRange.Rows.Count
.Range("I2:I" & H).FormulaLocal = _
"=IF((AND(OR(E2=""Unrated"", E2=TEXT(,)), OR(G2<>""Unrated"", G2<>TEXT(,)))), G2, IF(E2>=4,25, ""High Performance"", IF(E2<3,35, ""Low Performance"", ""Medium Performance"")))"
.Range("I2:I" & H).Formula = _
"=IF((AND(OR(E2=""Unrated"", E2=TEXT(,)), OR(G2<>""Unrated"", G2<>TEXT(,)))), G2, IF(E2>=4.25, ""High Performance"", IF(E2<3.35, ""Low Performance"", ""Medium Performance"")))"
end with
with Worksheets("Report-Charles, M")
'any of the following will fill column I with formulas to the last row in .UsedRange
'all of the following assumes a valid formula in I2
h = .UsedRange.Rows.Count
.Range("I2:I" & H).Formula = .Range("I2").Formula
.Range("I2:I" & H).FillDown
.Range("I2:I" & H).DataSeries Rowcol:=xlColumns, Type:=xlAutoFill
.Range("I2").AutoFill Destination:=.Range("I2:I" & H), Type:=xlFillDefault
end with
I've shortened one IF condition since the AND was unnecessary and Medium was the default response. Using TEXT(,) is the same as saying "" and does not have to double-up double-quotes.
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.