【VBA】ファイルを立ち上げずに、エクセルの情報を抜き出す方法
エクセルで他のシートからセルの情報を持ってこようとすると、
ブックを立ち上げて、情報をコピーして、閉じてを繰り返し行う必要があります。
が、そんなことやっていたら日が暮れてしまいますよね。。
そこで今回は、ファイルを立ち上げずに、下記のように
・特定のフォルダ内の
・全ブックの
・全シートの
・特定のセルの情報
を持ってくる方法を紹介したいと思います。
プログラム紹介
プログラムを動かす前に、
①VBAの編集画面「ツール→参照」で、
Microsoft ActiveX Data Objects 2.8 Library
を追加して下さい。
②フォルダパスを検索したいパスに設定してください。
③「任意のセルに変更」の箇所を思い通りに変更ください。
※ダブルクリックでコピーできます。
Sub JIKKOU()
Call DBMacro("C:\Users\bluei\OneDrive\ドキュメント\blog\fp") '←検索したいフォルダを指定する。
End Sub
Sub DBMacro(Path As String)
Application.ScreenUpdating = False
' Application.Calculation = xlCalculationManual '自動計算停止(手動計算)
Dim objCn As New ADODB.Connection
Dim objRS As ADODB.Recordset
Dim sSheet As String
Dim i As Long
Set fso = CreateObject("Scripting.FileSystemObject")
Set cf = fso.GetFolder(Path)
Z = 2
Cells(Z, 1) = "ファイルへのパス"
Cells(Z, 2) = "ファイル名"
Cells(Z, 3) = "シート名"
Cells(Z, 4) = "計算用"
Cells(Z, 5) = "フォルダパス"
Cells(Z, 6) = "シートへのリンク"
Cells(Z, 7) = "ここからセルの値⇒⇒"
Z = Z + 1
For Each sFile In cf.Files
If sFile = "False" Then
Exit Sub
End If
If sFile.Name Like "*.xls*" Then
Else
GoTo Continue
End If
'db関数を使用。
With objCn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Properties("Extended Properties") = "Excel 12.0"
.Open sFile
Set objRS = .OpenSchema(ADODB.adSchemaTables)
End With
’シート名を取り出す作業
Do Until objRS.EOF
sSheet = objRS.Fields("TABLE_NAME").Value
If Right(sSheet, 1) = "$" Or Right(sSheet, 2) = "$'" Then
If Right(sSheet, 1) = "$" Then
sSheet = Left(sSheet, Len(sSheet) - 1)
End If
If Right(sSheet, 2) = "$'" Then
sSheet = Left(sSheet, Len(sSheet) - 2)
End If
If Left(sSheet, 1) = "'" Then
sSheet = Mid(sSheet, 2)
End If
sSheet = Replace(sSheet, "''", "'")
'情報を張っていく。
Application.DisplayAlerts = False
Cells(Z, 1) = sFile.Path
Cells(Z, 2) = sFile.Name
Cells(Z, 3) = "'" & Replace(sSheet, "#", ".")
Cells(Z, 4) = InStrRev(Cells(Z, 1), "\")
Cells(Z, 5) = Left(Cells(Z, 1), Cells(Z, 4))
CELLPASS = "'" & Cells(Z, 5) & "[" & Cells(Z, 2) & "]" & Cells(Z, 3) & "'!"
Cells(Z, 6) = "=HYPERLINK(A" & Z & "&""#""&C" & Z & "&""!A1"",""リンク"")"
Cells(Z, 7) = "=" & CELLPASS & "F6" '任意のセルに変更
Cells(Z, 8) = "=" & CELLPASS & "Y6" '任意のセルに変更
Cells(Z, 9) = "=" & CELLPASS & "M9" '任意のセルに変更
Cells(Z, 10) = "=" & CELLPASS & "M15" '任意のセルに変更
Cells(Z, 11) = "=" & CELLPASS & "E19" '任意のセルに変更
Cells(Z, 12) = "=" & CELLPASS & "B26" '任意のセルに変更
Cells(Z, 13) = "=" & CELLPASS & "I26" '任意のセルに変更
Cells(Z, 14) = "=" & CELLPASS & "P26" '任意のセルに変更
Cells(Z, 15) = "=" & CELLPASS & "B28" '任意のセルに変更
DoEvents '重すぎるのでフリーズしないように入れる。
'シートをリンクさせないバージョン↓
' Cells(Z, 8).Value = ExecuteExcel4Macro("'" & Cells(Z, 5) & "[" & Cells(Z, 2) & "]" & Cells(Z, 3) & "'!R26C2")
Application.DisplayAlerts = True
Z = Z + 1
End If
objRS.MoveNext
Loop
objRS.Close
objCn.Close
Set objRS = Nothing
Set objCn = Nothing
Application.StatusBar = Z
Continue:
Next
'子フォルダも同様に、subFolderを実行する。
With CreateObject("Scripting.FileSystemObject")
For Each childf In .GetFolder(Path).SubFolders
Call DBMacro(childf.Path)
Next
End With
Application.Calculation = xlCalculationAutomatic '自動計算開始
Range(Cells(1, 1), Cells(Z, 30)).Formula = Range(Cells(1, 1), Cells(Z, 30)).Formula
Application.ScreenUpdating = True
End Sub
プログラムの説明
ADOを使って、エクセルをDBとみなして、
各ファイルのシートをすべてとってきています。
'db関数を使用。
With objCn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Properties("Extended Properties") = "Excel 12.0"
.Open sFile
Set objRS = .OpenSchema(ADODB.adSchemaTables)
End With
’シート名を取り出す作業
Do Until objRS.EOF
sSheet = objRS.Fields("TABLE_NAME").Value
If Right(sSheet, 1) = "$" Or Right(sSheet, 2) = "$'" Then
If Right(sSheet, 1) = "$" Then
sSheet = Left(sSheet, Len(sSheet) - 1)
End If
If Right(sSheet, 2) = "$'" Then
sSheet = Left(sSheet, Len(sSheet) - 2)
End If
If Left(sSheet, 1) = "'" Then
sSheet = Mid(sSheet, 2)
End If
sSheet = Replace(sSheet, "''", "'")
その情報を使って、
・そのブックにリンクを作っていきます。
【='パス名[ブック名]シート名'セル名】
例)='C:\Users\bluei\OneDrive\ドキュメント\blog\fp[(201912)簡易FP.xlsx]→'!F6】
他のファイルで↓の表示が出ると、かなり萎えますが、今回の場合は、これを思う存分行うようにしています。
そのまま数式は残してありますが、最後にコピーして値貼り付けをすれば、
このリンクは削除できますので、変に重たいファイルになることを防ぐことも可能です。
まとめ
暗黙知を形式知にしたり、情報の共有を図るために、
・何かしらのフォーマットにある程度のルールにのっとったファイル
を作っていくことがあると思いますが、
残念ながらそれがうまく活用されることが少ないように感じます。
そのハードルを下げるためにも、誰もが使っているエクセルで、
DBを作ることに意味はあると思います。
是非検討してみてください!!
コメント欄