Parsing String based on spaces?

jversusjjversusj Member Posts: 489
hello,
can anyone point me to existing NAV code (or nudge me with a custom design idea) to parse a string based on word-breaks?

here is my scenario:
we send mailings to NAV contacts using the United States Postal Service and we subscribe to a Change of Address notification system with them. Essentially, we barcode every piece of mail (so the NAV contact can be identified) and if it is undeliverable or a change of address has been initiated, we receive notification via an ASCII file.

i have put together a dataport to parse the 561 character ascii file, populating a custom Pending Address change table. the user will then view the records in a custom form, and click a button to "update address and create interaction." the interaction will be automated, describing the address change or undeliverable reason.

Here comes my question. The USPS provides the parsed address and a concatenated (formatted) address label of length 66 (so i know i have to do some trimming somewhere since address 1 and address 2 are both Text30 fields). i am importing all of this data into my custom table. i would therefore have fields such as
primary number new (example = 1000)
pre-directional new (example = N)
street name new (example = Broadway)
street suffix new (example = Blvd)
post-directional new
unit designator new (example = STE)
secondary number new (example = 9B)
city new (example = big city)
state new (example = ohio)
post code new (example = 44444)
label format new address (1000 N Broadway Blvd STE 9B)

in cases where the label format new address is <= 30 characters, it can be copied to the Address field of contact record (on button push). What if, however, that address lable is >30 characters? i have to chop it up and populate some data in address 1 and some data in address 2.

so, what is the better approach, to take the nice and clean label new format address from USPS and find a convenient place to break the value into Address 1 and Address 2, or build up address 1 and address 2 manually with my own concatenation within NAV? How could i approach either of these options? i'm not looking for full code, just some ideas to get me started. i haven't done this sort of string manipulation before.

Thanks in advance!
kind of fell into this...

Answers

  • BeliasBelias Member Posts: 2,998
    here's my idea: in your custom table, crate 3 new field:
    - address 1 (text30)
    - address 2 (text30)
    - address to check (boolean)

    Moreover, enlarge your "label format new address" to 66 (unless it's already long like this)
    First of all, populate your label format new address with the whole data from the text file.
    Then populate "address 1" and "address 2" fields: you can simply split 30-30 or do an alghorytm (wrote correctly? :? ) to split at the last space before 30 chars (be careful to put the space in the "address 2", because trailing spaces disappear in text fields) of your "label format new address" field.

    evaluate "address to check" if the "label format new address" overcome 30 chars.

    In this way, you import the adress as is, and (if necessary) you suggest an address splitting to the user who is "validating" this table. Train him to filter the table with "address to check" = true before validating the table. Obviously let him modify address 1 and address 2 if he wants

    Also: this is not a good solution if the 90% of your addresses are larger than 30 chars :mrgreen:
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • jversusjjversusj Member Posts: 489
    Belias wrote:
    here's my idea: in your custom table, crate 3 new field:
    - address 1 (text30)
    - address 2 (text30)
    - address to check (boolean)

    Moreover, enlarge your "label format new address" to 66 (unless it's already long like this)
    First of all, populate your label format new address with the whole data from the text file.
    Then populate "address 1" and "address 2" fields: you can simply split 30-30 or do an alghorytm (wrote correctly? :? ) to split at the last space before 30 chars (be careful to put the space in the "address 2", because trailing spaces disappear in text fields) of your "label format new address" field.

    evaluate "address to check" if the "label format new address" overcome 30 chars.

    In this way, you import the adress as is, and (if necessary) you suggest an address splitting to the user who is "validating" this table. Train him to filter the table with "address to check" = true before validating the table. Obviously let him modify address 1 and address 2 if he wants

    Also: this is not a good solution if the 90% of your addresses are larger than 30 chars :mrgreen:

    i am already pulling in the label format new address to a field of length 66, and i already have the Update Address 1 and Update Address 2 fields as well. In fact, i have almost everything you spoke of, except the Address to check. They will technically have to process every record (they want human eyes running the update). I am curious how to create the algorithm you mention (the address i programmatically suggest them to use). all i can think of is a complicated series of STRPOS and COPYSTR.

    any similar code i could peak at in NAV?
    kind of fell into this...
  • BeliasBelias Member Posts: 2,998
    all i can think of is a complicated series of STRPOS and COPYSTR.
    
    me, too...i also tought about using the "text variable = array of single characters" feature...anyway, i didn't really think seriously about the algorithm...give me some time :wink:
    (i hoped you thought about and post it, so i could copy it in my utility folder :whistle: )
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • BeliasBelias Member Posts: 2,998
    I've done it in 15-20 minutes...it's better for you to do some tests before using it :-$
    It's ad hoc for your specific case, because lenghts should be more dynamical, also maxstrlen should be used, but i think that with numbers is easier to read and understand...althought, mine it's only an idea

    Name DataType Subtype Length
    TXTWhole Text 60
    TXT1 Text 30
    TXT2 Text 30
    INTLastSpacePos Integer
    INTActualPos Integer
    TXTWhole := '12345678901234567890123456789012345678901234567890123456789';
    if TXTWhole[30] = ' ' then begin
      txt1 := copystr(txtwhole,1,29);
      txt2 := copystr(txtwhole,30,30);
    end else begin
      intlastspacepos := 0;
      for INTActualPos := 1 to 30 do begin
        if txtwhole[INTActualPos] = ' ' then begin
          intlastspacepos := intactualpos;
        end;
      end;
      if intlastspacepos <> 0 then begin
        txt1 := copystr(txtwhole,1,intlastspacepos - 1);
        txt2 := copystr(txtwhole,intlastspacepos,30);
      end else begin
        txt1 := copystr(txtwhole,1,30);
        txt2 := copystr(txtwhole,31,30);
      end;
    end;
    message(txt1);
    message(txt2);
    
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • jversusjjversusj Member Posts: 489
    Belias wrote:
    I've done it in 15-20 minutes...it's better for you to do some tests before using it :-$
    It's ad hoc for your specific case, because lenghts should be more dynamical, also maxstrlen should be used, but i think that with numbers is easier to read and understand...althought, mine it's only an idea

    Name DataType Subtype Length
    TXTWhole Text 60
    TXT1 Text 30
    TXT2 Text 30
    INTLastSpacePos Integer
    INTActualPos Integer
    TXTWhole := '12345678901234567890123456789012345678901234567890123456789';
    if TXTWhole[30] = ' ' then begin
      txt1 := copystr(txtwhole,1,29);
      txt2 := copystr(txtwhole,30,30);
    end else begin
      intlastspacepos := 0;
      for INTActualPos := 1 to 30 do begin
        if txtwhole[INTActualPos] = ' ' then begin
          intlastspacepos := intactualpos;
        end;
      end;
      if intlastspacepos <> 0 then begin
        txt1 := copystr(txtwhole,1,intlastspacepos - 1);
        txt2 := copystr(txtwhole,intlastspacepos,30);
      end else begin
        txt1 := copystr(txtwhole,1,30);
        txt2 := copystr(txtwhole,31,30);
      end;
    end;
    message(txt1);
    message(txt2);
    
    i will give this test and make it more dynamic, as you say. thank you!

    i got a little sidetracked today and wrote the rest of my processing/interaction/archiving routine. it's working smooth as silk, can't wait to get this little condition resolved to cap it all off. then i will be a happy person. :)
    kind of fell into this...
  • jversusjjversusj Member Posts: 489
    i started working with your code sample and started to think about it...

    the label address can contain up to 66 characters - to long for NAV anyhow. This means that even if i do successfully break apart the address as a space (minus 1 character = 65), i still have too much data. so, i'm thinking of taking the easy way out. another thing i considered while reading your code was that i was breaking text at space (as i thought i wanted), but it could still result in less than ideal address values. for example, i could inadvertently put a break between Suite and the Suite number. address 1 would have the Suite but Address 2 would have the value that defines which Suite. it would still be less than perfect data structure.

    during my dataport, i check the STRLEN on the label address. if it is > 60, i flag the address (like you originally suggested). if it is <= 30, i copy the value to Address 1 field in custom table, else i copy 1 - 30 to address 1 and 31- 60 to address 2 and flag it for checking.

    then on the form, i use the OnFormat trigger to make the address fields red when they need to be checked. i think it might be good enough for now. i will keep looking into this to see if can make it work how i'd like better.
    kind of fell into this...
  • BeliasBelias Member Posts: 2,998
    Glad to be helpful...
    indeed, as you understood, a program is "stupid" and cannot think what is the "Best space", but only the last...in a procedure like this, a user interaction is inevitable.
    i also hope you noticed that when i cut out the space, i move it to the "address 2", so you're not gaining any character.
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
Sign In or Register to comment.