home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / c / codebk11.zip / CODEBOOK.BAS next >
BASIC Source File  |  1990-12-21  |  27KB  |  245 lines

  1. 1 'Centrum voor Medische Informatica TNO       <Email>              |  |  |\/|
  2. 2 'TNO Center for Medical Informatics | GROENEVELD@CMI.TNO.NL  |  \_/  |  |  |
  3. 3 '( CMI-TNO )    | Y. Groeneveld     | GROENEVELD@CMIHP1.UUCP | Jim Groeneveld
  4. 4 'P.O.Box 124    | Wassenaarseweg 56 | GROENEVELD@TNO.NL      | Schoolweg 14
  5. 5 '2300 AC Leiden | 2333 AL Leiden    | ...@HDETNO51.BITNET    | 8071 BC Nunspeet
  6. 6 'Nederland.     | (+31|0)71-181810  | Fax (+31|0)71-176382   | 03412-60413
  7. 10 CLEAR:CLOSE:SCREEN 0:WIDTH 80:KEY OFF:COLOR 7,1,1:CLS:DEFINT A-Z:OPTION BASE 1
  8. 20 CHECK.RESULT$="BAD":PRINT "+++ Program CODEBOOK.BAS, version 1.1 by Jim Groeneveld, 21 December 1990. +++"
  9. 25 MAX.N.OF.VARS=0:WHILE MAX.N.OF.VARS=0 ''' or max.n.of.vars<-32767 or max.n.of.vars>32767
  10. 30   PRINT "--- Enter (at least) total number of variables to reserve array space or";"    enter a NEGATIVE starting number for automatic adaptation";"    to the actual number in the codebook file [-100]: ";
  11. 35   INPUT"",MAX.N.OF.VARS '====== in order to reserve array space
  12. 40   IF MAX.N.OF.VARS=0 THEN MAX.N.OF.VARS=-100
  13. 50   IF MAX.N.OF.VARS<-32767 OR MAX.N.OF.VARS>32767 THEN BEEP:PRINT "*** Illegal number of variables entered! ***"
  14. 55   IF MAX.N.OF.VARS<0 THEN MAX.N.OF.VARS=-MAX.N.OF.VARS:EXTRA.VARS=MAX.N.OF.VARS:AUTO.NOV$="YES" ELSE AUTO.NOV$="NO"
  15. 60 WEND
  16. 70 MAX.VARS.PER.FILE=32767:MAX.LINE.INPUT.LENGTH=255:WILDCARD$="NO"
  17. 80 DIM VARIABLE.NAME$(MAX.N.OF.VARS),BEGIN.COLUMN!(MAX.N.OF.VARS),END.COLUMN!(MAX.N.OF.VARS),MISSING.VALUE$(MAX.N.OF.VARS),VAR.TYPE$(MAX.N.OF.VARS)
  18. 99 N.OF.DATA.LINES=1:MAX.COL.SPEC=254
  19. 102 PRINT "--- Do you want to check the codebook for identical variable names? [Y]/N: ";
  20. 104 CHECK.VAR.NAME$="":WHILE CHECK.VAR.NAME$="":WHILE CHECK.VAR.NAME$="":CHECK.VAR.NAME$=INKEY$:WEND:IF INSTR("YyNn"+CHR$(13),CHECK.VAR.NAME$)=0 THEN BEEP:CHECK.VAR.NAME$=""
  21. 106 WEND:IF INSTR("Yy"+CHR$(13),CHECK.VAR.NAME$)>0 THEN CHECK.VAR.NAME$="YES" ELSE CHECK.VAR.NAME$="NO"
  22. 108 PRINT CHECK.VAR.NAME$
  23. 110 WHILE CHECK.RESULT$<>"OK"
  24. 111   WHILE CHECK.RESULT$<>"OK"
  25. 120     GOSUB 12010:PRINT "--- Enter codebook [drive:][path\]filename: ";:LINE INPUT CODEBOOK.COL$
  26. 130     D.PATH.FILENAME.EXT$=CODEBOOK.COL$:GOSUB 11000:GOSUB 12040 'check file name and split name and extension as CODEBOOK$ and COL$.
  27. 140     IF CHECK.RESULT$<>"OK" AND CHECK.RESULT$<>"WILDCARD" THEN BEEP:PRINT CHECK.RESULT$:GOTO 160
  28. 150     CODEBOOK.COL$=D.PATH.FILENAME.EXT$:CODEBOOK$=D.PATH.FILENAME$:COL$=EXT$:GOSUB 12020
  29. 160   WEND
  30. 170   ON ERROR GOTO 11400:OPEN "I",#1,CODEBOOK.COL$:ON ERROR GOTO 0
  31. 180   IF CHECK.RESULT$<>"OK" THEN BEEP:PRINT CHECK.RESULT$
  32. 190 WEND:PRINT "=== Scanning and reading codebook file......please wait and see......"
  33. 200 TOT.N.OF.VARS=0:LINE.COUNT=0:CHECK.FIELD.WIDTH$="OK":WHILE NOT EOF(1)
  34. 202   LINE.COUNT=LINE.COUNT+1:CHECK.RESULT$="OK":ON ERROR GOTO 11400:FIRST.COLUMN$=INPUT$(1,#1)
  35. 204   IF FIRST.COLUMN$=CHR$(13) THEN SECOND.COLUMN$=INPUT$(1,#1):ON ERROR GOTO 0:GOTO 285 '====== (reading LF as the second character) This is an empty line (only CRLF)
  36. 206   IF FIRST.COLUMN$<>" " AND FIRST.COLUMN$<>"'" AND FIRST.COLUMN$<>CHR$(34) THEN LINE INPUT #1,COMMENT.LINE$:J=LEN(COMMENT.LINE$):GOSUB 1050:ON ERROR GOTO 0:GOTO 285 '====== this is a comment line
  37. 208   IF TOT.N.OF.VARS=>MAX.N.OF.VARS AND AUTO.NOV$="NO" THEN BEEP:PRINT "*** Number of variables exceeds maximum of";MAX.N.OF.VARS;", correct and rerun ***";STRING$(80-POS(0),32):CLOSE:STOP
  38. 210   IF TOT.N.OF.VARS=100 THEN PRINT "If running under interpreter BASIC time consuming garbage collection may occur!"
  39. 212   IF TOT.N.OF.VARS=MAX.N.OF.VARS AND AUTO.NOV$="YES" THEN GOSUB 1100 '------ increase arrays VAR.TYPE$, MISSING.VALUE$, BEGIN.COLUMN!, END.COLUMN! and VARIABLE.NAME$ by EXTRA.VARS elements and continue
  40. 214   TOT.N.OF.VARS=TOT.N.OF.VARS+1:VAR.TYPE$(TOT.N.OF.VARS)=FIRST.COLUMN$ ''''':if var.type$(tot.n.of.vars)=" " then var.type$(tot.n.of.vars)="" leads to erroneous copying to another array!!!
  41. 216   INPUT #1,MISSING.VALUE$(TOT.N.OF.VARS),BEGIN.COLUMN!(TOT.N.OF.VARS),END.COLUMN!(TOT.N.OF.VARS),FIELD.WIDTH:LINE INPUT #1,VARIABLE.NAME$(TOT.N.OF.VARS):J=LEN(VARIABLE.NAME$(TOT.N.OF.VARS)):GOSUB 1050:ON ERROR GOTO 0
  42. 218   IF (TOT.N.OF.VARS MOD 10)=0 THEN PRINT "===";TOT.N.OF.VARS;"variables processed from codebook file ";CODEBOOK.COL$;STRING$(80-POS(0),32);:LOCATE ,1
  43. 220   IF CHECK.RESULT$<>"OK" THEN BEEP:PRINT "*** Error";ERROR.NUMBER;"in codebook at line";LINE.COUNT;", variable";TOT.N.OF.VARS;", program abort! ***";STRING$(80-POS(0),32):CLOSE:STOP
  44. 230   WHILE LEFT$(VARIABLE.NAME$(TOT.N.OF.VARS),1)=" ":VARIABLE.NAME$(TOT.N.OF.VARS)=MID$(VARIABLE.NAME$(TOT.N.OF.VARS),2):WEND
  45. 240   I=INSTR(VARIABLE.NAME$(TOT.N.OF.VARS)," "):J=INSTR(VARIABLE.NAME$(TOT.N.OF.VARS),",")
  46. 250   IF J<>0 AND (I>J OR I=0) THEN I=J 'else I remains I
  47. 255   IF I<>0 THEN VARIABLE.NAME$(TOT.N.OF.VARS)=LEFT$(VARIABLE.NAME$(TOT.N.OF.VARS),I-1)
  48. 260   IF VARIABLE.NAME$(TOT.N.OF.VARS)="" THEN VARIABLE.NAME$(TOT.N.OF.VARS)="Var"+MID$(STR$(TOT.N.OF.VARS),2) '====== if no variable name defined, use "Var"&VarNumber
  49. 262   IF CHECK.VAR.NAME$<>"NO" THEN GOSUB 13100 '====== optional check for identical variable names
  50. 265   IF BEGIN.COLUMN!(TOT.N.OF.VARS)<=0 OR END.COLUMN!(TOT.N.OF.VARS)<=0 THEN GOSUB 999:PRINT "*** Illegal fields for variable";TOT.N.OF.VARS;", ";VARIABLE.NAME$(TOT.N.OF.VARS);" at line";LINE.COUNT;" ***";STRING$(80-POS(0),32)
  51. 270   IF BEGIN.COLUMN!(TOT.N.OF.VARS)>END.COLUMN!(TOT.N.OF.VARS) THEN GOSUB 999:PRINT "*** Starting field > ending one for variable";TOT.N.OF.VARS;", ";VARIABLE.NAME$(TOT.N.OF.VARS);" at line";LINE.COUNT;" ***";STRING$(80-POS(0),32)
  52. 271   IF FIELD.WIDTH=0 THEN FIELD.WIDTH=END.COLUMN!(TOT.N.OF.VARS)-BEGIN.COLUMN!(TOT.N.OF.VARS)+1 '###### added in vs. 1.1 to support additional check of field width if FIELD.WIDTH not given
  53. 272   IF FIELD.WIDTH<0 OR FIELD.WIDTH>255 THEN GOSUB 999:PRINT "*** Illegal field width for variable";TOT.N.OF.VARS;", ";VARIABLE.NAME$(TOT.N.OF.VARS);" at line";LINE.COUNT;" ***";STRING$(80-POS(0),32)
  54. 275   IF FIELD.WIDTH<>END.COLUMN!(TOT.N.OF.VARS)-BEGIN.COLUMN!(TOT.N.OF.VARS)+1 AND FIELD.WIDTH<>0 THEN GOSUB 999:PRINT "*** Non-matching field width for variable";TOT.N.OF.VARS;", ";VARIABLE.NAME$(TOT.N.OF.VARS);" at line";LINE.COUNT;" ***" '#
  55. 281   IF END.COLUMN!(TOT.N.OF.VARS)>MAX.COL.SPEC! THEN MAX.COL.SPEC!=END.COLUMN!(TOT.N.OF.VARS) ELSE 285
  56. 282   N.OF.DATA.LINES=INT((MAX.COL.SPEC!)/MAX.LINE.INPUT.LENGTH)+1:MAX.COL.SPEC!=N.OF.DATA.LINES*MAX.LINE.INPUT.LENGTH-1
  57. 283 ''if n.of.data.lines>32767 then gosub 999:print "*** Ending field > maximum";32767*max.line.input.length-1;"for variable";tot.n.of.vars;", ";variable.name$(tot.n.of.vars);" at line";line.count;" ***"
  58. 285 WEND:CLOSE 1:PRINT "===";TOT.N.OF.VARS;"variables processed from codebook file ";CODEBOOK.COL$;STRING$(80-POS(0),32)
  59. 290 IF CHECK.FIELD.WIDTH$="BAD" OR CHECK.VAR.NAME$="BAD" THEN BEEP:PRINT "*** Correct errors in codebook file and rerun......program abort ***":STOP
  60. 295 IF TOT.N.OF.VARS=0 THEN 800
  61. 400 CHECK.RESULT$="BAD"
  62. 410 WHILE CHECK.RESULT$<>"OK"
  63. 420   WHILE CHECK.RESULT$<>"OK"
  64. 430     GOSUB 12010:PRINT "--- Enter database [drive:][path\]filename: ";:LINE INPUT DATABASE.DAT$
  65. 440     D.PATH.FILENAME.EXT$=DATABASE.DAT$:GOSUB 11000:GOSUB 12040 'check file name and split name and extension as DATABASE$ and DAT$
  66. 450     IF CHECK.RESULT$<>"OK" AND CHECK.RESULT$<>"WILDCARD" THEN BEEP:PRINT CHECK.RESULT$:GOTO 470
  67. 460     DATABASE.DAT$=D.PATH.FILENAME.EXT$:DATABASE$=D.PATH.FILENAME$:DAT$=EXT$:GOSUB 12020
  68. 470   WEND
  69. 475   GOSUB 14000:IF CHECK.RESULT$<>"OK" THEN BEEP:PRINT "*** File name error: numerical extension not permitted, used for output! ***":PRINT "*** Rename database file to a valid name and rerun......program abort ***":STOP
  70. 480   ON ERROR GOTO 11400:OPEN "I",#1,DATABASE.DAT$:ON ERROR GOTO 0:CLOSE 1
  71. 490   IF CHECK.RESULT$<>"OK" THEN BEEP:PRINT CHECK.RESULT$
  72. 500 WEND:DIM DATA.LINE$(N.OF.DATA.LINES)
  73. 501 PRINT "--- Do you want to check the database for equal record lengths? Y/[N]: ";
  74. 502 CHECK.RECORD.LENGTH$="":WHILE CHECK.RECORD.LENGTH$="":WHILE CHECK.RECORD.LENGTH$="":CHECK.RECORD.LENGTH$=INKEY$:WEND:IF INSTR("YyNn"+CHR$(13),CHECK.RECORD.LENGTH$)=0 THEN BEEP:CHECK.RECORD.LENGTH$=""
  75. 503 WEND:IF INSTR("Yy",CHECK.RECORD.LENGTH$)>0 THEN CHECK.RECORD.LENGTH$="YES" ELSE CHECK.RECORD.LENGTH$="NO"
  76. 504 PRINT CHECK.RECORD.LENGTH$
  77. 505 PRINT "=== Output files wil be called: ";DATABASE$;" with a numerical extension."
  78. 510 PRINT "--- Do you want to overwrite any already existing output file? [Y]/N: ";
  79. 512 OVERWRITE$="":WHILE OVERWRITE$="":WHILE OVERWRITE$="":OVERWRITE$=INKEY$:WEND:IF INSTR("YyNn"+CHR$(13),OVERWRITE$)=0 THEN BEEP:OVERWRITE$=""
  80. 514 WEND:IF INSTR("Yy"+CHR$(13),OVERWRITE$)>0 THEN OVERWRITE$="YES" ELSE OVERWRITE$="NO"
  81. 516 PRINT OVERWRITE$
  82. 520 PRINT "--- Choose type of output data files: BLANK or COMMA delimited or FIXED";"    formatted or Report with 1..9 spaces as delimiters: B/[C]/F/1/../9: ";
  83. 522 DELIMITER$="":WHILE DELIMITER$="":WHILE DELIMITER$="":DELIMITER$=INKEY$:WEND:IF INSTR("BbCcFf"+CHR$(13),DELIMITER$)=0 AND VAL(DELIMITER$)=0 THEN BEEP:DELIMITER$=""
  84. 524 WEND:DEL.SPACES=VAL(DELIMITER$):IF DEL.SPACES>0 GOTO 526
  85. 525 IF INSTR("Bb",DELIMITER$)>0 THEN DELIMITER$="BLANK" ELSE IF INSTR("Ff",DELIMITER$)>0 THEN DELIMITER$="FIXED" ELSE DELIMITER$="COMMA"
  86. 526 PRINT DELIMITER$:IF DEL.SPACES>0 THEN DELIMITER$="" ELSE IF DELIMITER$="BLANK" THEN DELIMITER$=" " ELSE IF DELIMITER$="FIXED" THEN DELIMITER$="" ELSE DELIMITER$=","
  87. 530 PRINT "--- Do you want a header with variable names as the first line of each output":IF DELIMITER$="" AND DEL.SPACES=0 THEN PRINT "    file? Y/[N]: "; ELSE PRINT "    file? [Y]/N: ";
  88. 532 HEADER$="":WHILE HEADER$="":WHILE HEADER$="":HEADER$=INKEY$:WEND:IF INSTR("YyNn"+CHR$(13),HEADER$)=0 THEN BEEP:HEADER$=""
  89. 534 WEND:IF INSTR("Yy",HEADER$)>0 OR (HEADER$=CHR$(13) AND (DELIMITER$<>"" OR DEL.SPACES>0)) THEN HEADER$="YES" ELSE HEADER$="NO"
  90. 536 PRINT HEADER$
  91. 540 MISSING$="":WHILE MISSING$=""
  92. 542   PRINT "--- Enter (missing) value to replace entirely blank fields for variables for";"    which not yet specified in the codebook file [-1]: ";:LINE INPUT MISSING$
  93. 544   IF MISSING$="" THEN MISSING$="-1"
  94. 546 WEND
  95. 550 IF DELIMITER$="" THEN REM.SPACES$="NO":GOTO 560 ELSE PRINT "--- Do you want to remove insignificant spaces from the values? [Y]/N: ";
  96. 552 REM.SPACES$="":WHILE REM.SPACES$="":WHILE REM.SPACES$="":REM.SPACES$=INKEY$:WEND:IF INSTR("YyNn"+CHR$(13),REM.SPACES$)=0 THEN BEEP:REM.SPACES$=""
  97. 554 WEND:IF INSTR("Yy"+CHR$(13),REM.SPACES$)>0 THEN REM.SPACES$="YES" ELSE REM.SPACES$="NO"
  98. 556 PRINT REM.SPACES$
  99. 560 N.VARS.PER.FILE=0:N.OF.OUTPUT.FILES=0:WHILE N.VARS.PER.FILE<=0 OR N.VARS.PER.FILE>MAX.VARS.PER.FILE OR N.OF.OUTPUT.FILES>999
  100. 562   PRINT "--- Enter (max.) number of variables per output file (max.";MAX.VARS.PER.FILE;") [58]: ";:INPUT"",N.VARS.PER.FILE
  101. 564   IF N.VARS.PER.FILE=0 THEN N.VARS.PER.FILE=58
  102. 566   IF N.VARS.PER.FILE<0 OR N.VARS.PER.FILE>MAX.VARS.PER.FILE THEN BEEP:PRINT "*** Illegal number of variables entered! ***"
  103. 568   N.OF.OUTPUT.FILES=INT((TOT.N.OF.VARS-1)/N.VARS.PER.FILE)+1
  104. 570   IF N.OF.OUTPUT.FILES>999 THEN BEEP:PRINT "*** Too few variables per file, needing more than 999 output files, specified,";"    minimum number of variables per output file is";INT((TOT.N.OF.VARS-1)/999)+1;"***"
  105. 572 WEND
  106. 580 LINES.PER.PAGE=0:WHILE LINES.PER.PAGE<=0 AND DEL.SPACES>0
  107. 582   PRINT "--- Enter (max.) number of lines (header/records) per page [60]: ";:INPUT"",LINES.PER.PAGE
  108. 584   IF LINES.PER.PAGE=0 THEN LINES.PER.PAGE=60
  109. 586   IF LINES.PER.PAGE<1-(HEADER$="YES") OR LINES.PER.PAGE>32767 THEN BEEP:PRINT "*** Illegal number of lines per page entered! Minimum:";1-(HEADER$="YES");", maximum: 32767 ***":LINES.PER.PAGE=0
  110. 588 WEND
  111. 590 PRINT "=== Processing database ";DATABASE.DAT$;"......please wait and see......"
  112. 600 FOR OUTPUT.FILE.NUMBER=1 TO N.OF.OUTPUT.FILES
  113. 602   PRINT STRING$(40,"-");" Pass";OUTPUT.FILE.NUMBER;STRING$(5,"-");" Passes to follow:";N.OF.OUTPUT.FILES-OUTPUT.FILE.NUMBER
  114. 605   ON ERROR GOTO 11400:OPEN "I",#2,DATABASE$+"."+MID$(STR$(OUTPUT.FILE.NUMBER),2):ON ERROR GOTO 0:CLOSE 2 '====== check for existence of output file
  115. 607   IF CHECK.RESULT$="*** FILE NOT FOUND ***" THEN CHECK.RESULT$="OK":GOTO 610 ELSE IF CHECK.RESULT$<>"OK" THEN BEEP:PRINT CHECK.RESULT$:PRINT "    This may not occur: program bug! Notify author! Program abort!":STOP
  116. 609     IF OVERWRITE$="NO" THEN PRINT "*** Output file ";DATABASE$+"."+MID$(STR$(OUTPUT.FILE.NUMBER),2);" already exists; skipped this pass ***":GOTO 790 '====== BAD=not existing, OK=existing
  117. 610   OPEN "O",#2,DATABASE$+"."+MID$(STR$(OUTPUT.FILE.NUMBER),2) '====== open DATABASE.nr as output file with freefield data
  118. 615   ON ERROR GOTO 11400:OPEN "I",#1,DATABASE.DAT$:ON ERROR GOTO 0
  119. 620   FIRST=OUTPUT.FILE.NUMBER*N.VARS.PER.FILE-N.VARS.PER.FILE+1:LAST=OUTPUT.FILE.NUMBER*N.VARS.PER.FILE:IF LAST>TOT.N.OF.VARS THEN LAST=TOT.N.OF.VARS
  120. 655   GOSUB 2000 '====== header with variable names if applicable
  121. 660   RECORD.COUNT#=0:MAX.LENGTH#=0:MIN.LENGTH#=-1
  122. 670   WHILE NOT EOF(1) '====== process all records in database file
  123. 675   IF DEL.SPACES>0 AND LINE.COUNT#=LINES.PER.PAGE THEN PRINT #2,CHR$(12);:GOSUB 2000 '====== header with variable names if applicable
  124. 680     READ.PAST.EOL$="":PREVIOUS.RECORD.LENGTH#=RECORD.LENGTH#:RECORD.LENGTH#=0:I=0:RECORD.COUNT#=RECORD.COUNT#+1:WHILE RECORD.LENGTH#=I*MAX.LINE.INPUT.LENGTH
  125. 685       IF I=>N.OF.DATA.LINES THEN J=MAX.LINE.INPUT.LENGTH:GOSUB 1050:RECORD.LENGTH#=RECORD.LENGTH#+ADD.LENGTH#:ADD.LENGTH#=0#:GOTO 700 '====== read record until EOL
  126. 690       I=I+1:LINE INPUT #1,DATA.LINE$(I):RECORD.LENGTH#=RECORD.LENGTH#+LEN(DATA.LINE$(I)) '====== read complete record by multiple LINE INPUT's until CRLF
  127. 700     WEND:IF RECORD.LENGTH#>MAX.LENGTH# THEN MAX.LENGTH#=RECORD.LENGTH#
  128. 701     IF RECORD.LENGTH#<MIN.LENGTH# OR MIN.LENGTH#<0 THEN MIN.LENGTH#=RECORD.LENGTH#
  129. 702     IF CHECK.RECORD.LENGTH$="YES" AND RECORD.COUNT#>1 AND PREVIOUS.RECORD.LENGTH#<>RECORD.LENGTH# THEN PRINT "*** Length";RECORD.LENGTH#;"of record";RECORD.COUNT#;"is unequal to length";PREVIOUS.RECORD.LENGTH#;"of record";RECORD.COUNT#-1;"***" '#
  130. 705     PRINT "=== Processing";LAST-FIRST+1;"variables";FIRST;"to";LAST;"for record";RECORD.COUNT#;"into file ";DATABASE$+"."+MID$(STR$(OUTPUT.FILE.NUMBER),2);STRING$(80-POS(0),32);:LOCATE ,1
  131. 710     FOR VARIABLE.NUMBER=FIRST TO LAST:VALUE$="":FIELD.WIDTH=END.COLUMN!(VARIABLE.NUMBER)-BEGIN.COLUMN!(VARIABLE.NUMBER)+1 '====== process variables in parts of max. N.VARS.PER.FILE
  132. 720       FOR COLUMN!=BEGIN.COLUMN!(VARIABLE.NUMBER) TO END.COLUMN!(VARIABLE.NUMBER)
  133. 730         IF COLUMN!<=RECORD.LENGTH# THEN VALUE$=VALUE$+MID$(DATA.LINE$(INT((COLUMN!-1)/MAX.LINE.INPUT.LENGTH)+1),((COLUMN!-1) MOD MAX.LINE.INPUT.LENGTH)+1,1)
  134. 731 '====== IF statement to prevent 'Subscript out of range' and to prevent interpreting DATA.LINE$-elements which have not not been read, but contain characters
  135. 733         IF COLUMN!>RECORD.LENGTH# THEN VALUE$=VALUE$+" " '====== add trailing spaces after incomplete fields
  136. 735         IF COLUMN!>RECORD.LENGTH# AND COLUMN!=END.COLUMN!(VARIABLE.NUMBER) AND LEN(READ.PAST.EOL$)<=250 THEN READ.PAST.EOL$=READ.PAST.EOL$+STR$(VARIABLE.NUMBER) '====== remember variable number(s) read past EOL
  137. 740       NEXT COLUMN!:IF VALUE$<>STRING$(LEN(VALUE$)," ") THEN 743 '###### '744' changed into '743' in vs. 1.1 to solve bug in vs. 1.0 concerning EXTRA.SPACE$
  138. 742       IF MISSING.VALUE$(VARIABLE.NUMBER)<>"" THEN VALUE$=MISSING.VALUE$(VARIABLE.NUMBER) ELSE IF MISSING$<>"" THEN VALUE$=MISSING$ '=== replace entirely blank fields by the value MISSING(.VALUE)$
  139. 743       EXTRA.SPACE$=""
  140. 744       IF DELIMITER$="" THEN IF LEN(VALUE$)<FIELD.WIDTH+DEL.SPACES THEN EXTRA.SPACE$=STRING$(FIELD.WIDTH+DEL.SPACES-LEN(VALUE$),32) ELSE IF LEN(VALUE$)>FIELD.WIDTH+DEL.SPACES THEN VALUE$=RIGHT$(VALUE$,FIELD.WIDTH+DEL.SPACES)
  141. 750       GOSUB 3000:GOSUB 13000:GOSUB 1011:PRINT #2,EXTRA.SPACE$;VALUE$;:GOSUB 1011 '====== remove leading and trailing spaces or enclose value within quotes and double embedded quotes, and write (un)formatted literal value to the output file
  142. 755       IF VARIABLE.NUMBER<LAST THEN PRINT #2,DELIMITER$; '====== DELIMITER$ is empty ("") with FIXED format and Report output
  143. 760     NEXT VARIABLE.NUMBER:LINE.COUNT#=LINE.COUNT#+1#:PRINT #2, '====== eol
  144. 765     IF CHECK.RECORD.LENGTH$="YES" AND READ.PAST.EOL$<>"" THEN PRINT "*** Record";RECORD.COUNT#;"read past end-of-line for variable number(s):";READ.PAST.EOL$;" ***";STRING$(80-POS(0),32)
  145. 770   WEND:CLOSE 2:CLOSE 1
  146. 780   PRINT "===";LAST-FIRST+1;"variables";FIRST;"to";LAST;"for";RECORD.COUNT#;"records processed into file ";DATABASE$+"."+MID$(STR$(OUTPUT.FILE.NUMBER),2);STRING$(80-POS(0),32)
  147. 785   PRINT "=== Minimum record length was";MIN.LENGTH#;" /  Maximum record length was";MAX.LENGTH#
  148. 790 NEXT OUTPUT.FILE.NUMBER
  149. 800 PRINT "=== End of program CODEBOOK === Rerun? [Y]/N: ";:COMMENT$=INPUT$(1):IF INSTR("Yy"+CHR$(13),COMMENT$) THEN RUN ELSE KEY ON:END '====== routines follow
  150. 999 CHECK.FIELD.WIDTH$="BAD":RETURN
  151. 1011 IF VAR.TYPE$(VARIABLE.NUMBER)<>" " AND DELIMITER$<>"" THEN PRINT #2,VAR.TYPE$(VARIABLE.NUMBER);:RETURN
  152. 1050 ADD.LENGTH#=0#:WHILE J=MAX.LINE.INPUT.LENGTH:LINE INPUT #1,COMMENT.LINE$:J=LEN(COMMENT.LINE$):ADD.LENGTH#=ADD.LENGTH#+J:WEND:RETURN '====== read line until length NE 255: CRLF encountered
  153. 1100 REM ====== Adapt maximum number of variables to actual one (from codebook file) by adjusting dimensions of BEGIN.COLUMN!, END.COLUMN! and VARIABLE.NAME$ increasing them by EXTRA.VARS after temporaryly saving their contents to SHADOW! and SHADOW$
  154. 1101 IF EXTRA.VARS=MAX.N.OF.VARS THEN PRINT "!!! If running under interpreter BASIC auto-adaptation may be time consuming!"
  155. 1103 PRINT "=== Automatic adaptation to more than";MAX.N.OF.VARS;"variables in progress......";STRING$(80-POS(0),32);:LOCATE ,1
  156. 1110 IF MAX.N.OF.VARS=32767 THEN BEEP:PRINT "*** Number of variables exceeds maximum of";MAX.N.OF.VARS;", correct and rerun ***";STRING$(80-POS(0),32):CLOSE:STOP
  157. 1115 I!=MAX.N.OF.VARS+EXTRA.VARS:IF I!>32767 THEN I!=32767 '====== define increasing maximum number of variables (compromise between speed and memory space)
  158. 1120 DIM SHADOW!(MAX.N.OF.VARS),SHADOW$(MAX.N.OF.VARS):FOR J=1 TO MAX.N.OF.VARS:SHADOW!(J)=BEGIN.COLUMN!(J):SHADOW$(J)=VAR.TYPE$(J)+VARIABLE.NAME$(J):NEXT J
  159. 1130 ERASE BEGIN.COLUMN!,VARIABLE.NAME$,VAR.TYPE$:DIM BEGIN.COLUMN!(I!),VARIABLE.NAME$(I!),VAR.TYPE$(I!):FOR J=1 TO MAX.N.OF.VARS:BEGIN.COLUMN!(J)=SHADOW!(J):VAR.TYPE$(J)=LEFT$(SHADOW$(J),1):VARIABLE.NAME$(J)=MID$(SHADOW$(J),2):NEXT J
  160. 1150 FOR J=1 TO MAX.N.OF.VARS:SHADOW!(J)=END.COLUMN!(J):SHADOW$(J)=MISSING.VALUE$(J):NEXT J:ERASE END.COLUMN!,MISSING.VALUE$:DIM END.COLUMN!(I!),MISSING.VALUE$(I!)
  161. 1160 FOR J=1 TO MAX.N.OF.VARS:END.COLUMN!(J)=SHADOW!(J):MISSING.VALUE$(J)=SHADOW$(J):NEXT J:ERASE SHADOW!,SHADOW$:MAX.N.OF.VARS=I!:RETURN '===================================
  162. 2000 REM ========== Header with variable names if applicable ==========
  163. 2010 LINE.COUNT#=0#:IF HEADER$="NO" THEN 2060
  164. 2020   FOR VARIABLE.NUMBER=FIRST TO LAST:VAR.NAME$=VARIABLE.NAME$(VARIABLE.NUMBER):FIELD.WIDTH=END.COLUMN!(VARIABLE.NUMBER)-BEGIN.COLUMN!(VARIABLE.NUMBER)+1:EXTRA.SPACE$=""
  165. 2030     IF DELIMITER$="" THEN IF LEN(VAR.NAME$)<FIELD.WIDTH+DEL.SPACES THEN EXTRA.SPACE$=STRING$(FIELD.WIDTH+DEL.SPACES-LEN(VAR.NAME$),32) ELSE IF LEN(VAR.NAME$)>FIELD.WIDTH+DEL.SPACES THEN VAR.NAME$=RIGHT$(VAR.NAME$,FIELD.WIDTH+DEL.SPACES)
  166. 2040     PRINT #2,EXTRA.SPACE$;VAR.NAME$;:IF VARIABLE.NUMBER<LAST THEN PRINT #2,DELIMITER$; '====== write variable names on the same line separated by spaces or commas to the deduced data file for STATGRAPHICS
  167. 2050   NEXT VARIABLE.NUMBER:LINE.COUNT#=LINE.COUNT#+1#:PRINT #2, '====== eol
  168. 2060  RETURN
  169. 3000 REM ========== double embedded single or double quotes within quoted string values ==========
  170. 3010 IF VAR.TYPE$(VARIABLE.NUMBER)=" " OR DELIMITER$="" THEN 3060 'return
  171. 3020 I=INSTR(VALUE$,VAR.TYPE$(VARIABLE.NUMBER)):IF  I=0  THEN 3060 'return
  172. 3030 WHILE I>0 AND I<255:IF LEN(VALUE$)=255 THEN VALUE$=LEFT$(VALUE$,254) '====== if VALUE$ has maximum length delete last character to make room for extra quote
  173. 3040 VALUE$=LEFT$(VALUE$,I)+MID$(VALUE$,I):I=INSTR(I+2,VALUE$,VAR.TYPE$(VARIABLE.NUMBER)):WEND
  174. 3060 RETURN
  175. 9999 '================== routines ==================
  176. 10000 REM ********** Remove leading and trailing spaces from file name *********
  177. 10010 WHILE LEFT$(D.PATH.FILENAME.EXT$,1)=" ":D.PATH.FILENAME.EXT$=MID$(D.PATH.FILENAME.EXT$,2):WEND
  178. 10020 WHILE RIGHT$(D.PATH.FILENAME.EXT$,1)=" ":D.PATH.FILENAME.EXT$=LEFT$(D.PATH.FILENAME.EXT$,LEN(D.PATH.FILENAME.EXT$)-1):WEND
  179. 10030 RETURN
  180. 11000 REM ********** check drv:path\file names ********** (result in CHECK.RESULT$)
  181. 11010 GOSUB 10000:CHECK.RESULT$="OK"
  182. 11020 U=INSTR(D.PATH.FILENAME.EXT$,":"):IF U=1 OR U>2 THEN CHECK.RESULT$="*** ILLEGALLY PLACED ':' ***":RETURN
  183. 11030 D$="":IF U=2 THEN W=ASC(LEFT$(D.PATH.FILENAME.EXT$,1)):IF W>96 AND W<123 THEN W=W-32:D$=CHR$(W)+":" ELSE IF W>64 AND W<91 THEN D$=CHR$(W)+":" ELSE CHECK.RESULT$="*** ILLEGAL DRIVE NAME ***":RETURN
  184. 11040 PATH$="":PATH.FILENAME.EXT$=MID$(D.PATH.FILENAME.EXT$,U+1):U=INSTR(PATH.FILENAME.EXT$,"\"):IF U=1 THEN PATH$="\":PATH.FILENAME.EXT$=MID$(PATH.FILENAME.EXT$,2)
  185. 11050 U=INSTR(PATH.FILENAME.EXT$,"\"):IF U=0 THEN FILENAME.EXT$=PATH.FILENAME.EXT$:WILDCARD$="YES":GOSUB 11110:WILDCARD$="NO":IF CHECK.RESULT$<>"OK" THEN RETURN ELSE D.PATH.FILENAME.EXT$=D$+PATH$+FILENAME.EXT$:D.PATH.FILENAME$=D$+PATH$+FILENAME$:RETURN
  186. 11060 PATHNAME.EXT$=LEFT$(PATH.FILENAME.EXT$,U-1):IF PATHNAME.EXT$<>"." AND PATHNAME.EXT$<>".." THEN FILENAME.EXT$=PATHNAME.EXT$:GOSUB 11110:IF CHECK.RESULT$<>"OK" THEN RETURN ELSE PATHNAME.EXT$=FILENAME.EXT$
  187. 11070 PATH$=PATH$+PATHNAME.EXT$+"\":PATH.FILENAME.EXT$=MID$(PATH.FILENAME.EXT$,U+1):GOTO 11050 '====== repeat check for every subdirectory name
  188. 11110 REM ********** check file names ********** (result in CHECK.RESULT$)
  189. 11120 CHECK.RESULT$="OK":IF LEN(FILENAME.EXT$)=0 THEN CHECK.RESULT$="*** ZERO LENGTH PATH/FILENAME ***":RETURN
  190. 11125 CHECK.RESULT$="OK":IF LEN(FILENAME.EXT$)>12 THEN CHECK.RESULT$="*** TOO LONG PATH/FILENAME ***":RETURN
  191. 11130 V=INSTR(FILENAME.EXT$,"."):IF V=0 AND LEN(FILENAME.EXT$)>8 THEN CHECK.RESULT$="*** PATH/FILENAME TOO LONG ***":RETURN
  192. 11133 IF V=0 THEN EXPL.PERIOD$="NO" ELSE EXPL.PERIOD$="YES"
  193. 11140 IF V>0 AND INSTR(V+1,FILENAME.EXT$,".")>0 THEN CHECK.RESULT$="*** TOO MANY PERIODS IN PATH/FILENAME ***":RETURN
  194. 11150 IF V>9 OR V=1 THEN CHECK.RESULT$="*** ILLEGALLY PLACED '.' IN PATH/FILENAME ***":RETURN
  195. 11160 IF V>0 AND (LEN(FILENAME.EXT$)-V)>3 THEN CHECK.RESULT$="*** TOO LONG EXTENSION IN PATH/FILENAME ***":RETURN
  196. 11170 IF INSTR(FILENAME.EXT$,"\")>0 THEN CHECK.RESULT$="*** ILLEGAL '\' IN PATH/FILENAME ***":RETURN
  197. 11180 IF INSTR(FILENAME.EXT$,"+")>0 THEN CHECK.RESULT$="*** ILLEGAL '+' IN PATH/FILENAME ***":RETURN
  198. 11190 IF INSTR(FILENAME.EXT$,"=")>0 THEN CHECK.RESULT$="*** ILLEGAL '=' IN PATH/FILENAME ***":RETURN
  199. 11200 IF INSTR(FILENAME.EXT$,"[")>0 THEN CHECK.RESULT$="*** ILLEGAL '[' IN PATH/FILENAME ***":RETURN
  200. 11210 IF INSTR(FILENAME.EXT$,"]")>0 THEN CHECK.RESULT$="*** ILLEGAL ']' IN PATH/FILENAME ***":RETURN
  201. 11220 IF INSTR(FILENAME.EXT$,":")>0 THEN CHECK.RESULT$="*** ILLEGAL ':' IN PATH/FILENAME ***":RETURN
  202. 11230 IF INSTR(FILENAME.EXT$,";")>0 THEN CHECK.RESULT$="*** ILLEGAL ';' IN PATH/FILENAME ***":RETURN
  203. 11240 IF INSTR(FILENAME.EXT$,CHR$(34))>0 THEN CHECK.RESULT$="*** ILLEGAL '"+CHR$(34)+"' IN PATH/FILENAME ***":RETURN
  204. 11250 IF INSTR(FILENAME.EXT$,"/")>0 THEN CHECK.RESULT$="*** ILLEGAL '/' IN PATH/FILENAME ***":RETURN
  205. 11260 IF INSTR(FILENAME.EXT$,",")>0 THEN CHECK.RESULT$="*** ILLEGAL ',' IN PATH/FILENAME ***":RETURN
  206. 11270 IF INSTR(FILENAME.EXT$,"|")>0 THEN CHECK.RESULT$="*** ILLEGAL '|' IN PATH/FILENAME ***":RETURN
  207. 11280 IF INSTR(FILENAME.EXT$,"<")>0 THEN CHECK.RESULT$="*** ILLEGAL '<' IN PATH/FILENAME ***":RETURN
  208. 11290 IF INSTR(FILENAME.EXT$,">")>0 THEN CHECK.RESULT$="*** ILLEGAL '>' IN PATH/FILENAME ***":RETURN
  209. 11292 IF INSTR(FILENAME.EXT$,"*")>0 AND WILDCARD$="NO" THEN CHECK.RESULT$="*** ILLEGAL '*' IN PATH/FILENAME ***":RETURN
  210. 11294 IF INSTR(FILENAME.EXT$,"?")>0 AND WILDCARD$="NO" THEN CHECK.RESULT$="*** ILLEGAL '?' IN PATH/FILENAME ***":RETURN
  211. 11300 FOR W = 1 TO LEN(FILENAME.EXT$):V = ASC(MID$(FILENAME.EXT$,W,1)):IF V > 96 AND V < 123 THEN V=V-32:MID$(FILENAME.EXT$,W,1)=CHR$(V) '====== change lower case to upper case
  212. 11310 IF V <= 32 THEN CHECK.RESULT$="*** ILLEGAL SPACE OR CONTROL CHARACTER IN PATH/FILENAME ***":W = LEN(FILENAME.EXT$)
  213. 11320 NEXT W:IF CHECK.RESULT$<>"OK" THEN RETURN
  214. 11325 V=INSTR(FILENAME.EXT$,"."):FILENAME$=FILENAME.EXT$:EXT$=""
  215. 11330 IF V>0 THEN FILENAME$=LEFT$(FILENAME.EXT$,V-1):EXT$=MID$(FILENAME.EXT$,V+1)
  216. 11340 RETURN '========================
  217. 11400 ERROR.NUMBER=ERR:CHECK.RESULT$="*** ERROR NUMBER"+STR$(ERROR.NUMBER)+" ***"
  218. 11500 IF ERROR.NUMBER=53 THEN CHECK.RESULT$="*** FILE NOT FOUND ***":GOTO 11800
  219. 11600 IF ERROR.NUMBER=64 THEN CHECK.RESULT$="*** BAD FILE NAME ***":GOTO 11800
  220. 11700 IF ERROR.NUMBER=76 THEN CHECK.RESULT$="*** PATH NOT FOUND ***":GOTO 11800
  221. 11800 RESUME NEXT
  222. 12010 PRINT "=== Enter [drive:][path\][wildcard] for directory or":RETURN
  223. 12020 IF INSTR(FILENAME.EXT$,"*")>0 OR INSTR(FILENAME.EXT$,"?")>0 THEN CHECK.RESULT$="WILDCARD":ON ERROR GOTO 12030:FILES D.PATH.FILENAME.EXT$:ON ERROR GOTO 0:RETURN ELSE RETURN
  224. 12030 PRINT "No files ";D.PATH.FILENAME.EXT$:RESUME NEXT
  225. 12040 IF FILENAME.EXT$="" THEN FILENAME.EXT$="*.*":D.PATH.FILENAME.EXT$=D.PATH.FILENAME.EXT$+"*.*":CHECK.RESULT$="WILDCARD"
  226. 12050 IF FILENAME.EXT$="." THEN FILENAME.EXT$=".\*.*":D.PATH.FILENAME.EXT$=D.PATH.FILENAME.EXT$+"\*.*":CHECK.RESULT$="WILDCARD"
  227. 12060 IF FILENAME.EXT$=".." THEN FILENAME.EXT$="..\*.*":D.PATH.FILENAME.EXT$=D.PATH.FILENAME.EXT$+"\*.*":CHECK.RESULT$="WILDCARD"
  228. 12070 RETURN
  229. 13000 REM ====== remove leading and trailing spaces of VALUE$ only if not quoted
  230. 13001 IF VAR.TYPE$(VARIABLE.NUMBER)<>" " OR DELIMITER$="" THEN 13030
  231. 13005 IF REM.SPACES$="NO" THEN 13030 '====== return if no removing of insignificant spaces wanted
  232. 13010 WHILE LEFT$(VALUE$,1)=" ":VALUE$=MID$(VALUE$,2):WEND
  233. 13020 WHILE RIGHT$(VALUE$,1)=" ":VALUE$=LEFT$(VALUE$,LEN(VALUE$)-1):WEND
  234. 13030 RETURN
  235. 13100 REM ====== optional check for (case sensitive) identical variable names ======
  236. 13110 FOR I=1 TO TOT.N.OF.VARS-1
  237. 13120 IF VARIABLE.NAME$(TOT.N.OF.VARS)=VARIABLE.NAME$(I) THEN CHECK.VAR.NAME$="BAD":PRINT "*** Variables";I;"and";TOT.N.OF.VARS;"have identical names '";VARIABLE.NAME$(I);"' ***";STRING$(80-POS(0),32)
  238. 13130 NEXT I:RETURN
  239. 14000 REM ====== check for numerical extension EXT$, if so: CHECK.RESULT$<>"OK" ==========
  240. 14010 IF EXT$="" THEN RETURN '====== OK, no numerical extension, if no extension at all
  241. 14020 FOR J=1 TO 3:FOR I=0 TO 9:IF MID$(EXT$,J,1)=RIGHT$(STR$(I),1) THEN 14040
  242. 14030   NEXT I:RETURN '====== OK if any character of extension is not numerical
  243. 14040   IF LEN(EXT$)=J THEN CHECK.RESULT$="BAD":RETURN '====== BAD if only character(s) of extension is/are numerical
  244. 14050 NEXT J:RETURN '====== this way will never be gone
  245.