次の方法で共有


保存されたビューを十分に活用するフォームの作成

保存されたビューは、財務と運用アプリケーションにおけるパーソナライズ機能の中でも重要な拡張機能です。 保存されたビューの記事では、この機能の総合的な詳細情報を提供します。ここでは、保存されているビューの技術的な要素のみでなく、ビューの影響を受ける可能性のあるフォーム開発の側面も対象とします。

「ユーザー視点」のページ

従来、パーソナライゼーションには、1セットにつきモデル化されたフォームに対する 1:1 のリンクが含まれています。 多くのページでは、これはユーザーにとって理にかなっています。ユーザーが知覚するページとフォームをモデル化した方法とが合致するためです。 ただし、場合によっては 1:1のリンクとモデル化されたフォームが、パーソナライゼーションに対して直感的ではなく、わかりにくい場合があります。これはユーザーがモデル化されたフォーム間の境界に対して注意を払っていないためです。

保存されたビューには、このような混乱を解消するべく 「ユーザー視点」 ページ上でビューを作成できる機能があります。 したがって、ユーザーはパーソナライゼーションを適用する方法とタイミングを知るために、フォームがどのようにモデル化されているかを理解する必要はありません。 たとえば、次の2つのシナリオを考えてみます。

  • 単一のモデル化されたフォームにある複数の「ユーザー視点」ページ: マスター詳細およびトランザクション詳細フォーム (たとえば CustTablePurchTable フォームなど) は一般的に、グリッド ページと詳細ページからなる複数の「ユーザー視点」ページで構成されています。

    これはユーザーはリストから詳細への切り替えることによってフォームの境界を超えていることに気づかない (気づく必要もないのですが) ためです。詳細フォームでのビューのサポートは、グリッド部分と詳細部分で別々にビューを定義できるように、異なる方法で処理されています。 つまり、「グリッド」と「詳細」のビュー セレクターでは、異なる一連の使用可能なビューを表示できます。 これらのフォームで対応している特殊ケースのビューを使用することで、「グリッド」ビューによるビュー定義でのフィルター適用も可能になります。その一方で「詳細」ビューではパーソナライゼーションのみが必要です。

  • 単一の「ユーザー視点」ページに複数のモデル化されたフォーム: モデル化されたフォーム (FactBox またはフォーム パーツ) にサブフォームを埋め込む機能により、複数のモデル化されたフォームが単一の「ユーザー視点」ページに対応している場合があります。 たとえば、 すべての顧客 ページの詳細の部分には、情報ボックスの数と、フォームパーツの内容情報を取得する2つのファストタブがあります。 従来のパーソナライゼーションでは、ユーザーの期待に反して、CustTable フォームのパーソナライゼーションのエクスポートに任意の FactBox のパーソナライゼーションや住所または連絡先情報のクイック タブ内で行われたパーソナライゼーションも含まれていませんでした。 これと同様にユーザーが予期しないこととして、これらのサブフォームで行われたパーソナライゼーションはすべて、該当するフォームパーツが使用されているアプリケーションの他の部分にも反映されます。 例えば すべての顧客 ページ内の 住所 クイックタブに変更を加えると、変更した内容が すべての仕入先 ページの 住所 クイックタブにも反映されます。

    ビューでは、フォームパーツのパーソナライゼーションの範囲が、ユーザーの期待に合うように変更されています。 特にサブフォームのパーソナライゼーションは、作成された基本フォームに関連付けられるようになっています。 つまり、 すべての顧客 の詳細ページからビューをエクスポートすると、元となっている CustTable フォームのパーソナライゼーションと、FactBox またはフォーム上の該当部分でモデル化されたフォームパーツからの個人設定が含まれます。 同様に、 すべての顧客 ページ内の 住所 ファストタブ (フォームパーツ) で行ったパーソナライゼーションは、そのフォームパーツを使用している他のフォームには反映されません。

これらはパーソナライゼーション・サブシステムに対する高度な技術的変更であり、ビューが使用可能となっている場合にのみ利用できます。 これらの変更は、ユーザーがビューに関して予測可能で理解しやすいなエクスペリエンスを確実に得るために重要です。

ビューのサポート

フォームのスタイルは、ビューのサポートレベルによって決まります。

  • ビューには、こちらのフォーム タイプのクエリが含まれています。

    • リスト ページ (Design.Style = ListPage)
    • 簡易リスト (Design.Style = SimpleList)
    • マスター詳細とトランザクション詳細のグリッド部分 (Design.Style=ListPage)
    • タスク シングルとタスク ダブルのページ (Design.Style または Design.Pattern = TaskSingle または TaskDouble)
  • ビューには、こちらのフォーム タイプのクエリは含まれません。

    • このセクションで説明したその他のフル ページ フォーム

    • ワークスペース

      "ワークスペースの保存済みビュー サポート" 機能を使用すると、モデリング されたワークスペースとユーザー作成のワークスペースの両方で保存済みビューを定義および共有できます。

    • ダイアログ

    • [マスタの詳細] フォーム と [トランザクションの詳細] フォーム の詳細

  • ビューは現在、次のフォーム タイプでサポートされていません。

    • ダッシュボード
    • ドロップダウンダイアログ、ルックアップ、強化されたプレビューなどの、副次的なフォーム

フォームを変更してビューを完全に活用する

ほとんどのフォームは保存されたビューで十分に機能しますが、フォー上でビューが問題なく想定どおりに機能するためには、フォームロジックへの変更が必要となる部分も存在します。 以下は、新しいフォームを開発する際に留意すべき重要な項目です。

カスタム フィルター

カスタム フィルターは、フォームをモデル化され、クエリが変更されるコントロールです。 ビューとこれらのカスタム フィルタの統合が実装されていない場合、ユーザーには最適でないユーザー エクスペリエンスが必要です。 たとえば、カスタム フィルターを使用した後にビューが未保存の変更を行ったとマークされていない場合や、カスタム フィルター値が現在のビューまたはクエリに常に揃えされていない場合があります。

フォームの所有者は、次の 2 つの方法を活用して、カスタム フィルターのより良い経験を提供できます。 これらの方法は、保存したビューでカスタム フィルター サポートを改善するために特別に導入されました。

  • パブリック 無効 queryFiltersChanged(): この新しいメソッドは、クエリへの変更後、システムによってクエリが再実行される場合に呼び出されます (ビューの負荷やシステムのフィルター処理メカニズムが使用される場合など)。 したがって、カスタム フィルター コントロールを使用すると、最も最近実行したクエリを尋問して適切なフィルターを検索し、そのクエリが適切に反映するようにその値を更新することができます。
  • element.formCustomFilterChanged(): この新しい API は、ユーザーの代わりにクエリを変更した場合、カスタム フィルター コントロールで呼び出されます。 呼び出されているとき、システムはビュー定義に未保存の変更をマークします。 推奨される方法として、コントロールに対する変更によってクエリが直ちに更新される場合や、1 つ以上のカスタム フィルターの調整で変更を有効にするボタンが必要な場合に、ボタン クリックのカスタム フィルタ用にコントロールの modified() 方法の最後の API を呼び出します。

相対フィルター値

フォームでは、ページが読み込まれたときに、相対的なフィルター条件を使用して適切な情報の取得が必要となる場合があります。 たとえば、通常はフィルター条件を使用して、現在のユーザー、現在の日付、および現在の法人のデータを制限する必要があります。 フォームでフィルターを特定の値にハードコーディングすると、そのフィルターで保存されたビューは、目的のデータを表示したり、他のユーザーと共有したりする際に問題が発生する場合があります。 たとえば、あるフォームで "現在の日付" フィルターを特定の日付にハードコーディングし、そのクエリをビューに保存し、そのビューを別のユーザーと共有するとします。 この場合、ビューは現在の日付ではなく過去のハードコーディングされた日付からデータを取得しようとするため、予期しない結果が生成される可能性があります。 またはフィルター条件が、現在のユーザーを表すことを目的としていたが、特定のユーザーに対してハードコーディングされたとします。 この場合、ビューが別のユーザーと共有されると、そのユーザーがビューを読み込むかインポートしようとするときにエラーが発生することがあります。

この状況を回避するには、相対的なフィルター条件があるフォームでは、SysQueryRangeUtil メソッドを財務と運用の高度なフィルター構文、特にフィルター値が括弧で囲まれた構文と組み合わせて使用するフィルター値を含める必要があります。 フィルター メソッドの評価は、クエリが実行されるまで延期されます。 したがって、相対的なフィルター処理条件をビューで使用し、問題なくユーザー間で渡すことができます。 ユーザー インターフェイスのユーザーは、この同じ構文を "matches" 演算子と併用して、同じ効果を実現できます。

明示的な例として、ユーザー フィールドのフィルター条件を含むフォームを考慮します。 フィルター値が currentUserId() に設定されている場合、関数は直ちに評価され、ハードコーディングされたユーザー名がクエリで使用されます。 フィルター値に単純な変更を加えたため、その値が代わりに (currentUserId()) に設定された場合、関数はクエリ定義に保存されます。 したがって、この条件を持つビューはビューに保存され、問題なく他のユーザーに渡すことができます。

次にいくつか典型的な例を挙げます。

Description フィルター値
現在のユーザー (currentUserId())
現在の法人 (currentCompany())
今日 (Day(0))
昨日 (Day(-1))

相対的な日付クエリについては、SysQueryRangeUtil メソッドを使用する詳細な日付クエリを参照してください。

ビューによる既定のクエリの処理に関する改善された開発者制御

メニュー項目クエリに対する既定の表示優先順位の指定

デフォルトでは、クエリが関連付けられているメニュー項目を使用してページに移動すると、既定のビューのクエリではなくメニュー項目のクエリが実行されます。 この場合、ユーザーに対して、既定のビューのクエリを強制的に読み込むアクションを含む情報メッセージが表示されます。

バージョン 10.0.32 では、フォーム開発者が個々のフォームに対してこの既定のシステム動作を上書きするために新しい拡張子ポイントが追加されました。 具体的には、フォームのライフ サイクルの中で、フォームのライフ サイクル中の init()super() の前に FormRunPersonalizationSettings クラスから EnableSavedViewQueryPriority メソッドを呼び出して、メニュー項目のクエリに対する既定のビューのクエリ優先順位を設定できます。

この動作が有効な場合、システムはライフサイクルの run() 部分中に、既定のビューのクエリをメニュー項目のクエリとマージします。

クエリの差し込みエラーの手動処理

フォームの読み込み中に既定のビューのビューの一部として、既定のビューに関連付けられているクエリは、既定のフォームのクエリ (EnableSavedViewQueryPriority メソッドが呼び出された場合の既定のメニュー項目のクエリ) を含む結合プロセスを通過します。 クエリを結合できない場合、ビューのクエリとフォームの (またはメニュー項目の) クエリの間の、システムの視点では非互換性を示します。 これは互換性のないエラーが発生する可能性があります。たとえば、非表示のフィルタまたはロックされているフィルタが既に適用されているフィールドにフィルタがビューによって追加される場合です。

フォームには追加のコンテキストが含まれる場合があります。これにより、ユーザーの期待に応じてビューのクエリを正しくマージできます。 バージョン 10.0.32 では、必要に応じてこれらの調整を行う代替方法として、新しい拡張ポイントが追加されました。 具体的には、標準のクエリ結合が失敗した場合、開発者は OnFailureQueryPersonalizationApply メソッドの実装を置き換え、ターゲット クエリに対して必要な変更を行うことができます。 この _sourceQuery パラメータはビューの _targetQuery クエリを提供し、クエリの個人用設定を持つビューが読み込まれたときに実行されるクエリを表します。

[Replaceable]
public boolean OnFailureQueryPersonalizationApply(Query _sourceQuery, Query _targetQuery)
{
    return false;
}

ビューからフォームをアプトアウト

この方法では、一般にインストールは推奨されませんが、バージョン 10.0.25 では、開発者は必要に応じて、保存したビューのサポートから個々のフォームを選択できます。 この場合、フォームでビュー セレクターは使用できず、公開機能もありません。

保存済みビュー サポートからオプトするには、フォームの init() 方法の super() 前に、次のコードを入力します。

this.disableSavedViewsOnForm();

ビューに悪影響を与える可能性があるコード

フォームのスタートアップ サイクルにて X++ コードの遅延が発生すると、ビューがユーザーの期待どおりに機能しない可能性があります。 特に、次の項目にご注意ください:

  • executeQuery()super() の後、または run()super() の後のクエリの変更により、ビューのクエリ側面が無視される可能性があります。
  • run()super() の後にフォームを変更すると、一部のユーザー パーソナライゼーションが既定ビューに誤って適用される可能性があります。

二次リストのページ

長期的には、ビューがモデル化された二次リストのページを置き換える計画です。

  • 通常、保留中の得意先などのセカンダリ リスト ページは、同じフォームを指すが異なるクエリを持つメニュー項目です。 クエリ内で渡されるメニュー項目は、既定のビューで定義されているクエリを上書きする可能性があり、これらのエントリ ポイントは、ユーザーがこれらのメニュー項目のいずれかを使用してフォームに移動しても既定のビュー クエリは実行できないので、ユーザーの混乱を引き起こす可能性があります。 現在の長期計画では、セカンダリ リスト ページを廃止 (非推奨) にして、それらをビューに移動させます。
  • ユーザがフォーム キャプション (「すべての顧客」など) とビュー名 (「お客様」など) を混同しないように、フォーム キャプションを対応するエンティティの名前に変更することを検討してください。 たとえば、フォーム キャプションとして 「すべての顧客」 や 「すべての販売注文」 を使用する代わりに、「顧客」または「販売注文」へ変更します。

フォーム読み込みパフォーマンスの向上

従来、パーソナル化は、フォーム クエリの最初の実行後、run()super() 中に適用されてきました。 このようなタイミングにより、パーソナル化に追加フィールドが含まれている場合、クエリが再実行され、追加のデータがフェッチされる可能性があります。 保存されたビューでは、既定のビューに関連付けらたパーソナル化が以前と同じタイミングで適用されました。 ただし、フォームの読み込み中に 1 つ余分実行される可能性が増加するのは、既定のビューにクエリに影響を与えるパーソナル化が含まれている場合、追加の実行が発生したためです。 パーソナル化には、フィールドの追加、フィルタの変更、並べ替えの変更が含まれます。

バージョン 10.0.29 から、保存したビューのパフォーマンス向上機能を使用して、クエリに影響を与えるパーソナル化を含む既定のビューのフォーム読み込みパフォーマンスを向上させることができます。 この機能は、既定のビューの一部が適用されると変更され、フォームで最初に super()run() でクエリが実行されると、すべてのクエリ関連の変更 (追加フィールド、変更フィルタ、変更並べ替えなど) が設定されます。 したがって、複数回実行される可能性はなく、フォーム クエリはフォームの読み込み時に 1 回だけ実行されます。 これにより、フォームの読み込み時間を短縮できます。

ただし、既定のビューに関連付けられているいくつかのパーソナル化が適用されると、この機能が変更され、ページの動作が変わる可能性があります。 特に、フォームの OnPostRun イベント ハンドラーでクエリに影響を与えるコードは、ビュー クエリの実行前ではなく実行後に実行されます。 したがって、機能を有効にする前に、フォームの OnPostRun イベント ハンドラーでクエリに影響を与えるコードを評価する必要があります。