Good morning all,
I have a problem with vba translating formulas into excel:
I've got this code:
'Tramos para calcular el total, mañana, tarde y noche
TramoIni = Array(4, 20, 36, 4)
TramoFin = Array(51, 35, 51, 19)
'Formulas
FormulaTramo = _
Array("=SUMIFS('Mapa Turnos'!C[4],'Mapa Turnos'!C1,RC1,'Mapa Turnos'!C3,RC2)/30", _
"=R[-1]C*(1-SUM(R[5]C:R[8]C))", _
"=IFERROR(IF(IFERROR((R[13]C*R[-1]C*1800)/R[3]C,0)/R[2]C>1,1," _
& "IFERROR((R[13]C*R[-1]C*1800)/R[3]C,0)/R[2]C),0)", _
"=sla(IF(R[-2]C=0,0,IF(R[-2]C<1,1,R[-2]C)),INDIRECT(ADDRESS(MATCH(RC2,Objetivos!C2,0),4," _
& ",,""Objetivos"")),R[1]C,R[2]C)", _
"=IF(AND(R[-7]C>0,R[-11]C=0),""SI"",""NO"")", _
"=1", _
"=1", _
"=SUM(RC1:RC2)", _
"=R[-11]C-R[-2]C", _
"=CallCapacity(R[-12]C,INDIRECT(ADDRESS(MATCH(RC2,Objetivos!C2,0),3," _
& ",,""Objetivos"")),INDIRECT(ADDRESS(MATCH(RC2,Objetivos!C2,0),4,,,""Objetivos"")),R[-8]C)", _
"=IF(R[-1]C>R[-10]C,R[-10]C,R[-1]C)", "=Utilisation(R[-14]C,R[-11]C,R[-10]C)")
LastRow = ws.Range("A100000").End(xlUp).Row
Col = ws.Range("XDF4").End(xlToLeft).Column
ColTotal = ws.Cells.Find("Total").Column
ColF = ColTotal - 1
ColMañana = ws.Cells.Find("Mañana").Column
ColTarde = ws.Cells.Find("Tarde").Column
ColNoche = ws.Cells.Find("Noche").Column
For i = 1 To UBound(KPI)
ws.Range(ws.Cells(4, 1), ws.Cells(LastRow, Col)).AutoFilter Field:=3, Criteria1:=KPI(i)
If KPI(i) <> "5.Pronóstico" And KPI(i) <> "92.Requeridos" Then
With ws.Range(ws.Cells(5, 4), ws.Cells(LastRow, ColF)).SpecialCells(xlCellTypeVisible)
.FormulaR1C1 = "'" & FormulaTramo(i - 1)
End With
End If
For x = 0 To UBound(TramoIni)
'Formulas total, mañana, tarde y noche
FormulaTotal = _
Array("=SUM(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ")/2", _
"=SUM(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ")/2", _
"=IFERROR(IF(SUMPRODUCT(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ",R[2]C" & TramoIni(x) & _
":R[2]C" & TramoFin(x) & ")/R[2]C>1,1,SUMPRODUCT(RC" & TramoIni(x) & _
":RC" & TramoFin(x) & ",R[2]C" & TramoIni(x) & ":R[2]C" & TramoFin(x) & ")/R[2]C),0)", _
"=IFERROR(SUMPRODUCT(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ",R[1]C" & TramoIni(x) & _
":R[1]C" & TramoFin(x) & ")/R[1]C,0)", _
"=SUM(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ")", _
"=SUM(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ")/2", _
"=IF(COUNTIF(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ",""SI"")>0,""SI"",""NO"")", _
"=IFERROR(SUM(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ")/2,0)", _
"=SUM(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ")", _
"=IF(R[-2]C>R[-10]C,R[-10]C,R[-2]C)", _
"=IFERROR(IF(SUMPRODUCT(RC" & TramoIni(x) & ":RC" & TramoFin(x) & ",R[-14]C" & _
TramoIni(x) & ":R[-14]C" & TramoFin(x) & ")/R[-14]C>1,1,SUMPRODUCT(RC" & _
TramoIni(x) & ":RC" & TramoFin(x) & ",R[-14]C" & TramoIni(x) & ":R[-14]C" & _
TramoFin(x) & ")/R[-14]C),0)")
With ws.Range(ws.Cells(5, TramoFin(0) + x + 1), ws.Cells(LastRow, TramoFin(0) + x + 1)). _
SpecialCells(xlCellTypeVisible)
.FormulaR1C1 = "'" & FormulaTotal(i - 1)
End With
Next x
Next i
ws.Rows(4).AutoFilter
x = ws.Range("A100000").End(xlUp).Row
i = ws.Range("XDF4").End(xlToLeft).Column
ws.Range(ws.Cells(5, 4), ws.Cells(x, i)).Value = ws.Range(ws.Cells(5, 4), ws.Cells(x, i)).Value
This is just some arrays containing formulas and the column where they should start taking values.
The thing is that the if, countif and sum aren't taking the cells references when going to excel:
As you can see above every formula has the same cell reference, the one that vba has.
But later on when we convert it to excel (last line of code):
As you can see sumproducts worked well, but the rest are taking literally the column RC and the row which was supposed to be the column reference on VBA.
Any thoughts what could be doing this? I need to work like this because this worksheet can have up to 7k rows and 50+ columns with formulas in like the 80% of them so introducing the formulas in every loop would take ages, instead I'm doing this so they all recalculate at the same time.
This way still takes ages to calculate and I don't know if there is a more efficient way to input so many formulas which include erlangs and custom functions.
Any help would be appreciated! Thanks!
MCVE of the problem in question:
Range("A1").FormulaR1C1 = "'" & "=SUM(RC20:RC25)"
Range("A1").Value = Range("A1").Value
Formula in RC-notation is assigned to the Value property. Excel tries to recognize the formula type. There are only absolute references in this formula, so it looks like valid A1-notation relative formula.
Some of the formulas containing relative references (with square brackets) were correctly recognized as RC notation - because those would not be valid A1 formulas.
To solve the problem, array with formulas needs to be assigned to FormulaR1C1 property:
ws.Range(ws.Cells(5, 4), ws.Cells(x, i)).FormulaR1C1 = ws.Range(ws.Cells(5, 4), ws.Cells(x, i)).Value
Much better way to avoid long calculations during code execution is to disable automatic calculation:
Application.Calculation = xlCalculationManual
'all code here
Application.Calculation = xlCalculationAutomatic
When I run this code, I repeatedly am getting error 1004
with activecell
.Formula = "=CONCATENATE(" & ActiveCell.Offset(0, -2).Address & "," _
& ":" & "," & ActiveCell.Offset(0, -1).Address & ")"
end with
Does anyone have an idea of where the issue is presenting itself?
You want
"=CONCATENATE(" & ActiveCell.Offset(0, -2).Address & ","":""," & ActiveCell.Offset(0, -1).Address & ")"
Because your current formula evaluates to (with F4 selected)
=CONCATENATE($D$4,:,$E$4)
Which is wrong hence the error.
Try
Option Explicit
Public Sub test()
With ActiveCell
.Formula = "=CONCATENATE(" & .Offset(0, -2).Address & ","":""," & .Offset(0, -1).Address & ")"
End With
End Sub
That has a formula which evaluates to
=CONCATENATE($D$4,":",$E$4)
This adds the missing "" surrounding your :
I'm trying to create a macro for a Personal Budget worksheet, where there is a cell with tedious work.
Using the "Record Macro" button I traced the coding behind the operation I made in the cell, which is the following:
Sub calculo_otherex()
' calculo_otherex Macro
' Cálculo de otros gastos con tarjeta.
'
ActiveCell.FormulaR1C1 = _
"=Extractos!R[-89]C[-2]-('Home Expenses'!R[-105]C+'Home Expenses'!R[-60]C+'Home Expenses'!R[-16]C+Health!R[-105]C+Health!R[-67]C+Health!R[-29]C+Gifts!R[-99]C+'Daily Living'!R[-87]C+'Daily Living'!R[-29]C+'Daily Living'!R[20]C+'Daily Living'!R[59]C+'Daily Living'!R[102]C+Entertainment!R[-105]C+Entertainment!R[-67]C+Entertainment!R[-29]C+Entertainment!R[9]C+Transportation!R[-105]C)"
Range("H129").Select
End Sub
As you can see, in the formula I refer to other sheets, and to specific cells which reflect a result of a certain month (in this case July) and a specific subset (charges to a credit card).
What I want to do is insert a loop so this procedure repeats for all the months, but the problem is that the data in the sheet "Extractos" appears every 7th cell to the right from "Extractos!R[-89]C[-2]", as the other data in the formula appears in the next column.
How could I solve this??
Thank you very much.
Give the following a try... It's hard to read R1C1, so I changed it up a bit and you'll need to replace all my "A1" references to the first month's cell reference. Also, the for loop will only loop 12 times - 12 months in a year. You can manually change this if you'd like. Lastly, the formula will be written in the activecell then the following formulas will be written in the next cell/column to the right.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'instead of using R1C1, use ranges with offsets - it's much easier to read :) ''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'I used "A1" as a placeholder. Replace this with the actual cell reference for the first month
'The first loop will use the "A1" range. Then, the 2nd and following loops will move over 1 or 7 columns
'i = move over 1 column
'x = move over 7 columns
For i = 0 To 11 'this will loop through 12 times 0-11
ActiveCell.Offset(0, i).Formula = _
"=Extractos!" & Range("A1").Offset(0, x).Address _
& "-('Home Expenses'!" & Range("A1").Offset(0, i).Address _
& "+'Home Expenses'!" & Range("A1").Offset(0, i).Address _
& "+'Home Expenses'!" & Range("A1").Offset(0, i).Address _
& "+Health!" & Range("A1").Offset(0, i).Address _
& "+Health!" & Range("A1").Offset(0, i).Address _
& "+Health!" & Range("A1").Offset(0, i).Address _
& "+Gifts!" & Range("A1").Offset(0, i).Address _
& "+'Daily Living'!" & Range("A1").Offset(0, i).Address _
& "+'Daily Living'!" & Range("A1").Offset(0, i).Address _
& "+'Daily Living'!" & Range("A1").Offset(0, i).Address _
& "+'Daily Living'!" & Range("A1").Offset(0, i).Address _
& "+'Daily Living'!" & Range("A1").Offset(0, i).Address _
& "+Entertainment!" & Range("A1").Offset(0, i).Address _
& "+Entertainment!" & Range("A1").Offset(0, i).Address _
& "+Entertainment!" & Range("A1").Offset(0, i).Address _
& "+Entertainment!" & Range("A1").Offset(0, i).Address _
& "+Transportation!" & Range("A1").Offset(0, i).Address & ")"
'add 7 to x variable
x = x + 7
'loop and add 1 to i
Next i
'macro done, select H129
Range("H129").Select
This code previously worked, I changed some of the strings and it has started malfunctioning. About halfway through the script it will start assigning "N/A" for about 10 lines then proceeds to assign numbers again. Example, "O" + i returns "level 1" and is changed to "N/A" with the other affected column changing as well as if it registered a "level 0", it will then place the "1" further down, after about 20 instances of offset placement the code returns to working. If I re-input just column O and run it again, the code functions properly. I am greatful for any assistance.
PS, I am not a coder so I know it is kind of messy.
Sub Fix_Haz_Rec()
Dim lastRow3 As Integer 'last row of sheet 3
Sheets(3).Activate
lastRow3 = Cells(Rows.Count, 1).End(xlUp).Row
For i = 4 To lastRow3
ActiveSheet.Range("D" & i).Value = Math.Round(ActiveSheet.Range("D" & i).Value, 3)
ActiveSheet.Range("E" & i).Value = Math.Round(ActiveSheet.Range("E" & i).Value, 3)
ActiveSheet.Range("F" & i).Value = Math.Round(ActiveSheet.Range("F" & i).Value, 3)
ActiveSheet.Range("G" & i).Value = Math.Round(ActiveSheet.Range("G" & i).Value, 3)
ActiveSheet.Range("I" & i).Value = Math.Round(ActiveSheet.Range("I" & i).Value, 2)
ActiveSheet.Range("J" & i).Value = Math.Round(ActiveSheet.Range("J" & i).Value, 3)
ActiveSheet.Range("K" & i).Value = Math.Round(ActiveSheet.Range("K" & i).Value, 3)
ActiveSheet.Range("L" & i).Value = Math.Round(ActiveSheet.Range("L" & i).Value, 3)
If ActiveSheet.Range("M" & i).Value = "N/A" Or ActiveSheet.Range("M" & i).Value = "#N/A" Then
Else
If ActiveSheet.Range("O" & i) = "Level 4" Then
ActiveSheet.Range("O" & i) = 4
Else
If ActiveSheet.Range("O" & i) = "Level 3" Then
ActiveSheet.Range("O" & i) = 3
Else
If ActiveSheet.Range("O" & i) = "Level 2" Then
ActiveSheet.Range("O" & i) = 2
Else
If ActiveSheet.Range("O" & i) = "Level 1" Then
ActiveSheet.Range("O" & i) = 1
Else
If ActiveSheet.Range("O" & i) = "Level 0" Then
ActiveSheet.Range("L" & i) = ActiveSheet.Range("N" & i).Value / 12
ActiveSheet.Range("O" & i) = "N/A"
Else
If ActiveSheet.Range("O" & i) = ">Max." Then
ActiveSheet.Range("O" & i) = "> Max"
End If
End If
End If
End If
End If
End If
Next i
Sheets("Recommended").Activate
ActiveSheet.Range("A4:P" & lastRow3).Select
Selection.Sort Key1:=Range("A3"), Order1:=xlAscending, Header:=xlYes
ActiveSheet.Range("D4:M" & lastRow3).Select
Selection.NumberFormat = "0.00"
End Sub
give this a go - it should go a long way to helping you to achieve what you're after.
Sort out the value replacements first, then move to the mopping up - i.e. keep trying to find "Level 0" and do the L / N operation until you can't find that value any more.
With ActiveSheet.Range("O4:O" & lastRow3)
.Replace "Level 4", 4, xlWhole
.Replace "Level 3", 3, xlWhole
.Replace "Level 2", 2, xlWhole
.Replace "Level 1", 1, xlWhole
.Replace ">Max.", "> Max", xlWhole
Set rngLevel0 = .Find(What:="Level 0", LookAt:=xlWhole)
Do While Not rngLevel0 Is Nothing
ActiveSheet.Range("L" & rngLevel0.Row) = ActiveSheet.Range("N" & rngLevel0.Row).Value / 12
rngLevel0.Value = "N/A"
Set rngLevel0 = .Find(What:="Level 0", LookAt:=xlWhole)
Loop
End With
i have a debug in my code, but i cannot figure out why it is happening, could you please review the code and see where i messed up? Note the error debug is happening on the ActiveCell.FormulaR1C1 line.
'ENRICHMENT CODE FOR VARIOUS TITLES
For Each wbtitle In wbrange
sThisWorkTitle = wbtitle
sThisWorkColumnNum = wbtitle.Column
sThisWorkColumnNam = Split(Cells(, sThisWorkColumnNum).Address, "$")(1)
'identifying CASH RADICAL COLUMN LETTER
If sThisWorkTitle = "Account Cash Radical" Then
scashradicalcolumnnam = Split(Cells(, sThisWorkColumnNum).Address, "$")(1)
Else
'do nothing
End If
''' CASH RELATED?
If sThisWorkTitle = "Cash Related?" Then
wbtitle.Select
Range(sThisWorkColumnNam + gspstart).Select
ActiveCell.FormulaR1C1 = Application.WorksheetFunction.VLookup(Range(scashradicalcolumnnam & ActiveCell.Row), Range(scashradicalcolumnnam & immsstart & ":" & scashradicalcolumnnam & immsfinal), 1, False)
ActiveCell.AutoFill Range(ActiveCell.Address, Cells(gspfinal))
Columns(sThisWorkTitle).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
Else
'do nothing
End If
Scott has highlighted the problem line.
You could try amending so an actual formula is inserted into the cell.
So instead of the following:
ActiveCell.FormulaR1C1 = _
Application.WorksheetFunction.VLookup( & _
Range(scashradicalcolumnnam & ActiveCell.Row) & _
, Range(scashradicalcolumnnam & immsstart & ":" & scashradicalcolumnnam & immsfinal), 1, False)
Something like:
ActiveCell = "=vlookup(" & scashradicalcolumnnam & ActiveCell.Row & _
"," & scashradicalcolumnnam & immsstart & ":" & _
scashradicalcolumnnam & immsfinal & _
", 1, False)"