Windows 11プラットフォームでは,テキスト入力中にマウスポインターの形状がアイビーム(テキスト選択用)に変化しません。これはオペレーションシステムに由来する仕様です。
On Web ConnectionやOn Web Authenticationなど,HTTPリクエストで実行されたデータベースメソッドのシンタックスエラーは表示されません。これは仕様です。ON ERR CALL
でエラーハンドリングメソッドがインストールされていないWebプロセスでランタイムエラーが発生した場合,メソッドは中断され,レスポンスとしてエラーHTMLページがユーザーエージェントに返されます。
旧式ネットワークレイヤーでクライアント/サーバー通信を暗号化した場合,アプリケーションの公開名には^
というプリフィックスが追加されます。新ネットワークレイヤーの公開名は暗号化の設定に左右されません。
クイックレポートの出力パスを変更せずにレコードやフィールド区切り文字だけを変更した場合,つまりQR SET DOCUMENT PROPERTY
でqr field separator
をセットした場合,新しい区切り文字はレポート設定に反映されません。これは仕様です。クイックレポートエディターは内部的にQR BLOB TO REPORT
をコールしていますが,コマンドで区切り文字だけを更新することができないためです。区切り文字を変更するためには,まず,出力パスを変更し,それから新しい設定を保存する必要があります。
Mac版のOracle Instant Client ODBCとunixODBCで登録したOracleのDSNには,4DのODBCで接続することができません。これは仕様です。4Dおよび4D ServerはunixODBCではなく,iODBCを使用していますが,Oracle ODBC DriverはiODBCのサポートを中止したようです。
collection.distinct()およびentitySelection.distinct()は,オブジェクトの集合に対して使用できるDISTINCT VALUESのようなものです。
値を集積したい属性またはプロパティのパスはドット記法で記述します。このパスが間違っていると,正しい値が返されません。
たとえば,obj
というオブジェクト型フィールドのprop
というプロパティからdistinct()
を取り出したい場合を考えましょう。
$values:=ds.Table_1.all().distinct("obj") //#1
$values:=ds.Table_1.all().distinct("obj.prop") //#2
#1のobj
というパスはオブジェクト型のフィールド自体を指します。
#2のobj.prop
という属性パスは,リレーション属性obj
でリンクされたデータクラスのprop
プロパティ,あるいはオブジェクト型のストレージ属性obj
内部のprop
プロパティを指します。しかし,ドキュメントに明記されているように,リレートされた属性をdistinct()
で参照することはできません。obj.prop
はストレージ属性なので,一見,シンタックスには問題がないように思われます。実際,obj.prop
がスカラー値であれば,正しいコレクションが返されます。また,obj.prop.value
のようにオブジェクト内部のスカラー値プロパティまでパスを延長すれば,やはり正しいコレクションが返されます。しかし,obj.prop
がオブジェクト型の場合,distinct()
は空のコレクションを返します。
entitySelection.distinct()
がサポートしていない属性パス,つまり
は,プロジェクションとcollection.distinct()
で取り出すことができます。
$values:=ds.Table_1.all().obj.distinct("prop")
obj
がdistinct()
のパス名ではなく,ORDAのパス名に含まれているのがポイントです。
ORDAでは,クラシック言語の自動リレーションの代わりにプロジェクションを使用し,リレーション先を参照するクエリを実行したり,逆にクエリからリレーション先のデータを参照したりすることができます。
エンティティセレクションをオブジェクト記法で発展させた場合,パスがリレーション名であればプロジェクションはエンティティセレクションを返しますが,パスがフィールド名であればコレクションを返します。つまり,ORDAのオブジェクト記法にはRELATE MANY SELECTION
やRELATE ONE SELECTION
だけでなくSELECTION TO ARRAY
のような働きもあるということです。
複数の属性からコレクションを作成したい場合はentitySelection.toCollection()
やentitySelection.extract()
を使用することができます。
entitySelection.extract()
はcollection.extract()
に似ていますが,v19で追加された新コマンドです。
View Proエリアは,SpreadJSテクノロジーを利用したWebアプリケーションです。操作感は標準的なデスクトップ版アプリケーションにかなり似ていますが,JavaScriptで動作しているため,いくつかの点に注意する必要があります。
たとえば,別のセル値を参照するセルがあり,参照されているセル自体も別のセルを参照しているような場合を考えてみましょう。
A | |
---|---|
1 | 10 |
2 | =関数()+A1 |
3 | =関数()+A2 |
4 | =関数()+A3 |
普通に考えれば,動的なセルの数は3個(A2, A3, A4)ですので,3回の計算をすれば良いように思えます。つまり,関数を3回だけ評価すれば良いはずです。しかし,実際に計測してみると関数は7回コールされます。なぜ4回も余計に呼び出されるのでしょうか。
ポイントは,JavaScriptの関数コールは非同期処理である,という点にあります。A1に値を入力すると,A2の関数が呼び出されます(1)。A2を参照するA3,A3を参照するA4の関数も連鎖的に呼び出されます(2, 3)。しかしながら,このタイミングで値が確定しているのはA1だけであり,A2, A3, A4は値が確定していません。見方を変えるなら,このタイミングでの2番と3番目の呼び出しは早すぎます。
(1)で呼び出された関数が値を返すと,A2の値が確定します。するとA2を参照するA3,A3を参照するA4の関数が再び連鎖的に呼び出されます(4, 5)。このタイミングで値が確定しているのはA2だけなので,5番目の呼び出しは早すぎます。
(2)で呼び出された関数が値を返すと,A3には不完全な値が代入されます。(2)の呼び出しは時期尚早だっためです。それでもA3を参照するA4の関数が連鎖的に再び呼び出されます(6)。この呼び出しも早すぎます。
(3)で呼び出された関数が値を返すと,A4に値が代入されます。この呼び出しは時期尚早だったので,値は不完全なものです。
(4)で呼び出された関数が値を返すと,ようやくA3の値が確定します。また,A3を参照するA4の関数が連鎖的に呼び出されます(7)。
(5)で呼び出された関数が値を返すと,A4に値が代入されます。この呼び出しは時期尚早だったので,値は不完全なものです。
(6)で呼び出された関数が値を返すと,A3に値が代入されます。この呼び出しは時期尚早だったので,値は不完全なものです。
(7)で呼び出された関数が値を返すと,ようやくA4の値が確定します。
まとめると,必要なのは1・4・7番目の呼び出しだけであり,2・3・5・6番目の呼び出しは無駄です。
無駄な関数コールを回避するテクニックとして,演算の順序を入れ替えることができます。
A | |
---|---|
1 | 10 |
2 | =A1+関数() |
3 | =A2+関数() |
4 | =A3+関数() |
これが効果的なのは,最初の連鎖ではA2およびA3の評価値が未定義(#VALUE!)であり,未定義を加算した値は未定義に決まっているので,そこで数式の評価が中断され,後続の関数が呼び出されないためです。それぞれのセルは参照先に値が代入されるたび連鎖的に再評価されますが,参照先のセルが未定義である間はそのセルに加算するべき値を求める関数の呼び出しはスキップされます。その結果,無駄な非同期コールを回避することができるというわけです。