RIM Tool on 5.0 SP1

Although the RIM tool was originally designed to assist in the setup of Master data; i.e. Customers, Vendors, Items, etc., the reality is that many are using the Data Migration tool to bring in journal lines to set up beginning balances and to bring over historical data from legacy applications.

With the release of 5.0 SP1, a new data type conversion routine was introduced with codeunit 5302 - Outlook Synch. Type Conversion. There are several known issues with data conversion due to these changes.

All of these issue have been reported to development and are being considered for a fix in a future release of the NAV product.

This post offers some code suggestions and workarounds for the more common and/or critical issues. Many of the suggested workarounds involve one particular codeunit in the Data Migration tool, 8611 – Migration Management, so the following combined change log should be helpful.


This change log applies to 5.0 SP1 application objects ONLY.

Issues addressed by the change log:

1) Overflow on type conversion from Text to Text in Form 8626 when a text field larger than 100 chars is imported.
2) Error on import of fields beginning with a number (i.e. 1099 Code) -
The call to member selectSingleNode failed. msxml6.dll returned the following message: Expression must evaluate to a node-set.
3) Imported dates are blank after migration data is applied.
4) Decimal values are converted incorrectly. Ex. - 7,500 becomes 7.5 after the migration data is applied.
5) Negative decimal values are converted incorrectly, resulting in changed values.
6) Error - Expected token 'EOF' found '$'. Error on fields with $ symbol
7) Error - The expression Text cannot be type-converted to a Boolean value (or Date value). This may occur on Setup Questionnaire, Data Migration or Data Template.


Changes are labeled with the associated number above.


*****Start Code fix*****


Form 8626 Migration Records
---------------------------
Before:
CODE
  {
    VAR
      MatrixColumnCaptions@1000 : ARRAY [100] OF Text[100];
      MigrationData@1001 : Record 8615;
      MatrixCellData@1002 : ARRAY [100] OF Text[100];
      MigrationColumnField@1004 : ARRAY [100] OF Integer;
      MatrixColumnOrdinal@1003 : Integer;
      FormCaption@1005 : Text[1024];
      TableNo@1006 : Integer;
      Text001@1007 : TextConst 'ENU=%1 value ''%2'' does not exist.';

After:
CODE
  {
    VAR
      MatrixColumnCaptions@1000 : ARRAY [100] OF Text[100];
      MigrationData@1001 : Record 8615;
      MatrixCellData@1002 : ARRAY [100] OF Text[250];  // #1 Change Text[100] to Text[250]
      MigrationColumnField@1004 : ARRAY [100] OF Integer;
      MatrixColumnOrdinal@1003 : Integer;
      FormCaption@1005 : Text[1024];
      TableNo@1006 : Integer;
      Text001@1007 : TextConst 'ENU=%1 value ''%2'' does not exist.';


* XMLport 8610 - Setup DataSchema
---------------------------------
...
NameIn := DELCHR(NameIn,'=','Ù''`');
NameIn := DELCHR(CONVERTSTR(NameIn,'<>,./\+-&()%','            '),'=',' ');
NameIn := DELCHR(NameIn,'=',' ');

EXIT(NameIn);
...


After:
...
NameIn := DELCHR(NameIn,'=','Ù''`');
NameIn := DELCHR(CONVERTSTR(NameIn,'<>,./\+-&()%$','             '),'=',' ');  // #6 Change line- add $ symbol
NameIn := DELCHR(NameIn,'=',' ');

IF (NameIn[1] >= '0') AND (NameIn[1] <= '9') THEN    // #2 Add line
  NameIn := '_' + NameIn;         // #2 Add line

EXIT(NameIn);

 

* Codeunit 8611\Function FieldNodeExists ...
--------------------------------------------
Before:

FieldNode := RecordNode.selectSingleNode(FieldNodeName);

IF NOT ISCLEAR(FieldNode) THEN
  EXIT(TRUE);

After:

IF (FieldNodeName[1] >= '0') AND (FieldNodeName[1] <= '9') THEN         //  #2 Add line
  FieldNodeName := '_' + FieldNodeName;                                                   //  #2 Add line
FieldNode := RecordNode.selectSingleNode(FieldNodeName);

IF NOT ISCLEAR(FieldNode) THEN
  EXIT(TRUE);


* Codeunit 8611, Function GetElementName
----------------------------------------
Before:

...
NameIn := DELCHR(NameIn,'=','Ù''`');
NameIn := DELCHR(CONVERTSTR(NameIn,'<>,./\+-&()%','            '),'=',' ');
NameIn := DELCHR(NameIn,'=',' ');

EXIT(NameIn);
...


After:
...
NameIn := DELCHR(NameIn,'=','Ù''`');
NameIn := DELCHR(CONVERTSTR(NameIn,'<>,./\+-&()%$','             '),'=',' ');  // #6 Change line - add $ symbol
NameIn := DELCHR(NameIn,'=',' ');

IF (NameIn[1] >= '0') AND (NameIn[1] <= '9') THEN    // #2 Add line

  NameIn := '_' + NameIn;     // #2 Add line

EXIT(NameIn);

* Codeunit 8611, Function ValidateFieldValue
--------------------------------------------
Before:


Field.GET(RecRef.NUMBER,FieldRef.NUMBER);

IF Field.Type <> Field.Type::Option THEN BEGIN
  IF Value <> '' THEN
    //IF CompanySetupRun THEN                                           // #7 Delete
      EVALUATE(FieldRef,Value)
    //ELSE                                                                               // #7 Delete
    //  FieldRef.VALIDATE(Value);                                         // #7 Delete
END ELSE
  IF GetOption(Value,FieldRef.OPTIONCAPTION,OptionAsInteger) THEN
    IF CompanySetupRun THEN
      FieldRef.VALUE := OptionAsInteger
    ELSE
      FieldRef.VALIDATE(OptionAsInteger);

IF NOT CompanySetupRun THEN
  IF NOT TestRelation(FieldRef) THEN
    FieldRef.VALIDATE;

After:


Field.GET(RecRef.NUMBER,FieldRef.NUMBER);

IF Field.Type <> Field.Type::Option THEN BEGIN
  IF Value <> '' THEN
      EVALUATE(FieldRef,Value)
END ELSE
  IF GetOption(Value,FieldRef.OPTIONCAPTION,OptionAsInteger) THEN
    IF CompanySetupRun THEN
      FieldRef.VALUE := OptionAsInteger
    ELSE
      FieldRef.VALIDATE(OptionAsInteger);

IF NOT CompanySetupRun THEN
  IF NOT TestRelation(FieldRef) THEN
    FieldRef.VALIDATE;

* Codeunit 8611, Function ModifyRecordWithOtherFields
-----------------------------------------------------
Before:

VAR
      MatrixData@1002 : Record 8615;
      MigrationTableField@1000 : Record 8616;
      Question@1003 : Record 8612;
      Field@1007 : Record 2000000041;
      MigrationTable@1009 : Record 8613;
      DataTemplateHeader@1011 : Record 8618;
      QuestionnaireMgt@1006 : Codeunit 8610;
      TemplateMgt@1012 : Codeunit 8612;
      OSynchTypeConversion@1014 : Codeunit 5302;
      FieldRef@1001 : FieldRef;
      OptionInt@1008 : Integer;
      DateFormula@1010 : DateFormula;
      ToValidate@1013 : Boolean;

After:

 VAR
      MatrixData@1002 : Record 8615;
      MigrationTableField@1000 : Record 8616;
      Question@1003 : Record 8612;
      Field@1007 : Record 2000000041;
      MigrationTable@1009 : Record 8613;
      DataTemplateHeader@1011 : Record 8618;
      QuestionnaireMgt@1006 : Codeunit 8610;
      TemplateMgt@1012 : Codeunit 8612;
      OSynchTypeConversion@1014 : Codeunit 5302;
      FieldRef@1001 : FieldRef;
      OptionInt@1008 : Integer;
      DateFormula@1010 : DateFormula;
      ToValidate@1013 : Boolean;
      DateValue@1500000 : Date;                   // #3 Add

Before:


    IF MigrationTableField.FIND('-') THEN
      IF NOT IsKeyField(MigrationTableField.TableID,MigrationTableField.FieldID) THEN BEGIN
        FieldRef := RecRef.FIELD(MatrixData.FieldID);
        IF CompanySetupRun THEN
          ToValidate:= FALSE
        ELSE
          ToValidate := MigrationTableField.Validate AND NOT TestRelation(FieldRef);
        OSynchTypeConversion.EvaluateTextToFieldRef(MatrixData.Value,FieldRef,ToValidate)
      END;
      IF DataTemplateHeader.GET(MigrationTable."Data Template") THEN
        TemplateMgt.UpdateRecord(DataTemplateHeader,RecRef);

After:

    IF MigrationTableField.FIND('-') THEN
      IF NOT IsKeyField(MigrationTableField.TableID,MigrationTableField.FieldID) THEN BEGIN
        FieldRef := RecRef.FIELD(MatrixData.FieldID);
        IF CompanySetupRun THEN
          ToValidate:= FALSE
        ELSE
          ToValidate := MigrationTableField.Validate AND NOT TestRelation(FieldRef);

        //OSynchTypeConversion.EvaluateTextToFieldRef(MatrixData.Value,FieldRef,ToValidate)          // #3 Delete

        Field.GET(RecRef.NUMBER, FieldRef.NUMBER);       // #3 Add line
        IF Field.Type <> Field.Type::Date THEN                 // #3 Add line
          OSynchTypeConversion.EvaluateTextToFieldRef(MatrixData.Value,FieldRef,ToValidate)      // #3 Add line

        ELSE BEGIN                     // #3 Add line
          EVALUATE(DateValue, MatrixData.Value);          // #3 Add line

          FieldRef.VALUE := DateValue;      // #3 Add line
        END;         // #3 Add line

      END;
      IF DataTemplateHeader.GET(MigrationTable."Data Template") THEN
        TemplateMgt.UpdateRecord(DataTemplateHeader,RecRef);
 
* Codeunit 8611, Function ImportSetupDataXML
--------------------------------------------
Before:


            IF MigrationData.Value <> '' THEN BEGIN
              ConvertXMLDates(FieldRef,MigrationData.Value);
              FieldError(MigrationData,EvaluateValue(FieldRef,MigrationData.Value));
              IF FORMAT(FieldRef.VALUE) <> '' THEN
                IF FORMAT(FieldRef.TYPE) <> 'Option' THEN
                  MigrationData.Value := FORMAT(FieldRef.VALUE)
                ELSE
                  MigrationData.Value := GetOptionString(FieldRef,FORMAT(FieldRef.VALUE));

After:

            IF MigrationData.Value <> '' THEN BEGIN
              ConvertXMLDates(FieldRef,MigrationData.Value);
              FieldError(MigrationData,EvaluateValue(FieldRef,MigrationData.Value));
              IF FORMAT(FieldRef.VALUE) <> '' THEN
                IF FORMAT(FieldRef.TYPE) <> 'Option' THEN BEGIN                                    // #4 Add BEGIN 
                  IF FORMAT(FieldRef.TYPE) <> 'Decimal' THEN                                          // #4 Add line 
                    MigrationData.Value := FORMAT(FieldRef.VALUE);
                END ELSE                                                                                                       // #4 Add END 
                  MigrationData.Value := GetOptionString(FieldRef,FORMAT(FieldRef.VALUE));          


* Codeunit 8611, Function ConvertXMLDates
-----------------------------------------
Before:


     CASE Field.Type OF
    
       Field.Type::Date:
         BEGIN
           IF EVALUATE(Date, Value,XMLFormat) THEN BEGIN
             Value := FORMAT(Date);
             FldRef.VALUE := Date;
           END;
         END;


After:

 

      CASE Field.Type OF

        Field.Type::Decimal:                                             // # 4 Add line
          BEGIN                                                              // # 4 Add line
            IF EVALUATE(Decimal,Value) THEN BEGIN      // # 4 Add line
              Value := FORMAT(Decimal,0,XMLFormat);     // # 4 Add line

              FldRef.VALUE := Decimal;                           // # 4 Add line
            END;                                                           // # 4 Add line
          END;                                                             // # 4 Add line

        Field.Type::Date:
          BEGIN
            IF EVALUATE(Date, Value,XMLFormat) THEN BEGIN
              Value := FORMAT(Date);
              FldRef.VALUE := Date;
            END;
          END;

 

* Codeunit 5302, Function TextToDecimal
----------------------------------------
Before:


InputText := CONVERTSTR(InputText,'.',',');
IF STRPOS(InputText,',') = 0 THEN
  EXIT;

PartArray[1] := GetSubStrByNo(1,InputText);
                                                                            

After:

InputText := CONVERTSTR(InputText,'.',',');
IF STRPOS(InputText,',') = 0 THEN BEGIN                         // # 4 Add BEGIN

  IsConverted := TextToInteger(InputText,IntegeralPart);       // # 4 Add line
  IF IsConverted THEN                                                      // # 4 Add line
    DecVar := IntegeralPart;                                              // # 4 Add line
  EXIT;
END;                                                                            // # Add END

PartArray[1] := GetSubStrByNo(1,InputText);

 

Before:


DecVar := IntegeralPart + (FractionalPart / POWER(10,STRLEN(PartArray[2])));    


After:


IF STRPOS(InputText,'-') = 0 THEN  // # 5 Add line
  Sign := 1       // # 5 Add line
ELSE        // # 5 Add line
  Sign := -1;      // # 5 Add line
DecVar := (Sign * (ABS(IntegeralPart) + (FractionalPart / POWER(10,STRLEN(PartArray[2])))));  // #5 Change line

*****End Code fix*****


Laura K. Lake

Microsoft Dynamics NA


Microsoft Customer Service and Support (CSS) North America

These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use. 

Related
Recommended