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
我目前使用以下代码提示用户输入工作簿,打开它,从中获取一些信息,然后关闭它。目前,我通过使用带有索引 ("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