Office関連

表の特定の列に対して処理を行うWordマクロ

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オブジェクトを使って処理をするためにわざと上記のようなコードにしています。

このコードを実行すると、

Word_Table_Column_01

上図の通り、ちゃんと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

下図のような結果になります。

Word_Table_Column_02

“なんでやねん!!お前さっきまで2列目だけ選択しとったやろ??”

Wordに対して思わずツッコみ炸裂です。
恐らく下図のようなことなんだと思いますが、正直意味分かりません。

Word_Table_Column_03

だからといって、

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を使って選択範囲を変えることなく、表中の特定列に対して処理を行うことができました。
(ループを使うのも何だか負けた気がしますが、この際気にしないでおきます。)

Word_Table_Column_04

で、どっちが早いの?

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セルずつ処理しているので、仕方ないと言えば仕方がない結果ですね。

Word_Table_Column_05

Ctrl + Zキー一発で元の状態に戻せることも考えても、Selectionで処理した方が良いのかもしれません。

ただ、“Selectするのは負けだ!”という方は、Rangeで処理することをお薦めいたします。

新しいOutlook.comのプレビュー版を触ってみました。前のページ

[Officeアドイン]メールアドイン(旧メールアプリ)がExchange不要になりました。次のページ

関連記事

  1. Office関連

    「NetOffice」で簡単に.NETからOfficeを操作

    ネットで「NetOffice」なるツールがあることを知ったので、早速試…

  2. Office関連

    アドインやテンプレートのバージョンチェックを行うVBAマクロ

    色々なアプリケーションに実装されている、「最新バージョンの確認」機能、…

  3. Office関連

    Evernote Cloud SDKを使ったVBAマクロ

    3年ほど前にEvernote for Windowsを操作するVBAマ…

  4. Office アドイン

    Visio JavaScript APIで遊んでみました。

    前回の記事でプレビュー版がリリースされた「Visio JavaScri…

  5. Office関連

    関数一覧(Excel 2013)

    関数の挿入ダイアログから抽出したExcel 2013の関数情報を表にし…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP