如何使Excel VBAvariables可用于多个macros?

我有一串macros调用对方并引用工作簿A和B.我希望第一个macros提示用户select文档A和B,这些select成为工作簿A和Bvariables我在各种macros。

我如何使选定的文件在所有的macros中引用variables?

提前致谢!

在子例程之外声明它们,如下所示:

Public wbA as Workbook Public wbB as Workbook Sub MySubRoutine() Set wbA = Workbooks.Open("C:\file.xlsx") Set wbB = Workbooks.Open("C:\file2.xlsx") OtherSubRoutine End Sub Sub OtherSubRoutine() MsgBox wbA.Name, vbInformation End Sub 

或者,您可以在子例程之间传递variables:

 Sub MySubRoutine() Dim wbA as Workbook Dim wbB as Workbook Set wbA = Workbooks.Open("C:\file.xlsx") Set wbB = Workbooks.Open("C:\file2.xlsx") OtherSubRoutine wbA, wbB End Sub Sub OtherSubRoutine(wb1 as Workbook, wb2 as Workbook) MsgBox wb1.Name, vbInformation MsgBox wb2.Name, vbInformation End Sub 

或者使用Functions返回值

 Sub MySubroutine() Dim i as Long i = MyFunction() MsgBox i End Sub Function MyFunction() 'Lots of code that does something Dim x As Integer, y as Double For x = 1 to 1000 'Lots of code that does something Next MyFunction = y End Function 

在第二种方法中,在OtherSubRoutine的范围内,通过它们的参数名称wb1wb2来引用它们。 通过variables不需要使用相同的名称,只是相同的variablestypes。 这可以让你有一些自由,例如你可以循环使用几个工作簿,并且可以将每个工作簿发送到一个子例程,以便在该工作簿上执行一些操作,而不必将所有(或任何)variables公开在范围内。

关于用户表单的说明

就个人而言,我会build议在所有的模块和表单中保留 Option Explicit (这样可以防止你在名称中使用拼写错误实例化variables,比如lCoutn当你的意思是lCount等等等等)。

如果你使用Option Explicit (你应该这样做 ),那么你应该限定风格的模块范围的variables,并且避免含糊不清,并且你必须限定用户forms的Public范围variables,因为这些variables在相同意义上不是“公共”的。 例如, i是未定义的,虽然它在UserForm1范围内是Public的:

在这里输入图像说明

您可以将其引用为UserForm1.i以避免编译错误,或者由于表单是New -able,您可以创build一个variables对象来包含对表单的引用,并以此方式引用它:

在这里输入图像描述

注意:在上面的截图中, x在另一个标准代码模块中被声明为Public x as Long ,并且不会引起编译错误。 将这个称为Module2.x以避免模糊和可能的阴影,以备重用variables名称。

你可以考虑用moudule级别范围声明variables。 模块级variables可用于该模块中的所有过程,但不适用于其他模块中的过程

有关Scope of variables详细信息,请参阅此链接

请将下面的代码复制到任何模块中,保存工作簿,然后运行代码。

这是什么代码呢

  • 示例子例程设置文件夹path和稍后的文件path。 请在运行代码之前相应地设置它们。

  • 我已经添加了一个函数IsWorkBookOpen来检查工作簿是否已经设置工作簿variables工作簿名称否则打开工作簿将相应地分配给工作簿variables。

Dim wbA As Workbook
Dim wbB As Workbook

 Sub MySubRoutine() Dim folderPath As String, fileNm1 As String, fileNm2 As String, filePath1 As String, filePath2 As String folderPath = ThisWorkbook.Path & "\" fileNm1 = "file1.xlsx" fileNm2 = "file2.xlsx" filePath1 = folderPath & fileNm1 filePath2 = folderPath & fileNm2 If IsWorkBookOpen(filePath1) Then Set wbA = Workbooks(fileNm1) Else Set wbA = Workbooks.Open(filePath1) End If If IsWorkBookOpen(filePath2) Then Set wbB = Workbooks.Open(fileNm2) Else Set wbB = Workbooks.Open(filePath2) End If ' your code here End Sub Function IsWorkBookOpen(FileName As String) Dim ff As Long, ErrNo As Long On Error Resume Next ff = FreeFile() Open FileName For Input Lock Read As #ff Close ff ErrNo = Err On Error GoTo 0 Select Case ErrNo Case 0: IsWorkBookOpen = False Case 70: IsWorkBookOpen = True Case Else: Error ErrNo End Select End Function 

使用提示select文件使用下面的代码。

 Dim wbA As Workbook Dim wbB As Workbook Sub MySubRoutine() Dim folderPath As String, fileNm1 As String, fileNm2 As String, filePath1 As String, filePath2 As String Dim filePath As String cmdBrowse_Click filePath, 1 filePath1 = filePath 'reset the variable filePath = vbNullString cmdBrowse_Click filePath, 2 filePath2 = filePath fileNm1 = GetFileName(filePath1, "\") fileNm2 = GetFileName(filePath2, "\") If IsWorkBookOpen(filePath1) Then Set wbA = Workbooks(fileNm1) Else Set wbA = Workbooks.Open(filePath1) End If If IsWorkBookOpen(filePath2) Then Set wbB = Workbooks.Open(fileNm2) Else Set wbB = Workbooks.Open(filePath2) End If ' your code here End Sub Function IsWorkBookOpen(FileName As String) Dim ff As Long, ErrNo As Long On Error Resume Next ff = FreeFile() Open FileName For Input Lock Read As #ff Close ff ErrNo = Err On Error GoTo 0 Select Case ErrNo Case 0: IsWorkBookOpen = False Case 70: IsWorkBookOpen = True Case Else: Error ErrNo End Select End Function Private Sub cmdBrowse_Click(ByRef filePath As String, num As Integer) Dim fd As FileDialog Set fd = Application.FileDialog(msoFileDialogFilePicker) fd.AllowMultiSelect = False fd.Title = "Select workbook " & num fd.InitialView = msoFileDialogViewSmallIcons Dim FileChosen As Integer FileChosen = fd.Show fd.Filters.Clear fd.Filters.Add "Excel macros", "*.xlsx" fd.FilterIndex = 1 If FileChosen <> -1 Then MsgBox "You chose cancel" filePath = "" Else filePath = fd.SelectedItems(1) End If End Sub Function GetFileName(fullName As String, pathSeparator As String) As String Dim i As Integer Dim iFNLenght As Integer iFNLenght = Len(fullName) For i = iFNLenght To 1 Step -1 If Mid(fullName, i, 1) = pathSeparator Then Exit For Next GetFileName = Right(fullName, iFNLenght - i) End Function 

创build一个“模块”对象并在那里声明variables。 与每次必须实例化的类对象不同,模块对象始终可用。 因此,“模块”中的公共variables,函数或属性将可用于VBA项目中的所有其他对象,macros,Excel公式甚至MS Access JET-SQL查询def中。