我正在尝试编写一个VBA例程,该例程将某些值替换为单元格“ B16”(从另一个工作簿上的列表中删除),在每次替换后重新计算整个工作簿,并记录单元格“ I31”的值(后重新计算)在另一本工作簿中。
我观察到的行为与我的预期有很大不同。假设在运行例程之前,“ I31”的值为0,并且在第一次迭代后必须等于1,在第二次迭代后必须等于2。当我运行例程时,两个记录的值均为0(而不是1和2),并且“ I31”本身的值为2。后者很有意义。似乎Excel在将它们复制到其他单元格之前没有刷新单元格值。也许在复制单元格值之前,它不等待'SendKeys“ {F9}”'终止。因此,我迫使例程在每次迭代后暂停一分钟(重新计算大约需要十秒钟),这一次记录的值都再次为0,而“ I31”本身也为0。更糟糕的是。
在相关说明中,Application.Calculate(或其变体,如Worksheet.Calculate)对工作表没有任何影响。当我使用这些而不是SendKeys“ {F9}”时,什么都不会重新计算。即使例程中唯一的行是Application.Calculate,也会发生这种情况。我不知道为什么会这样。
我的例程在下面。任何帮助表示赞赏。谢谢。
Sub createData()
Dim x As Integer
For x = 1 To 2
Range("B16").value = Worksheets("Types").Cells(x, 1)
'Application.Calculate
SendKeys "{F9}"
'Application.Wait Now() + TimeValue("00:01:00")
Worksheets("Results").Cells(x, 1).value = Range("I31").value
Next
End Sub
答案 0 :(得分:1)
隐含的ActiveSheet
引用是主要问题。
如果您正在使用的3个工作表在编译时位于ThisWorkbook
中(即它们不是在运行时创建的,那么您可以在VBE的 Project Explorer中看到它们 em>),然后在 Project Explorer (Ctrl + R)中找到它们,然后打开 Properties 工具窗口(F4)并更改其(Name)
属性(默认值为Sheet1
。
因此,您有一个TypesSheet
,其名称为“ Types”-“ Types”是工作表的“ tab”上的名称,并且TypesSheet
是一个标识符,您可以在代码中的任何位置引用该标识符到那张纸。
对其他两个进行相同操作,因此您拥有TypesSheet
,ResultsSheet
和MainSheet
。
现在您既可以明确又高效:
TypesSheet.Range("B16").Value = TypesSheet.Cells(x, 1).Value
ResultsSheet.Cells(x, 1).Value = TypesSheet.Range("I31").Value
不确定您要引用的是哪个工作表,但这是明确的代码,不取决于宏开始运行时处于活动状态的工作表。
如果工作表是在运行时创建的(即通过某些VBA代码添加到工作簿中),则您不能使用其代号,而必须从{{1} } Worksheets
对象的集合。
如果工作表存在于Workbook
中(即,与该VBA代码写入位置相同的文件中),则可以执行以下操作:
ThisWorkbook
以此类推。请注意,像这样通过工作表名称检索工作表引用,会使您的代码容易受到用户的攻击,该用户会重命名选项卡(假定不受保护的工作簿结构)。这就是为什么您应该尽可能使用代号的原因。