2

I'm having trouble parsing a CSV from a text file and was wondering if you guys could assist me. So far I have the following,

The CSV file (DATA.txt) looks something like this, it will always have 15 fields all separated by a comma. Not all fields are mandatory so some will be filled and some are blank.

Seattle,Lastname,Firstname,DOB,SEX,etc,etc
Seattle,Lastname,Firstname,DOB,,etc,etc
Portland,Lastname,Firstname,DOB,SEX,,,etc
Portland,Lastname,Firstname,DOB,SEX,etc,etc

And here is my REXX Code

SOURCEFILE = "C:\DATA\DATA.TXT"
IF A=2 THEN DO COUNTER=1 TO LINES(SOURCEFILE)
    PARSE VALUE LINEIN(SOURCEFILE) WITH CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc
    CALL SETCURSOR 4,23
    CALL CREATEDATA
END

CREATEDATA:
CALL TYPE CITY
CALL PRESS TAB
CALL TYPE LAST_NAME
CALL PRESS TAB
CALL TYPE DATE(U)
CALL PRESS TAB
CALL TYPE FIRST_NAME
CALL PRESS TAB
CALL PRESS ENTER
RETURN

I'm not sure if I should be using ARG or VAR when parsing or if I wrote first two lines correctly. I know for fact that my CREATEDATA function works properly because I'm getting the "CITY" typed in but not the parsed value. Any help would be very much appreciated. Thank you!

Ross Patterson
  • 9,527
  • 33
  • 48

2 Answers2

1

A few comments:

1) Lines(SourceFile) on a Windows system probably involves reading the entire file to count CR-LF sequences. Then your Parse value LineIn(SourceFile) loop reads it again. The typical Rexx way to do this would be:

Address SYSTEM 'TYPE' SourceFile with output stem Lines.
Do Counter = 1 to Lines.0
    Parse var Lines.Counter ...
End
Drop Lines.

At least, as long as the file isn't so large that keeping it in an array is costly in memory.

2) You're flowing down into CreateData at the end of your loop, which is why you're seeing "CITY". You need a Return or Exit after that End instruction.

3) In light of #2, it's obvious that the Parse is never being executed, because City is uninitialized (the value of an uninitialized variable in Rexx is its name in upper case). It's conditional on A=2, which must not be the case.

Ross Patterson
  • 9,527
  • 33
  • 48
  • According to Cowlishaw's Rexx book, the LINES built in function may return the number of lines in the referenced file or, if that cannot be determined, a '1' where a non-zero count would be appropriate, otherwise a '0'. I use ooRexx on windows quite a bit and can confirm that ooRexx does not count all lines, it just returns a 0/1. I use the following to read files one line at a time: DO WHILE LINES(filename) > 0; PARSE VALUE LINEIN(filename) with... ; END – NealB Apr 12 '13 at 13:38
  • The result of `Lines()` is implementation-dependent. Some implementations return a count, others just 1 or 0 as you've observed. It's also why I prefer to load the stem up: `Lines.0` is an actual count. – Ross Patterson Apr 12 '13 at 23:33
1

One question what is the purpose of if A=2 then in

IF A=2 THEN DO COUNTER=1 TO LINES(SOURCEFILE)

if A != 2 the loop is bypassed. I suspect your program should be:

SOURCEFILE = "C:\DATA\DATA.TXT"
DO COUNTER=1 TO LINES(SOURCEFILE) 
    PARSE VALUE LINEIN(SOURCEFILE) WITH CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc
    CALL SETCURSOR 4,23
    CALL CREATEDATA
END

RETURN   /* prevent the fall through to createdata */

CREATEDATA:




---------------------------

The parse statement has the following basic format

parse [source] [parse-control]

where [source] icludes

arg - arguments on a procedure call pull - data pulled off the stack var - data comes from a variable value ... with data supplied inline

So your parse could be done like

   linein = LINEIN(SOURCEFILE)
   PARSE var linein CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc

or

    DO COUNTER=1 TO LINES(SOURCEFILE) 
        CALL SETCURSOR 4,23
        CALL CREATEDATA LINEIN(SOURCEFILE)
    END

    RETURN   /* prevent the fall through to createdata */

    CREATEDATA:
    parse arg CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc

Finally ass ross said you should try and aviod lines(sourcefile) as it involves reading the entire file

Bruce Martin
  • 10,358
  • 1
  • 27
  • 38