2013-05-04 78 views
9

Tôi có một chuỗi các macro gọi nhau và tham khảo sổ làm việc A và B. Tôi muốn macro đầu tiên nhắc người dùng chọn tài liệu A và B và các Lựa chọn này để trở thành các biến A và B bảng tính mà tôi tham khảo trong các macro khác nhau.Làm thế nào để tạo các biến Excel VBA có sẵn cho nhiều macro?

Làm cách nào để làm cho các tài liệu đã chọn được gọi là biến trong tất cả các macro?

Cảm ơn trước!

Trả lời

20

Khai báo họ bên ngoài thủ tục con, như thế này:

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 

Cách khác, bạn có thể vượt qua các biến giữa chương trình con:

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 

Hoặc sử dụng Functions-trở lại giá trị:

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 

Trong th phương pháp thứ hai, trong phạm vi OtherSubRoutine bạn tham chiếu đến chúng bằng tên thông số wb1wb2. Các biến được truyền không cần sử dụng cùng tên, chỉ các kiểu biến tương tự. Điều này cho phép bạn tự do, ví dụ bạn có một vòng lặp trên nhiều sổ làm việc và bạn có thể gửi mỗi sổ làm việc cho một chương trình con để thực hiện một số hành động trên Sổ làm việc đó mà không cần thực hiện tất cả (hoặc bất kỳ) biến nào trong phạm vi công cộng.

Lưu ý Về tài Forms

Cá nhân tôi muốn giới thiệu giữOption Explicit trong tất cả các mô-đun và các hình thức của bạn (điều này ngăn cản bạn từ instantiating biến với lỗi chính tả trong tên của họ, giống như lCoutn khi bạn có nghĩa là lCount vv ., trong số các lý do khác).

Nếu bạn đang sử dụng Option Explicit (mà bạn nên), sau đó bạn nên đủ điều kiện biến mô-đun-chỉnh phạm vi cho phong cách và để tránh sự mơ hồ, và bạn phải đủ điều kiện sử dụng hình thức Public scoped biến, vì đây là những không "công khai" theo cùng nghĩa. Ví dụ, i là undefined, mặc dù nó là Public trong phạm vi của UserForm1:

enter image description here

Bạn có thể tham khảo nó như UserForm1.i để tránh những lỗi biên dịch, hoặc kể từ khi hình thức là New -able, bạn có thể tạo ra một biến đối tượng chứa tham chiếu đến hình thức của bạn, và tham khảo nó như vậy:

enter image description here

NB: Trong ảnh chụp màn hình trên x được khai báo Public x as Long trong một mô-đun mã tiêu chuẩn khác và sẽ không làm tăng lỗi biên dịch. Có thể thích hợp hơn khi tham chiếu đến điều này là Module2.x để tránh sự mơ hồ và có thể bị che khuất trong trường hợp bạn sử dụng lại tên biến ...

+1

+1: Có thể muốn đề cập đến điều này hoạt động cho 'Công khai' trong Mô-đun. 'Công khai' trong các Lớp, Biểu mẫu và Bảng tính phức tạp hơn một chút. – RBarryYoung

+0

Tôi đã gặp sự cố với điều này trong khi gỡ lỗi - VBA vẫn nói với tôi rằng tôi đã có biến không khai báo. Tôi đã phải loại bỏ Option Explicit khỏi các biểu mẫu và mô-đun của tôi và chỉ xác định biến Công khai ở một vị trí. Có lẽ rất cơ bản, nhưng tôi chưa bao giờ sử dụng một biến trong 12 userforms và 2 mô-đun cùng một lúc trước đây. – TheFontSnob

+0

@ TheFontSnob có, như bạn đã phát hiện có một số hạn chế (@RBarryYoung gợi ý ở trên). Cá nhân tôi khuyên bạn nên * giữ * 'Option Explicit' trong tất cả các mô-đun và biểu mẫu của bạn (điều này ngăn cản bạn tạo các biến với các lỗi chính tả trong tên của chúng, như' lCoutn' khi bạn có nghĩa là 'lCount', v.v.). Nếu bạn đang sử dụng 'Option Explicit' (mà bạn ** nên **), thì bạn nên hội đủ điều kiện biến mô-đun cho phong cách, và bạn ** phải ** đủ điều kiện biến dạng phạm vi người dùng, vì đây không phải là" công khai "trong cùng một nghĩa. –

5

Bạn có thể xem xét khai báo các biến với phạm vi cấp moudule. biến mô-đun cấp cao nhất là dành cho tất cả các thủ tục trong mô-đun đó, nhưng nó không phải là có sẵn cho các thủ tục trong module khác

Để biết chi tiết về Scope of variables tham khảo này link

Vui lòng sao chép mã dưới đây vào bất kỳ mô-đun, lưu sổ làm việc và sau đó chạy mã.

Đây là những gì mã không

  • Các chương trình con mẫu đặt đường dẫn thư mục & sau, đường dẫn tập tin. Vui lòng đặt chúng cho phù hợp trước khi bạn chạy mã.

  • Tôi đã thêm hàm IsWorkBookOpen để kiểm tra xem sổ làm việc đã được đặt rồi hay không, đặt bảng tính tên sổ làm việc khác mở sổ làm việc sẽ được gán cho biến sổ làm việc tương ứng.

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 

Sử dụng Prompt để chọn việc sử dụng tập tin bên dưới mã.

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 
2

Tạo đối tượng "mô-đun" và khai báo biến trong đó. Không giống như các đối tượng lớp phải được khởi tạo mỗi lần, các đối tượng mô-đun luôn có sẵn. Do đó, một biến công cộng, hàm hoặc thuộc tính trong một "mô-đun" sẽ có sẵn cho tất cả các đối tượng khác trong dự án VBA, macro, công thức Excel hoặc thậm chí trong truy vấn MS Access JET-SQL def.

Các vấn đề liên quan