早上好,
vba将公式转换为excel时出现问题:
我有以下代码:
'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
这只是一些包含公式的数组以及应从中开始获取值的列。
问题是,当进入excel时,if,countif和sum不会采用单元格引用:
如上所示,每个公式都具有相同的单元格引用,即vba的单元格引用。
但是稍后,当我们将其转换为excel(代码的最后一行)时:
您可以看到sumproducts效果很好,但是其余的实际上都是使用RC列和应该作为VBA上列引用的行。
有什么想法可以做到这一点?我需要这样工作,因为该工作表最多可以包含7k行和50+列,其中包含80%的公式,因此在每个循环中引入公式都需要一定的时间,相反,我这样做是为了让它们全部重新计算同时。
这种方法仍然需要花费很多时间来计算,我不知道是否有一种更有效的方法来输入这么多包含erlangs和自定义函数的公式。
任何帮助将不胜感激!谢谢!
答案 0 :(得分:1)
有关问题的MCVE:
Range("A1").FormulaR1C1 = "'" & "=SUM(RC20:RC25)"
Range("A1").Value = Range("A1").Value
以RC表示的公式已分配给Value
属性。 Excel尝试识别公式类型。该公式中只有绝对引用,因此它看起来像有效的A1表示法相对公式。
某些包含相对引用的公式(带有方括号)被正确识别为RC表示法-因为这些公式不是有效的A1公式。
要解决此问题,需要将具有公式的数组分配给FormulaR1C1
属性:
ws.Range(ws.Cells(5, 4), ws.Cells(x, i)).FormulaR1C1 = ws.Range(ws.Cells(5, 4), ws.Cells(x, i)).Value
在代码执行期间避免长时间计算的更好的方法是禁用自动计算:
Application.Calculation = xlCalculationManual
'all code here
Application.Calculation = xlCalculationAutomatic