HTMLのtable要素を作る
HTMLで表を作るのはメンドクサイ
Excelでちゃちゃっと表を作って、それをHTMLタグで囲って構造化するマクロを作った。
リスト1 標準モジュール
Public Function createHTMLTable( _
ByVal targetRange As Range, _
Optional ByVal hasHeader As Boolean = True, _
Optional ByVal hasBorder As Boolean) As String '……(1)'
Dim rowCount As Long '……(2)'
rowCount = targetRange.Rows.Count
Dim columnCount As Long
columnCount = targetRange.Columns.Count
Dim i As Long
Dim j As Long
Dim stringOfCell() As String '……(3)'
ReDim stringOfCell(0 To rowCount - 1, 0 To columnCount - 1)
For i = 0 To rowCount - 1
For j = 0 To columnCount - 1
stringOfCell(i, j) = targetRange.Cells(i + 1, j + 1).Value
Next
Next
Dim str As String
If hasBorder Then '……(4)'
str = "<table border=""1"">"
Else
str = "<table border="""">"
End If
For i = 1 To rowCount '……(5)'
str = str & "<tr>" '……(6)'
For j = 1 To columnCount '……(7)'
If hasHeader And i = 1 Then '……(8)'
str = str & "<th>" & stringOfCell(i - 1, j - 1) & "</th>"
Else
str = str & "<td>" & stringOfCell(i - 1, j - 1) & "</td>"
End If
Next
str = str & "</tr>" '……(9)'
Next
str = str & "</table>" '……(10)'
str = Replace(str, vbLf, "<br>") '……(11)'
createHTMLTable = str
End Function
(1)の
Public Function createHTMLTable( _
ByVal targetRange As Range, _
Optional ByVal hasHeader As Boolean = True, _
Optional ByVal hasBorder As Boolean) As String
では、引数3つと返り値の型を設定。
第1引数では、対象のセル範囲を指定。
第2引数は、表が項目ラベルを持っているかどうか。持っているならTrue。
第3引数は、境界線をどうするか。Trueだったらborder属性に"1"をセットする。Falseなら""。
で、返り値はString型。
(2)からの4行
Dim rowCount As Long rowCount = targetRange.Rows.Count Dim columnCount As Long columnCount = targetRange.Columns.Count
では、表の行数・列数を変数にぶち込んでおく。
(3)からの7行
Dim stringOfCell() As String
ReDim stringOfCell(0 To rowCount - 1, 0 To columnCount - 1)
For i = 0 To rowCount - 1
For j = 0 To columnCount - 1
stringOfCell(i, j) = targetRange.Cells(i + 1, j + 1).Value
Next
Next
では、String型の2次元配列stringOfCell()に表の各セルの値をぶち込んでいる。
もっと簡単にできたと思うけれど、調べるのがめんどくさいんで(←コラ!)、とりあえずこういう原始的なやり方で。
(4)からの5行
If hasBorder Then str = "<table border=""1"">" Else str = "<table border="""">" End If
では、引数hasBorderの値に応じて、tableの開始タグを書き分けている。
で、(5)からの11行
For i = 1 To rowCount
str = str & "<tr>" '……(6)'
For j = 1 To columnCount '……(7)'
If hasHeader And i = 1 Then '……(8)'
str = str & "<th>" & stringOfCell(i - 1, j - 1) & "</th>"
Else
str = str & "<td>" & stringOfCell(i - 1, j - 1) & "</td>"
End If
Next
str = str & "</tr>" '……(9)'
Next
二重のForループで一気にtableタグの中身を作っていく。
まず、外側のForループでは、表の各行を作っていくので、ループの最初に(6)の
str = str & "<tr>"
で<tr>タグを付け足し、次のループに移る直前に(9)の
str = str & "</tr>"
で</tr>タグを付け足すようにしている。
また、内側のForループ、すなわち(7)からの7行
For j = 1 To columnCount
If hasHeader And i = 1 Then '……(8)'
str = str & "<th>" & stringOfCell(i - 1, j - 1) & "</th>"
Else
str = str & "<td>" & stringOfCell(i - 1, j - 1) & "</td>"
End If
Next
では、引数hasHeaderの状態に応じて分岐。(8)の
If hasHeader And i = 1 Then
でhasHeaderがTrueで、かつ i = 1 のとき、つまり表の1行目が各列のラベルである場合は、セルの値を<th></th>で囲まないといけないので、このような条件分岐にしている。
hasHeader And i = 1
がTrueのときは、
str = str & "<th>" & stringOfCell(i - 1, j - 1) & "</th>"
によって、セルの値を<th></th>でくくった文字列をstrに追加し、
hasHeader And i = 1
がFalseのときは、
str = str & "<td>" & stringOfCell(i - 1, j - 1) & "</td>"
によって、セルの値を<td></td>でくくる、という仕掛け。
二重のForループから抜けると、表の中身は全てタグ打ちができているはずなので、(10)の
str = str & "</table>"
でtableタグを閉じる。
ついでに、(11)の
str = Replace(str, vbLf, "<br>")
では、Replace関数を用いて、セル内改行(vbLf)を<br>に置き換えておく。
使ってみる

シート(Sheet2です)にこんなふうに表を用意して、次のコードで実験してみる。
リスト2 標準モジュール
Public Sub testHTMLTable()
Dim Sh As Worksheet
Set Sh = ThisWorkbook.Worksheets("Sheet2")
Debug.Print createHTMLTable(Sh.Range("A1").CurrentRegion, True, True)
End Sub

イミディエイトに、タグ打ちした文字列が表示されるので、それをHTMLソースにコピペしてブラウザで開いてみた。


セル内改行した表でも実験してみたが、

こんなふうに、うまく表示された。
おわりに
Excelでちょこちょこっと表を作って、table要素にできたらいいなーと思っただけです。
「ちょwww もっと簡単にできるじゃねーかよwww」とか、笑われるかもしれませんが、HTMLなんてつい最近までろくに知らなかったし、Webページを触るようなこともしたことがなかったので、ホームページビルダー(っていうの?)なんかも触ったことのない素人の思いつきですから、笑って許してくだされ。
しっかし、これ、セルの結合とかに対応しようとしたら、途端に激ムズになるんじゃね???