LotusScriptのメソッド実行に成功した

LotusScriptのメソッド使用に成功した

少し前、コチラの記事

akashi-keirin.hatenablog.com

で泣き言を言ったら、こんな過疎ブログにもかかわらず大勢の方がアドヴァイスをくださった。なんとありがたいことよ……。

あれこれ試してみて、なんとかうまく行ったので、ご報告もかねてコチラでお返事させていただきます。

thom (id:t-hom)さん、id:imihitoさん、そしてExcelVBAer (id:x1xy2xyz3)さん、

ホントーに、あざす!!!!!!!!

【参考】前回使用したコード

リスト0
Dim notesSession As Object
Dim notesDatabase As Object
Dim notesDocument As Object
Dim notesUIWorkSpace As Object
Dim notesUIDocument As Object    '……(1)'
Set notesSession = CreateObject("Notes.NotesSession")
Set notesUIWorkSpace = CreateObject("Notes.NotesUIWorkspace")
Set notesDatabase = notesSession.GetDatabase("", "")
notesDatabase.OpenMail
Set notesDocument = notesDatabase.CreateDocument()
notesDocument.Save False, False
Set notesUIDocument = notesUIWorkSpace.EditDocument(True, notesDocument, False)
notesUIDocument.Print(0)    '……(*)'

この、(*)のところがうまく行かない、というお話でした。

目次

読むのがメンドクサイ人のために、今回は目次をつけます。「成功」のところだけ読んでもらったら良いかと。

型指定の厳密化

まず、id:imihitoさんのアドヴァイスに従って、単にObject型で指定していた変数を厳密に型指定することにした。

ExcelVBAer (id:x1xy2xyz3)さんによると、参照設定できるということなので探してみると、確かにあった。

職場で見ただけなのでうろ覚えだけど、「Lotus」で始まるやつです。

んで、喜び勇んで参照設定にチェックを入れ、リスト0の(1)を

Dim notesUIDocument As NotesUIDocument

としてみたが、うまく行かなかった。今にして思えば、変数名と型名が同じだったのがマズかったのかも知れん。

ただ、仮に参照設定してうまく行ったとしても、ノーツの入っているPCでしか動かないのでは困るなあ。

というわけで、このやり方は見送ることにした。

メソッド名に[]

これが一番簡単な対応なので期待したのだが、

リスト0の(*)を

notesUIDocument.[Print]0

としてみたが、何も起こらなかった……(エラーは出ていたかも)。

CallByName関数の使用

「CallByName関数」なんてものがあることを知らなかったので、ちょっとggってみた。

すると、たとえばコチラには、

オブジェクトに対してメソッドを実行します。また、オブジェクトのプロパティを設定または取得します。

パラメータ
ObjectRef

必ず指定します。オブジェクト型 (Object) です。プロパティまたはメソッドを公開するオブジェクトへのポインタを指定します。

ProcName

必ず指定します。文字列型 (String) です。オブジェクトのプロパティまたはメソッドの名前を含む文字列式を指定します。

UseCallType

必ず指定します。呼び出されるプロシージャの種類を表す CallType 列挙型 型の列挙体のメンバです。CallType の値は、Method、Get、Set のいずれかです。

Args

(省略可能。) パラメータ配列型 (ParamArray) です。呼び出されるプロパティまたはメソッドに渡す引数を含むパラメータ配列を指定します。

だってさ。おお、これならなんとかなりそうだ!

ちなみに、第3引数の「UseCallType」の指定には定数が使える。コチラによると、メソッド呼び出しの場合は「VbMethod」(実体は「1」)を使えば良い。

リスト1
Dim notesSession As Object
Dim notesDatabase As Object
Dim notesDocument As Object
Dim notesUIWorkSpace As Object
Dim notesUIDocument As Object
Set notesSession = CreateObject("Notes.NotesSession")
Set notesUIWorkSpace = CreateObject("Notes.NotesUIWorkspace")
Set notesDatabase = notesSession.GetDatabase("", "")
notesDatabase.OpenMail
Set notesDocument = notesDatabase.CreateDocument()
notesDocument.Save False, False
Set notesUIDocument = notesUIWorkSpace.EditDocument(True, notesDocument, False)
CallByName notesUIDocument, "Print", VbMethod, (0)    '……(1)'
notesUIDocument.Close True    '……(2)'

(1)の

CallByName notesUIDocument, "Print", VbMethod, (0)

では、CallByName関数に4つの引数を渡している。

今回は、

NotesUIDocumentクラスのオブジェクトであるnotesUIDocumentのPrintメソッドに引数「0」を渡して実行

したいわけなので、引数にはそれぞれ

  • 第1引数(対象のオブジェクト)にはnotesUIDocument
  • 第2引数(メソッド名)にはPrint
  • 第3引数(呼び出されるものの種類)にはVbMethod
  • 第4引数(メソッドに渡す引数)には(0)

を指定した。ちなみに、notesUIDocumentクラスのPrintメソッドに引数「0」を渡して実行すると「1部だけ印刷」になる。

あとは、(2)の

notesUIDocument.Close True

で作成したメールを閉じる。このコードは前回もこのまま実行できたのでCallByName関数は不使用。

実行結果

職場のPCでしか実験できないので、画像がなくてすみません。

実行すると、ノーツの画面に作成したメールが一瞬表示され、すぐに閉じられる。並行してプリンタからメール文面が出てきた。おおっ、うまく行ったぞ!

第4引数の「0」を「()」で括るというのが必要なのかどうかよく分かっていないが、とりあえずこれでうまく行っている。

最後に注意

ひとまずこれで意図したとおりの結果が得られたわけだが、1点だけ注意。

今回のコードを利用したマクロでは、メールを作成するだけして送信せずに印刷だけして閉じているので、メールが作成されるごとにドラフトに未送信のメールがばかすか溜まっていきます。添付ファイル次第ではすぐにメールが送れなくなってしまうので注意が必要です。

ともあれ、これで

多くの宛先にそれぞれ異なるメールを送る

というときに、

一旦全てプリントアウトして文面をチェックしてから一気に自動送信

という形に持って行けそうです。

アドヴァイスをくださった皆様、

あざーしたっ!!!!!!!!