次の方法で共有


X++ プリミティブ データ型

この記事では、X++ のプリミティブ データ型について説明します。 X++ のプリミティブ データ型は、anytypebooleandateenumguidintint64realstrtimeOfDay、および utcdatetime です。

anytype

anytype データ型は任意のデータ型のプレースホルダーです。

anytype を変数として使用する場合、実際の基になる型は最初の割り当てによって決まります。 値が割り当ての前に使用されている場合は、実行時エラーが発生します。 anytype 値に割り当てた後、別のデータ型に変換することはできません。

変換対象のデータ タイプを使用するように、anytype を使用することができます。 たとえば、整数を割り当てる場合、変数にリレーショナル演算子と算術演算子を適用できます。

anytype 変数は値をタイプに割り当てるとき、日付、列挙 (enum)、整数、実数、文字列、拡張データ型 (EDT) (レコード)、クラス、またはコンテナーを自動的に変換します。 また、次の明示的な 変換関数 を使用できます: any2dateany2enumany2intany2realany2str

anytype 例

// An example of using anytype variables.
public static str range(anytype _from, anytype _to)
{
    return queryValue(_from) + '..' + queryValue(_to);
}

// Another example of using anytype variables. The conPoke predefined function
// can put put in data of any primitive type into the container, so anytype
// is the correct type here.
void put(int position, anytype data)
{
    container = conPoke (container, position, data);
}

public void anytypeMethod()
{
    // An example of automatic conversion for anytype.
    anytype a;
    a = "text"; // Automatically assigns a string literal.
}

ブール型

ブール データ型には、true または false のいずれかとして評価される値が含まれます。 ブール 式が予期される場所では、引当済のリテラル キーワード true および false を使用することができます。 既定値は false です。

どの値も、次の表に示すように、ブール値として解釈できます

データ タイプ True 値 False 値
整数 (int, int64) ゼロ以外の値 0
実数 (10 進数) ゼロ以外の値 0.0
ブール型 true false
文字列 (str)* 空でない文字列 空の文字列 ("")
日付 有効な日付 null 日付 (1900-01-01)
列挙 ゼロ以外の値 0 (最初の列挙型の値)
GUID 有効な GUID 空の GUID ({00000000-0000-0000-0000-000000000000})
コンテナー 空でないコンテナー 空のコンテナー (conNull())
テーブル インスタンス化されたテーブル レコード データベースからフェッチされていないテーブル (RecId = 0)
クラス インスタンス化されたクラス オブジェクト 初期化されていないクラス オブジェクト (null)

ブール値の例

public void booleanMethod()
{
    // Simple declaration of a boolean variable, b. The default value is false.
    boolean b;

    // Boolean variable is initialized to true.
    boolean b3 = true;

    // Declares a dynamic array of booleans.
    boolean b4[];

    // This example shows the most common usage of a boolean: a boolean in
    // a conditional statement and as a result of a logical expression.
    void main()
    {
        // Declares a boolean called exprValue.
        boolean exprValue;

        // Assigns ExprValue the value of (7*6 == 42), which equates to true.
        exprValue = (7*6 == 42);

        // If the conditional statement is true, print "OK".
        if (exprValue)
        {
            print "OK";  //"OK" is printed because the expression is true.
        }
    }
}

日付

date データ型は、年、月、日を格納します。 日付は、次の構文を使用してリテラルとして記述できます。日付リテラル = 日 \ 月 \ 年。 その年の 4 桁の数字を使用する必要があります。

日付データ型は、1900 年 1 月 1 日~ 2154 年 12 月 31 日の日付を保持できます。 date のサイズは 32 ビットです。 既定値は 1\1\1900 で、内部表示は日付です。

日付に暗黙的な変換はありません。ただし、次の明示的な 変換関数が使用できます: str2datedate2strdate2num、およびint2date

日付から整数を足したり引いたりすることができ、それぞれ指定した日数分、日付が将来や過去に移動します。 日付どうしの引き算は、日数の差を計算しますが、2 つの日付を足し合わせることはできず、コンパイラ エラーになります。

date の例

public void DateMethod()
{
    // Multiple declaration of two date variables.
    date d1, d2;

    // A date variable, d3, is initialized to the 21st of November 1998.
    date d3 = 21\11\1998;

    // Declaration of a dynamic array of dates.
    date d4[];

    // Using arithmetic operators with integer variables and dates.
    void myMethod()
    {
        int anInteger;
        date aDate;

        // Sets the date variable aDate to January 1, 1998.
        aDate = 1\1\1998;
        
        // Sets the integer variable anInteger to 30.
        anInteger = 30;
        
        // Uses an integer value in the computation of dates.
        // This sets aDate to aDate + 30; that is the 31st of January 1998.
        aDate = aDate + anInteger;

        // Create 2 variables, set bDate, and then subtract from that date.
        date bDate = 2\10\1998;
        int dateDifference;

        dateDifference = bDate - aDate; // dateDifference will equal 244.
    }
}

列挙型

列挙はリテラルのリストです。 列挙を使用する前に、アプリケーション エクスプローラーで宣言する必要があります。

列挙型 (または enum) は、一連の名前付き定数を定義する個別の型であり、コードの読み取りと管理が容易になります。 列挙は、小さな定義済値のセットから1つの値を識別する変数がある場合に便利です。 列挙型を使用すると、意味のある名前を一連の整数値に割り当て、コードの明確さを向上させることができます。

リテラルの値は、内部的に整数で表されます。 最初のリテラルは数字 0、次のリテラルは 1、次のリテラルは 2 というように続きます。 式の中では 列挙型 の値を整数として使用することができます。 最初のエントリの既定値は、0 または false です。

列挙値は自動的にブールint、または real に変換されます。 また、次の明示的な 変換関数 を使用できます: enum2str および str2enum

数千の列挙可能な型が標準アプリケーションに組み込まれています。 たとえば、NoYes 列挙には関連付けられている 2 つのリテラルがあります: No0 の値を、およびYes1 の値です。 必要なだけ列挙型を作成して、最大で 251 (0 から 250) のリテラルを単一列挙型で宣言することができます。 列挙型の値を参照するには、列挙型の名前、2 つのコロン、およびリテラルの名前を入力します。 たとえば、NoYes 列挙でリテラルの No を使用するには、NoYes::No を入力します。

列挙型を作成する

列挙はコードではなく、メタデータで作成されます。

列挙型を作成するには、次の手順に従います:

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、追加 をポイントして 新しい項目 をクリックします。
  2. Dynamics 365 項目データ型 を選択します。
  3. 基本列挙をクリックし、を新しい項目の種類を選択します。
  4. 名前 フィールドに列挙型の名前を入力して、追加 をクリックします。 新しい列挙型がプロジェクトに追加され、新しい要素の列挙型デザイナーが開きます。
  5. 列挙型デザイナーで列挙名を右クリックして、新しい要素 をクリックします。
  6. プロパティ ウィンドウで、列挙要素の名前を入力します。

列挙型の例

public void EnumMethod()
{
    // Declare the enum (a NoYes enum) in the Application Explorer.
    NoYes done;

    // An array of Criteria enums.
    Criteria crit[100];
}

guid

guid データ型は、グローバルに一意の識別子 (GUID) 値を保持します。 GUID は、固有の識別子が必要な場合に、すべてのコンピューターとネットワークで使用できる整数です。 数字が重複することはあまりありません。 有効な GUID は、次のすべての仕様を満たします。

  • 32 桁の 16 進数が必要です。
  • 次の場所では埋め込まれるダッシュ文字が 4 つ必要です: 8-4-4-4-12。
  • 文字列の先頭と末尾の中かっこ ({}) はオプションです。 たとえば、「12345678-BBBb-cCCC-0000-123456789012」および「{12345678-BBBb-cCCC-0000-123456789012}」は、両方とも有効な GUID 文字列です。
  • かっこを追加するかどうかに応じて、合計 36 文字または 38 文字になります。
  • a 〜 f (または A 〜 F) の 16 進数は、大文字、小文字、または混在することができます。

guid のサイズは 16 byte または 128 ビットです。 次の明示的な 変換関数any2guidguid2strnewGuidstr2guidGlobal::guidFromString、および Global::stringFromGuid も使用できます。

新しい guid 値を作成する方法は 1 つだけです。つまり、newGuid() 定義済み関数を使用します。

guid の例

次の例は、guid 関数の使い方を示しています。 これらの例のコード出力は次のとおりです。

// An example of how to use the GUID functions.
static void GuidRoundTripJob(Args _args)
{
    guid guid2;
    str string3;

    // Convert a guid to a string, and back to a guid.
    guid2 = newGuid();
    info(strFmt("Info_a1:  guid2 == %1", guid2));

    string3 = guid2str(guid2);
    info(strFmt("Info_a2:  string3 == %1", string3));

    guid2 = str2guid(string3);
    info(strFmt("Info_a3:  guid2 == %1", guid2));

    // Test string representations of a guid. Mixing upper and lower case letters does not affect the guid.
    guid2 = str2guid("BB345678-abcd-ABCD-0000-bbbbffff9012");
    string3 = guid2str(guid2);
    info(strFmt("Info_b1:  8-4-4-4-12 format for dashes works (%1)", string3));
    info(strFmt("Info_b2:  Mixed upper and lower case works."));

    // Test invalid dash locations, see output is all zeros. Dash locations must be exact.
    guid2 = str2guid("CC2345678abcd-ABCD-0000-cccc9012");
    string3 = guid2str(guid2);
    info(strFmt("Info_c1:  These embedded dash locations are required.  %1", string3));

    // Braces {} are optional.
    guid2 = str2guid("{DD345678-abcd-ABCD-0000-ddddaaaa9012}");
    string3 = guid2str(guid2);
    info(strFmt("Info_d1:  Braces {} are optional (%1)", string3));
}

guid コード出力

次の出力は、情報ログに表示されます。 文字列にはオプションのかっこが含まます。

Message (02:26:46 pm)
Info_a1:  guid2 == {93945629-734B-475E-99CE-6AA7AFA43259}
Info_a2:  string3 == {93945629-734B-475E-99CE-6AA7AFA43259}
Info_a3:  guid2 == {93945629-734B-475E-99CE-6AA7AFA43259}
Info_b1:  8-4-4-4-12 format for dashes works ({BB345678-ABCD-ABCD-0000-BBBBFFFF9012})
Info_b2:  Mixed upper and lower case works.
Info_c1:  These embedded dash locations are required.  {00000000-0000-0000-0000-000000000000}
Info_d1:  Braces {} are optional ({DD345678-ABCD-ABCD-0000-DDDDAAAA9012})

int および int64

整数 は、分数や小数点以下の桁数のない数字です。 int および int64 の、2 つの整数タイプがあります。 整数は、繰り返しのステートメントの制御変数または配列のインデックスとして使用されます。

また、整数式が必要で、リレーショナル演算子と算術演算子の両方を適用することができる任意の場所で 整数リテラル を使用することができます。 整数リテラルは整数で、例えば 32768 と記述されます。 Int は 32 ビット幅、int64 は 64 ビット幅で、2 の補数形式で格納されます。 どちらの場合も、既定値は 0 です。 整数は自動的に booleanenum または real に変換されます。

また、次の明示的な 変換関数 を使用できます: str2intint2strstr2int64int642strint の範囲は [-2,147,483,648 : 2,147,483,647]、int64 の範囲は [-9,223,372,036,854,775,808 : 9,223,372,036,854,775,807] です。

int および int64 の例

次の例は、整数を宣言して式で使用する方法を示しています。 最大の整数値に正の値を追加することで、オーバーフロー値を取得できます。 これは、2 の補数形式の結果です。

public void integerOverflow()
{
    // Assign the largest possible value to the 32 bit integer.
    int i = 2147483647

    // Add one to this value. 
    i = i + 1;
    
    // The value is now -2,147,483,648 because the sign but how is set.
    i = i + 1;
}

X++ は、符号なし整数型をサポートしていません。

public void IntegerMethod()
{
    // Declaration of an integer variable, i.
    int i;

    // Declaration of two int64 variables.
    int64 i1, i2;

    // An integer variable is initialized to the value 100.
    int i3 = 100;

    // Declaration of a dynamic array of integers.
    int i4[];

    void element()
    {
        // Two integer variables are declared and initialized.
        int k = 1, j = 2;

        // j is assigned the result of j + ((i + i) DIV 2).
        j +=(i + i) div 2;

        // This results in: j=3.

        if (j > 2 )
        {
            print "J is greater than 2";
        }
        else
        {
            print "J is NOT greater than 2";
        }
    }
}

real

実数 変数は、整数値に加えて小数値を保持できます。 10 進リテラル実数 が予期される場所ではどこでも使用することができます。 実数リテラルは、1.0e3 などの指数の表記を使用して記述することができます。

実数 は 128 ビットの精度を持ち、約 28 桁の有効数字をバイナリ コード化された 10進数 (BCD) としてエンコードすることができます。 実数 の既定値は 0.0 です。

10 進数 は、次の要素で構成される浮動小数点値です:

  • 符号
  • 各桁が0 ~ 9の範囲にある数値
  • 数値の整数部分と小数部分を区切る浮動小数点の位置を示すスケーリング係数。

実数値のバイナリ表現は、1 ビットの符号、96ビットの整数、スケーリング係数で構成されます。 拡大縮小係数は、96 ビット整数を分割し、小数部の部分を指定するのに使用されます。 拡大縮小係数は、0 から 28 の範囲の指数に暗黙的に 10 を引いたものです。 したがって、10 進数のバイナリ表現は ([-2⁹⁶ ~ 2⁹⁶] ÷ 10(0\ ~\ 28)) を表します。ここで -(2⁹⁶-1) は表現できる最小値と等しく、2⁹⁶-1 は最大値になります。 これらの値は、±1.0 × 10⁻²⁸ から ±7.9 × 10²⁸ です。

この表現により、実数 型は丸めエラーに強くなります。

この範囲内のすべての実数は X++ でリテラルとして使用できます。

実数は、レーショナル演算子と算術演算子の両方で使用できます。 実数変数は、自動的にブールenum、または int に変換されます。結果が整数の場合、または演算子が整数演算子の場合には、実数は整数に変換されます。 結果がブール値である場合、実数ブール値に変換されたりします。 また、次の明示的な 変換関数 を使用できます: str2numnum2str

実数 型のすべてのインスタンスが .NET 小数タイプ (System.Decimal) のインスタンスとして実装されます。

real の例

// Shows rounding issues caused by bad numerics, remedied by using the round function.
public static void roundingProblem(Args a)
{
    real dividend = 1.0;
    real divisor = 3.0;
    str stringvalue;

    System.Decimal valueAsDecimal;
    // 1.0/3.0 does not have an exact value.
    real value = dividend / divisor * divisor;

    valueAsDecimal = value;
    info(valueAsDecimal.ToString("G28"));

    // An example of using the Round function to round to the number of decimals required.
    value  = round(value, 2);
}
public void RealMethod()
{
    // Simple declaration of a real variable, r.
    real r;

    // Multiple declaration of two real variables.
    real r1, r2;

    // A real variable is initialized to the approximate value of pi.
    real r3 = 3.1415;

    // Declaration of a dynamic array of reals.
    real r4[];

    // An example of a real literal written using exponential notation.
    real r;
    r = 1.000e3;
    r = 1.2345e+3;
    r = 1.2345e+03;
    r = 1234.5e4;
    r = 1.0e1; // Means 1.0E1
}

// An example of automatic conversions.
void main()
{
    // Declares a variable of type integer with the name exprValue.
    int exprValue;

    // Declares a real variable with the name area.
    real area = 3.141528;
    exprValue = Area/3;

    // The expression Area/3 is a real expression because
    // division is a real operator, and the result is 1.047176. This result is
    // automatically converted (actually truncated) to an integer with the value 1,
    // because exprValue is an integer.
}

// An example of a real being converted to .NET System.Decimal.
void AnotherMain(Args _args)
{
    real real9;
    System.Decimal sysdec1;

    // Direct assignments supported between these types.
    sysdec1 = 2.3456;
    real9 = sysdec1;
    info(strFmt("strFmt says real9 == %1", real9));
}

/***
Message (05:48:43 pm)
strFmt says real9 == 2.35
***/

// An example of using reals in expressions.
void myMethod()
{
    // Two real variables are declared and initialized.
    real i = 2.5, j = 2.5;

    // j is assigned the result of j * i, so j=6.25.
    j = j * i;
    if (j > (i * 2)) // If j > 5
    {
        print "Great"; // "Great" is printed.
    }
    else
    {
        print "Oops"; // else "Oops" is printed.
    }
}

str

str 変数 (文字列) は、テキスト、ヘルプ行、住所、電話番号などとして使用される Unicode 文字のシーケンスです。

文字列を宣言するには、str キーワードを使用します。

文字列リテラルは、引用符 ("") または単一引用符で囲まれた文字です。 文字列式が必要な場合はいつでも、文字列リテラルを使用することができます。 文字列リテラルの例には、"StringLit" および "Hello world" が含まれます。 文字列を複数の行にまたがるようにするには、その前にアットマーク (@) を付けます。 比較などの論理式では文字列を使用することができます。 また、+ 演算子を使用することで文字列を連結することができます。

文字列の既定値は 、つまり "" で内部表示は文字のリストです。 文字列の自動変換はありません。ただし、次の明示的な 変換関数 が使用できます: str2intstr2int64int2strstr2numnum2strstr2date、および date2str

文字列は、実質的に無制限の文字数を保持できます。 変数の宣言で文字列の最大の長さを指定できます。 文字列はその最大長に切り捨てられます。 例として次のセクションに表示します。

str の例

void StringMethod()
{
    // Declare a dynamic string of unlimited length.
    str unlimitedString;

    // Declare a string with a maximum of 64 characters
    // in order to force a truncation, initialized to "A".
    str 64 maxLengthString = 'A';

    // Declare an array of 100 strings.
    str 30 hundredStrings[100];

    // Using strings in expressions.
    void myMethod()
    {
        // Two strings are declared and initialized.
        str a="Hello", b="World";

        // The concatenation of a, " " and b is printed in a window.
        print a + " " + b;
    }
}

文字列の切り捨て

文字列値は、最大文字数を格納するために X++ で宣言できます。 これは通常、拡張データ型でこの情報をエンコードし、プロパティ ウィンドウで 文字列サイズ を設定することで達成されます。 次のスクリーンショットでは、FMCreditCardNum は 20 文字を超えることはできません。

FMCreditCardNum 文字列のサイズ。

次のコードを静的 メイン メソッドに含めてデバッガーで実行し、動作を確認します。

creditCardNumber = "12345678901234567890Excess string";

X++ では長さ制約も指定できます:

str 20 creditCardNumber;

これらの値に対するすべての割り当ては最大長に暗黙的に切り捨てられます。

timeOfDay

timeOfDay (時間) データ型は、午前 0 時から経過した秒数を表す整数値です。 整数と同様に、timeOfDay 変数はリテラルとして使用することができます。 リレーショナルおよび算術演算子は、timeOfDay 変数に適用できます。 timeOfDay 変数も式で使用できます。 timeOfDay データ型の範囲は [0; 86,400] のクローズ区間にあります。 86,400 (23: 59:59) を超える値は解釈できません。 timeOfDay 変数は、自動的にブールenum、または実数に変換されます。 また、次の明示的な 変換関数 を使用できます: str2timetime2str

timeOfDay の例

public void TimeofdayMethod()
{
    // Declaration of a timeOfDay variable, time1.
    timeOfDay time1;

    // Declaration and initialization of a timeOfDay variable to 00:21:35.
    timeOfDay time2 = 1295;
}

utcdatetime

utcdatetime データ型は、date 型と timeOfDay 型を結合します。 Utcdatetime 変数は、タイムゾーンに関する情報も保持しますが、ただし、この情報はコードではアクセスできません。

utcdatetime リテラルの形式は、yyyy-mm-ddThh:mm:ss です。 日付部分と時間部分の間には大文字の "T" が必要です。 最小値は、1900-01-01T00:00:00 で、最大値は 2154-12-31T23:59:59 です。 この最大値は、datetimeOfDay の上位範囲に一致します。 utcdatetime の最小単位は 1 秒です。

宣言されているもののまた初期化されていない utcdatetime 変数の規定値は、 1900-01-01T00:00:00 です。 この値は、DateTimeUtil::minValue() によって返されます。 一部の機能は、この最小値の入力パラメーターを null として扱います。 たとえば、DateTimeUtil::tostrメソッドは空の文字列を返しますが、DateTimeUtil ::addseconds メソッドは使用可能な utcdatetime 値を返します。

utcdatetime データ型の暗黙的な変換はありません。 DateTimeUtil クラスは、utcdatetime 値を操作するために使用できるさまざまなメソッドを提供します。

次の明示的な 変換関数str2datetime および datetime2str も使用できます。

また、グローバル クラスは、utcDateTime2SystemDateTimeCLRSystemDateTime2UtcDateTime 変換メソッドを提供して、共通言語ランタイム (CLR) 相互運用をサポートします。

比較演算子は、utcdatetime データ型で使用できる唯一の演算子です。 次の演算子を使用して、2つの utcdatetime 値を比較することができます: !=、<、<=、==、>、および >=。 テーブルに utcdatetime フィールドを追加するときは、そのフィールドを EDT にもとづいて決めることをお勧めします。

utcdatetime の例

public void utcdatetimeMethod()
{
    // Declaring a utcdatetime literal.
    utcdatetime myUtc2 = 1988-07-20T13:34:45;

    // Another example of declaring a utcdatetime literal.
    int iDay = DateTimeUtil::day(1988-07-20T13:34:45);

    // utcdatetime using a quoted string parameter into the DateTimeUtil::parse method.
    utcdatetime myUtc4 = DateTimeUtil::parse("1988-07-20T13:34:45");
}