Tableオブジェクトの謎挙動(Word)

Tableオブジェクトの謎挙動(Word)

なんだかよくわからん現象が起こるので報告。

ドキュメントに表を挿入する

ドキュメントに表を挿入するには、Document.TablesコレクションのAddメソッドを用いる。

リスト1 標準モジュール
Dim targetTable As Table
With ThisDocument
  Set targetTable = .Tables.Add(Selection.Range, 5, 5)
End With

たとえば、このようにすれば、カーソル位置に5行×5列の表を挿入することができる。ちなみに、この例では、挿入した表をすかさず変数targetTableにぶちこんでいるが、単に表をカーソル位置に挿入するだけなら

Call .Tables.Add(Selection.Range, 5, 5)

このようにすればよい。

表のサイズを変える

上記のやり方だと、表の大きさ(横幅)は印刷範囲の横幅いっぱいになる。

表の横幅を変えるには、PreferredWidthに値を設定してやればよい。

ただし、『Word 2013 developers docs』の「Table.PreferredWidth Property (Word) 」の項によると、

If the PreferredWidthType property is set to wdPreferredWidthPoints, the PreferredWidth property returns or sets the width in points. If the PreferredWidthType property is set to wdPreferredWidthPercent, the PreferredWidth property returns or sets the width as a percentage of the window width.

とある。PreferredWidthTypeプロパティに設定する値によって、PreferredWidthプロパティに設定する数字の意味が変わるらしい。

たとえば、PreferredWidthTypeの値をwdPreferredWidthPointsに指定しておくと、表の横幅をポイント単位で指定できるようだ。

スト2 標準モジュール
Dim targetTable As Table
With ThisDocument
  Set targetTable = .Tables.Add(Selection.Range, 5, 5)
End With
With targetTable
  .PreferredWidthType = wdPreferredWidthPoints
  .PreferredWidth = 240
End With

たとえば、このようにすると、表全体の横幅を240ポイントに設定できるっぽい。

表の各セルに値を書き込む

表の各セルは、TableオブジェクトのCellメソッドで取得できる。

Cellメソッドをオブジェクト ブラウザーで見てみると、

f:id:akashi_keirin:20190426221243j:plain

Function Cell(Row As Long, Column As Long) As Cell
  Word.Table のメンバー

とあるので、CellメソッドはCellオブジェクトを返す、言い換えるとCellメソッドを実行するとCellオブジェクトを取得する、ということだ。

Cellオブジェクトの配下にはRangeオブジェクトがあり、そのRangeオブジェクトのTextプロパティに文字列を設定してやれば、セルに文字を書き込んだことになる。

うむ。だいぶWordのオブジェクト・モデルに慣れてきたぞ。

したがって、たとえば、

Dim targetTable As Table
With ThisDocument
  Set targetTable = .Tables.Add(Selection.Range, 5, 5)
End With
targetTable.Cell(2, 2).Range.Text = "ち~んw"

とすれば、5行×5列の表をカーソル位置に挿入し、しかる後その表の2行2列のセルに「ち~んw」と書き込むことができる。

リスト3 標準モジュール
Public Sub test02()
  Dim Doc As Document
  Set Doc = ThisDocument
  Call deleteTables(Doc)    '……(1)'
  Dim targetTable As Table
  With Doc    '……(2)'
    Set targetTable = .Tables.Add(Selection.Range, 5, 5)
  End With
  Dim r As Long
  Dim c As Long
  Dim n As Long
  n = 1
  Dim targetCell As Cell
  With targetTable
    .PreferredWidthType = wdPreferredWidthPoints    '……(3)'
    .PreferredWidth = 240
    For r = 1 To .Rows.Count    '……(4)'
      For c = 1 To .Columns.Count
        .Cell(r, c).Range.Text = n
        n = n + 1
        Call WindowsAPI.waitFor(200)    '……(*)'
      Next
    Next
  End With
End Sub

Private Sub deleteTables(ByVal targetDocument As Document)
  Dim tablesCount As Long
  tablesCount = targetDocument.Tables.Count
  If tablesCount = 0 Then Exit Sub
  Dim i As Long
  For i = tablesCount To 1 Step -1
    Call targetDocument.Tables(i).Delete
  Next
End Sub

(*)のWindowsAPIクラスについては、

akashi-keirin.hatenablog.com

コチラをどうぞ。

セルに数字を書き込むごとに200ミリ秒待機するようにしている。

さて、上掲コードを実行すると、

  • ドキュメント上の表を消去 ……(1)
  • カーソル位置に5行×5列の表を挿入 ……(2)
  • 表の横幅を240ポイントにする ……(3)
  • 表の各セルに数字を記入 ……(4)

となるはずである。

実行

リスト3を実行すると、

f:id:akashi_keirin:20190426221247g:plain

こうなる。

Tableオブジェクトのサイズ変更が後回しにされてしまうのだ。

おわりに

なぜ、なぜなんだ~~~?!