我有几个excel文件,它们有计时器和宏执行。但是一个大问题是当调用工作簿A的宏时,工作簿B是活动的。宏在错误的书中执行并失败。
期待您的回答
答案 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对象重写这些。