t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBAでテンプレートを元にHTMLコードを自動生成する

今回はVBAを利用してHTMLを生成するテクニックを紹介

題材は先日紹介した、参照設定とCreateObjectの対応リスト - You.Activate
thom.hateblo.jp

このページはご覧いただくとわかるように、項目名は同じで内容だけ異なるものが複数回出てくる。
f:id:t-hom:20170206031011p:plain

ひとつのオブジェクトの紹介は以下のHTMLで構成されている。

<h3>ファイルシステムオブジェクト</h3>
<dl class="ProgIDList">
<dt>説明</dt><dd>ファイル・フォルダの生成・移動・削除やテキストファイルの生成、読み込みなどに使用</dd>
<dt class="fl">ProgID</dt><dd>Scripting.FileSystemObject</dd>
<dt class="fl">参照設定名</dt><dd>Microsoft Scripting Runtime</dd>
<dt class="fl">ライブラリ名</dt><dd>Scripting</dd>
<dt class="fl">オブジェクト名</dt><dd>FileSystemObject</dd>
<dt>アーリーバインディング書式</dt>
<dd class="code"><pre class="brush:vb toolbar:false">
    Dim fso As Scripting.FileSystemObject
    Set fso = New Scripting.FileSystemObject
</pre></dd>

<dt>レイトバインディング書式</dt>
<dd class="code"><pre class="brush:vb toolbar:false">
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
</pre></dd>

これをバカ正直にコピー&ペーストで編集しても良いのだけれど、いかんせん効率が悪い。
ということで、これもテンプレートを作ってVBAでやってしまおう。

※本来はDBにデータを格納してPHPで動的にページを生成するのがセオリーだが、たかだか1ページのために仕組みを作るのも面倒だしこれくらいなら得意のVBAで良いかなと。

まず、シートはこんな感じ。
f:id:t-hom:20170206032220p:plain

薄い黄色で塗ってあるのがテンプレートで可変項目は$$$としている。
その右がデータ部で、1列がひとつのオブジェクト紹介。右へ右へとどんどんデータが続くイメージ。

ふつうはデータ方向は下なんだけど、HTMLのテンプレートは縦に書きたかったのでやむなく。
※もっとデータが多ければ、可変項目を「$$1$$」などとナンバリングしたテンプレートを別シートに作り、データは1行1レコードとする方法もある。

コードは以下の通り。シートモジュールに直接貼り付けて実行する。

Option Explicit
Sub HTMLOutput()
    Const MAX_ROW = 19
    Const START_COLUMN = 3
    Const END_COLUMN = 5
    Dim template: template = Range("B1:B" & MAX_ROW).Value
    
    Dim j, i
    For j = START_COLUMN To END_COLUMN
        Dim data: data = Range(Cells(1, j), Cells(MAX_ROW, j)).Value
        For i = 1 To MAX_ROW
            Debug.Print Replace(template(i, 1), "$$$", data(i, 1))
        Next
    Next
End Sub

実行するとイミディエイトウインドウにHTMLコードが生成されるので、あとは切り取ってエディタに貼り付ければ完成。
f:id:t-hom:20170206033502p:plain

最大行、開始列、終了列はハードコーディングしてるので使用時は定数を変更する必要あり。自動取得も簡単だけれど、今回は使い捨てマクロなのでそこは適当に。。

やってることは単純で、テンプレート部とデータ部をそれぞれ別の二次元配列に入れ、あとは1行ずつ$$$をリプレースしながらイミディエイトウインドウに出力している。

ちなみにイミディエイトウインドウは最大200行までしか出力できないので、一気に大量のデータをさばきたいときは変数に入れて最後にクリップボードに送るか、テキストファイルとして出力するなどの工夫が必要。まあ本格的にデータ扱うなら、PHP等で仕組み化した方が良いと思うが。

上記マクロで使っているセル範囲を配列に転記するテクニックはこちらに詳しく書いた。
thom.hateblo.jp

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。