Dynamics 365 Business Centralでページを作ってみる

# 前置き
最近Dynamics 365 Business CentralのAL言語でページを作ったので、その時学んだことを備忘録的に書く初心者向けの記事になります。

# Dynamics 365 Business Central (D365BC) とは
色々な機能がありすぎて説明しきれないので、Microsoftのページを見てみてください。
[Business Central | Microsoft Dynamics 365](https://www.microsoft.com/ja-jp/dynamics-365/products/business-central)
本記事ではD365BCと略します。

# AL言語とは
AL言語とはD365BCのデータを操作したり、既存のテーブル・ページ・機能を拡張したりして、D365BCを自社のビジネスに合わせてカスタマイズするための言語です。
[Programming in AL - Business Central | Microsoft Learn](https://learn.microsoft.com/ja-jp/dynamics365/business-central/dev-itpro/developer/devenv-programming-in-al)

# AL言語の大変なところ
上記のMicrosoft公式のAL言語のページを見ていただければわかると思いますが、基本的に英語のドキュメントしかありません。
あと、個人で触る人が少ないであろうためか、ネットを検索しても必要な情報が中々見つけらなかったりします。

ただ、Microsoft Larnのトレーニングは日本語で提供されている物もあるので、入門者の方はそちらで学習してみると良いかもしれません。
ラーニングパスへのリンクを張っておきます。
- [Microsoft Dynamics 365 Business Central 向けの AL プログラム言語を使用してアプリケーション基盤を学習する](https://learn.microsoft.com/ja-jp/training/paths/application-foundation-al-language/)


# 開発環境を作る
Visual Studio CodeにMicrosoft公式が提供している[AL言語拡張](https://marketplace.visualstudio.com/items?itemName=ms-dynamics-smb.al)をインストールします。
[Get started with AL - Business Central | Microsoft Learn](https://learn.microsoft.com/ja-jp/dynamics365/business-central/dev-itpro/developer/devenv-get-started)
コマンドパレットで ```>AL: Go!``` と入力して実行するとプロジェクトが作られます。 

環境への接続等については今回は割愛します。


# 画面を作ってみる
AL言語の実践ということで、リストページを作ってそのリストを別の画面から使用する構成で作ってみます。
標準で用意されている画面の拡張を行う機会も多いと思いますが、今回は新規の画面を作ります。

## テーブル定義
まず、リストに使用するデータを保存するテーブルを定義します。
（記事作成時点では当然のようにシンタックスハイライトに対応していませんでした）
```
table 51098 "Test 01"
{
    Caption = 'Test 01';
    DataPerCompany = true;
    LookupPageID = "Test 01";
    DataClassification = CustomerContent;

    fields
    {
        field(1; "Number"; Code[10])
        {
            Caption = 'Number';
            DataClassification = CustomerContent;
        }
        field(2; "Name"; Text[128])
        {
            Caption = 'Name';
            DataClassification = CustomerContent;
        }
        field(3; "Flag"; Boolean)
        {
            Caption = 'Flag';
            DataClassification = CustomerContent;
        }
    }

    keys
    {
        key("Numger"; "Number")
        {
            Clustered = true;
        }
    }
}
```
これはDBのテーブルを定義しているようなもので、フィールドの名前・データ型とレングス・キーカラム等を定義できます。
今回は単純に番号・名前・フラグを持ったテーブルを作りました。

## リストページを作成する
次に上で定義したテーブルを表示・編集するためのリストページを作ります。

```
page 51098 "Test 01"
{
    Caption = 'Test 01';
    PageType = List;
    ApplicationArea = All;
    UsageCategory = Administration;
    SourceTable = "Test 01";
    SourceTableView = sorting("Number") order(ascending);

    layout
    {
        area(content)
        {
            repeater(General)
            {
                field("Number"; Rec."Number")
                {
                    Caption = 'Number';
                    ApplicationArea = All;
                }
                field("Name"; Rec." Name")
                {
                    Caption = 'Name';
                    ApplicationArea = All;
                }
                field("Flag"; Rec.Flag)
                {
                    Caption = 'Flag';
                    ApplicationArea = All;
                }
            }
        }
    }
}
```
PageTypeはListを選択し、SourceTableに先ほど作成したテーブルを指定します。
SourceTableViewに書いてあるのはページの表示時にデフォルトのソート順序を定義しています。
今回はページを開いた時にNumberの昇順でソートされるように記載しています。

repeaterの中に繰り返し表示する項目と名前を定義します。
今回は先ほど定義したテーブルの内容を順に全て表示します。


## リストを使うページを作成する
上記のリストページを使用してデータを選択してみたいので、リストを使うページを作成します。

```
page 51099 "Test 02"
{
    Caption = 'Test 02';
    PageType = Card;
    ApplicationArea = All;
    SourceTable = "Test 01";
    UsageCategory = Administration;

    layout
    {
        area(content)
        {
            group(test)
            {
                field("Number"; Rec."Number")
                {
                    Caption = 'Number';
                    TableRelation = "Test 01"."Number";
                    ApplicationArea = All;
                }
                field("Name"; Rec."Name")
                {
                    Caption = 'Name';
                    ApplicationArea = All;
                }
                field("Flag"; Rec.Flag)
                {
                    Caption = 'Flag';
                    ApplicationArea = All;
                }
            }
        }
    }
}
```
特に意味はありませんが、リストと同じフィールドを用意しました。
Numberの部分は先ほど作ったテーブルから選択できるようにするため、TableRelationにTest 01テーブルのNumberと紐づくように指定しました。


## 開発用デプロイ
```AL: Publish without debugging ``` コマンドで開発用のデプロイをして画面を表示してみます。


## 作成した画面を見てみる
画面上の虫眼鏡ボタンを押してTest 01と入力してTest 01画面を選択して表示します。
![D365BC_02.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150005/6ae05d82-14ba-cdb5-5fbd-da96e5ed3270.jpeg)
上の画像は既にデータを登録した後ですが、リストにデータを入力・編集・削除をすることができます。
リストページは表示され、データも登録できました。

今度はTest 02画面を見てみます。
![D365BC_04.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150005/64355c1e-0f5f-97cc-fd72-f95608d6d27a.jpeg)
Numberのところにドロップダウンのボタンが表示されています。これを押下してみます。
![D365BC_06.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150005/f4022398-c603-b277-1bab-b8551fbf76d3.jpeg)
Test 01で入力したデータが表示されていますが、Numberだけしか表示されていないので選択し辛いですね。

## ドロップダウンを見やすくする
NumberだけではなくNameもセットで表示されるとわかりやすくなるので、そうなるように変更してみます。

Test 01のテーブル定義を変更します

```
table 51098 "Test 01"
{
    Caption = 'Test 01';
    DataPerCompany = true;
    LookupPageID = "Test 01";
    DataClassification = CustomerContent;

    fields
    {
        field(1; "Number"; Code[10])
        {
            Caption = 'Number';
            DataClassification = CustomerContent;
        }
        field(2; "Name"; Text[128])
        {
            Caption = 'Name';
            DataClassification = CustomerContent;
        }
        field(3; "Flag"; Boolean)
        {
            Caption = 'Flag';
            DataClassification = CustomerContent;
        }
    }

    keys
    {
        key("Numger"; "Number")
        {
            Clustered = true;
        }
    }

    fieldgroups
    {
        fieldgroup(DropDown; "Number", "Name") { }
    }
}
```
fieldgroupsを追加し、DropdownにNumberとNameを記載しました。
これを再度デプロイします。

![D365BC_05.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150005/c1e98cb3-3c60-2ca4-0522-74bdc5175162.jpeg)
NumberとNameがセットで表示されるようになりました。これで表示がわかりやすくなりました。


# あとがき
上記は私が出会った困りごとの一つです。
この手の物はページ側に定義する物だと思っていたので、テーブル側の定義だったのは意外でした。
上にも書いた通りドキュメントは基本英語、公式ドキュメントにも抜けがあり、ネット上の情報も他のプログラミング言語に比べると探しにくいので、ちょっとした躓きでも調べるのに時間がかかりました。

この記事が読んだ方の助けになれば幸いです。