2025/06/30

LotusScript でメール送信 ② - フォームの送信とは?

前回は、LotusScript でメールを送信する基本的な方法を紹介しました。今回はその続きなのですが、テーマは構文の最初の引数 attachForm です。

Call notesDocument .Send( attachForm [, recipients ] )

1 attachForm BooleanTrue:フォームを送信
False:フォームを送信しない
2 recipients  文字列
文字列リスト
省略可能。
メールの宛先です。


テストフォームの準備

まずは、単純なフォームを用意します。

メールの宛先と件名、本文のリッチテキストを配置します。これらのフィールド名は『@MailSend の動作 ①』で紹介した予約フィールド名で作成します。

また、フォーム下部には、テスト用にメール配信とは関係のないフィールドも配置します。

アクションボタン[メール送信]には、次の LotusScript を記述します。画面上の文書を NotesUIDocument から取得して、メール送信します。Send メソッドコール時には、今回のテーマである attachForm に True を指定しています。

Sub Click(Source As Button)
   Dim nuiw As New NotesUIWorkspace
   Dim nuid As NotesUIDocument
   Dim nd As NotesDocument

   '現在の文書を取得
   Set nuid = nuiw.CurrentDocument
   Set nd = nuid.Document

   'メールを送信
   Call nd.Send(True)
End Sub

既存文書内のフィールドを利用してメールするパターンですので、前回 よりシンプルなコードになっていますね。


フォーム送信の動作

フォームが完成したらテストデータを作成して、[メール送信]ボタンをクリックします。

すると、宛先に設定したユーザにメールが届きます。そのメールを開くと、送信した文書と全く同じ画面が開きます。

その状態で、データベースのプロパティを確認するとメールボックスを指しています。メールボックス内でありながら、アプリの画面が開いていることがわかります。

このように、フォーム送信機能は、メール内にフォーム設計を含めて送信する機能です。


フォーム送信利用時の注意

届いたメール上部には[メール送信]ボタンが表示されており、クリックするとサンプルフォームと同様にメールが送信されます。このように、フォームの送信ではフォームの見た目だけでなく、アクションボタンなどの機能までもが送信されます。

また、送信されるのはフォームのみとなる点も注意が必要です。例えば、フォームがスクリプトライブラリを参照していたとします。

このフォームの文書をフォーム付きでメール送信した場合、受け取ったユーザがメールを開くと、ライブラリのロードエラーが発生します。これはメールボックス内にスクリプトライブラリが存在しないからですね。

フォーム付きでメールを送信する場合、メール DB 内で確実に表示 / 動作するよう、フォームはシンプルな構造にしておく必要があります。


まとめ

今回は、Send メソッドの attachForm 引数を使用した、フォーム付きメール送信について紹介しました。フォームに配置されているボタンなどのプログラムもメールで通知されます。また、届いたメールのプロパティを確認すると、フォーム上に配置したフィールドも配置されています。これらを利用すれば、簡単なアンケートなど、さまざまな ”機能付きメール” を実現することができることがわかりますね。

今では、HTML メールのように見た目がよく、多少の機能がついたメールは普通ですが、ノーツは 30 年前からフツウに実現できていました。ノーツってすごいですよね。


2025/06/24

LotusScript でメール送信 ①

先日、@関数を使用した メール送信の方法についてまとめました。

今回は LotusScript でメールを送信する方法についてまとめます。


構文

LotusScript でメールを送信するには、NotesDocument クラスの Send メソッドを使用します。まずは、構文を確認しましょう。

Call notesDocument .Send( attachForm [, recipients ] )

引数は役割は次の通りです。

1 attachForm BooleanTrue:フォームを送信
False:フォームを送信しない
2 recipients  文字列
文字列リスト
省略可能。
メールの宛先です。


一般的な使い方

Send メソッドを使用した一般的はメール送信のプログラムは次の通りです。

Sub Click(Source As Button)
   Dim ns As New NotesSession
   Dim ndb As NotesDatabase
   Dim ndMail As NotesDocument

   Set ndb = ns.CurrentDatabase

   '送信する文書を新規作成
   Set ndMail = ndb.CreateDocument

   ndMail.Form = "Memo"     'フォームを指定
   ndMail.SendTo = "Masayuki Hama/NCOsaka"    '宛先をセット
   ndMail.Subject = "LotusScript でメール送信 ①"    '件名をセット

   '本文をセット
   ndMail.Body = "これは『LotusScript でメール送信 ①』のサンプルで送信したメールです。"

   'メールを送信
   Call ndMail.Send(False)
End Sub

処理の流れは単純です。新規文書を作成して、フォーム、宛先、件名をセットします。本文はプレーンテキストでよいのであれば文字列として与えるだけで OK です。送信する内容が出来上がったら Send メソッドをコールします。

届いたメールは次の通りです。指定した宛先とメールの内容がセットされています。

基本的な動作の仕組みは、@MailSend の引数なしのパターン と同じで、SendTo など文書内の予約フィールドを利用してメールが送信されます。


ちなみに、構文に記載した通り、Send メソッドの recipients 引数で宛先を指定できます。SendTo フィールドと 2 通りの宛先指定方法が提供されています。両方が指定されている場合、recipients 引数が優先され、SendTo フィールドは無視されます。動作がわかりにくくなるのでどちらか一方になるようにしたほうがいいですね。


メール送信の動作

@関数では画面上に存在するフィールドは、メール配信に関係していなくてもメール内に保持されました。上記プログラムでは、CreateDocument でメール文書を別途生成しているので、メール配信に不必要なフィールドがメールとともに配送されることはありません。無用な漏洩を止めることができますね。

また、Send メソッドでメールを送信すると、その内容はコピーされて、サーバ上のメールルータに渡されます。よって、保存しなくてもメールが送信でき、新規作成した文書はスクリプトの終了とともに消滅します。


フォームの指定

サンプルプログラムでは、Form フィールドに "Memo" と設定していました。この設定がなくてもメールとしては正常に送信されます。しかし、届いたメールには Form フィールドが作成されません。

ただ、Form フィールドがなくてもメールは通常通りのフォームで参照できます。これは、Memo フォームがデフォルトフォームに設定されているからです。

このように、たとえ忘れていても、正しく参照できるのですが、プログラムの意図を明示する観点からも設定しておくべきです。


2025/06/22

DominoHub 2025 Tokyo レポート

6 月 19 日・20 日の 2 日間にわたり、DominoHub 2025 Tokyo を開催いたしました。ご参加いただいた皆様に、心より御礼申し上げます。

今年のテーマは「#DX(Domino Experience)〜Dominoの真実を語る〜」。Notes/Domino の実力や可能性を紹介するセッションをはじめ、実際の活用事例、さらには開催週にリリースされたばかりの 14.5 に関する最新情報 など、充実した内容となりました。

今回のイベントが、皆様のビジネスに少しでもお役立ていただける機会となったのであれば幸いです。

イベントの内容を詳細にレポートしたいのですが、スタッフとしての参加だったので、セッションは、ほとんど聞くことができませんでした(面白そうなテーマが盛りだくさんだったので、残念でなりません)。そこで、今回は、私が担当した部分だけのまとめとさせていただきます。


オンラインセッション

初日は、『Notes をもっと魅力的に! 今すぐ使える Excel 連携術』と題して、オンラインセッションを行いました。このブログで連載 Notes - Excel 連携 を再編集して、Notes データから帳票やグラフを作成する方法の紹介でした。

また、後半は、Excel で作成したグラフ画像をノーツ文書に書き戻し、見栄のいいレポートを作成する方法です。こちらは DXL Step-by-Step で連載している DXL(Domino XML Language)の事例で、昨年リリースした dxlSuite for LotusScript の利用例を紹介させていただきました。

Excel 連携と DXL を使えば、Notes のニガテを克服でき、ノーツをもっとリッチに、もっと魅力的にできます。今回のセッションでは、具体的なコードとともに解説を加えました。また全コードは資料内に掲載しています。1か月間は DominoHub のポータルサイトで、セッション動画と資料が掲載されていますので、ご興味のある方はご参照ください。すでにイベントは終了していますが、後付けで登録いただいても参照可能です。


展示ブース

二日目はセミナー会場前で展示ブースを担当しました。これまで作成した数々のアプリケーションを一堂に展示しました(私が開発していないアプリも含まれます)。

AI 連携や Nomad アプリ、DXL や Excel 連携のアプリケーションを中心に、Notes/Domino の可能性を感じていただけるようなアプリが紹介できたかと思います。

また、会場セッションの合間に展示ブースを紹介する機会がありました。そこでは上記リストにない新しいアプリを紹介しました。

OpenAI 社の画像生成 AI である、Dall-e3 の API を利用して、Notes アプリのアイコンを生成させるアプリです。Dall-e3 で正方形の画像を生成すると 1024x1024 の画像となるので、それを Excel で 64x64 の画像に変換、DXL でアイコンとして nsf に登録する機能を持ちます。

Dall-e3 の API や DXL で DB アイコンを操作する方法については、いずれこのブログでまとめたいと思います。


さいごに

今年の会場セッションは CIRQ -シルク- 表参道 で行いました。白を基調とした上品な会場で清潔感がありました。また、スタッフはとても丁寧で気持ちが良い対応でした。そのおかげで、これまでにない上質なイベントとなったと思っています。

今後もこのような会場でイベントを行いたい思った反面、もっとスムーズに運営しなければ...と感じました(DominoHub は HCL Ambassador を中心に有志で運営しています)。


2025/06/17

ODS の強制

本日、Notes/Domino 14.5 がリリースされ、先ほどまでリリースのウェビナーが配信されていました。14.5 の新機能についてはこれから検証して少しずつまとめたいと思います。

ところで、Notes/Domino 11.0.x のサポート終了が近いこともあり、各所でバージョンアップが行われています。新バージョンがリリースされたこともあり、この流れはしばらく続くと思います。

このような状況で、複数の環境をサポートしていると nsf ファイルのやり取りが発生し、ODS を意識する機会が多くあります。しかも、先日 ODS を間違え、現場で開けないというミスを起こしたことがあります。今回は、今後そのようなことがないようにするための戒めと手順の整理のための記事となります。

前回、突然 ODS の話を始めたのは、この記事の情報を記録しておきたかったためなんです...


ODS の強制

データベースを他のユーザにファイルとして渡す場合、相手の Notes クライアントが対応している ODS にしておかないと、開くことができません。

以下は前回紹介した Notes 14 でコピーした ODS 55 の nsf を Notes 9 で開いた場合のエラーです。

これに対応する機能が、ODS の強制です。Notes クライアントでデータベースをコピーするとき、拡張子を指定すると特定の ODS にすることができます。例えば、Notes 14 を使用しても .ns9 と指定してコピーすると ODS は 52 となります。

各 ODS と指定すべき拡張子の関係は次の通りです。

ODS 拡張子
55 NS12
53 NS10
52 NS9
51 N85
48 NS8
43 NS7, NS6

そのままだと、ノーツデータベースとして OS が認識しません。また、ノーツクライアントのアプリケーションを開くダイアログにも表示されません。

コピーした後に、エクスプローラなどで拡張子を nsf に戻しておきましょう。


2025/06/16

ODS(On Disk Structure )とは?

ODS とは?

ODS とは、On Disk Structure のことで、Notes/Domino データベースの内部構造を表すバージョン番号のことです。Notes クラアインとの場合、データベースのプロパティの[情報]タブに表示されます。

また、Administrator クライアントの[ファイル]タブを使えば、一覧で確認できます。


Notes/Domino のバージョンと ODS

当たり前ではありますが、新しい Notes/Domino ほど、新しい ODS をサポートします。整理すると次の通りとなります。デフォルトは、通常新規作成したデータベースで採用される ODS で、最大は、そのバージョンでアクセスできる最大の ODS バージョンです。

Notes/Domino デフォルト 最大
14.0.x 55 55
12.0.x 52 55
11.0.x, 10.0.x 52 53
9.0.1 43 52
9.0, 8.5.x 43 51
8.0.x 43 48
7.0.x, 6.x.x 43 43

例えば 9.0.x を利用している場合、ODS 52 まではアクセスできますが、ODS 55 のデータベースにはアクセスできません。例えば、以下の図は、ODS 55 の nsf ファイルを Notes  9.0.1 で開こうとした場合のエラーです。

ただし、Domino 14 サーバ上にある ODS 55 のデータベースを Notes 9 クライアントがアクセスすることは可能です。サーバ上のデータベースは、クライアントが直接アクセスするのではなく、サーバを介してアクセスするためです。

なお、Notes/Domino は上位互換性があり、新しい Notes/Domino であれば、古いバージョンで使用されていた ODS のデータベースにアクセスが可能です。


ODS と機能

ODS のバージョンが高いほど、機能が多く、制限が少なく、パフォーマンスが高くなります。例えば、1データベースの最大容量は、ODS 52 では 64 GB なのですが、 ODS 53 では 256 GB まで拡張されています。

現時点で最新の ODS である 55 の新機能は以下のリンクにまとまっています。

Domino 12 の ODS 55 で導入された拡張機能

リンクのページによると、ACL のエントリ数が 950 件から 65,535 件まで増加、サマリーフィールドのサイズが 64 KB から 16 MB まで拡張されたと記載があります。制限が緩和されること自体は良いことなのですが、利用に当たって注意が記載されています。

  • 新機能を利用するためには設定が必要である
  • 古いバージョンではエラーが出るなどアクセスが制限される場合がある

このように下位のバージョンに対して互換性のない機能は、通常、有効にするために設定が必要になっており、ODS を上げると自動的に適用されるわけではありません。管理者は、社内環境で安心して利用できる機能か確認したうえで採用する必要があります。


2025/06/10

DXL Step-by-Step:#58)ノード操作 ⑪ - ノードの置き換え

ノード操作シリーズの最終回は、ノードの置き換え操作についてまとめます。


置き換え操作の必要性

例えば、リッチテキスト内のプレーンテキストに装飾をする場合を考えます。

それぞれを DXL で表現すると下図のようになるのですが、装飾を加えるためには、プレーンテキストを run や font ノードで装飾されたノードに置き換えることになります。


ReplaceChild メソッドの注意点

このような操作を行う際に利用するのが、ReplaceChild メソッドです。

ReplaceChild (NotesDOMNode - LotusScript®)

構文は以下の通りです。

Set notesDOMNode = notesDOMNode .ReplaceChild( newChild , oldChild )

引数には、置き換えるノードの新・旧を指定する仕様となっています。そのためか、メソッドをコールするノードは、RemoveChild メソッドと同じく、親のノードから実行する仕様になっています。NotesDOM??? クラスの設計者の親はよほど偉大な方なのかもしれませんね...

このヘルプを見ればわかるのですが、このメソッドには重大な注意点があります。それは戻り値が、置換されたノードであることです。


ReplaceChild メソッドの挙動

ヘルプを読んだだけではわかりにくいので、最初に記載したプレーンテキストを装飾する場合を例に、挙動を順に確認しましょう。

ReplaceChild 実行前はこのような状態となります。

紫色のノードが置換元のプレーンテキストのノードで、par ノードの配下に配置されています。置換先のノードは Create ??? Node メソッドを利用して新規で作成し準備します。これはノードの新規作成と同じ操作ですね。

この置換元と置換先のノードを引数に、親のノードである par ノードから ReplaceChild メソッドを実行することになります。実行後の状態は下図のような状態となります。

新規で作成したノードが par ノード配下に配置され、希望通りの結果になっています。問題は、はじき出されたノードです。このノードは、新規作成したてのノードと同じく、DXL ツリーには属さない宙に浮いた状態となっているのですが、このノードが ReplaceChild メソッドの戻り値となります。

DXL のコーディングをしていると、この挙動がとても煩わしく感じます。例えば、ノードを置き換えた後、後続の処理でそのノードを使いたくても、プログラム上は行方不明になってしまうからです。


ノードを置き換える関数

なぜこのようなインプリになっているか真意はわかりかねますが、この仕様では DXL を自由自在な操作に支障をきたします。そこで、次のような関数を作成して、標準メソッドの不便を解消しています。

Function xReplaceNode(vdnNew As NotesDOMNode, vdnOld As NotesDOMNode) As NotesDOMNode
   Dim dnParent As NotesDOMNode
   Dim dnNext As NotesDOMNode
   Dim dnPrev As NotesDOMNode

   ' 元の位置を保存
   Set dnNext = vdnOld.NextSibling           ’ 次のノード
   Set dnPrev = vdnOld.PreviousSibling  ' 手前のノード
   Set dnParent = vdnOld.ParentNode     ' 親のノード

   ' 置き換え
   Call dnParent.ReplaceChild(vdnNew, vdnOld)

   ' 行方不明の捜索
   If dnPrev.IsNull = False Then
      '手前のノードが存在したのでその次のノードが置換されたノード
      Set xReplaceNode = dnPrev.NextSibling
   ElseIf dnNext.IsNull = False Then
      '手前のノードがないので、次のノードの1つ前が置換されたノード
      Set xReplaceNode = dnNext.PreviousSibling
   Else
      '前後にノードがないので一人っ子、置換後も最初のノードが置換されたノード
      Set xReplaceNode = dnParent.FirstChild
   End If
End Function

関数内の処理のポイントは、置換前に前後と親ノードを取得しておく点です。これで、置換後、自分自身が行方不明になっても、前後関係や親から自分探しができるというわけです。


ノード操作まとめ

昨年の DominoHub 2024 のオンラインセッション『 ”DXL” でリッチテキスト縦横無尽』でご紹介した DXL ノード操作をまとめたこのシリーズですが、今回の ⑪ で終了です。ここで紹介したテクニックは、DXL を使ったプログラミングをする中で必要となった知識や関数たちで、実体験に即したものをまとめました。

これらテクニックを利用すれば、DXL を自由自裁、縦横無尽に操作できるようになります。

前回 DXL Step-by-Step


2025/05/27

DXL Step-by-Step:#57)ノード操作 ⑩ - ノードの複製

今回はノードを複製する方法についてまとめます。同じフォーマットの表を複数個所に配置するなど応用方法はさまざまですね。


ノードの複製

ノードを複製するには、 Clone メソッドを使用します。

Clone (NotesDOMNode - LotusScript®)

前回紹介した RemoveChild メソッドと同様で、このメソッドも NotesDOMNode クラスのメソッドとなります。ですので、それを継承している NotesDOMEmenetNode でも使用できます。

構文は次の通りです。

Set notesDOMNode = notesDOMNode .Clone( deepClone )

引数 deepClone で True を指定するとサブノードを含めて複製します。False だとそのノードだけとなるのですが、DXL ツリーの階層構造を考えると、通常は True での利用となりますね。


複製したノードの状態

CreateElementNode メソッドで新規作成したノードは、DXL ツリーには属さず宙に浮いたような状態であると #51)ノード操作 ④ - ノードの新規作成 で紹介しました。複製したノードも同様の状態となり、ParentNode が存在しない状態となります。

DXL ツリーに配置するためには、AppendChild メソッドや #52)ノード操作 ⑤ - ノードを挿入する方法 で紹介した方法を追加って、希望する位置に配置する必要があります。


複製時の注意

例えば、リッチテキストフィールド直下にある 2 つ目の表を複製して一番後ろに挿入したいとします。そのサンプルは次の通りです( #55)ノード操作 ⑧ - ノードの検索 で紹介した関数を使用)。

      ・・・
   'リッチテキスト直下の2つ目のテーブルを取得
   Dim denTbl As NotesDOMElementNode
   Set denTbl = xGetNthChildByName(denRT, "table", 2)

   'テーブルの後ろの段落を得取得
   Dim denPar As NotesDOMElementNode
   Set denPar = xGetNextSiblingByName(denTbl, "par")

   'テーブルを複製して追加
   Dim denNew As NotesDOMElementNode
   Set denNew = denTbl.Clone(True)
   Call denTbl.ParentNode.AppendChild(denNew)

   'テーブルの後ろに段落を追加
   Set denNew = denPar.Clone(True)
   Call denTbl.ParentNode.AppendChild(denNew)
      ・・・

xGetNthChildByName(denRT, "table", 2) で 2 つ目の表を取得して、denTbl.Clone(True) で複製しています。ただ、ポイントはココではありません。表を配置後、その後ろに段落(par ノード)を配置しています。table ノードは前後に par ノードが必要となるための対応なのですが、ノードをコピーして配置するだけではなく、前後関係に配慮して DXL ツリーとして破綻しないよう注意することが重要です。


前回 DXL Step-by-Step 次回


2025/05/19

環境変数の利用と注意

先日、notes.ini 利用したアプリでちょっとしたトラブルがあったので、まとめておきます。

notes.ini ファイルは、ノーツの動作設定が記録されているファイルで、ノーツクライアントのプログラムディレクトリに存在します。セットアップするなどノーツ担当者であれば知らないはずはないファイルですね。


notes.ini ファイルのアクセス

アプリ開発では、notes.ini にアクセスする機能が提供されています。

@関数 LotusScript(NotesSessionクラス)
設定 @Environment SetEnvironmentVar メソッド
取得 @Environment GetEnvironmentString メソッド

例えば、SrcStr フィールドの値を notes.ini に Denaoshi という名前で設定するには、次のように記述します。

@関数 @Environment("Denaoshi"; SrcStr)
LotusScript Dim ns As New NotesSession
Dim nuiw As New NotesUIWorkspace
Dim nuid As NotesUIDocument
Dim sStr As String

Set nuid = nuiw.CurrentDocument
sStr = nuid.FieldGetText("SrcStr")
Call ns.SetEnvironmentVar("Denaoshi", sStr)

実行すると、以下のように notes.ini に新しいエントリ "$Denaoshi" が追加され、値が設定されます。すでにエントリがある場合には、値のみ更新します。

参考までの情報ですが、全角文字の前に付加されている □ は、LMBCS(Lotus Multi-Byte Character Set)の日本語を表すコード(0x10)です。LMBCS の日本語は、0x10 + Shift-JIS の 3 バイトで構成されます。バイナリエディタで ”出” の文字を確認すると次のようになります(”出” の文字コードは 0x8F6F)。

notes.ini ファイルから値を取得して、IniStr フィールドにセットする方法は、次の通りです。

@関数 xIni := @Environment("Denaoshi");
@SetField("IniStr"; xIni)
LotusScript Dim ns As New NotesSession
Dim nuiw As New NotesUIWorkspace
Dim nuid As NotesUIDocument
Dim sIni As String

Set nuid = nuiw.CurrentDocument
sIni = ns.GetEnvironmentString("Denaoshi")
Call nuid.FieldSetText("IniStr", sIni)

取得した値には LMBCS の □ は付加されず、セットした通りの値が取得できます。LMBCS については notes.ini をテキストエディタなどで直接開いたときにだけ気にすればいいということですね。


notes.ini の使い方

上記の通り、notes.ini に値を入出力する方法を紹介しました。これを ”環境変数” と呼び、その名の通り、変数のように利用できます。notes.ini はノーツクライアントに一つですから、アプリをまたがっても値の共有が可能となる点がポイントです。

ワークフローアプリを例にすると、前回選択した上司を保持させ、別のワークフローアプリでそれを上司として初期表示するというような使い方ができます。notes.ini を使えば、簡単な仕組みで大きな効果を得ることができます。

ただ、次にその値を利用するタイミングが、明日なのか1年後なのか定かではありません。先の例のように人の情報の場合、退職などによりノーツユーザとして存在しない場合も考えられます。このような不整合に備え、チェックや再選択させる機能などの用意が必要です。


notes.ini 利用時の注意

最後に先日発生したトラブルについて紹介します。

ワークフロー系のアプリで、質問形式で申請内容を確認するウィザード形式のフォームがありました。ウィザードの最後では、必要な申請書を表示して、起票する機能を提供していました。ウィザードで入力した情報を notes.ini に書き込み、申請書起票時に読み込んで初期表示させ、二重入力を省く仕組みでした。

この機能で、ウィザードと申請書で値が変わる現象が発生しました。連携データに全角スペースが含まれていたことが原因でした。実験したところ、全角スペースは notes.ini に出力時は全角のままですが、読み込んだ際には半角スペースに変換されるようです(@関数、LotusScript とも同様)。

また、複数の全角スペースや複数の半角スペースも半角スペース1つに変換されることも発見しました。この結果より、notes.ini から値を読み込む際には、Trim と同等の機能が実行されいると想定できます。


まとめ

今回紹介した環境変数の利用は、うまく使えば非常に便利な機能です。ただ、Trim のような処理が行われている点には注意が必要です。ご利用の際には、環境変数に格納される値についても意識しておくことをおススメします。

また、環境変数はすべてのノーツアプリで共通で使用できます。便利な反面、大量に使用すると、それそれぞれの目的や設定タイミング、どのアプリで利用しているかが不明瞭になり、バグや仕様の複雑化の要因となります。LotusScript でパブリック変数を使用すべきでない理由と同じですね。

利用の際には環境変数の名称や設定される値、設定タイミングなどの仕様を決め、チーム全体で周知することが重要です。


2025/05/14

@MailSend の動作 ②

@MailSend の紹介です。この関数は、引数なしと引数ありの構文があり、前回は引数なしの動作について説明しました。今回は引数ありのパターンの使い方についてまとめます。


構文

まずは、構文の確認です。

@MailSend( sendTo ; copyTo ; blindCopyTo ; subject ; remark ; bodyFields ; flags )

各引数にセットする値と役割は次の通りです。

1 sendTo 文字列
文字列リスト
メールの宛先
宛先、CC、BCC の 1 つ以上に指定が必要
2 copyTo 文字列
文字列リスト
3 blindCopyTo 文字列
文字列リスト
4 subject 文字列 メールの件名
5 remark 文字列 メールの本文
6 bodyFields 文字列リスト 本文に追加するフィールド
7 flags キーワード メールに関するフラグ


宛先の設定

宛先に設定できるのは、ユーザ名、グループ名です。一人だけに送信する場合は文字列、複数人に送信する場合はリスト値で設定します。宛先、CC、BCC のうちどれか 1 つには指定が必要です。設定しない引数にはからの文字列 ""  を設定します。


件名の設定

メールの件名を文字列で指定します。文字列リストを指定した場合、最初の要素が使用されます。


本文の設定

@MailSend で送信するメールの本文は、プレーンテキストとなります。引数の文字列に @NewLine を含むことで、改行させることができ、体裁を整えることが可能です。


ここまでが一般的な使い方となるので、簡単なサンプルを作成します。

メール送信ボタンの式は次の通りです。

xSubject := "『" + Destination + "』 の申請";
xBody := "新しい申請書を申請しました。";
xBody := xBody + @NewLine + "承認してください。";

@MailSend(Approver; ""; ""; xSubject; xBody)

フォームをプリビューして、メールを送信すると、メールが送信されます。


本文に追加するフィールドの設定

この機能は文書内のフィールドをメール内に埋め込める機能で、リストで複数のフィールドを指定すると、それらすべてを本文に表示します。

xSubject := "『" + Destination + "』 の申請";
xBody := "新しい申請書を申請しました。";
xBody := xBody + @NewLine + "承認してください。";
xBodyFlds := "Date":"Destination":"Purpose":"Amount";

@MailSend(Approver; ""; ""; xSubject; xBody; xBodyFlds)

メール送信ボタンを修正して、メールを送信すると次のようになりました。

指定したフィールドの一部しか表示されいません。しかも、改行も間隔も開けずただ羅列されています。ヘルプによると、数値や日付フィールドには対応していないようです。なかなか使いどころがわからない機能です...。この仕様だと remark にがんばって指定したほうが、自由に体裁が決定できるのでいいですね。


フラグの設定

最後の引数であるフラグは、送信優先度や署名、暗号化など、メール配信の細かな設定ができます。通常のアプリで使いそうなフラグは次の 2 つです。

キーワード 機能
[INCLUDEDOCLINK] @MailSend が実行されたときに開いていた文書の文書リンクを本文の最後に追加します。
ただし、文書は保存されている必要があります。
[RETURNRECEIPT] 受信者がメールを開いたとき、開封確認を送る設定をします。

フラグはリストのように記述すると複数指定することができます。例えば、次のように設定すると、文書リンクと開封確認付きのメールとなります。

xSubject := "『" + Destination + "』 の申請";
xBody := "新しい申請書を申請しました。";
xBody := xBody + @NewLine + "承認してください。" + @NewLine;

@MailSend(Approver; ""; ""; xSubject; xBody; ""; [IncludeDoclink]:[ReturnReceipt])


まとめ

引数付きの @MailSend を使えば、宛先、件名、本文が自由に設定でき、引数なしの場合のようにフィールド名の縛りもありません。また、文書リンク付きのメールを発信できるのでワークフローアプリでも活用できますね。


2025/05/10

@MailSend の動作 ①

Notes アプリ開発とメールの送信は切っても切れない関係といえますね。今回は、式言語でメールを送信する @MailSend について紹介します。


構文

ヘルプによると @MailSend の構文は次のように、引数のあり/なしの 2 通りあります。

@MailSend

@MailSend( sendTo ; copyTo ; blindCopyTo ; subject ; remark ; bodyFields ; [ flags ] )

今回は、前者の引数なしのパターンを紹介します。


引数なしでメール送信できる訳

引数なしということは、宛先も指定しないの? と疑問がわきますが、大丈夫です。この機能は、文書内のフィールド値を使用して送信する機能となっています。

簡単なサンプルとして次のようなフォームを作成します。

フォームをプリビューして、宛先と件名を入力し、[メール送信]ボタンをクリックします。

すると、宛先に指定したユーザのメールボックスにメールが届きます。

とっても簡単ですね。そして仕組みも単純です。

@MailSend を実行する文書にある SendTo が宛先、Subject が件名として使用されます。このように、特定の役割を持ったフィールド名を予約フィールドといいます。


予約フィールド

メールの配信制御に関連する予約フィールドはヘルプに詳細が記載されています。

メールオプションを制御する予約フィールド


通常、メール送信で使用する予約フィールドをまとめると次の通りです。

予約フィールド 役割・使い方
SendTo 宛先(リスト値可)
CopyTo CC(リスト値可)
BlindCopyTo BCC(リスト値可)
Subject メールの件名
Body メールの本文
ReturnReceipt 受信者がメールを開いたとき、開封確認を送る場合 "1" を指定


すべてのフィールドを送信

@MailSend では、送信する文書内のすべてのフィールドをメールで配信されます。例えば、次のようにフィールドを 3 つ追加してメールを送信してみます。

すると届いたメールの文書プロパティでこれらフィールドが確認できます。

Notes メールは、メールとは関係ないフィールドがメール内にあっても、そのまま配信するようです。文書を丸ごと配信する感じですね。いかにもノーツらしい挙動です。


リッチテキストの送信

メールの本文(Body)フィールドはリッチテキストです。これに倣い、作成したフォームの Body フィールドをリッチテキストに変更します。文書を新規作成し、本文を記入して送信しても、届いたメールの本文は空っぽとなります。

リッチテキストは文書を保存しないと @MailSend で送信できない仕様のようです。ただ、文書を保存してから送信するとメールを開く際にエラーが発生します。

これは、送信元の Form フィールドまで含めて送信されているからです。すべてのフィールドが送信される機能の弊害と言えますね。ちなみにメール DB にあわせて、送信元のフォーム名を "Memo" としておくとこのエラーは回避できます。


まとめ

今回は @MailSend の引数なしで使用する方法を紹介しました。引数がないので@式はシンプルになりますが、フィールド名が固定されたり、フォーム名を意識したする必要がありました。また、すべてのフィールドが送信されることもあり、アプリで利用するには制限が多く、活用しづらい機能と言えます。

このような課題を解決するのが引数ありの @MailSend となります。次回、使い方を紹介します。