Win32OLE 活用法 【第 1 回】 Win32OLE ことはじめ

書いた人:cuzic

はじめに

受信ボックスにたまった Excel ファイルを添付したメール。Excel の表にした がって、DB から検索して、特定のセルに入力を繰り返す面倒な作業。気が滅入 ります。

今まで、皆さんはこういう面倒な作業を効率化するためにどんなアプローチをし てきましたか? たとえば、MS Office には Visual Basic for Application (VBA) を使うことで自動的に処理させることができます。 だけど、VB はあまりよく知らないし、使い慣れた Ruby で自動化していきたい って思ったことありますよね。

こんなときに活躍するのが Win32OLE です。この連載では Win32OLE という Ruby の拡張ライブラリを使ったプログラムについて紹介していきます。 Win32OLE という名前からわかるとおり、Microsoft Windows (以下、Windows) でしか動作しません。そのため、本連載は Windows を利用している Rubyist を 対象としています。

Win32OLE は、COM とか ActiveX などと呼ばれたりする技術を扱うためのライブ ラリです。この記事の中では OLE/COM/ActiveX といった用語をあまり区別せず に COM という言葉でまとめておきます。Windows アプリケーションは一般に いくつかの部品を組み合わせてできています。この部品化する技術の中に Microsoft 社が開発した技術に Component Object Model (COM) があります。

COM には言語に非依存であるという特徴があります。つまり、COM で作られた部 品であれば C++ でも VB でも Delphi でも、そして Ruby でもプログラムの中 で扱うことができます。

こう言ってもピンとこないかもしれません。具体的に言うと、Ruby で書いたプ ログラムで Internet Explorer を制御したり、Excel 表の値を取得、変更した りすることが可能だということです。

COM を Ruby で扱えるようにする拡張ライブラリが Win32OLE です。Ruby 1.8 では標準添付されており、cygwin 版でもネイティブ win32 版の Ruby をインス トールした時点で使用可能です。

この連載では、この Win32OLE の使い方および Win32OLE を Ruby で効果的に使 うためのレシピについて紹介していきます。

今回の記事の目的と構成

今回の記事の目的は、3つあります。

  • Win32OLE を体験してもらうこと
  • COM の概要について理解してもらうこと
  • COM のオブジェクト、メソッドの調べられるようになること

まず、Win32OLE の体験として、Internet Explorer を操作するスクリプトを紹 介します。

次に、COM の概要について説明します。そして、今回の記事のメインである COM オブジェクトのインターフェースを調べる方法について説明します。具体的に言 うと、オブジェクトの作成の仕方やメソッドの名前や引数を調べる方法です。こ のオブジェクトやメソッドというのは、Ruby の世界ではなく、COM の世界での 意味のオブジェクトやメソッドのことを指しています。

これらの調べ方が分かれば自分が必要なオブジェクトを適切に選ぶことや、自分 が使いたい機能を持つメソッドが何かを調べることができるようになります。

Win32OLE を使う具体的な方法などについては、インターネットなどを調べても なかなか資料がなく、私自身使うときに苦労してきました。今回の内容を活用す ることで、Win32OLE を用いたプログラミングが楽になるでしょう。

Internet Explorer の制御を通じて Win32OLE を体験

このスクリプトでは自動的に Google で ruby という単語で検索を行います。実 際に実行してみてください。

ie.rb

   1|require 'win32ole'
   2|
   3|ie = WIN32OLE.new('InternetExplorer.Application')
   4|ie.Navigate("http://www.google.co.jp/")
   5|ie.Visible = true
   6|while ie.busy
   7|  sleep 1
   8|end
   9|q = ie.document.all.Item("q")
  10|q.Value = "ruby"
  11|btnG = ie.document.all.Item("btnG")
  12|btnG.click()

このスクリプトでは Internet Explorer の COM オブジェクトを作成していま す。COM オブジェクトというのは、ざっくりと Windows アプリケーションの 外部から利用できる形式の部品という理解をしておいてください。

実際にこのスクリプトが何をしているのかというと、Google のページに移動し、 テキストボックスに 「ruby」 と入力し、「Google 検索」のボタンをクリック する、という動作を行っています。

COM オブジェクトを作成することで、Internet Explorer があたかも Ruby の オブジェクトであるかのように使えるわけです。このような形で、他に Word や Excel などの MS Office のアプリケーションも Win32OLE を用いることであた かも Ruby のオブジェクトを扱うようにコントロールすることができます。

上記のプログラムで重要なことは、2 つあります。

  • COM オブジェクトの作成
  • COM オブジェクトのメソッド呼び出し

1 つ目は Internet Explorer のオブジェクトを作成するとき 'InernetExplorer.Application' という文字列を指定しているということです。 この文字列を ProgID といいます。つまり、COM オブジェクトは WIN32OLE::new(ProgID) の形式で作成します。この ProgID として指定する文字 列を変えることで、 Internet Explorer のオブジェクトを作成するか、Excel のオブジェクトを作成するかなどを制御できます。

2 つ目は呼び出すべきメソッドさえ分かっていれば、そのコンポーネントの内部 の詳細を知っている必要がないということです。ただ、メソッド名とその引数、 返り値などが分かっていれば十分なのです。

残りの行は、Internet Explorer のオブジェクトが持つメソッドやプロパティを 使っています。残りの行について詳しく解説することはもちろんできます。例え ば、Navigate というメソッドに URL を引数として渡すことで、目的のページに 自動的に移動できます。

しかし、この記事では、ここに深入りするのではなく、もっと大事なことを説明 します。

自分が作成したい COM オブジェクトの ProgID の調べ方やそのオブジェクト が持つメソッドの一覧を得る方法、そのメソッドがどういう引数をとるを調べる 方法などについて説明します。

この記事を読み終えて、いろいろ実験すると、さまざまなアプリケーションが COM のオブジェクトとして作成できるということにあなたは驚くはずです。そし て、Ruby の Win32OLE のライブラリを活用することで、今までやってきた面倒 な定型的な業務をとても簡単なプログラムで実現できるようになります。

COM とは

COM を使って Internet Explorer を実際に操作してみました。それでは COM と はどういう技術なのでしょうか。

COM をきちんと理解するにはいろいろと知らなければいけない知識があります。 しかしながら、この記事では Ruby と Win32OLE を利用できるようになることが 目的なので、難しい部分は省略して説明します。きちんと知りたい方は本稿末尾 にある参考文献を手がかりに調べてみてください。

Ruby では、たとえば String クラスのインスタンスに何かメソッド (たとえば length) を適用することで、ある機能を実行することができます (length なら ば、文字列の長さを取得することができる)。これを、Ruby で書くと、次のよう になるでしょうか。

str = String.new("abc")
str.length #=> 長さが返る

このとき、「あるクラス (String)」の「インスタンスを生成 (String.new("abc"))」し、「あるメッセージ (length)」をその生成したオブジ ェクトに投げる (str.length) ことで処理 (その文字列の長さを取得) をしてい きます。

Ruby ではインスタンスを生成するのに「あるクラス」に対して「new」という メソッドを実行するわけですが、COM ではインスタンスを生成するときに 「COM コンポーネント」を指定するための ProgID を引数として WIN32OLE.new メソッドを実行します。 COM コンポーネントとは、Windows に登録された、ある機能 (たとえば、IE や MS Office の制御機能) を提供するためのものです。 この「COM コンポーネント」を利用して作成したインスタンス を「COM オブジェクト」とこの記事では呼んでいます。 COM オブジェクトを作成した後は、その COM オブジェクトで定義されている 「メソッド」を実行することでそのコンポーネントが提供する機能を 実現することができます。

COM の特徴として オブジェクト指向でサービスを提供しているということが あります。ご存知のとおり、Ruby はオブジェクト指向で設計されているので COM の技術と相性がいいと言えます。

そこで、Win32OLE の出番です。Win32OLE は、Ruby から、COM コンポーネント を利用することを目的とした拡張ライブラリです。Win32OLE を使うと、 COM コンポーネントからオブジェクトの作成、COM のメソッドの実行などを、 Ruby オブジェクトに対するそれと同様のインターフェースで行えます。

Windows では、多数の COM コンポーネントが標準で利用できます。また、標準 以外の他のCOMコンポーネントをインストールして、標準のコンポーネントと同 じように利用することもできます。たとえば、Internet Explorer は、標準で COM コンポーネントとして利用可能ですし、MS Office の各アプリケーションも COM コンポーネントとして機能を提供しています。

COM コンポーネントを使うためには、まずどんな COM コンポーネントが利用可 能か、そしてその COM コンポーネントがどんな機能を提供しているのかを知ら なければなりません。この情報は、ドキュメントとして公開していれば話が早い のですが、多くの COM コンポーネントの情報は公開されていません。

しかしながら、COM ではオブジェクトの名やメソッド名といったインターフェー スなどを調べるための API が用意されています。Ruby でもこの機能を使うこと で、インターフェースを調査できます。今回は COM コンポーネントを利用する ために利用可能な調査方法について説明します。

COM オブジェクトの調べ方

この章では COM オブジェクトを使う方法を調べるための方法について説明し ます。

Ruby だけを利用する調べ方

まずは、Ruby のライブラリ Win32OLE を使うことで、COM のオブジェクトを生 成する方法や、メソッド名や引数について調べる方法を説明します。

作成したい COM オブジェクトの探し方

先ほど説明しましたように COM オブジェクトを生成するには その COM コンポーネントに対応した ProgID が何かを調べる必要があります。

そこでまず、あなたのパソコンで利用可能な ProgID の一覧を 表示させてみましょう。 コマンドラインから次のコマンドを入力してみてください。

ruby -rwin32ole -e 'puts WIN32OLE_TYPE.progids'

このコマンドを実行すると、ProgID の一覧、つまり、利用できる COM コンポーネントの一覧が得られます。実行するとインストール しているアプリケーションが多い方の場合は、数千行出力されると思います。 参考までに筆者の環境では、4906 行出力されました。

あなたの使いたいコンポーネントの ProgID をこの中から見つけて WIN32OLE.new メソッドで呼び出せば、そのコンポーネントのオブジェクトを Ruby の世界で作成できます。

どのような ProgID を指定すればどのような COM オブジェクトを作成できる かは、次の表を参考にしてください。有名なオブジェクトを幾つか紹介していま す。(MSDN: OLE プログラム ID などを参考にして作成)

作成するオブジェクトProgID
Microsoft Internet ExplorerInternetExplorer.Application
Microsoft ExcelExcel.Application
Microsoft AccessAccess.Application
ADODB ConnectionADODB.Connection
ADODB RecordsetADODB.Recordset
Microsoft OutlookOutlook.Application
Microsoft WordWord.Application|
Microsoft Word DocumentWord.Document
Windows Scripting HostWscript.Shell

先ほどのプログラムでは InternetExplorer.Application という ProgID を用いて COM オブジェクトを作成しています。

オブジェクトが持つメソッドの調べ方

次にすることは、作成する COM オブジェクトがどのようなメソッドを持つか を調べることです。つまり、それが実際にどんなことができるかを確認します。

WIN32OLE#ole_methods メソッドを使うことで、オブジェクトが持つメソッドの 一覧を得ることができます。

ruby -r win32ole -e "ie = WIN32OLE.new('InternetExplorer.Application');puts ie.ole_methods;"

上記コマンドは、ProgID が InternetExplorer の COM コンポーネントから COM オブジェクトを生成し、その COM オブジェクトが持つメソッドの一覧を 出力させています。 この出力に先ほど使いました Navigate という文字列が含まれています。

この Navigate というメソッドが何を引数とするどのようなメソ ッドかを調べるには次のスクリプトを実行します。

method_param.rb

   1|require 'win32ole'
   2|
   3|ie = WIN32OLE.new('InternetExplorer.Application')
   4|puts  ie.ole_obj_help.to_s
   5|method = ie.ole_method_help('Navigate')
   6|puts method.return_type
   7|method.params.each do |param|
   8|  str = ""
   9|  str.concat "[in] " if param.input?
  10|  str.concat "[out] " if param.output?
  11|  str.concat "[optional] " if param.optional?
  12|  str.concat "[retval] " if param.retval?
  13|  str.concat param.name
  14|  str.concat " = #{param.default}" if param.default
  15|  str.concat " As #{param.ole_type}"
  16|  puts str
  17|end

上記スクリプトの実行結果は次のとおりです。

IWebBrowser2
VOID
[in] URL As BSTR
[in] [optional] Flags As VARIANT
[in] [optional] TargetFrameName As VARIANT
[in] [optional] PostData As VARIANT
[in] [optional] Headers As VARIANT

実行結果の 1 行目は COM タイプライブラリの説明文。 2 行目は、返り値の型。3 行目以降は、引数についての情報を 第一引数から順に出力しています。

これから上記スクリプトとその実行結果について説明します。

ie = WIN32OLE.new('InternetExplorer.Application')

この行では、先ほど説明したように、ProgID を引数とすることで Internet Explorer の COM オブジェクトを作成しています。

puts  ie.ole_obj_help.to_s
#=> 出力結果
IWebBrowser2

という行は、指定した型のタイプライブラリの説明文を表示しています。タイプ ライブラリというのは、メソッド、定数、インタフェースなどを定義するものの 総称です。これがあるから、このようなリフレクションを行い、メソッドや インタフェースなどを調べることができるわけですね。

puts method.return_type
#=> 出力結果
VOID

という行はこのメソッドの返り値が COM の型で VOID であることを示します。 VOID は C 言語 の void 型と同じで戻り値がないことを意味します。

method = ie.ole_method_help('Navigate')

この行で使われている WIN32OLE#ole_method_help というメソッドはメソッド名 を引数としてとり、WIN32OLE_METHOD 型を返します。

WIN32OLE_METHOD 型では、params メソッドが重要です。 WIN32OLE_METHOD#params は、WIN32OLE_PARAM 型の配列を返します。 WIN32OLE_PARAM 型を用いることで引数の詳細を知ることができます。

WIN32OLE_PARAM 型を逐次まわすループのところが上記スクリプトのハイライト です。

method.params.each do |param|
  str = ""
  str.concat "[in] " if param.input?
  str.concat "[out] " if param.output?
  str.concat "[optional] " if param.optional?
  str.concat "[retval] " if param.retval?
  str.concat param.name
  str.concat " = #{param.default}" if param.default
  str.concat " As #{param.ole_type}"
  puts str
end

まず、WIN32OLE_PARAM#input? はその引数が入力用であるとき true、そうでな いとき false を返します。同様に、WIN32OLE_PARAM#output? はその引数が出力 用であるとき、 WIN32OLE_PARAM#optional? は省略可能なとき、 WIN32OLE_PARAM#retval? は返り値のときに true を返します。

WIN32OLE_PARAM#name は、その引数の名前を返します。いわゆる仮引数名と呼ば れるものです。これは実際に使う上での重要なヒントです。例えば上記の例でも 第一引数は文字列で URL という名をつけられています。何を引数とすれば良い か想像できますよね?

WIN32OLE_PARAM#default は省略時のデフォルト値、WIN32OLE_PARAM#ole_type は引数の COM での型を示します。

BSTR というのは、COM での文字列型のことです。Win32OLE が Ruby の文字列と の変換を勝手にしてくれます。なので、単に文字列型だと思っていただければい いです。

VARIANT というのは、数値、文字列、配列などさまざまなオブジェクトを表し得 る型です。

COM での型がどのように Ruby での型に変換されるかは、次回に詳しく説明する 予定です。

オブジェクトブラウザでの調べ方

ここまでは、いちいち手で ruby を実行して、必要な ProgID を調べ、そして ProgID で作成できる COM オブジェクトの持つメソッドやその引数について調べ る方法について紹介してきました。

こういう作業を GUI ベースで行える Simple OLE Browser という Ruby で書かれ たツールもあります。助田さんのページで無料でダウンロードできます。 (Win32OLE 製作過程の雑記)

名前のとおりシンプルな作りです。 しかしながら、上記 URL を確認してもらうと分かりますが、 DESCRIPTION というペインで簡単なメソッドの説明文を見ることもできたりするなど、 結構便利です。 詳しい使い方については上記 URL を参考にしてください。

この節で紹介する他のツールでもそうですが、Simple OLE Browser でもまずタ イプライブラリの名前を指定します。そして、そのタイプライブラリで定義され ているオブジェクトのメソッドの説明を見ることができます。

ProgID とタイプライブラリの名前との間の関係はレジストリを見れば分かりま す。詳しい説明については次のページを参考にしてください。([VB] ActiveX コンポーネントで作成されるレジストリ エントリ)

レジストリを見るのは面倒なので、私自身のやり方としては、あてずっぽでいく つかクリックして、対応関係を見つけています。この方法でもそれほど不便して いません。

ところで COM のテクノロジーは、言語に非依存です。そのため他の言語におい ても、COM を利用することができます。それはつまり他の言語向けに開発された COM オブジェクトの詳細を閲覧するツールも利用できるということです。

pythonwin_combrowser.GIF

たとえば海外では非常に人気があるスクリプト言語である Python では、 "Python Object Browser" というある COM の型が持つメソッドの引数などを簡 単に調べるためのツールがあります。 PythonWinをダウンロードしたら、Tools から選択して起動できます。ツリー形式で見 れて便利です。無料で手に入ります。

object_browser.png

とさまざまなブラウザがありますが、真打はやはり Microsoft が提供している オブジェクトブラウザでしょう。Visual Basic Editor に含まれるこのツールを 使うと、クラスが持つメソッドやプロパティの一覧やメソッドの使い方を見るこ とができます。オブジェクトブラウザは、MS Office の Visual Basic for Applications のエディタをまず起動して、[F2] キーを押すことで起動できます。 これは、無料では手に入りませんが使いやすくて便利です。

プロパティがどういう型かなどがよく分かる点や、「戻る」ボタンがあることな どが便利で私はよく利用します。

オブジェクトブラウザに関する説明は検索すれば解説がいくつか見つかると思います。 例えば、MSDN には次のページがあります。(オブジェクト ブラウザ)

他に、Microsoft が提供する無料で使えるツールとして、Microsoft の Resource Kit の Free Tool の中にある OLE View というツールもこの目的に使えます。 (Oleview.exe: OLE/COM Object Viewer)

その他の調べ方

WEB で検索して、COM オブジェクトのインターフェースについて調べることもで きます。

適当なメソッド名や ProgID を使って Google で検索すれば、詳しいドキュメン トが得られることもあります。

ProgID が分からないときは、CreateObject という単語を Google で検索すると Visual Basic や VB Script でのサンプルコードや説明を検索できるというテク ニックもあります。使える小技です。

Visual Basic で MS Office アプリケーションを自動化する話はよくありますから そういうコードを参考にするというのも非常に良い方法です。例えば、 Microsoft Office アプリケーションのオートメーションに関してドキュメント が次のページにあります。([HOWTO] Office オブジェクト モデルに関するドキュメントの検索および使用方法)

このページにも紹介されている方法ですが、Excel のようなマクロ機能がある MS Office のアプリケーションでは、行いたい動作を一旦マクロとして記録してみる という方法があります。生成された Visual Basic のコードを読めば何をすると きにどのようなプロパティ・メソッドを使うかの参考になると思います。

他に、MSDN や MS Office の Visual Basic に付属のヘルプはとても参考になりま す。MS Office のアプリケーションはドキュメントが充実しています。 見る価値はあります。

繰り返しますが、COM は言語に依存しないため、Visual Basic が呼び出しに使 用しているメソッド名や呼び出し規則はRuby と同じようになります。もちろん 文法に起因する違いはありますがオブジェクトがもつメソッドなどを調べるには 十分な情報が得られます。このような点で Visual Basic での書き方は参考にな りますので、一度見てみるようにした方がいいでしょう。

あ。一つ、言っておかないといけないことがあります。それは、COM において、 メソッド名やプロパティは大文字と小文字を区別しないということです。自分の 好きな方を使っていただいて結構です。Visual Basic のコードで大文字始まり のメソッド名であってもRuby では小文字始まりでかまいません。もちろん大文 字でも大丈夫です。

私の調べ方

以上、自分が求めるクラス、メソッドをどうやって見つけるかについて説明しま した。

最後に私が実際にどうやって新しいクラスの使い方を調べる方法について少しだ け書きます。ひょっとしたらこの節がこの記事で参考になるところかもしれませ ん。

まずは MS Office 付属の Visual Basic Editor のオブジェクトブラウザで勘で 使えそうなタイプライブラリを参照設定してみて、クラス名やメソッド名を眺め てみることから始めます。このようにして、だいたいやりたいことができるメソ ッドがあるかどうかを調べます。

メソッド名や、クラス名以上の情報が必要な場合は、Google で検索したり、 MSDN での情報も参考にします。MS Office に付属の VBA のヘルプも参考にしま す。

それでも情報が足りない場合は、使いたいメソッドを実際に使用するような小さ なスクリプトを書いてみたりします。スクリプトを書く目的は、短い時間でその オブジェクトが自分が必要としている機能を実際に持っているのかどうかを調査 することです。

あなたがもしもアジャイルなプログラマであれば、これをスパイクと呼んだりす るのもいいもしれません。スパイク中にメソッドの使い方を調べるときは、 WIN32OLE#ole_method_help などのメソッドを使います。実際にそのオブジェク トを作成するスクリプトを書いている途中にそのオブジェクトの使い方を調べる 場合は、Ruby に閉じて調べられるWin32OLE のメソッドは便利です。オブジェク トブラウザも平行して使いながら、自分が求める機能を実現するにはどうすれば よいのかを探っていきます。そして、だいたい目的が達成できそうだと分かると プログラムを書き上げていきます。

まとめ

さて、今回は、Win32OLE を使った簡単なアプリケーションを紹介し、そして自 分が欲しいオブジェクトを得るためにはどうするかということを解説しました。

次回以降では実際に Excel 等のオブジェクトを得て、それらを具体的に活用し ていく方法について紹介します。

(アドバイザー:arton、助田 雅紀)

今回の理解度チェック

今回の記事に出てきた Internet Explorer のサンプルファイルに出てきたメソ ッドの引数などについて調べてみましょう。

ヒント: オブジェクトブラウザを使って調べる場合は、 対応するタイプライブラリを知る必要があります。 [InternetExplorer.Application] という ProgID は、 [Microsoft Internet Controls] というタイプライブラリに 対応しています。 ie.document のメソッドについて調べる場合は [Microsoft HTML Object Library] というタイプライブラリを 調べるとよいでしょう。 Ruby だけで調べる場合は、対応するタイプライブラリが 分からなくても調べられます。

参考文献

Windows での Ruby プログラミングについて知りたい方へ

COM について詳しくなりたい方へ

著者について

cuzic は、通信系の会社に勤める会社員です。 世界史、経済学、健康、J-POP などに興味があります。 著者への連絡先は cuzic atmark cuzic dot com です。