ExcelVBA,使用FileDialog打开多个工作簿并引用

Excel VBA, using FileDialog to open multiple workbooks and reference them

我目前使用以下代码提示用户输入工作簿,打开它,从中获取一些信息,然后关闭它。目前,我通过使用带有索引 ("woorkbooks(2)") 的工作簿集合来处理打开的工作簿。现在我需要打开两个工作簿,我的问题是我不知道哪些工作簿将被索引为 2,哪些将被索引为 3。所以,我认为必须有一种方法来获取对每个工作簿的引用工作簿。

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

现在我看到了一些解决这个问题的方法,涉及获取每个工作簿的完整路径,但我宁愿避免使用完整路径,因为它包含不同语言的单词(并且工作簿的名称显示为问号)。此外,我更喜欢一种解决方案,在该解决方案中,对于 2 个文件只提示用户一次,而不是两次。

使用现有的 openfile 函数,将 return 从布尔值更改为 Excel.Workbook。如果他们不打开工作簿,则将其设置为 Nothing 而不是 false,否则将其设置为刚刚打开的文件的工作簿引用(您需要修改 openfile 以获取该引用)。然后您只需调用它两次并为每个不是 Nothing 的调用设置一个工作簿引用。

下面的示例代码是自由形式编写的并且未经测试 - 它实际上只是美化的伪代码 - 但应该为您指明正确的总体方向。

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

编辑添加:

这是修改后的 openfile 函数的一个非常基本的形状。同样,未经测试,但我已经从我自己的一个过程中修改了它,所以它应该可以工作

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

此版本为用户提供了一个对话框。享受。无论谁对我的其他答案投了反对票,请在评论中添加评论,解释您不喜欢它的原因,以至于需要投反对票。

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