[[20140514102932]] 『索引作成のためにPDFファイルの中から文字列検索ax(マクロ初心者) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『索引作成のためにPDFファイルの中から文字列検索し、ページ番号をExcelに抽出したい』(マクロ初心者)

一つのPDFファイルの中から文字列を検索し、ページ番号をExcelに抽出したい。
マクロ等で文字列(複数)を検索し、ページ番号をカンマ区切りでExcelに抽出できないでしょうか?

索引作成のためページ番号をひろっていかなくてはならないのですが、索引の文字列が膨大な量でさらにページ数も900超えと多いので途方もなく時間がかかってしまう。
現状では、PDFで文字列を一つずつ検索し、検索結果をみながら一つずつページ数をテキストに入力している。

< 使用 Excel:Excel2010、使用 OS:WindowsXP >


ReaderではないAcrobatを利用しているならば、AcroExch.AVDocオブジェクトの
GetPDDoc.GetNumPagesプロパティが、ページ数になります。

他に、直接PDFファイルをテキストとして開いてキーワードを探すことも可能ですが、
PDFといっても幾つかバージョンがあるため、キーワードが何種類もあるので、作成が大変です。
製品版のAcrobatをインストールしておくのが一番簡単です。
(???) 2014/05/14(水) 11:10


 目的がわかりませんが、
http://help.adobe.com/ja_JP/acrobat/using/WS58a04a822e3e50102bd615109794195ff-7c37.w.html
 あたりを使用して、都度検索の運用としてはどうでしょうか。

 現在の作業をプログラムでやるのであれば、
 Acrobat(Reader ではなく)を使用して、スクリプト処理が汎用的だと思いますが、
  あるいはこのあたりを参考にしてマクロ処理でしょうか。
http://pdf-file.nnn2.com/?p=111
http://pdf-file.nnn2.com/?p=178
(Mook) 2014/05/14(水) 11:19

冊子の一番後ろにある索引のページ番号をひろってきたいのです。

現状PDFをAcrobat pro9を使用して文字列を検索し、検索結果からPDFファイルのページ番号をテキストに一つずつ手入力しています。
マクロコードも書いていただけると助かります。

説明不足ですみません。
質問がありましたらどんどんしてください!
(マクロ初心者) 2014/05/14(水) 11:27


 他サイトなので何なのですが・・・。

http://oshiete.goo.ne.jp/qa/6680215.html

 PDFをエクセル上で開いて文字列の中からページ数を取得する、という方法が紹介されています。

 追記:???さんがテキストとして開く方法を提案されてましたね。
 失礼しました。
(カリーニン) 2014/05/14(水) 11:36

Acrobatはお持ちのようなので、あとは私が教えた2つのキーワードをググりましょう。
最初にでてきたブログあたりに、そのものずばりのサンプルが出ているようですよ。
http://www.ka-net.org/blog/?p=2320
(???) 2014/05/14(水) 14:22

 質問の内容は PDF ファイルのページ数ではなくて、検索語があるページ番号の列挙では
 ないかな?

 PDF のフッタに書かれているページと、先頭からのページ数一致している のかとか、
 いろいろ確認しておかないと、せっかく処理したのに使えないとか、懸念がありそうです。

 GoogleDesktop など 使用時に高速に一括検索も難しくないと思いますが、本当に EXCEL での
 インデックスが必要不可欠なのでしょうか。
(Mook) 2014/05/14(水) 14:37

PDFのページ数は一致してます。
マクロ関連を利用するとなるとExcelもしくはWordがいいのかと思いまして。
色々ググってみたのですがツール等なかったのでこちらのプロフェッショナルな人たちに駆け込みました。
どうしたいか例にしますね。

//////////////////////////

検索する文字列
関税
年金

PDF内文字列検索検索
ページ番号
50,158,250,630,700←このページ番号を一括で抽出したいです。現状ここを手入力です。
150,256,532,666,710

最終的には

関税 50,158,250,630,700
年金 150,256,532,666,710

////////////////////////

(マクロ初心者) 2014/05/14(水) 14:49


???さんへ

マクロ初心者なものでおっしゃっていたことをどうやってマクロにおこしていいかわかりません。

(マクロ初心者) 2014/05/14(水) 14:56


冊子の一番後ろにある索引のページ番号、との事だったので、つまりはページ数またはそこから
固定値引いたもの、と読み取ったのですが、どうもキーワードと、そのページを拾いたいような感じですね。

そうなると、オブジェクトにキーコードを送ってAcrobatを操作、検索してページ数情報を拾って…を
繰り返すようなマクロにしないといけないでしょう。ちょこちょこっと作ってあげられるレベルではないです。

PDFにする前のファイルは所持していないのでしょうか? それがExcelまたはWord等であれば、そっちから
検索するほうがはるかに簡単なのですが。
(???) 2014/05/14(水) 15:16


???さんへ

WordやExcelだったらと確かに私もそう思っております。
元データはWordなのですがページ番号があっていないというかセクション多々組み込んでいるためページがひろえない状態です。あといくつかにファイルがわかれてしまっています。
どういったものかという2段組みの本文で図表がぶちぬきではいっている冊子です。

ない頭で考えたのですが
Excelに検索文字列をもってきてセルを参照し→PDF検索→Excelにページ番号はきだしという操作が難しいのですね。

(マクロ初心者) 2014/05/14(水) 15:35


???さんへ

方法としてお聞きしたいのですがPDFデータをページそのままに
Wordにもってくることってできるのでしょうか?
要はテキストとページさえあっていればいいので。図表は無視してかまいません。

(マクロ初心者) 2014/05/14(水) 15:38


OfficeにPDFを読み込む機能は無いですね。出力のみです。読み込んでくれれば苦労しないのですが…。

ものすごく大変なコーディングになりますが、実現するとしたら、先に説明したAcrobatオブジェクトで
PDFを開き、Acrobatのツールバーを操作して文字列検索。表示されたページ番号を得て、Excelに記述。
これをキーワード分繰り返します。

現在のページを得るのも難しいので、良い命令が無ければ、ヘッダまたはフッタの固定文字を探し、
その後ろにある数字をコピー。クリップボード経由でExcelに取り込む、などの工夫が必要です。

レイアウトに問題のあるページも考えると、たとえ1万件のキーワードがあろうとも、
手で検索して埋めていくほうが確実でしょう。

別案ですが、元のdocファイルがあるならば、ページではなく、章番号を示す目次にしてはどうですか?

または、Doc上でキーワード出現箇所に目次対象となる印を付けておき、Word上で目次作成しておいてはどうです?
(元が複数あるのは、なんとかして1つにまとめる)
(???) 2014/05/14(水) 16:02


???さんへ

難しそうですね・・・
結構適当な冊子なのでそこまで正確さは求めてません。先方に修正いれてもらうので形だけできていればいいので。
見本の冊子があるのでそれに順次なければならないので索引の形はかえれません。

万が一Wordに変換出来た場合マクロで記述することはできますか?

(マクロ初心者) 2014/05/14(水) 16:20


横入り失礼します

PDFからWordやExcelに変換することは可能ですよ。
Acrobatのバージョンにもよる気がしましたがpro9ならできたんじゃないかな?
元のPDFのがそのままWordを変換させたものならそのまま綺麗にできたはず・・・
(とらら) 2014/05/14(水) 16:43


とららさんへ

テキスト形式ならなんとか改ページも生きてくるのでもどせました!

長々と迷惑かけてすみませんがここからマクロコーディングお願いします。
PDFがWordに変わっただけです。
(マクロ初心者) 2014/05/14(水) 17:05


お願いします、じゃなくて、まずは自力で検索して、マクロの使い方を覚えて、それからですよ?
丸投げ他力本願は止めてくださいね。

ちなみに、Wordに戻されてもExcelからは困るんですが…。どうせならExcelに変換出力しては?
いずれにせよ、ページ位置は得られないような?
(PDFならなんとかページ位置を得られますが、コーディングがとても難しい)
1ページの行数固定なら計算できますが、違うんですよね?

とりあえず、docxから文字列を探し、見つかったワード位置を返す例。
実行前に、A列にキーワードを列挙しておいてください。(結果はB列に出ます)
なお、行やページの情報は得られないため、何ワード目が一致したか、になっています。

 Sub test()
    Dim wkWord As Object
    Dim i As Long
    Dim j As Long

    Set wkWord = CreateObject("Word.Application")
    wkWord.Visible = False
    wkWord.Documents.Open "c:\aaa.docx"
    With wkWord.Documents
        For i = 1 To Cells(Rows.Count, "A").End(xlUp).Row
            For j = 1 To .Item(1).Content.Words.Count
                If .Item(1).Content.Words(j) Like "*" & Cells(i, "A").Text & "*" Then
                    Cells(i, "B").Value = j
                    Exit For
                End If
            Next j
        Next i
    End With
    wkWord.Quit
    Set wkWord = Nothing
End Sub
(???) 2014/05/14(水) 18:43

Wordで検索し、そのページ位置を抜き出し?

 Sub test()
    Dim myApp As Object
    Dim myDoc As Object
    Dim myDic As Object 
    Dim myRng As Object
    Dim c As Range
    Dim myP As Long

    Set myApp = CreateObject("Word.Application")
    myApp.Visible = True
    Set myDoc = myApp.Documents.Open("C:\*****\**.docx")

    Set myDic = CreateObject("Scripting.Dictionary")

    For Each c In Range("A1", Cells(Rows.Count, 1).End(xlUp))
        Set myRng = myDoc.Content
        With myRng.Find
            .Text = c.Value
            Do While .Execute
                myP = myRng.Information(3)
                myDic(myP) = Empty
            Loop
            c.Offset(, 1).Value = Join(myDic.keys, ",")
            myDic.RemoveAll
        End With
    Next
    myDoc.Close
    myApp.Quit

    Set myDic = Nothing
    Set myDoc = Nothing
    Set myApp = Nothing

 End Sub

(マナ) 2014/05/14(水) 22:19


丸投げすみません。
明日自分なりに調べてみます!
ページについてはテキストはきだししたときに改ページとしてページごとに抽出できたので問題ないかと思います。
忙しい中こんなことに付き合わせてしまってすみません。

独学で勉強するのにいい方法ありましたら教えていただきたいです。
これも参考に勉強しようと思っています。こちらでコーディングしていただいたものもそのまま使うのではなく理解した上で使うつもりです。

色々応用をきかせて自分で作れるようになりたいのです。
今回は仕事急ぎなためこんな形になってしまいました。すみません。
次回はもっと時間をかけて皆さんにご教授いただきたいです。
(マクロ初心者) 2014/05/15(木) 01:22


Sub sakuin()

    Dim cellc As Integer
    Dim wdObj As New Word.Application
    Dim wdDoc As Word.Document
    Dim wordFile As String
    Dim P As Long, L As Long

' ※ 実際に、OpenするWord文書ファイル名をパス名付きで入れます ※

    wordFile = ".docx"

' Word文書を開きます

    wdObj.Visible = True
    wdObj.Documents.Open wordFile

    Application.ScreenUpdating = False

    Workbooks.Open Filename:=".xlsx"

    Set objWord = CreateObject("Word.Application")
    objWord.Visible = True
    Set objSelection = objWord.Selection

    cellc = 1
    i = 1
    Do While i > 10 'テストなので10としました
        objSelection.Find.Text = Cells(i, 1)  ' 文字列格納
        objSelection.Find.Forward = True
        objSelection.Find.MatchWholeWord = True

        If objSelection.Find.Execute Then

            P = Selection.Range.Information(wdActiveEndPageNumber)

            If P = L Then
            Else
                ThisWorkbook.Worksheets("Sheet1").Cells(cellc, i + 1) = P & ","
                L = P
            End If
        End If

        i = i + 1
        cellc = i

    Loop

End Sub

自力でこういう感じに作成したのですがエラーはでないのですが何もされません。
何が間違っているか教えてください!
検索する文字列はセルA1に保存しました。

結果は
A1
検索文字列
B1
初めにみつかったページ番号+カンマ
c1
次にみつかったページ番号+カンマ

続く

(マクロ初心者) 2014/05/15(木) 14:37


突っ込みどころ満載ですが、とりあえず現在のポイントだけ。
i = 1 から始まりますが、i > 10 ではないですよね?

あとはxlsxなんだかdocxなんだか、とか。
似たようなWordオブジェクトをアーリーバインドとレイトバインド両方作成している、とか。

まだご自身でデバッグしないといけない状態です。少しくらい詰まった程度で質問せず、足掻いてみましょう。
(???) 2014/05/15(木) 15:18


Sub sakuin()

    Dim cellc As Integer
    Dim wdObj As New Word.Application
    Dim wdDoc As Word.Document
    Dim wordFile As String
    Dim sk As String
    Dim P As Long, L As Long
    Dim i As Integer

' ※ 実際に、OpenするWord文書ファイル名をパス名付きで入れます ※

    wordFile = "F:\02入稿 & 作業データ\02官庁 関係\経済産業省\2014年度不公正貿易報告書\販売用\索引用本文.docx"

' Word文書を開きます

    wdObj.Visible = True
    wdObj.Documents.Open wordFile
    Application.ScreenUpdating = False

    Do While i < 5

        wdObj.Selection.Find.Text = ThisWorkbook.Worksheets("Sheet1").Cells(i, 1) '検索文字列取得
        wdObj.Selection.Find.Forward = True
        wdObj.Selection.Find.MatchWholeWord = True

        If wdObj.Selection.Find.Execute Then

            P = wdObj.Selection.Range.Information(wdActiveEndPageNumber) 'ページ番号格納

            If P = L Then 'ページ番号だぶっていないか
            Else
                ThisWorkbook.Worksheets("Sheet2").Cells(cellc, i) = P & "," 'ページ番号出力
                i = i + 1
                L = P
            End If
        Else
            cellc = i
        End If

    Loop

    wdObj.Quit

End Sub

初心者なのでこれ以上はおてあげです。
どなたか改良していただきたいです。改良なくても変な箇所を指摘ください。
(マクロ初心者) 2014/05/15(木) 16:52


あと少しだと思うのですが。

 1)Cells(cellc,i)は、行と列が逆のような気がします。
   他にもcellcとiが混乱していると思われる箇所があります。
 2)i=i+1の位置が間違い。
  検索が文末まで終わってから実行されるようにする。
  今のままだろ、最初に検索された段階で、検索文字列が変更になってます。
 3)検索が文末まで終わったら、Lとcellcは初期化すべきでは?
 4)iとcellcの初期値は1と明示しないと0になってしまう。
 5)検索が文末まで終わったら、カーソルは文頭に移動させましょう。

つまり、こんな感じにします。

 Else
  i=i+1
  L=0
  cellc=1
  wdObj.Selection.HomeKey wdStory
 End if

 ところで、私のコードではだめでしたか。

(マナ) 2014/05/15(木) 20:44


マナさんへ

明日再度コーディングしてみます!
このマクロだと同じ文字列をページ最後まで検索して最後に検索されたページ番号しか抽出できないでしょうか?
1つの文字列で数ヶ所検索されます。
セルには列bcdefと横方向に1つずつ出力するように考えてます。
結果として
A列検索文字列 b列〜fがページ番号

(マクロ初心者) 2014/05/16(金) 02:32


前方検索しか指定していないため、末尾まで行ってしまうと前に戻っていなかったようですね。
マナさん案を追加しつつ、修正してみました。

なお、結果表示はキーワードの隣に並べるほうが分かりやすいと思われるので、Sheet1に変えています。

 Sub sakuin()
    Const wordFile = "F:\02入稿 & 作業データ\02官庁 関係\経済産業省\2014年度不公正貿易報告書\販売用\索引用本文.docx"
    Dim mySheet As Worksheet
    Dim wdObj As New Word.Application
    Dim cellc As Long
    Dim P As Long
    Dim L As Long
    Dim i As Long

    Application.ScreenUpdating = False
    Set mySheet = ThisWorkbook.Worksheets("Sheet1")
    wdObj.Visible = True
    wdObj.Documents.Open wordFile

    i = 1

    Do While i <= mySheet.Cells(mySheet.Rows.Count, 1).End(xlUp).Row
        wdObj.Selection.HomeKey wdStory
        cellc = 2
        L = 0

        With wdObj.Selection
            .Find.Text = mySheet.Cells(i, 1).Text '検索文字列取得
            .Find.Forward = True
            .Find.MatchWholeWord = True
            .Find.MatchFuzzy = True

            While .Find.Execute = True
                P = .Range.Information(wdActiveEndPageNumber)
                If P <> L Then 'ページ番号だぶっていないか
                    mySheet.Cells(i, cellc).Value = P & ","
                    cellc = cellc + 1
                    L = P
                End If
            Wend
        End With

        i = i + 1
    Loop

    wdObj.Quit
    Application.ScreenUpdating = True
End Sub
(???) 2014/05/16(金) 09:25

大変お返事遅くなり申し訳ありません。
???さんのコーディングを少し改良し無事解決いたしました。手間かけてしまいすみません。
???さん結局最後までお付き合いいただきありがとうございました。
他に投稿していただいた方々も感謝いたします。

(マクロ初心者) 2014/05/21(水) 09:41


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.