GXS AI: Tutorial, lesson 6

Variables (and Arrays)

In this lesson we’ll see how to use variables and the difference between variables and arrays.

It’s time to start working with more complex structures which are more similar to the “live” documents. We’ll be using our map “example02” we created on previous step as the base. Let’s change it.

First of all, we need to change the structures of both source and target documents. In the real life documents usually contain three main parts (blocks of data):

  • Header. This block usually contains the document number/date, addresses and so on – the common information.
  • Details. Usually there some kind of a repeatable data (Line Items and their IDs, names, quantity, price and so on)
  • Summary section. This block contains all the total amounts, taxes/fees, total quantities and so forth. This section is very similar to the Header section, but often it is placed at the end of the document to emphasize its “summary” role (like you can see in the paper documents).

The documents we created in the previous lessons (as you can guess) are very close to the details block, so we’ll leave it as is. All we need to make our structures to look like “live” documents is to add the Header and Summary sections. New formats will be:

Source Document:

Record Status Name Min Max
HDR M Header Record 1 1
LIN M Data Record 1 100
SUM M Summary Record 1 1
Record Field Name Data Type Status Length Position Notes
HDR
01 Record ID AN M 3 1-3 Always “HDR”
02 PO Number AN M 10 4-13 Purchase Order Number
03 PO Date DT M 8 14-21 Purchase Order Date, format YYYYMMDD
LIN
01 Record ID AN M 3 1-3 Always “LIN”
02 Line Item ID AN M 12 4-15 UPC Code
03 Quantity N M 3 16-18 Qty ordered
04 Unit Price N M 10 19-28 Item Price, USD
05 Expiration Date DT M 8 29-36 Expiration Date, format YYYYMMDD
SUM
01 Record ID AN M 3 1-3 Always “SUM”
02 Total Amount N M 10 4-13 Total Amount of PO

Example:

HDR000123456720100331
LIN0123456789120500000125,9920100412
LIN0123456654371500000025,0020100831
LIN6678456789142500000012,0020100416
LIN9923456789151000000005,7520100519
SUM00013624.5

Target Document:

Record Status Name Min Max
00 M Header Record 1 1
01 M Data Record 1 200
99 M Summary Record 1 1
Record Field Name Data Type Status Length Position Notes
00
01 Record ID AN M 2 1-2 Always “00”
02 PO Number AN M 5 3-7 Purchase Order Number
03 PO Date DT M 8 8-15 Purchase Order Date, format MM/DD/YY
01
01 Record ID AN M 2 1-2 Always “01”
02 Line # N M 3 3-5 Line Number
03 Line Item ID AN M 12 6-17 UPC Code
04 Unit Price N M 10 18-27 Item Price, USD
05 Quantity N M 3 28-30 Qty ordered
06 Expiration Date DT M 8 31-38 Expiration Date, format MM/DD/YY
99
01 Record ID AN M 2 1-2 Always “99”
02 Total Amount N M 10 3-12 Total Amount of PO
03 Total Quantity N M 10 13-22 Total Quantity of PO

Example:

003456703/31/10
010010123456789120000125,9905004/12/10
010020123456654370000025,0015008/31/10
010036678456789140000012,0025004/16/10
010049923456789150000005,7510005/19/10
9900013624.50000000550

Task #1: change our example02 map and add these Header/Summary records to both source and target models.

Hint: to add new records, click on the existing “LIN” record (for the source model) and select Model->Insert Item->Above for HDR and Model->Insert Item->Below for SUM:

Looks easy, huh? 🙂

Task #2: as you can guess, the relationship between the LIN and 01 records remain the same and we can use the same approach as we did on the previous lesson. Even more – you don’t need to change anything. Our main attention should be focused on HDR-00 and SUM-99 relationships. On this step you should find appropriate links between these records/fields and the differences between the fields.

Now it’s time to create rules for mooving data from the source’s HDR/SUM records to the target’s 00/99. How can we move data from source’s PONumber to the target’s PONumber? Of course, we can use an array, but it’s incorrect for the several reasons. There will be only one value, arrays require more resources during translation, it might confuse people who would work on this map later and so on. So, we need to use variables. Using of variables is very similar to arrays, but when you’re assigning a value to an array:

ARRAY->PONumber_PONumber = …

you’re adding next value to this array. When you’re assigning a value to a variable, you’re changing it to the new one.

VAR->PONumber_PONumber = …

So, we need to use variables. Let’s do it step by step:

  1. In the HDR record of the source model , add the following rule:
    [ ]
    VAR->PONumber_PONumber = STRTRIM(PONumber, "B", " ")
    VAR->PODate_PODate = STRTRIM(PODate, "B", " ")
  2. …and to the SUM:
    [ ]
    VAR->TotalAmount_TotalAmount = STRTRIM(TotalAmount, "B", " ")


    Remember that in the source document we have to add our rules into records, not fields!

  3. In the target model, we should use these variables in the appropriate fields. For example, 00->PONumber
    [ ]
    PONumber = VAR->PONumber_PONumber

    and so on

  4. The field 99-> TotalQuantity doesn’t have appropriate field in the source structure, so we’re using a stub and will change it later:
    [ ]
    TotalQuantity = "0"
  5. Trying to translate…
    000001203/31/10
    010010123456789120000125,9905004/12/10
    010020123456654370000025,0015008/31/10
    010036678456789140000012,0025004/16/10
    010049923456789150000005,7510005/19/10
    9900013624.50         

    As you can see, there are some differences from the expected output. The PONumber in the source model has the length of 10, but PONumber in the target model is only 5. As you can see, translator used the first 5 symbols but we need the last 5 ones. So, we need to somehow take the last 5 symbols. And one more question – where to put this code – on the left or right side? I strongly recommend you to always use only one part for all the data changes, and I also recommend you to do it on the left (source) part. You need to be consistent.

  6. Ok, let’s change our code from
    VAR->PONumber_PONumber = STRTRIM(PONumber, "B", " ")

    to

    VAR->TMP_PONumber = STRTRIM(PONumber, "B", " ")
    VAR->PONumber_PONumber = STRSUBS(VAR->TMP_PONumber, STRLEN (VAR->TMP_PONumber)-4, STRLEN(VAR->TMP_PONumber))

    Here we’re using STRSUBS function which takes a substring from a string. Syntax:

    STRSUBS(<str>, <start_position>, <end_position>)

    Also, we’re using STRLEN function which returns the length of a string.

  7. Try to translate one more time:
    003456703/31/10
    010010123456789120000125,9905004/12/10
    010020123456654370000025,0015008/31/10
    010036678456789140000012,0025004/16/10
    010049923456789150000005,7510005/19/10
    9900013624.50         

    Looks right except for the TotalQuantity field.

  8. As you can guess, we need to calculate the Total Quantity somehow. And I hope you remember how we used a variable for the LineNumber. Here we’ll use the same approach.
  9. Open the Initialization group in the target document and change
    [ ]
    VAR->Record_Cnt = 0

    to

    [ ]
    VAR->Record_Cnt = 0
    VAR->Total_Qty = 0
  10. Now open the Quantity field of the target document and change
    [ ]
    Quantity = ARRAY->Quantity_Quantity

    to

    [ ]
    Quantity = ARRAY->Quantity_Quantity
    
    VAR->Total_Qty = VAR->Total_Qty + ARRAY->Quantity_Quantity
  11. And finally change the code in the TotalQuantity from
    [ ]
    TotalQuantity = "0"

    to

    [ ]
    TotalQuantity = STRFILL(NUMTRIM(VAR->Total_Qty, 0), "L", "0", 10)
  12. Save both models (I hope you remember about it)
  13. Translate and check the result:
    003456703/31/10
    010010123456789120000125,9905004/12/10
    010020123456654370000025,0025008/31/10
    9900013624.50000000250

    Hmmm… What’s that? Where are two line items??? If you check it carefully you’ll see that the translator used 1st and 3rd lines for 00-records and 2nd and 4th for the total qty calculation.

    It’s very important moment. Every time you’re getting an element from the array, the pointer goes to the next element.

  14. So, let’s change the code in the Quantity field to this one:
    [ ]
    VAR->TMP_Quantity = ARRAY->Quantity_Quantity
    
    Quantity = VAR->TMP_Quantity
    VAR->Total_Qty = VAR->Total_Qty + VAR->TMP_Quantity
  15. Run the translator… this time the output looks right!
    003456703/31/10
    010010123456789120000125,9905004/12/10
    010020123456654370000025,0015008/31/10
    010036678456789140000012,0025004/16/10
    010049923456789150000005,7510005/19/10
    9900013624.50000000550

Gennady Kim

Advertisements

20 thoughts on “GXS AI: Tutorial, lesson 6

  1. thnks 🙂 can you please mail me some dcument or tips if you have any so that i can read those and try to implement.. m in project in which gxs is used, and i don’t know how to work with this. i have a knowledge of seeburger.. please help me ..

  2. Hi gennady,

    I really appreciate your effort in writing up this.I’m still confused about usage of Array and Variable.My interpretation is we use any array when we have a segment that has max occurence>1 and we want a particular element value to be stored in array.
    Say we have REF segment that loops 100 times and all REF01’s goes into array we assign.Please do correct me if I’m wrong and can you explain me with an example.

    • we need to use arrays for repeatable elements with the same type. Like LineItems or Free-Form text. REF (References) – it depends. For example, if we need to filter out Bill Of Lading from

      REF*AA*00001~
      REF*BM*BillOfLading02~
      REF*CC*00003~

      We need to use a Variable – since there is only one BillOfLading. We don’t need to put all the REFs into array. So I wouldn’t say that “>1” is a right indicator for “use arrays”. But for 0..1 or 1..1 elements we usually should use variables

  3. Hello KIM, please share how to read the error log that is generated by translation failure and how can we compare the log for successful translation and failed translation. I am new in this and usually work on errors and finding it very hard to read the logs..

    Best regards,
    sony

    • Indeed, good question. Unfortunately I don’t have any clear instructions for “how to read the error log”. Successful transaction ends with

      Session 004105 ended at {date}
      with error cd 0

      • Thank you and in case you come across anything valuable in this regards, please do share..

        Best regards,
        Sony

  4. Hi Kim,

    I’m working on EDI platform migration from Commerce Connect to Secure File Exchange.
    Please advise if you’ve any idea about this

  5. Hello Kim…this article is really interesting, is there any way to read a string character by character and catch the space or special character in that string

    • hard to say… from the first glance there is no easy and short solution. Probably you need to create a loop and check the characters one by one in the loop (using “WHILE” statement)

      • Can we use string functions such as STRLEN , also can you please provide me the list of string functions we can use in EDI mapping/ suggest me some url where I can get them ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s