这是我关于stackoverflow的第一篇文章。我在Excel VBA中有两个子过程。第一个名为Sub IAR_part_2()
,用于将两个工作表(按索引位置)分配给两个名为sheetname1和sheetname2的变量。分配变量后,我试图将它们传递给我的第二个子过程,称为IAR_macro,以进行处理。这两个工作表相互依赖,因此工作表4和8通过IAR宏运行,工作表5和9,工作表6和10等。我的问题是我无法弄清楚如何将工作表名称变量从IAR_part_2传递到IAR_macro。我在做什么错了?
Sub IAR_part_2()
sheetname1 = Worksheets(4)
sheetname2 = Worksheets(8)
Call IAR_macro
End Sub
Sub IAR_macro(sheetname1 As Worksheet, sheetname2 As Worksheet)
Dim h As Long
Dim i As Long
Dim l As Long
Dim j As Long
Dim k As Long
Dim lr As Long
Worksheets(sheetname1).Activate
' Find the number of the last cell with data in column A and subtract 1 to populate variable i
On Error GoTo Canceled
i = (Range("B1").End(xlDown).Row) - 1
'Switch over to the Code sheet
Worksheets(sheetname2).Activate
'While the number of loops is less than variable i minus 1, copy the contents of cells A2 through A29 over and over down the worksheet
Do While l < (i - 1)
Range("A2:A29").Select
Selection.Copy
lr = Cells(Rows.Count, "A").End(xlUp).Row
Range("A" & lr + 1).Select
ActiveSheet.Paste
l = l + 1
'rest of macro follows from here...
答案 0 :(得分:5)
如何将工作表对象传递到另一个子的简单示例:
Sub Macro1()
'Declare variables
Dim ws1 As Worksheet
Dim ws2 As Worksheet
'Assign variables to worksheet objects
Set ws1 = Worksheets(4)
Set ws2 = Worksheets(8)
'Call the second sub and pass the worksheet variables to it
Call Macro2(ws1, ws2)
End Sub
Sub Macro2(ByVal arg_ws1 As Worksheet, ByVal arg_ws2 As Worksheet)
'Reference the accepted arguments (in this case worksheet variables) directly:
MsgBox arg_ws1.Name
MsgBox arg_ws2.Name
'This will result in an error because you're using the passed argument incorrectly:
MsgBox ActiveWorkbook.Sheets(arg_ws1).Name '<-- Results in error
End Sub
您必须直接引用传递的参数。如果要使用代码中显示的结构,则传递的参数必须为字符串(但不建议使用此方法):
Sub Macro1()
'Declare variables
Dim sSheet1 As String
Dim sSheet2 As String
'Assign variables to worksheet objects
sSheet1 = Worksheets(4).Name
sSheet2 = Worksheets(8).Name
'Call the second sub and pass the worksheet variables to it
Call Macro2(sSheet1, sSheet2)
End Sub
Sub Macro2(ByVal arg_sSheetName1 As String, ByVal arg_sSheetName2 As String)
'Because the arguments are strings, you can reference the worksheets this way
'This method is NOT recommended
MsgBox Worksheets(arg_sSheetName1).Name
MsgBox Worksheets(arg_sSheetName2).Name
End Sub
答案 1 :(得分:0)
调用该过程时,需要将创建的两个变量传递给第二个子变量:
Sub IAR_part_2()
Set sheetname1 = Worksheets(4)
Set sheetname2 = Worksheets(8)
Call IAR_macro (sheetname1,sheetname2)
End Sub
答案 2 :(得分:0)
我在您的示例中注意到,您在函数内部声明了变量。通常,使用ThreadPoolExecutor
可以更好地实现您希望使用的任何变量。同样,在识别工作表时,用工作表编号而不是工作表名称寻址工作表时,您会遇到的问题更少。这样,如果您需要使用变量,则也可以只使用整数。
option explicit
Sheet ID可以位于开发工具中。这是一个示例:
答案 3 :(得分:0)
这是传递工作表的最小方式。至于它们是对象,默认情况下通过引用传递它们:
Sub TestMe()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Worksheets(1)
Set ws2 = Worksheets(2)
Passing ws1, ws2
End Sub
Sub Passing(arg_ws1 As Worksheet, arg_ws2 As Worksheet)
Debug.Print arg_ws1.Name
Debug.Print arg_ws2.Name
End Sub
答案 4 :(得分:0)
VBA并不像许多人(主要是那些想成为开发人员的人认为它是一种有趣的脚本语言)的人想的那样简单。有时它允许编写ByVal
,但是它遵循自己的规则并接受参数ByRef
,只是为了安慰您并确保您不会出错。
在这里看到了@tigeravatar的答案,我决定不写评论,而是在不同的帖子中解释它为什么是错误和危险的,就其解释为评论很难。 / p>
如果您尝试从答案中在此处写一个Stop
行:
Sub Macro1()
'Declare variables
Dim ws1 As Worksheet
Dim ws2 As Worksheet
'Assign variables to worksheet objects
Set ws1 = Worksheets(4)
Set ws2 = Worksheets(8)
'Call the second sub and pass the worksheet variables to it
Call Macro2(ws1, ws2)
End Sub
Sub Macro2(ByVal arg_ws1 As Worksheet, ByVal arg_ws2 As Worksheet)
'Reference the accepted arguments (in this case worksheet variables) directly:
MsgBox arg_ws1.Name
Stop
MsgBox arg_ws2.Name
'This will result in an error because you're using the passed argument incorrectly:
MsgBox ActiveWorkbook.Sheets(arg_ws1).Name '<-- Results in error
End Sub
运行答案并等待停止行:
如果arg_ws1
是由Val取的,那么如果Stop
亮着时有人更改了第8个工作表的名称,则它仍应采用旧名称。是ByVal
,记得吗?好吧,继续并更改名称。然后继续 F5 。你叫什么名字?为什么?
答案是因为在参数中用括号将Sub调用的方式。这些强制ByVal
并忽略任何明确编写的内容。