ブロックで固められて書かれた要素を複数持つ、ホームページのソースをテキスト化したものが手元にあります。
これをうまいことEXCELにリスト化したいです。
たとえばあるソースの中に
<TR>
<TD class="ln">
<A HREF="●">▲<BR>■</A></TD>
<TD>◆</TD>
</TR>
<TR>
<TD class="ln">
…
みたいな書き方で複数行にわたる要素が書かれたブロックが複数書かれていたら、
A1には最初に書かれていたデータ●の、B1には▲、C1には■、D1には◆日付、
次のデータの●をB1、▲をB2、…って感じですべての行のデータををexcelに取り込む方法です。
あくまでも指定したソースからEXCELデータが取り出せればいいので、
たとえばソースをテキスト化して取り出したい表現を正規表現を使って表してEXCELにぶち込めば勝手に抽出してくれる、みたいな機能でもかまいません。
個人的にはテキストでのタブによるインデントは隣の枠に移るので、それをうまく利用すれば簡単にexcelに取り込めるのではないかと考えましたが、自分では無理でした。
何かいい方法はないでしょうか。ご存知の方、どうかよろしくお願いします。
Sub Macro1() ' 参照設定で以下2つにチェックをいれておくこと ' Microsoft AxtiveX Data Objects x.x Library x.xは2.5以降(もう少し古いものでもOKかもしれませんが調べてません) ' Microsoft VBScript Regular Expressions x.x x.xは5.5以降 ' (実行時バインドに変更する場合はUTF-8やadTypeTextなどを数値指定に置き換える必要あり) ' ' 事前準備 Dim fileName As String, chrCode As String, sheetName As String, strText As String fileName = "d:\ソース.html": '読み込むファイル(フルパスでの指定が必要です ActiveWorkbook.Path を使うと便利かもしれません) chrCode = "UTF-8": 'ファイルの文字コード strText = "" sheetName = "Sheet1": '書き込むシート startCell = "A1": 'セル内の書き込み開始位置 ' 読み込み Dim st As ADODB.Stream Set st = New ADODB.Stream With st .Type = adTypeText: 'テキストモード .Charset = chrCode: 'ファイルの文字コード .Open: '開始 .LoadFromFile (fileName): 'ファイルオープン strText = .ReadText(adReadAll): '一括読み込み .Close: '閉じる End With Set st = Nothing ' シートのクリア Worksheets(sheetName).Select Cells.ClearContents: 'シート全体をクリアしますので、一部のみを削除する場合は変更が必要 Range(startCell).Select ' 抜き出しとセルへの書き込み Dim re As RegExp, mc As MatchCollection, m As Match Set re = New RegExp With re .Pattern = "<tr>(\n|.)+?href=""(.+?)"">(.+?)<br>(.+?)</a>(\n|.)+?<td>(.+?)</td>(\n|.)*?</tr>": 'パターンはもう少しスマートになるかもしれません .IgnoreCase = True: '大文字小文字は区別しない .Global = True: '全体を検索対象とする .MultiLine = False: '複数行として取り扱わない Set mc = .Execute(strText): '実行 For Each m In mc Selection.Value = m.SubMatches(1) Selection.Offset(0, 1).Value = m.SubMatches(2) Selection.Offset(0, 2).Value = m.SubMatches(3) Selection.Offset(0, 3).Value = m.SubMatches(5) Selection.Offset(1, 0).Select: '次の行にカーソル移動 Next m Set mc = Nothing Set re = Nothing End With End Sub
Sub Macro1() ' 参照設定で以下2つにチェックをいれておくこと ' Microsoft AxtiveX Data Objects x.x Library x.xは2.5以降(もう少し古いものでもOKかもしれませんが調べてません) ' Microsoft VBScript Regular Expressions x.x x.xは5.5以降 ' (実行時バインドに変更する場合はUTF-8やadTypeTextなどを数値指定に置き換える必要あり) ' ' 事前準備 Dim fileName As String, chrCode As String, sheetName As String, strText As String fileName = "d:\ソース.html": '読み込むファイル(フルパスでの指定が必要です ActiveWorkbook.Path を使うと便利かもしれません) chrCode = "UTF-8": 'ファイルの文字コード strText = "" sheetName = "Sheet1": '書き込むシート startCell = "A1": 'セル内の書き込み開始位置 ' 読み込み Dim st As ADODB.Stream Set st = New ADODB.Stream With st .Type = adTypeText: 'テキストモード .Charset = chrCode: 'ファイルの文字コード .Open: '開始 .LoadFromFile (fileName): 'ファイルオープン strText = .ReadText(adReadAll): '一括読み込み .Close: '閉じる End With Set st = Nothing ' シートのクリア Worksheets(sheetName).Select Cells.ClearContents: 'シート全体をクリアしますので、一部のみを削除する場合は変更が必要 Range(startCell).Select ' 抜き出しとセルへの書き込み Dim re As RegExp, mc As MatchCollection, m As Match Set re = New RegExp With re .Pattern = "<tr>(\n|.)+?href=""(.+?)"">(.+?)<br>(.+?)</a>(\n|.)+?<td>(.+?)</td>(\n|.)*?</tr>": 'パターンはもう少しスマートになるかもしれません .IgnoreCase = True: '大文字小文字は区別しない .Global = True: '全体を検索対象とする .MultiLine = False: '複数行として取り扱わない Set mc = .Execute(strText): '実行 For Each m In mc Selection.Value = m.SubMatches(1) Selection.Offset(0, 1).Value = m.SubMatches(2) Selection.Offset(0, 2).Value = m.SubMatches(3) Selection.Offset(0, 3).Value = m.SubMatches(5) Selection.Offset(1, 0).Select: '次の行にカーソル移動 Next m Set mc = Nothing Set re = Nothing End With End Sub
早速のご回答、どうもありがとうございます。
With reのPatternの正規表現の部分について、どの記号がどういう意味を持つのかを、もう少し詳しく教えていただきたいです。
不勉強ながら申し訳ありませんが、どうかご指導のほど、よろしくお願いします。
コメント欄に一度書いたのですが、少々崩れたので回答欄のほうに投稿しなおしました
いずれも大学の1講座になるようなものになりますので、最低限のさわりだけとさせていただきます
【1】マクロ記述の基本
マクロの記述方法については下記ページの「プログラムを書き始めるまでの準備」と「プログラミングと実行」がわかりやすいでしょう
http://brain.cc.kogakuin.ac.jp/~kanamaru/lecture/vba2003/2007_01...
Option Explicit をモジュールの一番上に書いておくと、変数の記述ミスなどを防げて便利なので書いておくほうがよいでしょう
ちなみに、私のコードの前にOption Explicitを書いた場合にはstartCell = の箇所で変数が宣言されていませんというエラーが出ますが、
これはdimで宣言するのを忘れているためなので、エラー発生場所の少し上にある宣言文にstartCell As Stringを加えて下記のようにすればエラーはなくなります
Dim fileName As String, chrCode As String, sheetName As String, strText As String, startCell As String
【2】正規表現パターンの説明
(1)正規表現を言葉で説明することは実に難しいため一部抜き出しでの説明とさせていただきます
. 改行以外の何か1文字を示します .+ 改行以外の文字が1つ以上つながっている状態を示します \n 改行文字です (\n|.)+ 上記を組み合わることによって、改行を含む何かが1つ以上つながっている状態を示します .* 何も無い。もしくは、改行以外の文字が1つ以上つながっている状態を示します (\n|.)* 何も無い。もしくは、改行を含む何かが1つ以上つながっている状態を示します ? 最短マッチ
その他にもパターンで使えるメタ文字はいくつかありますので下記参照してみてください
http://msdn.microsoft.com/ja-jp/library/cc392437.aspx
(2)パターンの意味を頭から見ていきます
<tr>(\n|.)+href= <tr>とhref=の間に色々な文字があるという状態を示します 上の表記では最初に見つかった<tr>から一番最後に見つかったhref=までを一まとめにしてしまう(最長マッチと言います)ため?を加えて一番最初に見つかったhref=で止まるようにします(最短マッチ) <tr>(\n|.)+?href= 同様に</tr>までの構成パターンを順に記述していくと回答1のようになります
スマートになるかもしれませんという言葉は、対象となるhtmlのソースをいくつも眺めてパターンを確実につかむことが出来れば、もしかするともっと単純なパターンですむかもしれないということです
なるほどです。ご丁寧な回答、ありがとうございます。
参照設定でチェックを入れたのですが、「この名前は既にあるモジュール、プロジェクト、オブジェクト ライブラリで使われています。」と表示が出てしまいチェックできませんでした。
回答可能件数を5件までに変更しましたので、どうか返信をよろしくお願いします。
なお、ページはUNICODE表記になります。読み込みたいファイルは高々10件程度なので、こちらは手作業で何とかなると思います。
しかし各々のファイルのテーブル情報が多いので、それらの解析は自動で行いたいと考えました。
http://codezine.jp/article/detail/2149
http://www001.upp.so-net.ne.jp/isaku/tips/download.html
http://codezine.jp/article/detail/1655
このあたりが参考になるのかな。
指定URLからダウンロードしたhtml データを文字列として取得し、
正規表現で必要なデータを取り出すという流れですね。
個人的にwebから同様にデータ取ることしてますが、
Visual Basic コードはどうも好きになれないので、
C#で組んで、csv として出すようにしてます。
プログラム組むことになれていないと
長く辛い闘いになるかもしれません。
早速のご回答、どうもありがとうございます。
With reのPatternの正規表現の部分について、どの記号がどういう意味を持つのかを、もう少し詳しく教えていただきたいです。
不勉強ながら申し訳ありませんが、どうかご指導のほど、よろしくお願いします。