【问题标题】:Access VBA how to deterine if file is Excel Format?Access VBA如何判断文件是否为Excel格式?
【发布时间】:2012-11-19 02:24:43
【问题描述】:

使用 MS Access VBA 如何检查文件以了解其是否为 Excel 格式?

【问题讨论】:

  • 您能详细说明您要做什么吗?通常检查文件扩展名是 .xls 还是 .xlsx 就足够了(可能还有 Excel“保存”对话框的“另存为类型”部分中列出的一些 Excel 扩展名,具体取决于您的需要)。如果这样做对您的项目不可行,我们需要知道。
  • 我有一个文件夹,里面有很多文件。许多(但不是全部)都是 Excel 格式。但这不能由扩展来确定。我想打开它们 - 使用 Workbook 对象 - 用于程序中的各种数据检查,但我需要知道它是否是 Excel 表。另外我想将 Excel 和非 Excel 分开。
  • 有许多与 Excel 相关的文件格式。 See here。您将什么定义为 Excel 格式?

标签: excel ms-access vba


【解决方案1】:

我从来没有遇到过无法通过扩展名直接确定 Excel 文件的问题,但如果我必须这样做,首先想到的是 UNIX 实用程序file,它可以识别文件类型通过查看其内容。它可以识别大量的文件类型。

我在 Windows 上使用Cygwin,它本质上是 Windows 上的 UNIX 环境。

当我在 Cygwin 中对已重命名为“.csv”的 Excel 2010 (xlsx) 文件使用 file 命令时,我得到:

$ file afile.csv
afile.csv: Microsoft Excel 2007+

这是一个有点尴尬的解决方案,但在您的 VBA 中,您可以使用 Windows Script Host 分叉一个 C:\cygwin\bin\file.exe 进程,并捕获每个文件的输出。

如果您在 Excel 文件的路径周围加上一个勾号(即“C:\path\to\file”),Cygwin 应该正确解释它(Cygwin 实用程序希望看到类似 unix 的路径:/path /to/文件)。我刚刚在普通的 Windows 命令提示符下验证了这一点,它确实有效:

c:\>c:\cygwin\bin\file.exe 'C:\path\to\afile.csv'
C:\path\to\afile.csv: Microsoft Excel 2007+

GnuWin32 SourceForge project里面还有filenative Windows binary,不过好像有点过时了;我没有尝试过,但它仍然可以识别现代 Excel 版本。

如果您需要本机 Excel 解决方案 - 我不完全确定我的头;希望其他人以前也这样做过。

【讨论】:

  • 感谢您的回复。这很有趣,当然也很尴尬。我正在寻找一种可以直接从 Access VBA 编码的东西。
  • 至于从来没有一个 Excel 文件不能直接从其扩展名中确定的地方 - 如果有人这样保存它,那就错了。
  • 我明白......如果没有扫描文件内容的东西,我不确定它还能如何自动完成。例如,我刚刚尝试使用Workbooks.Open打开一个DLL文件,Excel仍然打开它,但显示垃圾。我还没有看到 Office 内置的任何东西可以做到这一点,但你永远不知道......你可能会很幸运并找到有的人!
  • 另外,也许可以在记事本等文本编辑器中查看 Excel 文件...如果它们在文件开头都有一个共同的字符串,您可以使用 VBA 扫描前几个每个文件的字节数,类似于file 实用程序的工作方式。
  • 不是真正的记事本,你需要一个可以读取字节值的特殊文本编辑器。
【解决方案2】:

这不是用于 Access,而是用于 Excel,我使用它。这不是最好的解决方案,也不是任何人都喜欢的解决方案,但请做好准备。

Public Function IsExcelFormat(ByVal filePath As String) As Boolean

    On Error GoTo Nope
    Application.ScreenUpdating = False

    Dim wb As Workbook
    Set wb = Workbooks.Open(filePath )
    IsExcelFormat = (wb.FileFormat > 50)

CleanExit:
    Application.ScreenUpdating = True
Exit Function

Nope: ' Clearly not Excel format
    Err.clear
    IsExcelFormat = False
    Resume CleanExit:

End Function

是的,它使用 Excel 的自动魔法。我知道。太可怕了而且 ScreenUpdating 并不完全有效。当您打开和关闭文件时,您的任务栏将更新。但是,它仍然有效。

您可能需要在 Access VBA 脚本中创建一个 Excel 实例,并可选择将其传递给类似这样的功能。 请注意,我没有对此进行测试。

Public Function IsExcelFormat(ByVal file_path As String, _
        Optional byRef excel_instance as Excel.Application = Nothing) As Boolean
    On Error GoTo Nope

    Dim local_excel as boolean
    If excel_instance Is Nothing Then 
       Set excel_instance = New Excel.Application
       local_excel = True
    End If

    Dim wb As Excel.Workbook

    excel_instance.ScreenUpdating = False

    Set wb = excel_instance.Workbooks.Open(file_path)
    IsExcelFormat = (wb.FileFormat > 50)
    wb.Close savechanges:=False

CleanExit:
    If local_excel Then 
        excel_instance.Quit
    Else
        excel_instance.ScreenUpdating = True    
    End If
Exit Function
Nope: ' Clearly not Excel format
    Err.clear
    IsExcelFormat = False
    Resume CleanExit:
End Function

【讨论】:

  • 没有理由将屏幕更新设置为 false。只是不要让 excel 的实例可见。 (你没有,但为了 OPs 的利益......)
【解决方案3】:

关于使用 ADOX 的可能方法的一些说明

Sub SortFiles()
''Library reference: Windows Script Host Object Model
Dim fs As New FileSystemObject
Dim ts As TextStream
Dim sType As String
Dim sFile As File

For Each sFile In fs.GetFolder("Z:\Docs\").Files
    sType = sFile.Type

    If InStr(sType, "Microsoft") = 0 Then
        sList = ListTables(sFile.Name)
        If sList = "Error: Not Excel" Then
            ''Move to suitable folder
        Else
            Debug.Print sList
            Stop
            ''This can be read as Excel, most likely
        End If

    ElseIf sType Like "*Excel*" Then
       ''Includes CSV
        sFile.Move "z:\docs\Excelfiles\"
    Else
        sFile.Move "z:\docs\OtherMS\"
    End If
Next

End Sub

Function ListTables(sFile As String) As String
''Library reference: Microsoft ADO Ext. x.x for DDL and Security
Dim cat As New ADOX.Catalog
Dim scn As String
Dim t As ADOX.Table
Dim cn As New ADODB.Connection
Dim sList As String

On Error GoTo Handle_Err:

    scn = "Provider=Microsoft.ACE.OLEDB.12.0;" _
    & "Data Source=" & sFile & ";Extended Properties=""Excel 8.0;HDR=No"""

    cn.Open scn

    cat.ActiveConnection = cn

    For Each t In cat.Tables
        sList = sList & vbCrLf & t.Name
    Next t

    ListTables = sList

Exit_Proc:
Set cn = Nothing
Set cat = Nothing
Exit Function

Handle_Err:
    If Err.Number = -2147467259 Then
        ''External table is not in the expected format.
        ListTables = "Error: Not Excel"
        Err.Clear
        Resume Exit_Proc
    Else
        Debug.Print Err.Number, Err.Description
    End If

End Function

【讨论】:

  • 您是否建议如果我将 Excel 文件重命名为 .txt,它仍会被标记为 Excel 吗?
  • 我用一个名为 test.tst 的文件进行了测试,它通过了 ADOX 测试,返回了表名的各种工作表名称。
  • 我尝试在一个只有 XLS 文件的文件夹上运行它,它报告正确。但是,当我将其中一个 Excel 文件重命名为 .txt 时,它会返回“错误:不是 Excel”。
  • 这不是我的 PC 上发生的情况,一个名为 *.txt 的 Excel 文件有效。具有正确扩展名的 Excel 文件永远无法达到 ADOX 测试,因此这不算数。连接字符串似乎不适合您的 Excel 版本。您能否使用扩展名为正确的 Excel 文件测试 ADOX 函数,看看是否是这种情况?如果是这样,您可以在您的设置(Excel 版本等)上发布注释吗?我使用了相当多的 Excel 类型进行了测试,但正如您所见,使用的是最新的 ACE 12 驱动程序。
  • 无论电脑有没有excel,我都想知道文件是不是Excel类型的。 Excel 可以是任何版本,不限于特定版本。当我运行这段代码时,我的 Excel 包含“Microsoft Office Excel 97-2003 工作表”而不是“Microsoft Excel”,所以我当然必须更改代码。
猜你喜欢
  • 1970-01-01
  • 2011-04-28
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多