【发布时间】:2022-01-11 23:24:24
【问题描述】:
我正在尝试以迭代方式打开选定文件夹中的每个 Excel 文件,然后在每个文件上运行一系列子例程。我最初开发了打开单个文件并执行适当操作的宏(懒惰地命名为 Main)——据我所知,这个子工作得很好。
我现在正在构建一个名为 FolderPicker 的子程序,它将打开选定文件夹中的每个文件,然后运行 Main 子程序。
目前,我有这段代码,改编自https://www.thespreadsheetguru.com/the-code-vault/2014/4/23/loop-through-all-excel-files-in-a-given-folder
Sub FolderPicker()
Dim wb As Workbook
Dim myPath As String
Dim MyFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls*"
'Target Path with Ending Extention
MyFile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
Do While MyFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & MyFile)
vFileName = myPath & MyFile
'Ensure Workbook has opened before moving on to next line of code
DoEvents
'Run main sub
main
'Ensure main has completed
DoEvents
'Save and Close Workbook
wb.Activate
wb.Close savechanges:=False
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
MyFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
这个宏的开头运行得很好,文件夹对话框正常工作,它打开了第一个文件。但是,直接进行 Loop 的 MyFile = Dir 行似乎不起作用 - 它评估为空值,然后 sub 结束。我已验证该文件夹中有多个文件。
作为参考,vFileName 是在 Main 中使用的公开声明的变体。
有什么建议吗?
【问题讨论】:
-
你为什么不分享
main过程? -
main中的代码是否使用了Dir()?如果确实如此,那么它肯定是相关的......理想情况下,main至少有一个Workbook类型的参数,您可以将wb作为参数传递给该参数。 -
@TimWilliams 确实如此,我现在才意识到这就是问题所在。我不知道 Dir() 没有递归工作。我将切换到 FSO。谢谢,如果您将其作为答案提交,我会将其标记为正确。
-
@chris neilsen:
vFileName = myPath & MyFile怎么样?你真的会使用它,尤其是作为代码中的公共变量吗?还是您更愿意在main过程中将其用作参数(可能只是MyFile)? -
@VBasic2008 是的,我会将路径/文件名或工作簿传递给 Main,但这 不是 OP 所要求的。 FWIW,蒂姆成功了,我的评论无效