2

这可能是一个很长的描述,所以请耐心等待。我在使用 Excel 时遇到的问题与自定义宏、VBA 和文件访问有关。

背景:我正在尝试编写一个宏来处理多个 CSV 数据工作簿。在 RawData_x.csv 之前,我有名为 RawData_1.csv 的文件,其中 x 是我在特定文件夹中拥有的文件数。

我的宏代码如下所示:

Sub ImportData()
    
    Application.ScreenUpdating = False
    
    Dim strDir As String
    Dim strFileName As String
    Dim wbToCopy As Workbook
    Dim intCol As Integer

    Set master = ActiveSheet

    **PLEASE SEE BELOW FOR 2 VERSIONS OF CODE THAT CAN GO HERE!**

    strFileName = Dir(strDir & "\*.csv")

    intCol = 2

    Do While Len(strFileName) > 0
        Set wbToCopy = Workbooks.Open(strFileName, , True)

        //Do other things I need it to do here

        wbToCopy.Close (False)
    
        strFileName = Dir
        intCol = intCol + 2
    Loop

    Application.ScreenUpdating = True

End Sub

问题1(小问题):当我执行宏时,文件不知何故“改变”,下次我在同一个文件夹中执行相同的宏时,它会报告找不到文件。确切的错误是:

运行时错误“1004”:

找不到“RawData_1.csv”。检查文件名的拼写,并验证文件位置是否正确。

如果您尝试从最近使用的文件列表中打开该文件,请确保该文件现在已被重命名、移动或删除。

我已经找到了解决这个问题的办法。我所要做的就是进入包含所有 csv 文件的文件夹,打开列表中的第一个文件,然后“另存为”作为 MS-DOS CSV 文件。完成此操作后,我可以运行宏,它将能够打开所有文件(不仅仅是我“另存为”的第一个文件)。

虽然这很烦人,但这并不是世界上最糟糕的事情。如果excel这样做是有原因的,我很想知道!如果有解决这个问题的办法,那就更好了!

问题 2(大问题) 这是我想解决的主要难题。在上面的代码中,缺少的部分是告诉 Excel(或宏)在哪里找到文件的代码部分。我可以通过在路径中硬编码来做到这一点,如下所示:

方法一:

strDir = "C:\whateverPath"

这种方法总是有效的(除非遇到上面的问题 1)。

但是,这显然不是编写宏的最佳方式,因为我不仅会使用它一次,而且需要多次使用它,而且我希望导入的数据文件将位于不同的文件夹中。因此,我尝试将其编写如下:

方法二:

Dim folderDialog As fileDialog 
Set folderDialog = Application.FileDialog(msoFileDialogeFolderPicker)
folderDialog.AllowMultiSelect = False
folderDialog.Show
 
strDir = folderDialog.SelectedItems(1)

我比较了方法 1 中的 strDir 和方法 2 中的 strDir,发现它们的值没有明显差异。它们都包含正确的路径“C:\whateverPath”。

但是,使用方法 2,excel 将无法读取所选文件夹中的任何文件。它将返回与上面相同的运行时错误 1004,并且我为上面的问题 1 找到的快速修复对宏运行没有任何帮助。

如果有人知道这里发生了什么,我将非常感谢一些帮助解决这个问题!

4

1 回答 1

1

编辑:我想我发现了这个问题。Set wbToCopy = Workbooks.Open(strFileName, , True) ,strFileName不使用完全限定路径。因此,当您调用该.open方法时,我相信 VBA 正在使用该CurDir值并将其附加到strFileName. 当您执行“另存为”时,该CurDir值将更改为您保存 .csv 文件的目录。这给人一种“另存为”操作允许您的宏运行的错觉。实际上,它是将CurDir值更改为文件所在目录的行为。使用完全限定的文件名,.open它应该每次都运行。

上一个建议: 我不认为你的文件名是完全限定的(你的错误信息应该是'C:\whateverPath\RawData_1.csv' could not be found.not 'RawData_1.csv' could not be found.)。

我很难追踪代码中的错误。这是一种黑客攻击,但如果你遇到困难,请尝试使用:

Option Explicit
Sub ImportData()

Application.ScreenUpdating = False

Dim strDir As String
Dim strFolderName As String
Dim wbToCopy As Workbook
Dim intCol As Integer
Dim master As Excel.Worksheet

Dim FSO As Object
Dim FSO_FOLDER As Object
Dim FSO_FILE As Object
Dim FILE_EXT As String

FILE_EXT = "csv"
strFolderName = Get_Folder_Path() & "\"

''Create FileSystem Objects
Set FSO = CreateObject("Scripting.FileSystemObject")

Set FSO_FOLDER = FSO.GetFolder(strFolderName)

Set master = ThisWorkbook.ActiveSheet

''**PLEASE SEE BELOW FOR 2 VERSIONS OF CODE THAT CAN GO HERE!**

intCol = 2

If FSO_FOLDER.Files.Count > 0 Then

''Loop through each File in Folder
For Each FSO_FILE In FSO_FOLDER.Files

   ''Test extension
   If FSO.GetExtensionName(FSO_FILE.Name) = FILE_EXT Then

       Set wbToCopy = Workbooks.Open(strFolderName & FSO_FILE.Name, , True)

        ''//Do other things I need it to do here

        wbToCopy.Close (False)
        intCol = intCol + 2

   Else: End If

Next

Else

MsgBox "No Files Found at " & strFolderName

End If

Set FSO = Nothing
Set FSO_FOLDER = Nothing

Application.ScreenUpdating = True

End Sub

Function Get_Folder_Path() As String
Dim folderDialog As FileDialog
Set folderDialog = Application.FileDialog(4)
folderDialog.AllowMultiSelect = False
folderDialog.Show

Get_Folder_Path = folderDialog.SelectedItems(1)

End Function

请注意,这使用 FileSystem 库而不是本机Dir函数。您还将选择文件夹名称而不是对话框的文件名。

于 2013-07-23T23:22:42.113 回答