如何避免在错误的工作簿中执行VBA功能

时间:2011-03-10 13:05:00

标签: excel vba

我有几个excel文件,它们有计时器和宏执行。但是一个大问题是当调用工作簿A的宏时,工作簿B是活动的。宏在错误的书中执行并失败。

  1. 我是否需要在每个函数的开头放置windows()。?
  2. 如果我有不同的模块,如何将此工作簿名称传递给所有模块?
  3. 这似乎过分而且不对。这个问题有什么好的解决方案吗?
  4. 期待您的回答

3 个答案:

答案 0 :(得分:2)

你正走在正确的轨道上

  

2.如果我有不同的模块,我如何将此工作簿名称传递给所有模块

我假设你的宏正在使用ActiveWorkbook属性,或者只使用像Range这样的工作表属性而没有限定它们?

而不是使用ActiveWorkbook使用ThisWorkbook。而不是使用Range使用ThisWoorkbook.Worksheets(1).Range等等。否则,宏将假定活动工作表是您想要的。

Sub MyMacro
  Range("A1").Text = "Test"
End Sub

尝试

Sub MyMacro(ByVal oWorksheet as Worksheet)
  oWorksheet.Range("A1").Text = "Test"
End Sub

然后将工作表对象作为参数传递。

您可能还会发现ThisWorkbook对象很有用 - 它是宏所在的工作簿,或Application.Caller对象,它是调用当前宏的对象,例如Range对象(如果它)是一个单元格公式,或者可能是您案例中的计时器对象。

答案 1 :(得分:2)

如果您的宏的行为与您描述的方式相同,则它们可能明确地或隐含地依赖于

ActiveWorkbook

 ActiveSheet

如果可能的话,应该避免这种依赖。宏录制器生成此类代码,您应该在录制宏时立即更改它。

例如,如果你有一些像

这样的代码
s = Range("A1").Value

Excel隐式将其更改为

s = ActiveSheet.Range("A1").Value

通过明确使用正确的工作表或工作簿对象访问所有单元格,范围,工作簿部分等,可以避免这种情况:

Dim sh as Worksheet
Set sh = .... ' Initialize sh the first time where the sheet is created or loaded

'later on:

s = sh.Range("A1").Value

使用表格

的参数
sh as Worksheet, wb as workbook

对于您的子和函数,您可以在模块之间传递正确的工作表和工作簿,这将回答您的第二个问题。如果您需要访问宏所在的工作簿,请使用ThisWorkbook

答案 2 :(得分:0)

我会再往前走......确保你的代码没有 选择 要么 ActiveCell

其中的对象。您需要使用Range对象重写这些。