POP3 Transporter
またはIMAP Transporter
を使用してメールを受信する場合,結果はサーバー設定に左右されることに注意する必要があります。
たとえば,Microsoft Exchangeのサーバー設定でメッセージ取得形式がTextOnly
に設定されている場合,HTMLメールをトランスポーターまたはInternet Commandsの同等コマンドで取得することはできません。この設定は,モバイル機器などで使用されているExchange ActiveSyncとは別です。
Windows版のPLAY
コマンドはMCIというAPIを内部的に使用しているため,新しいオーディオコーデックを再生することができません。.wav
ファイルには,さまざまなフォーマットがあり,PLAY
コマンドで再生できない場合があります。再生できない場合,オーディオファイル変換ツールなどで.wav
ファイルを再エンコーディングする必要があるかもしれません。
CEF版のWebエリアは,著作権保護のため,オーディオ/ビデオの再生コーデックがサポートされていません。プレーヤーを表示するのであれば,システム版のWebエリアを検討してください。
IMAPのDELETE
コマンドを[Gmail]/All Mail
メールボックスに送信することはできません。このメールボックスには実体がないためです。DELETE
コマンドはINBOX
のようなメールボックスに送信するようにしてください。
[Gmail]/All Mail
メールボックスに対してCOPY
コマンドを実行することはできますが,注意が必要です。サーバーが内部的にEXPUNGE
を実行するため,結果的にMOVE
を実行したような状態になります。COPY
コマンドはINBOX
のようなメールボックスに対して実行するべきです。
RFC3501によれば,IMAPのSTORE \Deleted
は後にEXPUNGE
コマンドを実行したとき(あるいは接続を閉じた時)にメッセージを削除するよう,マークする働きがあります。メールボックスを移動したときにメッセージが削除されるわけではありません。
追記: ビルド262238
以降,メールボックスを移動したときには,自動的にEXPUNGE
コマンドが追加されるようになりました。(ACI0101704)
4D v18 R5 ではマクロが導入されました。フォームエディター上で繰り返しおこなうタスクを自動化するのに、マクロは非常に便利です。このブログ記事ではいくつかの基本的な例とともに、マクロがどう機能するのか、なにが可能なのかを紹介します。 詳細については、オンラインマニュアルも参照ください。
マクロを使って次のことをおこなえます:
など
いくつかの例を実際に見てみましょう。 例1ではマクロの作り方・実行の仕方も説明します。
選択されているフォームオブジェクトのフォントカラーを赤に設定するマクロです。
まず、JSONマクロファイル (FormMacros.json) 内で、次のようにマクロを宣言します:
{ { "macros": { "赤に設定する": { "class": "SetRedColor" } }
次に4D内で、マクロによって呼び出される “SetRedColor” クラスを作成します。
このクラスの関数として、呼び出し時に実行される onInvoke 関数を設定します。
実行時にこの関数に渡される引数には、フォームエディターの情報が含まれています。
引数内の “currentSelection” プロパティから、選択されているフォームオブジェクトのコレクションが取得できます。
コレクションに格納されている各フォームオブジェクトの属性を変更します。
最後に、戻り値として “currentPage” 属性を返すことで、4Dに変更内容を通知します。
コードは次のようになります:
Function onInvoke($editor : Object) : Object
var $name : Text
If ($editor.editor.currentSelection.length>0)
// 選択オブジェクトのstroke属性を "red" に設定します
For each ($name;$editor.editor.currentSelection)
$editor.editor.currentPage.objects[$name].stroke:="red"
End for each
Else
ALERT("フォームオブジェクトを選択してください。")
End if
// 4D に変更内容を通知します
$0:=New object("currentPage";$editor.editor.currentPage)
マクロが実行するには、フォームエディター上でコンテキストメニューを開き、「マクロ > 赤に設定する」 を選択します。
マクロのコードを格納している “SetRedColor” クラスを HDI内で確認してください。
赤だけでなく、緑のフォントカラーも利用したい場合、2つのマクロと、それぞれに専用のクラスを作成することもできますが、2つのマクロにそれぞれパラメーターを設定して、それらを1つのクラスで処理することも可能です。
JSONマクロファイル (FormMacros.json) 内で、同じ “SetFontColor” クラスと、異なる “color” パラメーターが設定された 2つのマクロを宣言します:
{ "macros": { "フォントカラーを赤に設定する": { "class": "SetFontColor", "color": "red" }, "フォントカラーを緑に設定する": { "class": "SetFontColor", "color": "green" }, }
この “color” パラメーターはクラスのコンストラクターで取得します:
Class constructor
var $1 : Object
This.color:=$1.color
“SetFontColor” クラスの onInvoke 関数には例1と同じコードが再利用できます。異なる点は “red” という文字列で色を指定する代わりに、変数 This.color を使うことです。
マクロを使って、メソッドの付いたフォームオブジェクトをフォームに追加することができます。メソッドを紐づける方法は複数あります。オンラインマニュアルにて、それらの方法を説明しています。
このHDIの例では、メソッドのコードをオブジェクトに格納して4Dに渡します。当該メソッドファイルは実行時に 4D によって作成されます。
Function onInvoke($editor : Object)->$result : Object
var $btnHello : Object
// "Hello" ボタンを作成します
$btnHello:=New object("type";"button";\
"text";"Hello World!";\
"method";New object("source";"ALERT(\"coucou\")");\
"events";New collection("onClick");\
"width";120;\
"height";20;\
"top";0;\
"left";0)
// 現在のページにボタンを追加します
$editor.editor.currentPage.objects.btnHello:=$btnHello
// フォームエディター上で新規作成したボタンを選択します
$editor.editor.currentSelection.clear()
$editor.editor.currentSelection.push("btnHello")
// 4D に変更内容を通知します
$result:=New object
$result.currentSelection:=$editor.editor.currentSelection
$result.currentPage:=$editor.editor.currentPage
作成したばかりのフォームオブジェクトを編集しやすいよう、”currentSelection” を対象に clear() および push() を使用することで、このフォームオブジェクトを選択します。
最後に、戻り値として ”currentPage” 属性とともに “currentSelection” 属性も返し、4Dに変更内容を通知します。
フォームを編集するだけでなく、フォームの情報、属性、プロパティを検証するマクロも作れます。たとえば、複数のページを持つフォーム内で使用されているピクチャーパスを検証することができます。
マクロはモーダルウィンドウを開いてダイアログを表示することができます。 たとえば、現在のページ上にあるオブジェクトの一覧を、それらのオブジェクト名、タイプ、クラスなど任意のプロパティとともに表示することができます。一覧からオブジェクトを選択して、ダイアログ内の “選択” ボタンをクリックすると、フォームエディター上でも選択されるようにできます。
このマクロのコードを格納している “ObjectList” クラスを HDI内で確認してください。
4Dでオブジェクトを整列するには “整列” ダイアログも使用できますが、いくつかのオブジェクトを選択して、ターゲットオブジェクト (マクロ呼び出し時にマウスカーソルが置かれているオブジェクト) を基準に位置を揃えることもできます。
コードを書く際には:
このように、整列も均等配置も任意に実行するマクロを作成することができます。 “AlignOnTarget” クラスでは、左揃え・右揃え・上揃え・下揃えの例を確認することができます。
ORDAで作成したエンティティセレクションには固有のORDAコンテキストが関連づけられます。ORDAのコンテキストを作成するコマンドは,下記のとおりです。
dataClass.query()
entitySelection.query()
dataClass.fromCollection()
dataClass.all()
Create entity selection
Use ORDA to boost performance in Client/Server mode
ORDAのコンテキストは,クライアント/サーバーのパフォーマンスを最適化するために使用されます。具体的には,REST APIでサーバーから転送されるデータクラス属性のリストを内部的に管理し,リクエストされた属性だけを追加してゆくことにより,クエリの特性を自動的に「学習」するために使用されます。通常,コンテキストを意識してコーディングする必要はありませんが,条件分岐を含むエンティティセレクションの一括処理などでアクセスする可能性のあるすべての属性が事前にわかっているのであれば,最初に必要な属性名すべてにアクセスしてコンテキストを最適化することにより,一括処理の途中で不足した属性を補うためのネットワークリクエストが発生することを防ぐこともできます。コンテキストはフォームの描画にも使用されており,リストボックスのカラム内で使用されている属性(非表示カラムを含む)が初期コンテキストとなります。
ORDAコンテキストは,クエリの用途に対して特化されたものであるべきです。コンテキストから属性を除外することはできないので,コンテキストを汎用的に使用した場合,属性のリストが肥大化してパフォーマンスが低下する恐れがあります。リレーション属性にアクセスする場合は特にそうです。たとえば,下記のコードはマルチレベルのリレーション属性にアクセスしているため,指数的にコンテキストが肥大化し,一括処理の後は非常に処理が重くなります。ORDAリクエストログをみれば,一括処理の後,レベルのリレーション属性がそれぞれ最大80
件ずつ返されていることがわかります。
$logFile:=Folder(fk logs folder).file("ORDARequests.txt")
ds.startRequestLog($logFile)
$entitySelection:=$anEntity.relatedEntities
For each ($entity; $entitySelection)
$relatedData:=$entity.link.link.link.link.toCollection()
End for each
$result:=$entitySelection.orderBy() //重い処理
コンテキストが肥大化してしまった場合,dataClass.get()
で新しいコンテキストを作成することができます。
$logFile:=Folder(fk logs folder).file("ORDARequests.txt")
ds.startRequestLog($logFile)
$entitySelection:=$anEntity.relatedEntities
For each ($entity; $entitySelection)
$relatedData:=$entity.link.link.link.link.toCollection()
End for each
$key:=$anEntity.getKey() //プライマリーキー
$entitySelection:=ds[$anEntity.getDataClass().getInfo().name].get($key) //新しいコンテキスト
$result:=$entitySelection.orderBy() //軽い処理