【PowerAppsモデル駆動型アプリ】JavaScriptでDataverseのデータ取得時に発生した問題点とその対応について

【PowerAppsモデル駆動型アプリ】JavaScriptでDataverseのデータ取得時に発生した問題点とその対応について

9月 13, 2024

記事の監修

S.Sato

記事の監修


S.Sato

マネジメント&イノベーション事業部 開発部/2グループ グループマネージャー
資格:Microsoft Offiece Specialist Master 2007、ITパスポートなど

2022年よりMicrosoft365とPowerPlatformの案件を担当。
それ以前は業務・Web系システムを要件定義からリリースまでの開発に従事。
IT業界歴15年の経験を活かし、PJを牽引し後続の育成にも力を注ぐ。
趣味は散歩で、思考が煮詰まった際には、近所の緑道を散歩し、新たな発見や自然からのインスピレーションを受けている。

無料ご相談受付中 まずはお気軽にご相談ください

Contents

目次

1. やりたいこと

今回は、新規登録時、都道府県テーブルのコードカラムを降順でソートして、先頭1件のデータを取得後、届出都道府県(検索列)の項目にデフォルト表示していきます。

2. 都道府県テーブルのデータ

3. JavaScriptでの実装

  
/**
 * 都道府県テーブルからコードの降順でソートして、先頭1件を取得後、都道府県1行テキストに設定します。
 */
async function sampleSort(excutionContext) {
    const formContext = excutionContext.getFormContext();
    const name = formContext.getAttribute("crf6e_name").getValue();

    // プライマリ列の値の有無で新規登録か編集かを判断(crf6e_nameがnull→新規登録、nullでない→編集)
    if (name == null) {
        // データ取得時のソート条件
        const filter = `?$orderby=crf6e_code desc&$top=1`;

        // 検索先テーブルのセット名(テーブル>ツール>セット名)とフィルターをセット
        var data = await this.fetchData("crf6e_todofukens", filter);
        if (data !== null) {

            // 検索列に設定する対象レコードの情報
            var lookupValue = [{
                id: data.value[0].crf6e_todofukenid, // 対象レコードのGUID
                name: data.value[0].crf6e_meisyo,    // 対象レコードの表示名
                entityType: "crf6e_todofuken"        // 対象エンティティ名
            }];

            formContext.getAttribute("crf6e_todokede_todofuken").setValue(lookupValue);
        }
    }
}

/**
 * HTTPリクエストで検索
 */
this.fetchData = async function (entityName, filter) {
    const webApiUrl = Xrm.Utility.getGlobalContext().getClientUrl() + "/api/data/v9.2/";
    let url= `${webApiUrl}${entityName}${filter}`
    try {
        const response = await fetch (url, {
            headers: {
                "OData-MaxVersion":"4.0",
                "OData-Version":"4.0",
                "Accept":"application/ json",
                "Content-Type":"application/ json; charset=utf-8"
            }
        });
        const data = await response.json();
        return data;
    } catch {
        throw console.error;
    }
}

4. 期待値

新規登録時、「47:沖縄県」を取得して、届出都道府県の検索列にデフォルト表示します。

5. 問題点

うまくソートされず、想定外のデータ(9:栃木県)が取得表示されてしまいます。

6. 原因

都道府県テーブルのコードカラムが1行テキストとなっているためです。

7. 対応

対応その1

都道府県テーブルの列を削除して、属性が1行テキストではなく整数で作り直しました。

メリット :ソースを修正する必要がありません。
デメリット:例に挙げている都道府県テーブルが共通テーブルとして利用されている場合、他のソースや使用状況など影響範囲を確認してから適用する必要があります。

対応その2

Dataverseの属性は修正せず、コードカラムの値を修正しました。
0 ~ 9までの値を、00 ~ 09 に変更していきます。(ゼロパディングする)

メリット :ソースを修正する必要がありません。
デメリット:例に挙げている都道府県テーブルが共通テーブルとして利用されている場合、プロジェクトでのルールを確認してから適用する必要があります。

対応その3

JavaScriptでmapやsortメソッドを使ってソートさせました。 

メリット :Dataverseの定義やデータを変更する必要がありません。
デメリット:ソースを修正するが必要あります。(対応1・2と比較して時間を要する)

/**
 * 都道府県テーブルからコードの降順でソートして、先頭1件を取得後、都道府県1行テキストに設定します。
 */
async function sampleSort(excutionContext) {
    const formContext = excutionContext.getFormContext();
    const name = formContext.getAttribute("crf6e_name").getValue();

    // プライマリ列の値の有無で新規登録か編集かを判断(crf6e_nameがnull→新規登録、nullでない→編集)
    if (name == null) {
        // 検索先テーブルのセット名(テーブル>ツール>セット名)をセット
        var data = await this.fetchData("crf6e_todofukens", "");
        if (data !== null) {
            // データをフィルタリングして、数値のみを抽出
            var numericResults = data.value
                .map(function (record) {
                    var numberValue = parseFloat(record["crf6e_code"]); // 数値に変換
                    return {
                        value: isNaN(numberValue) ? null : numberValue, // 数値でない場合は null を設定
                        record: record
                    };
                })
                .filter(function (item) {
                    return item.value !== null; // 数値に変換できたものだけ残す
                });

            // 数値順にソート(降順)
            numericResults.sort(function (a, b) {
                return b.value - a.value;
            });

            // ソートされたデータを処理(1件目を取得して表示)
            if (numericResults.length > 0) {
                console.log("最も大きな値のレコード:", numericResults[0]);

                // 検索列に設定する対象レコードの情報
                var lookupValue = [{
                    id: numericResults[0].record.crf6e_todofukenid, // 対象レコードのGUID
                    name: numericResults[0].record.crf6e_meisyo,    // 対象レコードの表示名
                    entityType: "crf6e_todofuken"                   // 対象エンティティ名\
                }];

                formContext.getAttribute("crf6e_todokede_todofuken").setValue(lookupValue);
            } else {
                console.log("数値が含まれるデータがありません。");
            }
        }
    }
}

/**
 * HTTPリクエストで検索
 */
this.fetchData = async function (entityName, filter) {
    const webApiUrl = Xrm.Utility.getGlobalContext().getClientUrl() + "/api/data/v9.2/";
    let url= `${webApiUrl}${entityName}${filter}`
    try {
        const response = await fetch (url, {
            headers: {
                "OData-MaxVersion":"4.0",
                "OData-Version":"4.0",
                "Accept":"application/ json",
                "Content-Type":"application/ json; charset=utf-8"
            }
        });
        const data = await response.json();
        return data;
    } catch {
        throw console.error;
    }
}

8. 所感

実際の現場では、都道府県テーブルではないですが、共通テーブルであったため列の作り直しができずかつ最小限の工数での対応ということで、対応その2をお客様に合意をとって実施しました。
文字型の属性の場合、OracleやMySQLなど同様の現象が発生するため、ちょっとしたTipsとなりますが、対応その2を覚えておくと役立つかもしれません。

無料ご相談受付中 まずはお気軽にご相談ください

Microsoftを導入してコスト効率をよくしたい

Microsoftを導入して
コスト効率をよくしたい

Microsoftに関して気軽に聞ける相談相手が欲しい

Microsoftに関して
気軽に聞ける相談相手が欲しい

Microsoftを導入したが、うまく活用できていない・浸透していない

Microsoftを導入したが、うまく活用できていない・浸透していない

社内研修を行いたいが社内に適任者がいない

社内研修を行いたいが
社内に適任者がいない

Bizwindでは、Microsoft導入支援事業などを中心に
IT・DX推進に関する様々なご相談を承っております。
ご相談・お見積りは無料です。まずはお気軽にお問い合わせください。

無料ご相談はこちら

ビズウインドでは、 様々な課題でお困りの お客様に対して、 無料相談を実施しております。

無料相談に申し込む

担当者に今すぐ質問する

簡単な情報入力でBizwind担当者が
お電話にて回答いたします!

すぐに電話で質問
日時指定で折り返し

以下の内容をご記入・送信ください。
確認次第お電話を差し上げます。

    以下の内容をご記入・送信ください。
    確認次第お電話を差し上げます。