Excel VBAでPDFをExcelに変換する方法をお探しですね。
広告
PDFの表をExcelに取り込んで使いたい!VBAでできること・できないこと
請求書や注文書、集計表などがPDFで届いたとき、「この表、Excelで使いたいな…」と思ったことはありませんか?手作業でコピペすると、列がぐちゃぐちゃになったり、数字なのに計算できなかったり、イライラすることも多いですよね。
この記事では、Excel VBAを使ってPDFの表データをうまく取り込んで、Excelで使える形にする方法を、現実的な視点で解説していきます。
残念ながら、VBAだけでPDFを読むのは難しい
最初にお伝えしておくと、Excel VBAには「PDFをそのまま表として読み込む」機能は標準で用意されていません。
ExcelファイルやCSVなら簡単に開けるのですが、PDFは「きれいに見せるための文書形式」なので、中身の構造がExcelの表とはまったく違うんです。
見た目は表でも、実は文字がバラバラに配置されているだけで、「ここからここまでが1つのセル」という情報がないPDFもたくさんあります。
じゃあどうするかというと、実際にはExcelの「データの取得」機能やPower Query、外部の変換ツール、OCR(画像から文字を読み取る技術)などを組み合わせます。
VBAの役割は、PDFを直接読むことではなく、「取り込んだ後の整理整頓」「必要な部分だけ抜き出す」「別のシートにコピーする」といった自動化を担当させるイメージです。
たとえば、PDFをPower Queryで読み込んで、VBAでその処理を更新して、取り込まれた表から「商品コード」「数量」「金額」だけを抜き出す、という流れが安定しやすいです。
それと、PDFには大きく分けて2種類あります。
「テキストPDF」は文字情報がちゃんと入っているので、Excelで表として認識できる可能性があります。
一方、FAXで届いた注文書やスキャンした書類のような「画像PDF」は、文字が画像として保存されているだけなので、そのままではExcelが読めません。
この場合はOCRで文字を読み取る必要があります。
処理を作る前に、相手にしているPDFがどっちのタイプなのか確認しておくと、後がスムーズです。
Power QueryのPDF読み込みをVBAで自動化してみよう
ExcelでPDFの表を読み込む一番使いやすい方法は、Power Queryの「PDFから」機能です。
Excelの画面で操作するなら、「データ」タブから「データの取得」→「ファイルから」→「PDFから」と進んで、PDFを指定します。
すると、PDF内で見つかった表やページがリストで出てきて、プレビューを見ながらExcelに読み込めます。
普通にコピペするより、列の構造を保ちやすいのがメリットです。
VBAで全部やろうとするんじゃなくて、Power Queryの読み込み処理をVBAから呼び出すようにすると、毎月同じ形式のPDFを処理するときにすごく楽になります。
以下は、PDF内の表をPower Queryで読み込んで、Excelシートに出力する基本的な例です。
実際のテーブル名やIDはPDFによって変わるので、最初は手動で試してから、VBAに落とし込むのが安全です。
“`vb
Sub ImportPdfTableByPowerQuery()
Dim pdfPath As String
Dim ws As Worksheet
Dim queryName As String
Dim mCode As String
pdfPath = “C:\PDF\sample.pdf”
queryName = “PDF_Table_Import”
Set ws = ThisWorkbook.Worksheets(“取込結果”)
ws.Cells.Clear
‘ 既存のクエリがあれば削除
On Error Resume Next
ThisWorkbook.Queries(queryName).Delete
On Error GoTo 0
‘ PDFから表を取得するM言語のコード
mCode = _
“let” & vbCrLf & _
” Source = Pdf.Tables(File.Contents(“”” & pdfPath & “””), [Implementation=””1.3″”]),” & vbCrLf & _
” Table001 = Source{0}[Data]” & vbCrLf & _
“in” & vbCrLf & _
” Table001″
‘ クエリを作成
ThisWorkbook.Queries.Add Name:=queryName, Formula:=mCode
‘ シートに読み込み
With ws.ListObjects.Add(SourceType:=0, _
Source:=”OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=” & queryName & “;Extended Properties=”””””, _
Destination:=ws.Range(“A1”)).QueryTable
.CommandType = xlCmdSql
.CommandText = Array(“SELECT * FROM [” & queryName & “]”)
.Refresh BackgroundQuery:=False
End With
End Sub
“`
このコードは、PDFから見つかった最初の表を読み込む例です。
ただ、実際には「Source{0}」が毎回目的の表になるとは限りません。
PDFのレイアウトが変わると、Power Queryが検出する表の順番も変わることがあります。
なので、最初は手動で取り込んでみて、どの表が必要かを確認してから、クエリの内容を調整するのが大事です。
毎月同じフォーマットの請求書や報告書なら、この方法でかなり効率化できますよ。
取り込んだ表を「使える形」に整えて抽出する
PDFからExcelに取り込めても、そのまますぐ集計できるとは限りません。
よくあるのが、数字が文字列として読み込まれていたり、変な空白や改行が入っていたり、列名がずれていたり、表の始まる行がPDFごとに違ったり…。
特に、PDF由来のデータは見た目「123」でも、Excel内部では文字列扱いになっていることがあります。
この状態だとSUM関数やピボットテーブルで正しく計算できないので、VBAで整形処理を入れておくと実務で使いやすくなります。
例えば、取り込んだシートから必要な列だけを抽出して、別のシートに転記する処理を作っておくと管理しやすいです。
注文書なら「商品コード」「配送先コード」「発注数量」、請求書なら「品目」「単価」「数量」「金額」みたいに、必要な項目を決めておきます。
表の位置が毎回ずれる場合は、固定のセル番地で読むんじゃなくて、見出しの文字を検索して、その位置を起点にデータ範囲を判定する方法が効果的です。
“`vb
Sub ExtractPdfImportedTable()
Dim src As Worksheet, dst As Worksheet
Dim headerCell As Range
Dim startRow As Long, lastRow As Long
Dim r As Long, outRow As Long
Dim codeCol As Long, qtyCol As Long
Set src = ThisWorkbook.Worksheets(“取込結果”)
Set dst = ThisWorkbook.Worksheets(“抽出結果”)
‘ 抽出先シートをクリアして見出しを設定
dst.Cells.Clear
dst.Range(“A1:C1”).Value = Array(“商品コード”, “配送先コード”, “発注数量”)
‘ 「商品コード」という見出しを探す
Set headerCell = src.Cells.Find(What:=”商品コード”, LookAt:=xlPart)
If headerCell Is Nothing Then
MsgBox “商品コードの見出しが見つかりません。
PDFの取り込み結果を確認してください。
”
Exit Sub
End If
‘ 見出しの次の行からデータ開始
startRow = headerCell.Row + 1
codeCol = headerCell.Column
qtyCol = codeCol + 2
lastRow = src.Cells(src.Rows.Count, codeCol).End(xlUp).Row
outRow = 2
‘ データを1行ずつ抽出
For r = startRow To lastRow
If Trim(src.Cells(r, codeCol).Value) <> “” Then
dst.Cells(outRow, 1).Value = Trim(src.Cells(r, codeCol).Value)
dst.Cells(outRow, 2).Value = Trim(src.Cells(r, codeCol + 1).Value)
‘ カンマを取り除いて数値化
dst.Cells(outRow, 3).Value = Val(Replace(src.Cells(r, qtyCol).Value, “,”, “”))
outRow = outRow + 1
End If
Next r
End Sub
“`
こんな感じで、見出しを検索してから抽出する設計にしておくと、表の開始行が数行ずれても処理を続けられます。
PDFから変換したExcelでは、途中に空白行が入ったり、1つの商品情報が2行に分かれたりすることもあります。
そういう場合は「空白行があっても次の見出しまで読み続ける」「前の行の値を引き継ぐ」「数量が入っている行だけを対象にする」など、帳票の特徴に合わせた条件分岐が必要です。
VBAでは完璧な汎用処理を目指すより、対象の帳票のパターンを分析して、例外を1つずつ潰していく作り方が現実的です。
数値の変換では、カンマ、円マーク、全角数字、余分な空白に注意しましょう。
「1,200」「¥3,500」「123」みたいな値は、そのままだと計算できない場合があります。
Replace関数で不要な記号を削除して、Val関数やCDbl関数で数値化します。
ただし、商品コードみたいに先頭のゼロが意味を持つ項目は数値化しちゃダメです。
「00123」を数値にすると「123」になっちゃうので、コード類は文字列、数量や金額は数値というように、項目ごとに扱いを分けることが大切です。
画像PDFやFAX注文書を扱うときの注意点
FAXやスキャンで作られた画像PDFの場合、Excelの「PDFから」取り込みやPower Queryだけでは表データを取得できないことがあります。
これは、PDF内に文字情報がなくて、ページ全体が画像として保存されているからです。
こういう場合はOCRを使って、画像から文字を読み取って、その結果をExcelに渡す流れになります。
ただ、OCRは万能じゃありません。
解像度が低かったり、罫線が薄かったり、文字が傾いていたり、手書きが混じっていたり、印字がかすれていたりすると、読み間違いや文字化けが起こりやすくなります。
OCRを使う場合でも、VBA側でできる工夫はあります。
まず、PDFを直接処理する前に、OCR結果を一度テキストやExcelに出力して、どのくらい安定して読めているか確認します。
次に、毎回同じセル位置を読むんじゃなくて、「注文内容」「商品コード」「合計」みたいなキーワードを探して、その周辺を抽出する設計にします。
さらに、読み間違えやすい文字を補正する辞書を作っておくと精度が上がります。
例えば、数字の「0」と英字の「O」、数字の「1」と英字の「I」は混同されやすいので、商品コードのルールに合わせて置換する処理を検討します。
PDF取り込みを安定させるための実務的な手順は、こんな流れで考えると整理しやすいです。
– テキストPDFか画像PDFかを確認する
– テキストPDFならPower Queryで表として取り込む
– 画像PDFならOCRで文字化してからExcelへ渡す
– VBAで見出し検索、不要行削除、数値変換、転記を行う
– 例外的な帳票を記録して、条件分岐や補正ルールを追加する
セキュリティ設定にも注意が必要です。
PDFによっては、内容のコピーや抽出が禁止されている場合があります。
こういうPDFは、Excelの取り込み機能で表を取得できないことがあります。
Adobe Acrobat Readerなどで文書のプロパティを確認して、内容のコピーが許可されているかを見ておくと、原因の切り分けに役立ちます。
あと、社外秘の注文書や個人情報を含むPDFを無料のWeb変換サービスにアップロードするのはリスクがあります。
業務データを扱う場合は、社内のルールに合ったツールや、ローカル環境で処理できる方法を選びましょう。
まとめ:PDFの表を取り込むなら「分業」が現実的
Excel VBAでPDFの表データを読み込んで、Excelのセルに変換・抽出する手法は、「PDFを直接VBAで読む」よりも「Power QueryやOCRで取り込んで、VBAで整形・抽出する」と考えるのが現実的です。
テキストPDFならPower QueryのPDF取り込みを使って、VBAで更新や転記を自動化できます。
画像PDFならOCRが必要になって、読み取り精度を確認したうえで補正処理を組み込みます。
最初にPDFの種類、表の安定性、必要な項目、数値変換のルールを整理しておくことで、手作業の転記を減らして、Excel上で再利用しやすいデータに変換できます。
完璧を目指すより、対象の帳票に合わせて少しずつ改良していく姿勢が、実務では一番うまくいきますよ。
広告
