次の方法で共有


日付の有効期間

コミュニティの関心グループが Yammer から Microsoft Viva Engage に移行されました。 Viva Engage コミュニティに参加し、最新のディスカッションに参加するには、「 Finance and Operations Viva Engage Community へのアクセスを要求する 」フォームに入力し、参加するコミュニティを選択します。

この記事では、日付に基づいて有効なデータエンティティとデータソースに関する情報を提供し、日付有効エンティティを作成する方法を示します。 また、日付の有効性が読み取りおよび書き込みアクティビティに適用される方法についても説明します。

データ エンティティを含む日付効果の高い機能には、さまざまな設計パターンが存在します。 これらのパターンは、次の 2 つの主要なカテゴリに分類されます。

  • 有効日エンティティ - エンティティには少なくとも 1 つの有効日データ ソースがあり、エンティティ自体も日付が有効です。
  • 非日付有効エンティティ – エンティティ自体は有効な日付ではありませんが、日付有効なデータ ソースが含まれています。

次のセクションでは、エンティティとその日付有効データ ソースの日付有効動作を制御するプロパティとメソッドについて説明します。

有効日のエンティティ

次のテーブルは、データ エンティティの日付を有効にする操作を制御するプロパティを示しています。

エンティティのプロパティ名 プロパティのノード 説明
ValidTimeStateEnabled デザイナーのデータ エンティティ ノード はい (またはいいえ) Yes は、エンティティの日付を有効にします。 エンティティには、ValidFrom および ValidTo フィールドが必要です。 これらのフィールドは、日付有効データ ソースの ValidFrom フィールドと ValidTo フィールドにマップされます。 値 No は、エンティティのデータ ソースである日付有効テーブルに対する日付の有効性の適用を無効にしません。
ValidTimeStateKey データ エンティティ ノードの下の、キー>EntityKey はい (またはいいえ) Yes は、この特定のエンティティに日付有効値を適用するキーを識別します。

リーディングアクティビティ

データ エンティティ レベルで日付の有効性を設定すると、エンティティからの読み取りはテーブルからの読み取りと同じように動作します。 エンティティには、システムが読み込み中に日付フィルターを適用する ValidFrom および ValidTo フィールドがあります。

クエリモードとX++ SQLのvalidtimestateキーワード

日付有効なエンティティは、X++ validtimestate キーワードの使用方法が異なる次の 3 つのクエリモードをサポートします。

  • 既定のモードselect * from FMVehicleRateEntity; // X++ SQL.を使用して現在のレコードを返します。
  • AsOfDate モード – 指定した日付に対して有効なレコードを返します。 select validtimestate(d1) * from FMVehicleRateEntity;
  • AsOfDateRange モード – 指定した日付範囲に対して有効なレコードを返します。 select validtimestate(d1,d2) * from FMVehicleRateEntity;

重要: 日付が有効なエンティティではなく、日付が有効なデータ ソースを持つデータ エンティティの場合は、既定のクエリ モードのみ使用できます。 この概念については、この記事の後半で説明します。

データ ソース レベルで日付フィルターを適用する

一部のシナリオでは、データ ソース レベルで、データ エンティティの外部で日付有効なフィルター処理が必要です。 たとえば、顧客エンティティ (CustTableTestEntity) にはデータ ソースとして CustTable および LogisticsPostalAddress が含まれています。LogisticsPostalAddress は日付の有効なテーブルであり、CustTable は通常のテーブルです。 顧客エンティティの目的は、顧客とそのアクティブなプライマリ アドレスのリスト (プライマリ アドレスがある場合) を含めることです。 したがって、顧客エンティティ自体は日付有効ではありませんが、データ ソースの 1 つに日付フィルターが必要です。 この場合は、エンティティ ValidTimeStateEnabled をマークしないでください。 代わりに、データ ソースに [日付フィルターの適用] プロパティを追加します。 [ 日付フィルターの適用 ] の値を [はい] に設定すると、そのデータ ソースに日付フィルターが自動的に適用されます。 次のテーブルでは、データ エンティティの有効日データ ソースの有効日動作を制御するプロパティについて説明します。

データ ソースのプロパティ名 プロパティのノード 説明
日付フィルターの適用 エンティティの特定のデータ ソースのノード はい (またはいいえ) 読み取りの場合、このプロパティは、システムがエンティティ データ ソースに日付フィルターを適用するかどうかを制御します。 この場合は、データ ソース ValidTimeStateEnabled をマークします。 このプロパティ値は、エンティティ自体が日付有効であるかどうかにかかわらず有効です。 書き込みで、このプロパティは影響を与えません。

この記事では、これらの日付が有効なプロパティの使用方法とそれらの相互作用について説明します。

読み取り用の状態行列

このセクションは、データ エンティティからの読み取りのみに関係します。 次の参照マトリックスのペアでは、データ エンティティとそのデータ ソースの間に存在できる日付有効状態の組み合わせについて説明します。 各テーブルには、4 つのクラスが含まれ、各ケースでは、2 つの異なるターゲットについて説明します。 理解しておく必要がある主要なポイントを次に示します。

  • エンティティからの任意の読み取りにおいて、クエリモードはエンティティと有効日データ ソースの両方で同じです。
  • エンティティが有効な日付でない場合、クエリ モードは既定のモードに制限されます。 したがって、日付が有効なデータ ソースは現在の日付のみにアクセスされます。
  • 日付有効データ ソースで、[ 日付フィルターの適用 ] プロパティを [いいえ ] に設定して、データ ソースが過去、現在、および将来のすべてのデータを返すようにします。
  • OData の場合、日付有効フィルターはデータ エンティティに適用されません。 ただし、データ ソースのフィルターはすべてのコード パスに適用されます。

A. エンティティは有効日である、なぜならば ValidTimeStateEnabled = はい

データソース日付が有効です

データ ソース日付が有効ではない

日付フィルターの適用 = はい

  • エンティティ 日付フィルターが適用されます。 すべてのクエリ モードがサポートされています。
  • データ ソース: フィルターが適用されます。 クエリ モードはサポートされていますが、モードはエンティティのコードと同じです。

有効日の対象外のデータ ソースは影響しません。

日付フィルターの適用 = いいえ

  • エンティティ 日付フィルターが適用されます。 すべてのクエリ モードがサポートされています。
  • データ ソース: 日付フィルターは適用されません。

有効日の対象外のデータ ソースは影響しません。

B. エンティティは日付で有効ではありません、これは ValidTimeStateEnabled = いいえ によるものです。

データ ソース日付によって有効

データ ソース日付が有効ではない

日付フィルターの適用 = はい

  • エンティティ 日付フィルターが適用されません。
  • データ ソース: 日付フィルターが適用されます。 既定のクエリ モードのみサポートされ、X++ validtimestate キーワードは省略されます。

有効日の対象外のデータ ソースは影響しません。

日付フィルターの適用 = いいえ

  • エンティティ 日付フィルターが適用されません。
  • データ ソース: 日付フィルターは適用されません。

有効日の対象外のデータ ソースは影響しません。

次のスクリーンショットは、[ 日付フィルターの適用] プロパティが [はい] に設定されている状態を示しています。 そのため、日付フィルターは アドレス データ ソースの読み取りに適用されます。

日付フィルターの適用 = はい。

活動の記述

このセクションでは、有効日エンティティとその有効日データ ソースの動作を設定するオプションについて説明します。 まず、日付有効テーブルの概念を確認し、日付有効エンティティと比較します。 日付有効テーブル: 日付有効テーブルにデータを挿入または更新する場合は、テーブル バッファーで xRecord.validTimeStateUpdateMode メソッドを呼び出すことができます。 このメソッドは、ValidTimeStateUpdate 列挙型の要素を受け入れます。 使用可能な要素値を次に示します。

  • 新しい時間の期間を作成
  • 訂正
  • EffectiveBased

日付有効エンティティ: これに対し、日付有効データ エンティティにデータを挿入または更新する場合は、エンティティ レベルで validTimeStateUpdateMode メソッドを使用しないでください。 書き込みについては、データエンティティは日付有効処理をテーブルレベルに委ねます。 エンティティ データ ソースの Valid Time State Update プロパティを使用して、データ エンティティの各データ ソースに使用する validTimeStateUpdateMode メソッドを指定します。

日付有効なエンティティを作成しています

このセクションでは、有効日のあるエンティティを作成する方法を示します。

新しいプロジェクトの作成

  1. [ファイル>新規作成>プロジェクトを選択して新しいプロジェクトを作成します。

  2. ソリューション エクスプローラーで、プロジェクトを右クリックしてから [プロパティ] を選択します。 プロジェクトの プロパティ ページ ダイアログ ボックスが開きます。

  3. [ビルド時にデータベースを同期する] プロパティの値を True に変更し、[OK] を選択します。 このプロパティは、プロジェクトごとに 1 回だけ設定します。

    ビルド上にデータベースを同期 = True。

プロジェクトへの新しいデータ エンティティの追加

FMVehicleRateEntity という名前の新しいエンティティを作成し、プロジェクトに追加します。

  1. 左側のウィンドウで、[ Microsoft Dynamics 365 Artifacts] を選択し、メイン ウィンドウの左側の列にある [データ エンティティ ] を選択します。

  2. [] を選択し、[] を追加します。 データ エンティティ ビュー ウィザードが起動します。

  3. 次のスクリーンショットに示すように、作成するデータ エンティティのプロパティ値を指定します。 最も重要なフィールドは、FMVehicleRate を選択する プライマリ データ ソース です。

    プライマリ データ ソース = FMVehicleRate。 [ 次へ] を選択します。

  4. プライマリ データ ソース、FMVehicleRate からエンティティにフィールドを追加します。

  5. すべてのフィールドを選択し、[ 完了] を選択します。

    新たに追加されたフィールドをすべて選択。

    項目は ソリューション エクスプローラーでプロジェクトに追加されます。

    ソリューション エクスプローラー内のプロジェクト。

プロジェクトの構築

  1. [ ビルド>ビルド ソリューション ] を選択してプロジェクトをビルドします。
  2. ビルドにエラーが含まれていないことを確認します。 この段階では、警告は許容されます。

プロパティ値の検証

  • ソリューション エクスプローラーFMVehicleRateEntity ノードを選択し、[プロパティ] ウィンドウの値と比較して FMVehicleRateEntity エンティティのプロパティを検証します。

    プロパティ ウィンドウの値。

エンティティの日付を有効にする

  1. ソリューション エクスプローラーでFMVehicleRateEntity ノードを右クリックし、[開く] を選択します。 エンティティのデザイナーが中央のウィンドウに表示されます。

    FMVehicleRateEntity エンティティのデザイナー。

  2. 時間状態が有効であるかどうかを検証するプロパティの値をはいに変更します。

    時間状態が有効であるかどうかを検証する = はい。

日付有効データソースの有効時間状態更新プロパティを構成する

  • FMVehicleRate データ ソースを選択し、有効時間状態の更新 プロパティを CreateNewTimePeriod に設定します。

    有効時間状態の更新 = CreateNewTimePeriod。

プロジェクトをテスト

  • プロジェクトを再度構築し、次の X++ コードを実行してプロジェクトをテストします。
/// <summary>
    /// Runs the class with the specified arguments.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>
    public static void main(Args _args)
    {
        FMVehicleRateEntity FMVehicleRateEntity;
        FMCarClass          vehicle;
        FMVehicleModel      model;
        FMVehicleRate       vehicleRateTable;
        TransDate           d1=1\1\1999,d2=31\12\2014;

        ttsbegin;

        select count(RecId) from FMVehicleRateEntity;
        info(strfmt("Entity - Valid today before insert %1",FMVehicleRateEntity.RecId));

        select count(RecId) from vehicleRateTable;
        info(strfmt("Table - Valid today before insert %1",vehicleRateTable.RecId));

        select firstonly model;

        vehicle.VehicleModel = model.RecId;
        vehicle.VehicleId = "TestV1001";
        vehicle.insert();

            if (vehicle)
            {
                FMVehicleRateEntity.clear();
                FMVehicleRateEntity.FMVehicle_VehicleId = vehicle.VehicleId;
                FMVehicleRateEntity.ValidFrom = d1;
                FMVehicleRateEntity.ValidTo = d2;
                FMVehicleRateEntity.RatePerDay = 100;
                FMVehicleRateEntity.RatePerWeek = 600;
                FMVehicleRateEntity.insert();

                // Should increase by one as compared to before insert numbers
                select count(RecId) from FMVehicleRateEntity;
                info(strfmt("Entity - Valid today after insert %1",FMVehicleRateEntity.RecId));

                // Should increase by one as compared to before insert numbers
                select count(RecId) from vehicleRateTable;
                info(strfmt("Table - Valid today after insert %1",vehicleRateTable.RecId));

                // New record should show in count
                select validtimestate(d1) count(RecId) from FMVehicleRateEntity;
                info(strfmt("Entity - Valid 1999 %1",FMVehicleRateEntity.RecId));

                // New record should show in count
                select validtimestate(d1) count(RecId) from vehicleRateTable;
                info(strfmt("Table - Valid 1999 %1",vehicleRateTable.RecId));

                // update newly created record
                // This should split record into two - 2009 to Today, today to 2014
                // Split happens because of mode in saveEntityDatasource
                select forupdate validtimestate(d1,d2) FMVehicleRateEntity 
                     where FMVehicleRateEntity.FMVehicle_VehicleId == vehicle.VehicleId &&
                           FMVehicleRateEntity.ValidFrom == d1 &&
                           FMVehicleRateEntity.ValidTo == d2;
                FMVehicleRateEntity.RatePerDay = 200;
                FMVehicleRateEntity.update();

                // validate the split
                while select validtimestate(d1,d2) FMVehicleRateEntity
                     where FMVehicleRateEntity.FMVehicle_VehicleId == vehicle.VehicleId
                {
                    info(strfmt("Entity - %1 to %2 , RatePerDay-%3, RatePerWeek-%4",
                            FMVehicleRateEntity.ValidFrom,
                            FMVehicleRateEntity.ValidTo,
                            FMVehicleRateEntity.RatePerDay,
                            FMVehicleRateEntity.RatePerWeek));
                }
                ttsabort;
            }
        }