2015/6/12 追記:
下記で紹介しているコードはセルの結合を考慮していません。
結合されたセルが列内に存在する場合は、新田さんの記事「【Wordマクロ】表の特定の列を選択する」をご参照ください。
Word MVPの新田さんの記事「【Wordマクロ】特定の列のフォント書式を変更する」とExcel MVPの伊藤さんの記事「表の列を選択するWordマクロ」を見て、
“あれ?Wordの表の列に対して何か処理するマクロって流行っているのか!?”
と思った私。
これはもう乗っかるしかない!(勝手に)
何で余計なところまで処理しちゃうの!?
新田さんの記事を読んで気になった点が一点。
Rangeオブジェクトで列を選択したいのですが、1列目だけを排他的に選択することができません。
“いけるんじゃないの?コレくらい!?”
というわけで試してみました。
作業中の文書にあるテーブルの2列目だけを選択するマクロです。
Public Sub Test1() Dim r As Word.Range Set r = ActiveDocument.Tables(1).Rows.First.Cells(2).Range r.EndOf wdColumn, wdExtend r.Select End Sub
「ActiveDocument.Tables(1).Columns(2).Select」で済む話なんですが、Rangeオブジェクトを使って処理をするためにわざと上記のようなコードにしています。
このコードを実行すると、
上図の通り、ちゃんと2列目だけ選択されます。
ところが、下記のように2列目の文字色を変更するコードになると、
Public Sub Test2() Dim r As Word.Range Set r = ActiveDocument.Tables(1).Rows.First.Cells(2).Range r.EndOf wdColumn, wdExtend r.Font.ColorIndex = wdRed End Sub
下図のような結果になります。
“なんでやねん!!お前さっきまで2列目だけ選択しとったやろ??”
Wordに対して思わずツッコみ炸裂です。
恐らく下図のようなことなんだと思いますが、正直意味分かりません。
だからといって、
Public Sub Test3() ActiveDocument.Tables(1).Columns(2).Select Selection.Font.ColorIndex = wdRed End Sub
のようにSelectionを使うのは、何だか負けた気がします。
ここはやはりRangeで攻めるべきです。
Rangeオブジェクトで表中の特定列を処理する
ではどうするか?
表の列を表すColumnオブジェクトからRangeオブジェクトを直接取得できれば良いのですが、残念ながらそれらしいプロパティはありません。
使えそうなのは列中のセルを表す“Cells”コレクション。
Cell“s”が示す通り、セルを表すCellオブジェクトの集まりです。
Cellオブジェクトからは目的のRangeオブジェクトが取得できるので、今回はこれを使うことにします。
Public Sub Test4() Dim c As Word.Cell For Each c In ActiveDocument.Tables(1).Columns(2).Cells c.Range.Font.ColorIndex = wdRed Next End Sub
これでようやくSelectを使って選択範囲を変えることなく、表中の特定列に対して処理を行うことができました。
(ループを使うのも何だか負けた気がしますが、この際気にしないでおきます。)
で、どっちが早いの?
Selectionで処理するのか、ループしてRangeで処理するのか、結果的に同じであればどちらでも良いわけですが、ここで気になってくるのは“どちらが早く処理できるか?”ということ。
試しに2,000行のテーブルに対して処理を行ってみました。
Private Declare Function timeGetTime Lib "winmm" () As Long Public Sub Test5() Dim tmp As Word.Range Dim start As Long start = timeGetTime() Set tmp = Selection.Range ActiveDocument.Tables(1).Columns(2).Select Selection.Font.ColorIndex = wdRed tmp.Select Debug.Print "Selectionでの処理時間:" & timeGetTime() - start End Sub Public Sub Test6() Dim c As Word.Cell Dim start As Long start = timeGetTime() For Each c In ActiveDocument.Tables(1).Columns(2).Cells c.Range.Font.ColorIndex = wdRed Next Debug.Print "ループ&Rangeでの処理時間:" & timeGetTime() - start End Sub
結果は下図の通りで、ループ&Rangeのコードの方が若干時間が掛かりました。
1セルずつ処理しているので、仕方ないと言えば仕方がない結果ですね。
Ctrl + Zキー一発で元の状態に戻せることも考えても、Selectionで処理した方が良いのかもしれません。
ただ、“Selectするのは負けだ!”という方は、Rangeで処理することをお薦めいたします。
この記事へのコメントはありません。