Wordの表の各セルの文字列を利用しやすくする
Wordの表の中の文字列を取得するクラス
WordTableOperatorクラス
クラスモジュールを挿入して、オブジェクト名を「WordTableOperator」にした。
とりあえず、次のようなコードを書いた。
リスト1
Option Explicit 'フィールド' Private wordApp_ As Word.Application Private wordDoc_ As Word.Document Private wordTable_() As Word.Table Private isReady_ As Boolean 'アクセサ' Public Property Get wordApp() As Word.Application Set wordApp = wordApp_ End Property Public Property Get wordDoc() As Word.Document Set wordDoc = wordDoc_ End Property Public Property Get wordTable(ByVal i As Integer) As Word.Table '……(1)' Set wordTable = wordTable_(i) End Property Public Property Get isReady() As Boolean isReady = isReady_ End Property 'コンストラクタ' Private Sub Class_Initialize() On Error GoTo ErrorCatch Set wordApp_ = GetObject(, "Word.Application") '……(2)' Set wordDoc_ = wordApp_.ActiveDocument '……(3)' Dim i As Integer ReDim wordTable_(wordDoc_.Tables.Count) '……(4)' For i = 1 To UBound(wordTable_) '……(5)' Set wordTable_(i) = wordDoc_.Tables(i) Next isReady_ = True '……(6)' Exit Sub ErrorCatch: '……(7)' isReady_ = False End Sub 'メソッド' Public Function getTextFromCell(ByVal tableNum As Integer, _ ByVal rowNum As Integer, _ ByVal colNum As Integer) As String '……(8)' On Error GoTo ErrorCatch Dim str As String str = wordTable_(tableNum).Cell(rowNum, colNum).Range.Text '……(9)' getTextFromCell = str '……(*)' Exit Function ErrorCatch: getTextFromCell = "" '……(10)' End Function
少し長くなった。ちょっと説明をば。
アクセサのところの(1)、
Public Property Get wordTable(ByVal i As Integer) As Word.Table Set wordTable = wordTable_(i) End Property
については、
コチラを参照。プロパティを配列にしている。
この場合は、Wordドキュメント内にある表を、配列として保持するようにしている。
さて、今回は珍しくコンストラクタを使う。
WordTableOperatorクラスのインスタンスが生成される時点でアクティブになっているWordアプリケーション及びドキュメントをセットしてしまうことにする。
まず、(2)の
Set wordApp_ = GetObject(, "Word.Application")
では、Wordアプリケーションのインスタンスを変数にセットするのに、GetObject関数を用いている。
このときにも使った方法だが、既に開いているWordアプリケーションを取得するため、このやり方にしている。
(3)の
Set wordDoc_ = wordApp_.ActiveDocument
で、現在アクティブになっているWordドキュメントを変数にセット。
この段階で、Wordドキュメント内にいくつの表があるかは判明しているので、(4)の
ReDim wordTable_(wordDoc_.Tables.Count)
で、配列用の変数wordTable_()を表の数でReDimしている。
(5)からの3行、
For i = 1 To UBound(wordTable_) '……(5)' Set wordTable_(i) = wordDoc_.Tables(i) Next
では、Wordドキュメント上の表を、配列wordTable_()に格納している。
Wordドキュメント上の表は、DocumentオブジェクトのTablesコレクションで取得できるので、Tablesコレクションのインデックスに1から順に数字を入れていけばそれぞれのTableオブジェクトが取得できる、という仕掛けだ。
続いて(6)。ここまでたどり着いたということは、エラーが出ていないということになるので、ここで
isReady_ = True
としてisReadyプロパティをTrueにしてやる。isReadyがTrueだということは、表が取得できているということなので、メインのコードで条件分岐に使うことができる。
なお、ここまでの過程でエラーが出ていたら、(7)の
ErrorCatch: isReady_ = False
に飛んでくるので、isReadyプロパティをFalseにして終了。
あとはメソッド。とりあえず1つだけにしている。
どうでもいいけど、「getTextFromCell」って、PANTERAの"Cowboys From Hell"みたいだな、オイw
(8)の
Public Function getTextFromCell(ByVal tableNum As Integer, _ ByVal rowNum As Integer, _ ByVal colNum As Integer) As String
を見たら分かるように、
- 第1引数:表の番号
- 第2引数:表内の行番号
- 第3引数:表内の列番号
の3つを渡すと、セル内の文字列を返す、という形にしている。
(9)の
str = wordTable_(tableNum).Cell(rowNum, colNum).Range.Text
で指定したセルから文字列を取得。
なお、途中でエラーが出たら、(10)の
getTextFromCell = ""
で""を返すようにした。
動作確認
標準モジュールに次のコードを書いて、動作確認した。
リスト2
Public Sub testWordTable01() Dim wtOperator As WordTableOperator Set wtOperator = New WordTableOperator Dim str As String If wtOperator.isReady = True Then str = wtOperator.getTextFromCell(1, 2, 2) '……(1)' Debug.Print "表1の2行2列目セル内の文字列は、" & _ Len(str) & "字ですわ。" Debug.Print "右端の文字のAsciiコードは、" & _ getAsciiCodeOfChar(Right(str, 1)) & "番でんねん。" '……(2)' Debug.Print "右端から2番目の文字のAsciiコードは、" & _ getAsciiCodeOfChar(Mid(Right(str, 2), 1, 1)) & "番だすな。" '……(3)' End If Set wtOperator = Nothing End Sub Private Function getAsciiCodeOfChar(ByVal objStr As String) As Integer Dim i As Integer For i = 0 To 255 If Chr(i) = objStr Then getAsciiCodeOfChar = i Exit Function End If Next getAsciiCodeOfChar = 266 End Function
(1)の、
str = wtOperator.getTextFromCell(1, 2, 2)
では、getTextFromCellメソッドに引数(1, 2, 2)を渡しているので、
1番目の表の2行2列目のセルに入っている文字列を寄こせや!
ということになる。んで、得られた文字列を変数strにセットしている。
ちなみに、
1番目の表の2行2列目のセルに入っている文字列
ってのは、見かけ上は
「吉岡 稔真」です。
(2)の
getAsciiCodeOfChar(Right(str, 1))
では、getAsciiCodeOfCharメソッドに、(1)で得られた文字列(str)の右端の文字の文字コード番号を取得している。
これはまあ、Right関数だけだから簡単。
(3)の
getAsciiCodeOfChar(Mid(Right(str, 2), 1, 1))
がちょっとややこしい。
まず、
Right(str, 2)
で右端の2文字を抜き出して、その2文字に対してMid関数を使うことで、
右端の2文字の1文字目
すなわち、
右端から2文字目
を取得している。
まあ、
Mid(str, Len(str) - 1, 1)
でもいいですね。ハイ。
実行結果
こうなった。
指定のセル内の文字列は、見かけ上は「吉岡 稔真」の5文字(全角スペース含む)のはずだが、7文字となっている。
6文字目の文字コードが「7」、7文字目の文字コードは「13」となっている。
再びコチラによると、
ということなので、
Wordのセル内の文字列の末尾には、「ハナクソ」と「改行文字」がくっついている
ということらしい。
最後に
ということは、リスト1の(*)のところを
str = Left(str, Len(str) - 2)
とするだけで良いということになるなあ。
あとは、このクラスの使い勝手をいかに上げるか、だな。