Office Space: Microsoft Office アプリケーションのスクリプト作成に関するヒントとテクニック

Office Space

Office Space へようこそ。Office Space は、Microsoft® Office アプリケーションのスクリプト作成に関するヒントとテクニックを紹介するコラムです。毎週火曜日と木曜日に新しいヒントを掲載します。過去のヒントについては、Office Space アーカイブを参照してください。Microsoft Office でのスクリプト作成について質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

*

Microsoft Word で表を作成する

1 シーズンで 4 割を超える打率をあげた最後のメジャーリーガーである Ted Williams が彼の打撃哲学を尋ねられたとき、"ボールを見て、ボールを打つことです" と答えたのは有名な話です。そういうことです。単純でわかりやすく、要領を得ていますね。Ted Williams のように殿堂入りしたいですか。でしたら単純にボールを見て、ボールを打ってください。

もちろん、Ted のアドバイスには 1 つ問題があります。それは、ボールを見ることとボールを打てることとの間には大きな隔たりがあるということです。これは Scripting Guys の辛い経験からも証明できます。"ボールを見て、ボールを打つ" というのは 非常に "聞こえ" は良いですが、いくつかの段階が抜けているように思われます。ひざを曲げるのか曲げないのか、手を高く保つのか低く保つのか、オープン スタンスかクローズド スタンスか、腕を広げるのか広げないのか、といったことです。最終的には、Ted のアドバイスが本当に役立つのかどうかを疑わなければなりません。

Scripting Guys は、聞こえは良くても実用的価値のほとんどないアドバイスをしたことがあるでしょうか。残念ながら、答えはイエスです。私たちスクリプト開発者は、少なくとも表形式での出力の表示に関しては、コマンド ウィンドウの制限を十分に理解しています。出力をきれいに見栄え良く並べるため、多少は装飾的な文字列操作を行うことはできますが、それが限界です。さまざまな色やフォントを使用して出力を表示したり、図を含めたり、表の行を交互に網かけ表示したりといったことは何もできません。では Scripting Guys がお勧めするこの問題の解決策は何でしょうか? "代わりに Microsoft Word で表を作成すること" です。

すばらしいアドバイスですが、1 つだけ不安があります。Microsoft Word で表を作成してくださいと言うことと、実際に Microsoft Word でそれらの表を作成することとの間には大きな隔たりがありませんか。これは、意欲的な野球選手たちに "ボールを見て、ボールを打ってください" と教えることとほとんど同じではありませんか。

そうかもしれませんね。でも、そうではないかもしれません。実際は、プログラムによって Microsoft Word で表を作成することは非常に簡単です。間違いなく非常に簡単なので、今回のコラムでは、基本的な表の作成方法に加えて、動的な表の作成方法についても説明します。おまけとして、表にオートフォーマットを適用できる 1 行のコードも紹介します。そうです、Ted Williams は三冠王を 2 回獲得しました。しかし彼は Microsoft Word で表を作成する VBScript スクリプトは一度も記述したことがないでしょう。

注 : 野球ファンでない皆さん、三冠王を獲得するということは、リーグで最も多くのホームラン、打点、さらに最も高い打率をあげてそのシーズンを終了したことを意味します。Ted Williams は三冠王を 2 回獲得しましたが、それらの年の最優秀選手賞はいずれも獲得できませんでした。彼はリーグで最も多くのホームラン、打点、さらに最も高い打率をあげてシーズンを終了しましたが、何かが少し足りなかったのかもしれませんね。

Microsoft Word で表を作成することはどれくらい簡単なのでしょうか。次のスクリプトを見てみましょう。

Const NUMBER_OF_ROWS = 1
Const NUMBER_OF_COLUMNS = 3

Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.Documents.Add()

Set objRange = objDoc.Range()

objDoc.Tables.Add objRange, NUMBER_OF_ROWS, NUMBER_OF_COLUMNS

Set objTable = objDoc.Tables(1)

objTable.Cell(1, 1).Range.Text = "Row 1, Column 1"
objTable.Cell(1, 2).Range.Text = "Row 1, Column 2"
objTable.Cell(1, 3).Range.Text = "Row 1, Column 3"

このスクリプトでは、まず 1 組の定数を定義しています。表の行数を表す NUMBER_OF_ROWS と、列数を表す NUMBER_OF_COLUMNS です (紹介するのは表に行を動的に追加する方法であるため、行数をあらかじめ知っておく必要がないことに注意してください)。次に Word.Application オブジェクトのインスタンスを作成し、Visible プロパティを (魔法がかかるのを見ることができるように) True に設定します。その後、Add メソッドを使用して新しい文書を作成します。新しい文書を作成したら、次のコード行を使用して、表の作成に必要な Range オブジェクトのインスタンスを作成します。

Set objRange = objDoc.Range()

これで表を文書に追加する準備ができました。表の追加は、Tables コレクションに新しい表を追加することによって行います。この操作は、Add メソッドを呼び出し、次に示す 3 つのパラメータを渡すことによって実行できます。

objRange: 作成した Range オブジェクトへのオブジェクト参照です。このパラメータは、文書内で表を配置する場所を表します。

NUMBER_OF_ROWS: 表の行数です。この最初の例では、行が 1 つだけ含まれた表を作成しています。

NUMBER_OF_COLUMNS: 表の列数です。この例では、列が 3 つ含まれた表を作成しています。

コード自体は次のようになります。

objDoc.Tables.Add objRange, NUMBER_OF_ROWS, NUMBER_OF_COLUMNS

するべきことはこれで終わりです。このスクリプトにより、1 行と 3 列の表が挿入されます。完成した文書は次のようになります (表が実際に存在することを確認できるように、グリッド線を追加しました)。

Microsoft Word


はい、その反論を受け付けましょう。確かにこの表に実際にいくつかのデータが含まれていれば、もう少し見栄えが良くなりますね。しかし、その操作はスクリプトの最後の数行で行います。表にデータを追加するには、次のコードのように、まず表へのオブジェクト参照を作成する必要があります。

Set objTable = objDoc.Tables(1)

このコード行では、単純に変数 objTable が Tables コレクションの最初のアイテム (objDoc.Tables(1)) を参照することを示します。文書に複数の表が含まれていて、表番号 3 を操作したい場合はどうすればよいでしょうか? この場合は、次のコードを使用します。

Set objTable = objDoc.Tables(3)

オブジェクト参照を作成したら、次のようなコードを使用して、表のセルにテキストを入力できます。

objTable.Cell(1, 1).Range.Text = "Row 1, Column 1"

ご覧のとおり、表のセル 1,1 (行 1、列 1) を参照しています。また、このセルの Range オブジェクト (各セルには独自の Range オブジェクトがあります) を取得してから、Text プロパティの値を "Row 1, Column 1" に設定しています。その後、行 1 の他の 2 つのセルに対してこの処理を繰り返します。スクリプトの実行が終了すると、表は次のようになります。

Microsoft Word


Ted Williams のように現役通算 521 本のホームランを打つのと、このような表を作成するのはどちらが良いですか。そうですか、そう言うと思いました。

もちろん、"表に 1 行しか含まれないことがあらかじめわかっていれば非常に簡単だが、イベント ログなどから情報を取得していて、必要な行数がわからない場合はどうすればよいのか"、と考えるでしょう。

お教えしましょう。表への新しい行の追加が必要になるたびに、Rows.Add() メソッドを使用すればよいのです。表を作成してから末尾に空白の行を 3 つ追加するように変更したスクリプトを次に示します。

Const NUMBER_OF_ROWS = 1
Const NUMBER_OF_COLUMNS = 3

Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.Documents.Add()

Set objRange = objDoc.Range()

objDoc.Tables.Add objRange, NUMBER_OF_ROWS, NUMBER_OF_COLUMNS

Set objTable = objDoc.Tables(1)

objTable.Cell(1, 1).Range.Text = "Row 1, Column 1"
objTable.Cell(1, 2).Range.Text = "Row 1, Column 2"
objTable.Cell(1, 3).Range.Text = "Row 1, Column 3"

objTable.Rows.Add()
objTable.Rows.Add()
objTable.Rows.Add()

objTable.AutoFormat(16)

そういえば、スクリプトの最後に次のコード行も追加しましたね。

objTable.AutoFormat(16)

なぜこのコードを追加したのでしょうか。既定では、このスクリプトで作成する表には、色、網かけ、グリッド線などの書式設定が行われません。AutoFormat メソッドを呼び出して値 16 ("表 (格子)" 書式設定を使用することを示しています) を渡すことにより、すばやく簡単に表の書式を設定できます。

注 : "表 (格子)" 書式設定の値が 16 だということがなぜわかったのか疑問に思うでしょう。私たちがスクリプトのすべてを知っていることも理由の 1 つですが、第一には、MSDN に記載されている wdTableFormat 定数の値を調べたからです。

より動的でオートフォーマットが適用される表は、次のようになります。

Microsoft Word


大分良くなりましたね。

最後に、より実用的な例を見てみましょう。次のスクリプトでは、コンピュータにインストールされているサービスに関する情報を取得してから、その情報を書式設定済みの Word の表に表示します。

Const NUMBER_OF_ROWS = 1
Const NUMBER_OF_COLUMNS = 3

Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.Documents.Add()

Set objRange = objDoc.Range()
objDoc.Tables.Add objRange, NUMBER_OF_ROWS, NUMBER_OF_COLUMNS
Set objTable = objDoc.Tables(1)

objTable.Cell(1, 1).Range.Text = "Service Name"
objTable.Cell(1, 2).Range.Text = "Display Name"
objTable.Cell(1, 3).Range.Text = "Service State"

x = 2

strComputer = "."

Set objWMIService = _
    GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Service")

For Each objItem in colItems
    objTable.Rows.Add()
    objTable.Cell(x, 1).Range.Text = objItem.Name
    objTable.Cell(x, 2).Range.Text = objItem.DisplayName
    objTable.Cell(x, 3).Range.Text = objItem.State
    x = x + 1
Next

objTable.AutoFormat(9)

ご覧のとおり、まず別の 1 行と 3 列の表を作成しています。行 1 はヘッダー行として機能させるので、次のコード行を使用して、行 1 の 3 つのセルにテキストを追加します。

objTable.Cell(1, 1).Range.Text = "Service Name"
objTable.Cell(1, 2).Range.Text = "Display Name"
objTable.Cell(1, 3).Range.Text = "Service State"

次に、x という変数に値 2 を代入します。なぜ 2 なのでしょうか。x は、表の現在の行を追跡するために使用します。表にデータを追加するときは、行 2 から開始します。これは、行 1 が既にヘッダー行として使用されているためです。したがって、x = 2 とします。

その後に、いくつかの標準 WMI コードを使用して、コンピュータにインストールされているすべてのサービスから構成されるコレクションを返します。コレクションに対して処理を行う (For Each ループ内) 際、まず Rows.Add() メソッドを呼び出して新しい行を表に追加します。このループで最初にこの行に該当するのは行 2 です (行 1 は既に存在し、ヘッダー行として機能していることを思い出してください)。その後、次のコード行を使用して、その行の 3 つのセルにサービスの Name、DisplayName、および State を追加します。

objTable.Cell(x, 1).Range.Text = objItem.Name
objTable.Cell(x, 2).Range.Text = objItem.DisplayName
objTable.Cell(x, 3).Range.Text = objItem.State

行番号がハードコードされておらず、代わりに変数 x を使用していることに注意してください。行の 3 つのセルに値を入力したら、次のコード行を使用して x の値を増やします。

x = x + 1

これで x の値は 3 になります。これは、2 回目のループでは行 3 のセルにデータが書き込まれることを意味します。動作がおわかりいただけたでしょうか。

スクリプトの最後で AutoFormat メソッドを使用して wdTableFormatColorful2 書式設定を適用し、処理を完了します。

Microsoft Word


私たち Scripting Guys がいつも言っていた、"表を見て、表のスクリプトを作成してください" という感じですね。


ページのトップへページのトップへ