VBA EXCEL:在不同的工作簿上执行代码

我有一个button,执行以下操作:

  • 打开一个名为“导入”的文件
  • 取消导入单元格
  • 如果单元格(k)为空,则复制单元格(k)上方的单元格的值
  • 编辑date单元格的date值。

每个子是自己的function,但将它们合并在一起给我的问题,可能是因为我试图改变一个不同的工作簿,并在初始工作簿上的代码。

Sub LoadData_Click() WPath = "K:\Chain\" WName = "import.xls" Workbooks.Open Filename:=WPath & WName With Workbooks(WName).Sheets(1) .Columns("A:H").UnMerge Call DataManager Call DateRegulator End With End Sub Sub DataManager() Dim Counter As Long Counter = Application.WorksheetFunction.CountA(Range("B:B")) Dim r As Integer For r = 1 And 5 To 8 For K = 1 To Counter If IsEmpty(Cells(K, r)) Then Cells(K, r) = Cells(K - 1, r) End If Next K Next r End Sub Sub DateRegulator() Dim Counter As Long Counter = Application.WorksheetFunction.CountA(Range("B:B")) For K = 2 To Counter Cells(K, 2) = DateSerial(Year(Now), Month(Cells(K, 2)), 1) Next K End Sub 

您的DataManagerDateRegulator子例程不明确指定他们正在工作的工作簿/工作表。 没关系,只要你意识到他们会在被调用的任何书籍和工作表被激活的情况下工作。

所以我会考虑的第一个改变是

 With Workbooks(WName).Sheets(1) .Activate ' this makes sure the target workbook & worksheet are the active ones 

更好的办法是将工作表作为parameter passing给子程序。

您的代码中还有其他几个潜在的问题需要解决

CountA()只计算非空单元格:如果列B有任何间隙,则不会在工作表中处理非空值的所有行。 如果列B从来没有差距,那么没关系。

这一行:

 For r = 1 And 5 To 8 

不做你认为的事情。 这并不会让你创build一个不相交的序列像[1,5,6,7,8],它是一个布尔(真/假)运算符,所以它是这样的:

 For r = (1 And 5) To 8 

…评估

 For r = 1 To 8 

假设我已经正确地猜测了这个意图,那么这将起作用:

 Dim r As Variant For Each r In Array(1, 5, 6, 7, 8) Debug.Print r ' replace with what you actually wanted to do here... Next