Sea*_*cut 11 excel vba excel-vba
我有一串宏相互调用并引用工作簿A和B.我希望第一个宏提示用户选择文档A和B,这些选择将成为我在中引用的工作簿A和B变量各种宏.
如何在所有宏中将所选文档作为引用变量?
提前致谢!
Dav*_*ens 26
在子例程之外声明它们,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
或者,您可以在子例程之间传递变量:
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
Run Code Online (Sandbox Code Playgroud)
或者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
Run Code Online (Sandbox Code Playgroud)
在第二种方法中,的范围之内OtherSubRoutine,你是指由他们自己的参数名称wb1和wb2.传递的变量不需要使用相同的名称,只需要使用相同的变量类型.这允许您有一些自由,例如您在多个工作簿上有一个循环,并且您可以将每个工作簿发送到子例程以对该工作簿执行某些操作,而不会在范围内公开所有(或任何)变量.
关于用户表单的说明
就个人而言,我建议保留 Option Explicit所有模块和表单(这可以防止你在名称中使用拼写错误实例化变量,比如lCoutn你的意思lCount等,以及其他原因).
如果您正在使用Option Explicit(您应该使用),那么您应该对模式范围的变量进行样式限定并避免歧义,并且您必须限定用户表单Public范围的变量,因为它们在同一意义上不是"公共的".例如,i未定义,但它Public在以下范围内UserForm1:
你可以引用它UserForm1.i来避免编译错误,或者因为表单是New-able,你可以创建一个变量对象来包含对表单的引用,并以这种方式引用它:
注意:在上面的屏幕截图中x是Public x as Long在另一个标准代码模块中声明的,并且不会引发编译错误.Module2.x如果你重复使用变量名,可能最好将其称为避免歧义和可能的阴影......
您可以考虑使用moudule级别范围声明变量.模块级变量可用于该模块中的所有过程,但不适用于其他模块中的过程
有关详细信息,Scope of variables 请参阅此链接
请将以下代码复制到任何模块中,保存工作簿,然后运行代码.
这是代码的作用
sample子例程设置文件夹路径,然后设置文件路径.在运行代码之前,请相应地设置它们.
我添加了一个函数IsWorkBookOpen来检查工作簿是否已经设置工作簿变量工作簿名称,否则打开将相应分配给工作簿变量的工作簿.
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
Run Code Online (Sandbox Code Playgroud)
使用提示选择文件使用下面的代码.
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
102786 次 |
| 最近记录: |