2017-03-12 7 views
1

Ich verwende den folgenden Code, um den Benutzer für eine Arbeitsmappe aufzufordern, öffnen Sie es, holen Sie einige Informationen aus und schließen Sie es dann. Im Moment adressiere ich die geöffnete Arbeitsmappe mit Hilfe der Arbeitsmappen-Sammlung mit und index ("woorkbooks (2)"). Jetzt muss ich zwei Arbeitsmappen öffnen, und mein Problem ist, dass ich nicht wissen würde, welche der Arbeitsmappen als 2 indiziert werden und welche als 3 indiziert werden. Also dachte ich, dass es einen Weg geben muss, eine Referenz zu jedem zu bekommen Arbeitsmappe.Excel VBA, FileDialog verwenden, um mehrere Arbeitsmappen zu öffnen und sie zu referenzieren

Function openfile() As Boolean 

Dim fd As FileDialog 
Dim file_was_chosen As Boolean 

Set fd = Application.FileDialog(msoFileDialogOpen) 

With fd 
    .Filters.Clear 
    .Filters.Add "Excel File", "*.xl*" 
End With 

file_was_chosen = fd.Show 

If Not file_was_chosen Then 
    MsgBox "You didn't select a file" 
    openfile = False 
    Exit Function 
End If 

fd.Execute 
openfile = True 

End Function 

Jetzt habe ich den vollständigen Pfad jede Arbeitsmappe bekommen, einige Lösungen für dieses Problem im Zusammenhang gesehen, aber ich würde es vorziehen, vermeiden Sie den vollständigen Pfad verwenden, da sie Worte in verschiedenen Sprachen (und den Namen der Arbeitsmappe enthalten erscheint mit Fragezeichen). Außerdem würde ich eine Lösung bevorzugen, in der der Benutzer nur einmal für 2 Dateien und nicht zweimal aufgefordert wird.

Antwort

2

Diese Version dem Anwender einen einzigen Dialog gibt funktionieren sollte. Genießen. Und wer auch immer meine andere Antwort abgelehnt hat, bitte fügen Sie einen Kommentar hinzu, der erklärt, was Sie so nicht mögen, dass ein Downvote erforderlich ist.

Function openfile() As Variant 
    Dim aOpen(2) As String, itm As Variant, cnt As Long, lAsk As Long 
    Dim fd As FileDialog 
    Dim file_was_chosen As Boolean 

    Set fd = Application.FileDialog(msoFileDialogOpen) 

    With fd 
     .Filters.Clear 
     .Filters.Add "Excel File", "*.xl*" 
    End With 

    Do 
     file_was_chosen = fd.Show 
     If Not file_was_chosen Or fd.SelectedItems.Count > 2 Then 
      lAsk = MsgBox("You didn't select one or two files, try again?", vbQuestion + vbYesNo, "File count mismatch") 
      If lAsk = vbNo Then 
       openfile = aOpen 
       Exit Function 
      End If 
     End If 
    Loop While fd.SelectedItems.Count < 1 Or fd.SelectedItems.Count > 2 

    cnt = 0 
    For Each itm In fd.SelectedItems 
     aOpen(cnt) = itm 
     cnt = cnt + 1 
    Next 
    openfile = aOpen 
    fd.Execute 
End Function 

Sub test() 
    Dim vRslt As Variant 
    Dim wkb As Excel.Workbook, wkb1 As Excel.Workbook, wkb2 As Excel.Workbook 

    vRslt = openfile 
    For Each wkb In Application.Workbooks 
     If wkb.Path & "\" & wkb.Name = vRslt(0) Then Set wkb1 = wkb 
     If wkb.Path & "\" & wkb.Name = vRslt(1) Then Set wkb2 = wkb 
    Next 

    If vRslt(0) = "" Then ' no files 
     MsgBox "No files opened so nothing happens..." 
    ElseIf vRslt(1) = "" Then ' one file was opened 
     MsgBox "One file so do whatever you want for one file" 
    Else ' two files were opened 
     MsgBox "Two files so do whatever you want for two files" 
    End If   
End Sub 
+0

Vielen Dank, genau das habe ich gebraucht! (Und danke, dass du mit meinen Variablen übereinstimmst, es war sehr hilfreich) – Sergey

0

Mit Ihrer vorhandenen Openfile-Funktion ändern Sie die Rückkehr von Boolean zu Excel.Workbook. Wenn sie keine Arbeitsmappe öffnen, setzen Sie sie auf Nothing statt auf False, ansonsten setzen Sie sie auf die Referenz der Arbeitsmappe der Datei, die Sie gerade geöffnet haben (Sie müssen Openfile ändern, um diese Referenz zu erhalten). Sie rufen es dann einfach zweimal auf und legen eine Arbeitsmappenreferenz für jeden Aufruf fest, der nicht Nothing ist.

Beispielcode unten ist Freeform geschrieben und ist ungeprüft - es ist wirklich nur verherrlichten Pseudocode - aber sollte Ihnen die richtige Richtung zeigen.

sub test 
    dim lAsk as long 
    dim wkb1 as excel.workbook 
    dim wkb2 as excel.workbook 
    do 
     if wkb1 is Nothing then 
      set wkb1 = openfile 
      if wkb1 is Nothing then 
       lAsk = msgbox("you didn't select a first file, try again?",vbyesno,"No file selected") 
       if lAsk = vbNo then exit do 
      end if 
     elseif wkb2 is Nothing then 
      set wkb2 = openfile 
      if wkb2 is Nothing then 
       lAsk = msgbox("you didn't select a second file, try again?",vbyesno,"No file selected") 
       if lAsk = vbNo then exit do 
      end if 
     end if 
    loop while wkb1 is Nothing or wkb2 is Nothing 

    ' do whatever with wkb1 and wkb2 here 

end sub 

Edited hinzufügen:

Hier ist eine sehr einfache Form für Ihre Openfile-Funktion überarbeitet. Auch hier nicht getestet, aber ich habe es von einem meiner eigenen Procs so modifiziert, dass es

Function openfile() As Excel.Workbook 
    Dim sFilter As String 
    Dim sTitle As String 
    Dim vFileName As Variant 

    sFilter = "Excel Files (*.xl*), *.xl*, CSV Files (*.csv), *.csv, All Files (*.*), *.*" 
    sTitle = "Select file to process" 

    vFileName = Application.GetOpenFilename(filefilter:=sFilter, Title:=sTitle) 
    If vFileName = False Then 
     Set openfile = Nothing 
    Else 
     Set openfile = Workbooks.Open(Filename:=vFileName) 
    End If 
End Function 
Verwandte Themen