Excelファイル(xls, xlsx, xlsm)をVBAとADOで開けるかどうかを判定する方法


Excelで多くのファイルを扱っていると、「このファイルは壊れていない?」「保護されていて読み取れない?」など、開く前に事前にチェックしたくなることがあります。
ここでは、VBAとADOを使って、Excelファイルを開かずに中身が読み取れるかどうかを判定する方法をご紹介します。


■ この方法でわかること

  • .xls(Excel 97-2003)、.xlsx(Excel 2007以降)、.xlsm(マクロ付き)すべてに対応
  • ファイルがパスワードで保護されている、破損している、壊れている場合は読み取り不可と判定
  • 開かずに調べられるので高速・安全

■ VBAコード:ADOでExcelファイルが開けるかを判定する関数(形式自動判定)

Function CanOpenAnySheetWithADO(filePath As String) As Boolean
    Dim cn As Object ' ADODB.Connection
    Dim rs As Object ' ADODB.Recordset
    Dim tbl As Object
    Dim result As Boolean
    Dim ext As String
    Dim connStr As String

    On Error GoTo ErrHandler

    ' 拡張子を取得して接続文字列を切り替え
    ext = LCase(Right(filePath, Len(filePath) - InStrRev(filePath, ".")))

    Select Case ext
        Case "xls"
            connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                      "Data Source=" & filePath & ";" & _
                      "Extended Properties=""Excel 8.0;HDR=YES;IMEX=1"";"
        Case "xlsx", "xlsm"
            connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                      "Data Source=" & filePath & ";" & _
                      "Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"
        Case Else
            CanOpenAnySheetWithADO = False
            Exit Function
    End Select

    Set cn = CreateObject("ADODB.Connection")
    cn.ConnectionString = connStr
    cn.Open

    ' シート一覧取得
    For Each tbl In cn.OpenSchema(20) ' adSchemaTables
        Dim sheetName As String
        sheetName = tbl("TABLE_NAME")
        
        If Right(sheetName, 1) = "$" Or Right(sheetName, 2) = "$'" Then
            On Error Resume Next
            Set rs = cn.Execute("SELECT TOP 1 * FROM [" & sheetName & "]")
            If Err.Number = 0 Then
                result = True
                Exit For
            End If
            On Error GoTo ErrHandler
        End If
    Next

CleanUp:
    On Error Resume Next
    If Not rs Is Nothing Then If rs.State = 1 Then rs.Close
    If Not cn Is Nothing Then If cn.State = 1 Then cn.Close
    Set rs = Nothing
    Set cn = Nothing

    CanOpenAnySheetWithADO = result
    Exit Function

ErrHandler:
    result = False
    Resume CleanUp
End Function

■ 使用例

Sub TestADOCheck()
    Dim path As String
    path = "C:\Path\To\Your\File.xlsm"
    
    If CanOpenAnySheetWithADO(path) Then
        MsgBox "少なくとも1つのシートはADOで開けます。"
    Else
        MsgBox "開けません(パスワード保護・破損などの可能性があります)。"
    End If
End Sub

■ 注意点

  • .xls 形式は古いため Microsoft.Jet.OLEDB.4.0 を使用します。
  • .xlsx.xlsm などの新形式は Microsoft.ACE.OLEDB.12.0 を使用します。
  • ACEプロバイダーがインストールされていない環境では .xlsx の読み取りができないことがあります(→ Officeのインストールで解決)。

■ まとめ

この関数を使えば、Excelファイルを事前に確認して「開けるファイルだけ処理する」「エラーが出そうなファイルを除外する」といったことが可能になります。
ファイルチェックの自動化やExcelツールの安定化にぜひご活用ください。


コメント

タイトルとURLをコピーしました