it-swarm.com.de

Wie kann ich Excel-VBA-Variablen für mehrere Makros verfügbar machen?

Ich habe eine Reihe von Makros, die sich gegenseitig aufrufen und auf Arbeitsmappen A und B verweisen. Ich möchte, dass das erste Makro den Benutzer auffordert, Dokument A und B auszuwählen und diese Auswahl zu den Arbeitsmappenvariablen A und B wird, auf die ich in der verweise verschiedene Makros.

Wie mache ich die ausgewählten Dokumente in allen Makros zur referenzierten Variablen?

Danke im Voraus!

11

Deklarieren Sie sie außerhalb der Subroutinen wie folgt:

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

Alternativ können Sie Variablen zwischen Unterprogrammen übergeben:

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

Oder verwenden Sie Functions, um Werte zurückzugeben:

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

In der zweiten Methode verweisen Sie im Rahmen von OtherSubRoutine auf sie mit ihren Parameternamen wb1 Und wb2. Übergebene Variablen müssen nicht dieselben Namen verwenden, sondern nur dieselben Variablentypen. Dies gibt Ihnen einige Freiheiten, z. B. Sie haben eine Schleife über mehrere Arbeitsmappen, und Sie können each Arbeitsmappen an eine Unterroutine senden, um eine Aktion für diese Arbeitsmappe auszuführen, ohne alle (oder eine) durchzuführen die Variablen öffentlich im Geltungsbereich.

Ein Hinweis zu Benutzerformularen

Persönlich würde ich KeepingOption Explicit In all Ihren Modulen und Formularen empfehlen (dies verhindert, dass Sie Variablen mit Tippfehlern in ihren Namen instanziieren, wie zum Beispiel lCoutn, wenn Sie meinten lCount etc. ua).

Wenn Sie Option Explicit Verwenden (welches Sie sollten ), sollten Sie modulbezogene Variablen für den Stil qualifizieren und Mehrdeutigkeiten vermeiden, und Sie müssen benutzerformulare Variablen mit dem Gültigkeitsbereich Public qualifizieren, da diese nicht im gleichen Sinne "öffentlich" sind. Zum Beispiel ist i undefiniert, obwohl es sich um Public im Bereich von UserForm1 Handelt:

enter image description here

Sie können darauf als UserForm1.i Verweisen, um den Kompilierungsfehler zu vermeiden, oder da Formulare New -fähig sind, können Sie ein variables Objekt erstellen, das Verweise auf Ihr Formular enthält, und auf diese Weise darauf verweisen :

enter image description here

NB: In den obigen Screenshots wird x in einem anderen standard Codemodul als Public x as Long Deklariert und löst keinen Kompilierungsfehler aus. Es kann vorzuziehen sein, dies als Module2.x Zu bezeichnen, um Mehrdeutigkeiten und mögliche Schatten zu vermeiden, falls Sie Variablennamen wiederverwenden ...

26
David Zemens

Sie können erwägen, die Variablen mit einem Gültigkeitsbereich auf Modulebene zu deklarieren. Die Variable auf Modulebene ist für alle Prozeduren in diesem Modul verfügbar, für Prozeduren in anderen Modulen jedoch nicht

Für Details zu Scope of variables refer this link

Kopieren Sie den folgenden Code in ein beliebiges Modul, speichern Sie die Arbeitsmappe und führen Sie den Code aus.

Hier ist, was Code macht

  • Die Beispielsubroutine legt den Ordnerpfad und später den Dateipfad fest. Bitte stellen Sie sie entsprechend ein, bevor Sie den Code ausführen.

  • Ich habe eine Funktion IsWorkBookOpen hinzugefügt, um zu prüfen, ob die Arbeitsmappe bereits vorhanden ist. Dann setze die Arbeitsmappenvariable auf den Namen der Arbeitsmappe, andernfalls öffne die Arbeitsmappe, die der Arbeitsmappenvariablen entsprechend zugewiesen wird.

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

Verwenden Sie die Eingabeaufforderung, um die Datei auszuwählen, und verwenden Sie den folgenden Code.

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
5
Santosh

Erstellen Sie ein "Modul" -Objekt und deklarieren Sie dort Variablen. Im Gegensatz zu Klassenobjekten, die jedes Mal instanziiert werden müssen, sind die Modulobjekte immer verfügbar. Daher steht eine öffentliche Variable, Funktion oder Eigenschaft in einem "Modul" allen anderen Objekten im VBA-Projekt, Makro, in der Excel-Formel oder sogar in einer JET-SQL-Abfragedefinition von MS Access zur Verfügung.

2
Steven