--- title: "Function list" slug: "bc-function-list" description: "Explore string manipulation functions in D365 BC, including XDELCHR, XCOPYSTR, and date formatting with XTODAY for efficient data handling." tags: ["BC", "BIS", "Business Central", "Business Integration Solutions", "Task"] updated: 2026-06-25T09:59:07Z published: 2026-06-25T09:59:07Z canonical: "docs.staedean.com/bc-function-list" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.staedean.com/llms.txt > Use this file to discover all available pages before exploring further. # Function list ### XDELCHR Deletes one or more characters in a string. ```plaintext procedure XDELCHR(String: Text; Where: Text; Which: Text): Text begin    // category   : string    // description: Deletes one or more characters in a string    exit(DelChr(String, Where, Which)); end; ``` ### XCOPYSTR Selects a substring from a specific position in a string. ```plaintext procedure XCOPYSTR(String: Text; Position: Integer; Length: Integer): Text begin    // category   : string    // description: Copies a substring of Anywhere Mobility Solutions length from a specific position in a string (text or code) to a new string.    exit(CopyStr(String, Position, Length)); end; ``` Example: `XCOPYSTR("Example",2,3)` returns `"xam"`. ### XSTRLEFT Copies a number of characters from the left side of a string. ```plaintext procedure XSTRLEFT(String: Text; Length: Integer): Text begin    // category   : string    // description: Copies a number of characters from the left side of a string    exit(CopyStr(String, 1, Length)); end; ``` ### XSTRRIGHT Copies a number of characters from the right side of a string. ```plaintext procedure XSTRRIGHT(String: Text; Length: Integer): Text begin    // category   : string    // description: Copies a number of characters from the right side of a string    if (String <> '') and (StrLen(String) - Length + 1 > 0) then        exit(CopyStr(String, StrLen(String) - Length + 1)); end; ``` ### XUPPERCASE Converts a string to uppercase. ```plaintext procedure XUPPERCASE(String: Text): Text begin    // category   : string    // description: Converts a string to uppercase    exit(UpperCase(String)); end; ``` ### XLOWERCASE Converts a string to lowercase. ```plaintext procedure XLOWERCASE(String: Text): Text begin    // category   : string    // description: Converts a string to lowercase    exit(LowerCase(String)); end; ``` ### XTODAY Gets the current date set in the operating system. ```plaintext procedure XTODAY(): Text begin    // category   : datetime    // description: Gets the current date set in the operating system.    exit(Convert.Date2Text(Today)); end; ``` Example: `Codeunit:11070243.XTODAY()` returns today's date in XML format (`YYYY-MM-DD`), for example `2023-09-24`. ### XWORKDATE Gets the work date for the current session. ```plaintext procedure XWORKDATE(): Text begin    // category   : datetime    // description: Gets the work date for the current session.    exit(Convert.Date2Text(WorkDate())) end; ``` ### XCALCDATE Calculates a new date based on a date expression and a reference date string. ```plaintext procedure XCALCDATE(DateExpression: Text; DateString: Text): Text var    TempDate: Date; begin    // category   : datetime    // description: Calculates a new date that is based on a date expression and a reference date string.    if DateExpression = '' then exit;    TempDate := Convert.Text2Date(DateString);    if TempDate = 0D then TempDate := Today();    exit(Convert.Date2Text(CalcDate(DateExpression, TempDate))); end; ``` Examples: ```plaintext Codeunit:11070243.XCALCDATE('+2D', Codeunit:11070243.XTODAY()); Codeunit:11070243.XCALCDATE('+2D', '2023-03-04'); ``` These two examples return the day after tomorrow and `2023-03-06` respectively. ### XTIME Gets the current time from the operating system. ```plaintext procedure XTIME(): Text begin    // category   : datetime    // description: Gets the current time from the operating system.    exit(Convert.Time2Text(Time)); end; ``` ### XCOMPANYNAME Gets the current company name. ```plaintext procedure XCOMPANYNAME(): Text begin    // category   : general    // description: Gets the current company name.    exit(CompanyName); end; ``` ### XSELECTSTR Retrieves a substring from a comma-separated string. ```plaintext procedure XSELECTSTR(String: Text; Separator: Text[1]; Number: Integer): Text var    TempChr: Char; begin    // category   : string    // description: Retrieves a substring from a comma-separated string.    if Number < 1 then exit;    TempChr := 7;    String := ConvertStr(String, Separator, Format(TempChr));    String := ConvertStr(String, Format(TempChr), ',');    exit(SelectStr(Number, String)); end; ``` ### ConvertToExternal Applies a conversion table on an internal value. ```plaintext procedure ConvertToExternal(ConversionTableCode: Code[20]; InternalValue: Text): Text[100] var    ConversionTableLine: Record BISConversionTableLine; begin    // category   : string    // description: Applies a conversion table on an internal value    ConversionTableLine.SetRange(Code, ConversionTableCode);    ConversionTableLine.SetRange("Internal Value", InternalValue);    if ConversionTableLine.FindFirst() then        exit(ConversionTableLine."External Value")    else        exit(CopyStr(InternalValue, 1, 100)); end; ``` ### ConvertToInternal Applies a conversion table on an external value. ```plaintext procedure ConvertToInternal(ConversionTableCode: Code[20]; ExternalValue: Text): Text[100] var    ConversionTableLine: Record BISConversionTableLine; begin    // category   : string    // description: Applies a conversion table on an external value    ConversionTableLine.SetRange(Code, ConversionTableCode);    ConversionTableLine.SetRange("External Value", ExternalValue);    if ConversionTableLine.FindFirst() then        exit(ConversionTableLine."Internal Value")    else        exit(CopyStr(ExternalValue, 1, 100)); end; ``` ### Base64Decode Decodes a base64-encoded value to a string. ```plaintext procedure Base64Decode(Base64String: Text) Result: Text var    TempBlob: Codeunit "Temp Blob";    NVInstream: InStream;    StreamLine: Text; begin    // category   : string    // description: Decodes a base64 encoded value to a string    Convert.Text2BLOB(Base64String, TempBlob);    TempBlob.CreateInStream(NVInstream);    while not NVInstream.EOS() do begin        NVInstream.ReadText(StreamLine);        Result += StreamLine;    end; end; ``` ### Base64Encode Encodes a string to a base64 value. ```plaintext procedure Base64Encode(StringValue: Text) Result: Text var    TempBlob: Codeunit "Temp Blob";    NVOutstream: OutStream; begin    // category   : string    // description: Encodes a string to a base64 value    TempBlob.CreateOutStream(NVOutstream);    NVOutstream.WriteText(StringValue);    Result := Convert.BLOB2Text(TempBlob); end; ``` ### ParseDate Parses a text value to a date and returns it in XML format. ```plaintext procedure ParseDate(DateString: Text; FormatExpression: Text): Text var    DateTimeLocal: Codeunit DotNet_DateTime;    CultureInfo: Codeunit DotNet_CultureInfo;    TimeStyle: Codeunit DotNet_DateTimeStyles;    BCDate: Date; begin    CultureInfo.InvariantCulture();    TimeStyle.None();    DateTimeLocal.TryParseExact(DateString, FormatExpression, CultureInfo, TimeStyle);    BCDate := DMY2Date(DateTimeLocal.Day(), DateTimeLocal.Month(), DateTimeLocal.Year());    exit(Convert.Date2Text(BCDate)); end; ``` ### FormatDate Formats a D365 BC date to an external format. ```plaintext procedure FormatDate(DateString: Text; FormatExpression: Text): Text var    NavDateTime: DateTime; begin    // category   : date    // description: Formats a BC Date to an external format    Convert.Text2DateTime(DateString, NavDateTime);    exit(Format(NavDateTime, 0, FormatExpression)); end; ``` ### FormatDecimal Formats a D365 BC decimal to an external format. ```plaintext procedure FormatDecimal(DecimalString: Text; FormatExpression: Text): Text var    NavDecimal: Decimal; begin    // category   : decimal    // description: Formats a NAV Decimal to an external format    NavDecimal := Convert.Text2Decimal(DecimalString);    exit(Format(NavDecimal, 0, FormatExpression)); end; ``` ### XIF Filters a value against a given filter. ```plaintext procedure XIF(iTxtValue: Text[250]; iTxtLogicalTest: Text[250]; iTxtDataType: Text[30]): Boolean var    tempTICText: Record "TIC Temp Text" temporary; begin    // category   : Framework    // description: Filters a value against logicaltest    case LowerCase(iTxtDataType) of        'integer':            begin                if not Evaluate(tempTICText."Integer Value 1", iTxtValue) then exit(false);                tempTICText.SetFilter("Integer Value 1", iTxtLogicalTest)            end;        'decimal':            begin                if not Evaluate(tempTICText."Decimal Value 1", iTxtValue) then exit(false);                tempTICText.SetFilter("Decimal Value 1", iTxtLogicalTest);            end;        'text':            begin                tempTICText."Text 1" := iTxtValue;                tempTICText.SetFilter("Text 1", iTxtLogicalTest);            end;        'boolean', 'bool':            begin                if not Evaluate(tempTICText."Boolean Value", iTxtValue) then exit(false);                tempTICText.SetFilter("Boolean Value", iTxtLogicalTest);            end;        'date':            begin                if not Evaluate(tempTICText."Date Value 1", iTxtValue) then exit(false);                tempTICText.SetFilter("Date Value 1", iTxtLogicalTest);            end;        else            if Evaluate(tempTICText."Integer Value 1", iTxtValue) then                tempTICText.SetFilter("Integer Value 1", iTxtLogicalTest)            else begin                tempTICText."Text 1" := iTxtValue;                tempTICText.SetFilter("Text 1", iTxtLogicalTest);            end;    end;    tempTICText.Insert();    exit(not tempTICText.IsEmpty()); end; ``` The `XIF` function is usually combined with one of the Return functions. The logical test applies as a filter, so standard Microsoft Dynamics 365 Business Central filters apply. Example, returns `Purchase Order`: ```plaintext Codeunit:11070243.FormatBooleanToText(Codeunit:11070243.XIF("Order","<>Quote","Text"),"Purchase Order","Purchase Quote") ``` ### LogicOperation Executes a logical operation on two booleans. ```plaintext procedure LogicOperation(Operator: Code[10]; BoolExpr1: Boolean; BoolExpr2: Boolean): Boolean begin    // category   : Framework    // description: Returns boolean result from logic operation    if not (Operator in ['AND', 'OR', 'NOT', 'XOR']) then        Error('Operator cannot be %1, it must be either AND, OR, NOT or XOR', Operator);    case Operator of        'AND': exit(BoolExpr1 and BoolExpr2);        'OR':  exit(BoolExpr1 or BoolExpr2);        'XOR': exit(BoolExpr1 xor BoolExpr2);        'NOT': exit(not (BoolExpr1));    end; end; ``` ### FormatBooleanToText Returns a text value based on a boolean expression. ```plaintext procedure FormatBooleanToText(Boolean: Boolean; ValueWhenTrue: Text; ValueWhenFalse: Text): Text begin    // category   : Framework    // description: returns specified value based on boolean    if Boolean then exit(ValueWhenTrue) else exit(ValueWhenFalse); end; ``` ### CompareDecimal Compares two decimals and returns the result. ```plaintext procedure CompareDecimal(Value1: Decimal; ComparisonOperator: Text[5]; Value2: Decimal): Boolean var    InvalidOperatorErr: Label 'Only ''<'', ''<='', ''='', ''>='', ''>'',''<>'' is allowed, not %1', Comment = '%1 = Replaced by the comparison operator'; begin    // category   : framework    // description: use this function when direct compare doesn't work    case ComparisonOperator of        '<':  exit(Value1 < Value2);        '=':  exit(Value1 = Value2);        '>':  exit(Value1 > Value2);        '<=': exit(Value1 <= Value2);        '>=': exit(Value1 >= Value2);        '<>': exit(Value1 <> Value2);        else  Error(InvalidOperatorErr, ComparisonOperator);    end; end; ``` ### CompareString Compares two strings and returns the result. ```plaintext procedure CompareString(Value1: Text; ComparisonOperator: Text[5]; Value2: Text): Boolean var    InvalidStrOperatorErr: Label 'Only ''<>'' or ''='' is allowed, not %1', Comment = '%1 = Replaced by the comparison operator'; begin    // category   : framework    // description: Compare text values    case ComparisonOperator of        '<>': exit(Value1 <> Value2);        '=':  exit(Value1 = Value2);        else  Error(InvalidStrOperatorErr, ComparisonOperator);    end; end; ``` ### CheckTextValue Checks if a text value matches a given filter. ```plaintext procedure CheckTextValue("Filter": Text; Value: Text): Boolean var    TempText: Record "TIC Temp Text" temporary; begin    // category   : framework    // description: Check text value against a filter    TempText."Text 1" := CopyStr(Value, 1, 250);    TempText.SetFilter("Text 1", Filter);    TempText.Insert();    exit(not TempText.IsEmpty()); end; ``` ### CheckDecimalValue Checks if a decimal value matches a given filter. ```plaintext procedure CheckDecimalValue("Filter": Text; Value: Decimal): Boolean var    TempText: Record "TIC Temp Text" temporary; begin    // category   : framework    // description: Check decimal value against a filter    TempText."Decimal Value 1" := Value;    TempText.SetFilter("Decimal Value 1", Filter);    TempText.Insert();    exit(not TempText.IsEmpty()); end; ``` ### CheckIntegerValue Checks if an integer value matches a given filter. ```plaintext procedure CheckIntegerValue("Filter": Text; Value: Integer): Boolean var    TempText: Record "TIC Temp Text" temporary; begin    // category   : framework    // description: Check integer value against a filter    TempText."Integer Value 1" := Value;    TempText.SetFilter("Integer Value 1", Filter);    TempText.Insert();    exit(not TempText.IsEmpty()); end; ``` ### CheckDateValue Checks if a date value matches a given filter. ```plaintext procedure CheckDateValue("Filter": Text; Value: Date): Boolean var    TempText: Record "TIC Temp Text" temporary; begin    // category   : framework    // description: Check date value against a filter    TempText."Date Value 1" := Value;    TempText.SetFilter("Date Value 1", Filter);    TempText.Insert();    exit(not TempText.IsEmpty()); end; ``` ### CheckTimeValue Checks if a time value matches a given filter. ```plaintext procedure CheckTimeValue("Filter": Text; Value: Time): Boolean var    TempText: Record "TIC Temp Text" temporary; begin    // category   : framework    // description: Check time value against a filter    TempText."Time Value 1" := Value;    TempText.SetFilter("Time Value 1", Filter);    TempText.Insert();    exit(not TempText.IsEmpty()); end; ``` ### CheckBooleanValue Checks if a boolean value matches a given filter. ```plaintext procedure CheckBooleanValue("Filter": Text; Value: Boolean): Boolean var    TempText: Record "TIC Temp Text" temporary; begin    // category   : framework    // description: Check boolean value against a filter    TempText."Boolean Value" := Value;    TempText.SetFilter("Boolean Value", Filter);    TempText.Insert();    exit(not TempText.IsEmpty()); end; ``` ### ReturnText Returns a text value based on a boolean expression. ```plaintext procedure ReturnText(Boolean: Boolean; ValueWhenTrue: Text; ValueWhenFalse: Text): Text begin    // category   : framework    // description: return textvalue based on boolean    exit(FormatBooleanToText(Boolean, ValueWhenTrue, ValueWhenFalse)); end; ``` ### ReturnInteger Returns an integer based on a boolean expression. ```plaintext procedure ReturnInteger(Boolean: Boolean; ValueWhenTrue: Integer; ValueWhenFalse: Integer): Integer begin    // category   : framework    // description: return integervalue based on boolean    if Boolean then exit(ValueWhenTrue) else exit(ValueWhenFalse); end; ``` ### ReturnDecimal Returns a decimal based on a boolean expression. ```plaintext procedure ReturnDecimal(Boolean: Boolean; ValueWhenTrue: Decimal; ValueWhenFalse: Decimal): Decimal begin    // category   : framework    // description: return decimalvalue based on boolean    if Boolean then exit(ValueWhenTrue) else exit(ValueWhenFalse); end; ``` ### XError Throws an error when the check is false. ```plaintext procedure XError(Check_if_valid: Boolean; ErrorMessage: Text) begin    // category   : framework    // description: Throws an error when false    if not Check_if_valid then Error(ErrorMessage); end; ``` ### GetEnumValueFromCaption Returns the enum value based on the caption. > [!NOTE] > Multilanguage support for captions is only available for options, not for enums. ```plaintext procedure GetEnumValueFromCaption(TableNo: Integer; FieldNo: Integer; EnumCaptionText: Text; LanguageId: Integer) Result: Text var    Dummy: Integer;    EnumValueErr: Label 'Could not get value for <%1> from table %2 in field %3', Comment = '%1 = Replaced by the enum caption, %2 = Replaced by the table name, %3 = Replaced by the field name'; begin    if (not EnumValueFromCaption(TableNo, FieldNo, EnumCaptionText, LanguageId, Result, Dummy)) then        Error(EnumValueErr, EnumCaptionText, TableNo, FieldNo); end;

GetEnumOrdinalFromCaption

Returns the ordinal (ID) from an enum caption.

Multilanguage support for captions is only available for options, not for enums.

procedure GetEnumOridinalFromCaption(TableNo: Integer; FieldNo: Integer; EnumCaptionText: Text; LanguageId: Integer) Result: Integer
var
    Dummy: Text;
    EnumValueErr: Label 'Could not get value for <%1> from table %2 in field %3', Comment = '%1 = Replaced by the enum caption, %2 = Replaced by the table name, %3 = Replaced by the field name';
begin
    if (not EnumValueFromCaption(TableNo, FieldNo, EnumCaptionText, LanguageId, Dummy, Result)) then
        Error(EnumValueErr, EnumCaptionText, TableNo, FieldNo);
end;

local EnumValueFromCaption

Helper function for GetEnumOrdinalFromCaption and GetEnumValueFromCaption.

[TryFunction]
local procedure EnumValueFromCaption(TableNo: Integer; FieldNo: Integer; EnumCaptionText: Text; LanguageId: Integer; var ResultTxt: Text; var ResultInt: Integer)
var
    FldRef: FieldRef;
    RecRef: RecordRef;
    OriginalGlobalLanguage: Integer;
begin
    RecRef.Open(TableNo);
    FldRef := Recref.Field(FieldNo);
    OriginalGlobalLanguage := GlobalLanguage();
    GlobalLanguage(LanguageId);
    if Evaluate(FldRef, EnumCaptionText) then begin
        ResultInt := FldRef.Value();
        ResultTxt := FldRef.GetEnumValueNameFromOrdinalValue(ResultInt)
    end;
    GlobalLanguage(OriginalGlobalLanguage);
end;

XStringReplace

Replaces a given search text with a given replace text.

procedure XStringReplace(String: Text; SearchValue: Text; ReplaceValue: Text) Result: Text
begin
    Result := String.Replace(SearchValue, ReplaceValue);
end;

XStringReplaceAndEscape

Replaces a given search text with a given replace text, but escapes {{variable.bc-Any}} occurrence of the replace value in the original text.

procedure XStringReplaceAndEscape(String: Text; SearchValue: Text; ReplaceValue: Text; EscapePlaceholderValue: Text) Result: Text
var
    PlaceHolder: Char;
    MessageErr: Label 'This function can''t be applied to your input';
begin
    PlaceHolder := 26;
    if String.Contains(PlaceHolder) then begin
        PlaceHolder := 27;
        if String.Contains(PlaceHolder) then error(MessageErr);
    end;
    Result := XStringReplace(String, ReplaceValue, PlaceHolder);
    Result := XStringReplace(Result, SearchValue, ReplaceValue);
    Result := XStringReplace(Result, PlaceHolder, EscapePlaceholderValue);
end;

Example, replacing l with w in "Hello world":

XStringReplaceAndEscape("Hello world","l","w","c");

Returns "Hewwo curld".

``` ## Related - [Expression function](/bc-expression-function.md)