将公式添加到单元格的VBA
我正在尝试写一些VBA,将标题文本添加到3个单元格,然后填充公式一直到最后一行。 我已经写了下面,它写入标题没有问题,但是当它到达我的第一个.Formula
它抛出一个
应用程序定义或对象定义的错误
什么需要改变,以便这个macros将成功执行? (公式直接从单元格中的公式中获得,所以我知道它们至less在“前端”是有效的公式)
Function Gre() Range("E2").Select ActiveCell.FormulaR1C1 = "Under" Range("F2").Select ActiveCell.FormulaR1C1 = "Over" Range("G2").Select ActiveCell.FormulaR1C1 = "Result" With Range("E2:E" & Cells(Rows.Count, "C").End(xlUp).Row) .Formula = "=IF(C2<B2,B2-C2,"")" End With With Range("F2:F" & Cells(Rows.Count, "C").End(xlUp).Row) .Formula = "=IF(C2>B2,C2-B2,0)" End With With Range("G2:G" & Cells(Rows.Count, "C").End(xlUp).Row) .Formula = "=IF(F2>0,'Issue',"")" End With End Function
这个问题很可能是你用公式逃避了引号。
你需要的是:
.Formula = "=IF(C2>B2,B2-C2,"""")"
例如第一个。 其他引号也需要翻倍。
作为一个侧面说明,最好还是指定你正在使用的工作表:
Dim ws as worksheet Set ws = Sheets("mySheet") ws.Range("E2").FormulaR1C1 = "Under"
等等
如果你不这样做,你有时会在运行代码时发生错误。
- 正如OpiesDad所build议的那样,为了尽量减less歧义,请避免使用
ActiveCell
等。 - 与直接分配给单元格相比,使用“
Select
也会降低性能。 - 我敢肯定,你需要通过加倍报价,在VBA中的Excel公式中的引号转义,所以一个正常的空string变成
""""
。 你也有一个公式中的单引号的Issue
,我很确定会在Excel中的错误; 这也应该在双引号中。 - 我很难弄清楚
Range("E2:E" & Cells(Rows.Count, "C").End(xlUp).Row)
实际上是做了什么,但是听起来好像你想要selectE2
最后使用的表单行。 避免Rows.Count
或只是泛指一张表的行,因为这将行10 ^ 31。 使用Worksheet.UsedRange
从内容的第一行和第一列到内容的最后一行和第一列。 这也包括空string,有时可能有点棘手,但通常比处理数以千计的额外行更好。
也,
-
如果只包含一个语句,则不需要使用
With
,尽pipe它不会导致任何问题。 -
除非你有理由,否则我不会混合使用
Range.Formula
和Range.FormulaR1C1
。Function Gre() Dim ws as Worksheet Set ws = ActiveSheet Dim used as Range Set used = ws.UsedRange Dim lastRow as Integer lastRow = used.Row + used.Rows.Count - 1 ws.Range("E2").Formula = "Under" ws.Range("F2").Formula = "Over" ws.Range("G2").Formula = "Result" ws.Range("E2:E" & lastRow).Formula = "IF(C2<B2, C2-B2, """")" ws.Range("F2:F" & lastRow).Formula = "IF(C2<B2, C2-B2, 0)" ws.Range("G2:G" & lastRow).Formula = "IF(F2>0, ""Issue"", """")" End Function
-
第一个问题是select细胞。 这要求macrosselect单元,然后确定单元地址。 如果您需要实际select一个单元格,请使用
Application.ScreenUpdating = False
。 然后macros不必显示单元格的光标select。 在下面的公式分配代码行中删除select和合并范围将获得一些速度/效率。Range("E2").FormulaR1C1 = "Under"
-
Range("E2:E" & Cells(Rows.Count, "C").End(xlUp).Row)
是select空白列(行1048576)中最后一个单元格的代码版本,然后使用Ctrl键和确定最低/最后使用的单元格的向上键。 由于列是空白的,所以每次都会得到1的行数。 既然你在找最后一行 倒数倒数可能会更快。 我最喜欢的方法是一个循环。 在循环内增加一个variables,同时查找最后一行。 然后,variables可以用来代替你的自下而上的策略。t = 0 Do Until Range("C2").Offset(t, 0).Value = "" t = t + 1 Loop With Range("E2:E" & t) .Formula = "=IF(C2<B2,B2-C2,"""")" End With`
-
就像TSQL一样,引号字符也需要自己的引用字符。
.Formula = "=IF(C2<B2,B2-C2,"""")"
- 在这种情况下,可以使用范围Fillup VBA函数来从底部填充所有单元格,并使用公式公式计算Excel公式参考相对性。 下面的代码从循环计数器的范围开始。 接下来,我们设置一个variables等于Excel中的总行数减去对应于计数器行的行。 然后,我们通过必要的行调整原始区域的大小,并使用FillDown函数向下复制第一个公式。
-
这是最终的代码。 这将填充从Excel最后一行开始的范围。
Sub Gre() Range("E2").FormulaR1C1 = "Under" Range("F2").FormulaR1C1 = "Over" Range("G2").FormulaR1C1 = "Result" Do While Range("e2").Offset(t, 0).Value <> "" t = t + 1 Loop Range("E2").Offset(t, 0).Formula = "=IF(C2<B2,B2-C2,"""")" r1 = Range("e2").EntireColumn.Rows.Count r2 = Range("E2").Offset(t, 0).Row Range("E2").Offset(t, 0).Resize(r1 - r2, 1).FillDown Range("F2").Offset(t, 0).Formula = "=IF(C2>B2,C2-B2,0)" Range("F2").Offset(t, 0).Resize(r1 - r2, 1).FillDown Range("G2").Offset(t, 0).Formula = "=IF(F2>0,""Issue"","""")" Range("G2").Offset(t, 0).Resize(r1 - r2, 1).FillDown End Sub
除了使用双引号之外,您可能需要在前两个公式中使用0,否则可能会计算为空string。 这可能会给最后一个公式带来意想不到的结果,即不正确地返回“问题”。
如果您的数据和3个新列之间没有空白列,则可以使用CurrentRegion来确定行数:
Range("E2:E" & Cells.CurrentRegion.Rows.Count).Formula = "=if(C2'<'B2,B2-C2,0)" Range("F2:F" & Cells.CurrentRegion.Rows.Count).Formula = "=if(C2>B2,C2-B2,0)" Range("G2:G" & Cells.CurrentRegion.Rows.Count).Formula = if(F2>0,""Issue"","""")"