home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / data / pdsdb40a.lzh / DBOPSUB.SRC < prev    next >
Text File  |  1989-02-15  |  22KB  |  291 lines

  1. |10 ' *** PROGRAM '|01' Using PDS*BASE Version 4.02 02-15-89 ***
  2. 20 '
  3. 30 ' *** This program operates a PDS*BASE Data Base
  4. 35 ' ** Almost all variables will start with the letter Y or Z to allow you to use any other variable name.
  5. |40 KEY OFF:COL$="|25" 'change this to COL$="C" if you have a color monitor or COL$="M" if you have a non-color monitor
  6. 42 DIM COLA%(21),COLB%(21):IF COL$="C" THEN FOR J=0 TO 21:COLA%(J)=J:COLB%(J)=J:NEXT ELSE FOR J=0 TO 20:COLA%(J)=7:COLB%(J)=0:NEXT
  7. 45 ZFOPEN=0 'sets open sort file flag to zero
  8. 50 ' *** OPEN THE DATA BASE FILES ***
  9. |60 CLS:ZO$=CHR$(44):ZB$="|11":ZQ=|02 ' Comma, Base Name, Number of files
  10. |65 '**** Be sure to start BASICA with the command extenders as follows: 'BASICA/F:|03' as you have more than 3 files
  11. *01 |70 DIM ZS$(|02,|09),ZS%(|02,10),ZT%(|02,|05,4),ZDATE$(|02),ZTIME$(|02),ZCHGFLAG(|02)
  12. *02 ,ZH(|04),ZE(|04),ZH$(|02,|04),ZE$(|02,|04)
  13. *03 ,YC%(|06,50),YC(|06)
  14. 71 ' ZS$(X,Y) Y=1 is name of set, Y=2-10 is name of associated sets
  15. 72 ' ZS%(X,1)=Set type (1=Master, 2=Detail)
  16. 73 ' ZS%(X,2)=Set capacity (number of records)
  17. 74 ' ZS%(X,3)=Record size or width
  18. 75 ' ZS%(X,4)=Number of associated sets
  19. 76 ' ZS%(X,5)=Number of drives required
  20. 77 ' ZS%(X,6)=Number of records assigned
  21. 78 ' ZS%(X,7)=Number of variables in the set
  22. 79 ' ZS%(X,8)=Pointer to next record to be created if a Detail file
  23. 80 ' ZS%(X,9)=1 If a companion active/sort file is present
  24. 81 ' ZS%(X,10)=Field number for search field hashing
  25. 83 ' For multi-disc files the location of records is located in ZT%(X,Y,Z). The file name will be the same, with the program keeping track of the correct file buffer number for the appropriate drive.
  26. 84 ' ZT%(X,Y,Z) X=Set number
  27. 85 ' Y=File section number (multi-disc files)
  28. 86 ' Z=1 = Starting record
  29. 87 ' Z=2 = Ending record
  30. 88 ' Z=3 = Drive 1=A and 2=B, etc.
  31. 89 ' Z=4 = File buffer number for this section
  32. |90 DIM ZI$(|07,|02),Y$(|07,|02),ZC$(|02),ZP$(|02),ZNEXT$(|02),ZB$(|02),ZF$(|02) 'Input and buffer arrays
  33. |100 FOR Z1=1 TO |02
  34. 105 READ ZS%(Z1,1),ZS%(Z1,2),ZS%(Z1,3),ZS%(Z1,4),ZS%(Z1,5),ZS%(Z1,7),ZS%(Z1,9),ZS%(Z1,10),ZS$(Z1,1)
  35. 110 IF ZS%(Z1,4)>0 THEN FOR Z2=1 TO ZS%(Z1,4):READ ZS$(Z1,Z2+1):NEXT 'Z2
  36. 120 FOR Z2=1 TO ZS%(Z1,5):READ ZT%(Z1,Z2,1),ZT%(Z1,Z2,2),ZT%(Z1,Z2,3),ZT%(Z1,Z2,4):NEXT 'Z2
  37. 125 NEXT 'Z1
  38. *04
  39. *05 |200 DIM ZN$(|02,|07,2), ZSIZE%(|02,|07)
  40. *06 |200 DIM ZSIZE%(|02,|07)
  41. *51 |201 DIM ZFLDPOSVERT%(|02,|07),ZFLDPOSHORIZ%(|02,|07),ZNAMEPOSVERT%(|02,|07)
  42. |205 FOR ZI=1 TO |02
  43. 210 FOR ZJ=1 TO ZS%(ZI,7)
  44. *07 215 READ ZN$(ZI,ZJ,1),ZN$(ZI,ZJ,2),ZSIZE%(ZI,ZJ):NEXT:NEXT
  45. *08 215 READ ZSIZE%(ZI,ZJ):NEXT:NEXT
  46. *51 |215 READ ZN$(ZI,ZJ,1),ZN$(ZI,ZJ,2),ZSIZE%(ZI,ZJ),ZFLDPOSVERT%(ZI,ZJ),ZFLDPOSHORIZ%(ZI,ZJ),ZNAMEPOSVERT%(ZI,ZJ):NEXT:NEXT
  47. *09
  48. 300 PRINT TAB(27);"PDS*BASE DATA BASE SYSTEM":PRINT:PRINT TAB(32);"OPENING FILE(S)":PRINT:PRINT
  49. *35 301 PRINT TAB(21);"Insert data disc(s) and press any key":YQ$=INPUT$(1):PRINT
  50. 304 ON ERROR GOTO 390
  51. 305 Z5=0
  52. |310 FOR Z1=1 TO |02
  53. *10 315 FOR Z2=1 TO ZS%(Z1,5) 'number of disc drives for this file
  54. *11 315 Z2=1
  55. *12 320 ZF$=CHR$(64+ZT%(Z1,Z2,3))+":"+ZS$(Z1,1) 'Add correct drive letter to the front of this section
  56. *13 320 ZF$=ZS$(Z1,1) 'data file name
  57. 322 OPEN ZF$ AS ZT%(Z1,Z2,4) LEN=ZS%(Z1,3):YC1=0:YC2=0:YC3=0:YC4=0
  58. 324 IF ZS%(Z1,1)=1 THEN FIELD ZT%(Z1,Z2,4), 5 AS ZC$(Z1), 5 AS ZP$(Z1), 5 AS ZNEXT$(Z1) : YC1=15
  59. *14 325 IF ZS%(Z1,1)=2 THEN FIELD ZT%(Z1,Z2,4), 5 AS ZB$(Z1), 5 AS ZF$(Z1) : YC1=10
  60. *14 326 IF ZS%(Z1,1)=1 AND ZS%(Z1,4)>0 THEN FOR Z3=1 TO ZS%(Z1,4):FIELD ZT%(Z1,Z2,4), YC1 AS DUMMY1$, 5 AS ZH$(Z1,Z3), 5 AS ZE$(Z1,Z3):YC1=YC1+10:NEXT 'Z3
  61. 330 FOR Z3=1 TO ZS%(Z1,7):Y0=ZSIZE%(Z1,Z3):FIELD ZT%(Z1,Z2,4),YC1 AS DUMMY1$,YC2 AS DUMMY2$,YC3 AS DUMMY3$,YC4 AS DUMMY4$,YC5 AS DUMMY5$,Y0 AS Y$(Z3,Z1)
  62. 331 IF YC1+Y0<256 THEN YC1=YC1+Y0 ELSE IF YC2+Y0<256 THEN YC2=YC2+Y0 ELSE IF YC3+Y0<256 THEN YC3=YC3+Y0 ELSE IF YC4+Y0<256 THEN YC4=YC4+Y0 ELSE YC5=YC5+Y0
  63. 332 NEXT 'Z3
  64. *10 335 IF Z2=ZS%(Z1,5) AND ZS%(Z1,1)=1 THEN GET ZT%(Z1,Z2,4),(ZT%(Z1,Z2,2)-ZT%(Z1,Z2,1)+2):ZS%(Z1,6)=VAL(ZC$(Z1)):ZDATE$(Z1)=ZP$(Z1):ZTIME$(Z1)=ZNEXT$(Z1) 'ZDATE$ & ZTIME$ give date & time this master file was last changed
  65. *11 335 IF ZS%(Z1,1)=1 THEN GET ZT%(Z1,Z2,4),ZS%(Z1,2)+1 : ZS%(Z1,6)=VAL(ZC$(Z1)) : ZDATE$(Z1)=ZP$(Z1) : ZTIME$(Z1)=ZNEXT$(Z1) 'ZDATE$ & ZTIME$ give date and time this master file was last changed
  66. 336 IF ZS%(Z1,1)=1 THEN IF MID$(ZTIME$(Z1),3,1)<>":" THEN BEEP:PRINT:COLOR COLA%(4),0:PRINT TAB(13);"THE BLANK DATA BASE FILE(S) HAVE NOT BEEN PRE-CREATED":COLOR 7,0:STOP
  67. *15 337 IF Z2=ZS%(Z1,5) AND ZS%(Z1,1)=2 THEN GET ZT%(Z1,Z2,4),(ZT%(Z1,Z2,2)-ZT%(Z1,Z2,1)+2) : ZS%(Z1,6)=VAL(ZB$(Z1)) : ZS%(Z1,8)=VAL(ZF$(Z1))
  68. *16 337 IF ZS%(Z1,1)=2 THEN GET ZT%(Z1,Z2,4),ZS%(Z1,2)+1 : ZS%(Z1,6)=VAL(ZB$(Z1)) : ZS%(Z1,8)=VAL(ZF$(Z1))
  69. *10 340 NEXT 'Z2
  70. *17
  71. 341 IF ZS%(Z1,6)=ZS%(Z1,2) THEN BEEP:COLOR COLA%(4),0:PRINT "WARNING - THE ";ZS$(Z1,1):PRINT "DATA FILE IS FULL.":COLOR 7,0:FOR Z2=1 TO 3000:NEXT Z2
  72. *18
  73. 342 IF ZS%(Z1,1)=1 GOTO 370
  74. *19 343 ZR=ZS%(Z1,8):IF ZR=0 THEN BEEP:COLOR COLA%(4),0:PRINT "Detail file ";ZF$;" has Zero for the next vacant record pointer":COLOR 7,0:GOTO 360
  75. *20 343 ZR=ZS%(Z1,8):IF ZR=0 THEN Z5=1:GOTO 360
  76. 344 ZA=Z1:ZZ=1:ZR=ZS%(Z1,8):GOSUB 610:Z5=0:FOR Y1=1 TO ZS%(ZA,7):IF Y$(Y1,Z1)<>STRING$(ZSIZE%(Z1,Y1),32) THEN Z5=1
  77. 345 NEXT 'Y1
  78. *20 360 IF Z5>0 THEN PRINT:BEEP:COLOR 0,COLA%(4):PRINT "The DETAIL file pointers are in error":PRINT "for ";ZF$:PRINT "Generate and RUN the UTILITY Program to fix - Must cancel":COLOR 7,0:CLOSE:SYSTEM
  79. *19 360 IF Z5>0 THEN BEEP:COLOR COLA%(4),0:PRINT "WARNING - The Detail file pointers in":PRINT ZF$;" are in error. Select Option 1 on the next screen to fix this.":PRINT:PRINT TAB(15);"(Press any key to continue)":COLOR 7,0:ZQ$=INPUT$(1):PRINT
  80. 370 NEXT 'Z1
  81. 380 ON ERROR GOTO 0:GOTO 2000 'to the main program
  82. 390 RESUME 392
  83. |392 PRINT:PRINT "You have more than the 3 file default for BASIC.":PRINT "Restart BASICA or GWBASIC as 'BASICA/F:|03/S:|10'":PRINT "Be sure your CONFIG.SYS file has the 'FILES=20' command."
  84. 395 PRINT "Strike any key to return to DOS":ZQ$=INPUT$(1):SYSTEM
  85. 400 ' ** CLOSE ALL FILES **"
  86. *21 402 IF ZREPTFLAG<>1 THEN 445 'no corrections to housekeeping records necessary
  87. *11 405 Z2=1
  88. |410 FOR Z1=1 TO |02
  89. *10 415 FOR Z2=1 TO ZS%(Z1,5)
  90. 420 IF ZS%(Z1,1)=1 THEN RSET ZC$(Z1)=STR$(ZS%(Z1,6)):ELSE RSET ZB$(Z1)=STR$(ZS%(Z1,6)):RSET ZF$(Z1)=STR$(ZS%(Z1,8))
  91. 425 IF ZS%(Z1,1)=1 AND ZCHGFLAG(Z1)=1 THEN RSET ZC$(Z1)=STR$(ZS%(Z1,6)):LSET ZP$(Z1)=LEFT$(DATE$,2)+MID$(DATE$,4,2)+RIGHT$(DATE$,1):LSET ZNEXT$(Z1)=LEFT$(TIME$,5) ELSE LSET ZP$(Z1)=ZDATE$(Z1):LSET ZNEXT$(Z1)=ZTIME$(Z1)
  92. *10 430 IF Z2=ZS%(Z1,5) THEN PUT ZT%(Z1,Z2,4),(ZT%(Z1,Z2,2)-ZT%(Z1,Z2,1)+2)
  93. *11 430 PUT ZT%(Z1,Z2,4),ZS%(Z1,2)+1:CLOSE ZT%(Z1,1,4)
  94. *10 435 NEXT 'Z2
  95. 440 NEXT 'Z1
  96. 445 CLOSE:IF ZQ=1 THEN PRINT
  97. 450 PRINT "ALL DONE";
  98. 460 ' END OF PROGRAM
  99. *52 470 ON ERROR GOTO 485
  100. *52 480 RUN"MENU" ' ** ALL DONE ** If you wish to return to the BASIC Ok prompt, replace the RUN command with END. If you wish to return to DOS, replace with SYSTEM.
  101. *53 480 SYSTEM ' ** ALL DONE ** If you wish to return to the BASIC Ok prompt, replace SYSTEM with END.  If you are setting up a MENU program use RUN with the menu program name in quotes.
  102. *54 480 END ' ** ALL DONE ** If you wish to return to DOS, replace END with SYSTEM. If you are setting up a MENU program use RUN with the menu program name in quotes.
  103. *52 485 BEEP:IF ERR=53 THEN RESUME 487
  104. *52 486 END
  105. *52 487 PRINT:PRINT "  You haven't copied MENU.BAS to this disk. Strike any key to return to DOS":ZQ$=INPUT$(1):SYSTEM
  106. *56
  107. 500 ' ** SUBROUTINE TO CALCULATE THE RANDOM ACCESS RECORD NUMBER **
  108. 502 '
  109. 504 ' Before calling this subroutine, ZA must=the number of the data set. Set ZR$=the search item. If necessary convert integer or real search items to a string for ZR$.
  110. 505 ZTESTFLD%=ZS%(ZA,10) 'Search field number you specified when defining this data base file. Also see line 610
  111. 506 '
  112. 510 Z3#=0:Z1=LEN(ZR$):Z2=ZS%(ZA,2)
  113. 520 FOR Z4=1 TO Z1:Z44#=Z4:IF Z1>12 THEN Z44#=1/Z44# 'better random spread if search string length is > 12. This is the major change in Version 3.1
  114. 522 Z0#=ASC(MID$(ZR$,Z4,1)):IF Z0#<>32 THEN Z0#=Z0#*Z44#:Z3#=Z3#+(Z0#*Z0#*Z0#) 'Skip blanks to reduce clumping in the random spread. See pages 3 & 4 of README.DOC
  115. 525 NEXT
  116. 530 Z2#=Z2:ZR=INT(Z3#-(Z2*(INT((Z3#-1)/Z2#)))):IF ZR<=0 THEN ZR=1
  117. 535 IF Z1<ZSIZE%(ZA,ZTESTFLD%) THEN ZR$=ZR$+STRING$((ZSIZE%(ZA,ZTESTFLD%)-Z1),32) 'pads blanks if necessary to make sure the search string is the proper length for testing in line 675
  118. 540 RETURN 'Version 4.02 converted many of the above variables to double precision (#) FOR MORE ACCURATE HASHING
  119. 550 '
  120. 600 ' ** SUBROUTINE TO DIRECT READ A DATA SET **
  121. 601 ' * Be sure that 'ZA'=the number of the desired set and ZR=the desired record number (from subroutine at 500). If a master is being read ZR$=the search item value. Y$(X,ZA) returned with the data.
  122. 605 ZZ=0:YZ=0:Z1=ZR ' when this subroutine is called from 800 or 1300 subroutines then ZZ will=1 and return will be at 665.
  123. 610 YR=ZR:Y1=1:ZTESTFLD%=ZS%(ZA,10):IF ZS%(ZA,5)=1 AND YZ=1 THEN YZ=0:RETURN 'ZS%(ZA,10) was specified by you during definition as the search field. Also see line 505
  124. *10 615 IF ZS%(ZA,5)=1 THEN Y1=1:GOTO 630
  125. *10 620 FOR Y2=1 TO ZS%(ZA,5):IF ZR >= ZT%(ZA,Y2,1) AND ZR <= ZT%(ZA,Y2,2) THEN Y1=Y2 : Y2=ZS%(ZA,5) 'locate correct file buffer for record ZR when file spans more than 1 disk drive
  126. *10 622 NEXT 'Y2
  127. *10 625 YR=ZR-ZT%(ZA,Y1,1)+1:IF YZ=1 THEN YZ=0:RETURN
  128. 630 GET ZT%(ZA,Y1,4),YR
  129. 635 ZV=0 ' ZV=0 if record found and ZV=1 if record not found
  130. 650 ZL$=Y$(ZTESTFLD%,ZA)
  131. *23 660 IF ZS%(ZA,1)=2 THEN ZB=VAL(ZB$(ZA)):ZF=VAL(ZF$(ZA))
  132. 665 IF ZS%(ZA,1)=1 THEN ZC=VAL(ZC$(ZA)):ZP=VAL(ZP$(ZA)):ZN=VAL(ZNEXT$(ZA))
  133. *23 666 IF ZS%(ZA,1)=1 AND ZS%(ZA,4)>0 THEN FOR Y24=1 TO ZS%(ZA,4):ZH(Y24)=VAL(ZH$(ZA,Y24)):ZE(Y24)=VAL(ZE$(ZA,Y24)):NEXT 'Y24
  134. 670 ' ** If a Detail data set, ZB=the backward pointer and ZF=the forward pointer. If a Master, ZC=number of secondary Masters, ZP=previous secondary pointer, ZN=next secondary Master rec # pointer.
  135. 671 ' ** With a Master, ZH(X)=the chain head of the Xth Detail set chain and ZE(X)=the chain end of the Xth chain.
  136. *23 672 IF ZS%(ZA,1)=2 THEN RETURN 'need no further info for a detail set.
  137. 673 IF ZR$=STRING$(ZSIZE%(ZA,ZTESTFLD%),32) OR ZZ=1 THEN ZZ=0:RETURN 'it's a Master but, no test for search item is desired.
  138. 674 ' ** TEST FOR SEARCH ITEM **"
  139. 675 IF ZL$=ZR$ THEN RETURN 'Found it! If you are having trouble finding a match, see line 535. your string lengths must be the same.
  140. 680 IF ZN=0 THEN IF NOMSG%=0 THEN BEEP:COLOR COLA%(4),0:PRINT "No Master for ";ZR$;" in the data base.":COLOR 7,0:ZV=1:RETURN ELSE ZV=1:RETURN
  141. 685 ZR=ZN:GOTO 610 ' look at the next secondary master
  142. 695 '
  143. *24 1500 ' ** SUBROUTINE TO CREATE ZI$(ZA,X) FROM Y$(ZA,X) **
  144. *24 1510 ' ** ZA MUST=THE NUMBER OF THE DATA SET
  145. *24 1520 FOR Z1=1 TO ZS%(Z1,7) : ZI$(ZA,Z1)=Y$(ZA,Z1) : NEXT 'Z1
  146. *24 1530 RETURN
  147. *24 1540 '
  148. *24 2000 ' *******MAIN PROGRAM******
  149. *25
  150. 700 ' ** SUBROUTINE TO UP-DATE OR CREATE A RECORD USING Y$(X,ZA) BUFFER **
  151. 701 ' ** Be sure that 'ZA'=The number of the data set and ZR=the desired record number
  152. *10 705 YZ=1:GOSUB 610 'for multi-disc files GOSUB 610 to get the file record numbers
  153. *26 710 IF ZS%(ZA,1)=1 THEN RSET ZC$(ZA)=MID$(STR$(ZC),2):RSET ZP$(ZA)=MID$(STR$(ZP),2):RSET ZNEXT$(ZA)=MID$(STR$(ZN),2)
  154. *27 :IF ZS%(ZA,4)>0 THEN FOR Y24=1 TO ZS%(ZA,4):RSET ZH$(ZA,Y24)=MID$(STR$(ZH(Y24)),2):RSET ZE$(ZA,Y24)=MID$(STR$(ZE(Y24)),2):NEXT 'Y24
  155. *59 :IF ZS%(ZA,4)>0 THEN FOR Y24=1 TO ZS%(ZA,4):RSET ZH$(ZA,Y24)=MID$(STR$(ZH(Y24)),2):RSET ZE$(ZA,Y24)=MID$(STR$(ZE(Y24)),2):NEXT 'Y24
  156. *23 720 IF ZS%(ZA,1)=2 THEN RSET ZB$(ZA)=MID$(STR$(ZB),2):RSET ZF$(ZA)=MID$(STR$(ZF),2)
  157. 730 ' The data must be in Y$(X,ZA)
  158. 740 PUT ZT%(ZA,Y1,4), ZR:RETURN 'write the record
  159. 750 ' ** SUBROUTINE TO UP-DATE OR CREATE A RECORD USING ZI$(X) VARIABLES **
  160. 751 ' ** Be sure that 'ZA'=the number of the data set and ZR=the desired record number and that ZI$(X,ZA)=the data
  161. *10 755 YZ=1:GOSUB 610 'for multi-disc files GOSUB 610 to get the file and record numbers
  162. *26 760 IF ZS%(ZA,1)=1 THEN RSET ZC$(ZA)=MID$(STR$(ZC),2):RSET ZP$(ZA)=MID$(STR$(ZP),2):RSET ZNEXT$(ZA)=MID$(STR$(ZN),2)
  163. *27 :IF ZS%(ZA,4)>0 THEN FOR Y24=1 TO ZS%(ZA,4):RSET ZH$(ZA,Y24)=MID$(STR$(ZH(Y24)),2):RSET ZE$(ZA,Y24)=MID$(STR$(ZE(Y24)),2):NEXT 'Y24
  164. *59 :IF ZS%(ZA,4)>0 THEN FOR Y24=1 TO ZS%(ZA,4):RSET ZH$(ZA,Y24)=MID$(STR$(ZHC(Y24)),2):RSET ZE$(ZA,Y24)=MID$(STR$(ZEC(Y24)),2):NEXT 'Y24
  165. *23 770 IF ZS%(ZA,1)=2 THEN RSET ZB$(ZA)=MID$(STR$(ZB),2):RSET ZF$(ZA)=MID$(STR$(ZF),2)
  166. 780 FOR Y24=1 TO ZS%(ZA,7):LSET Y$(Y24,ZA)=ZI$(Y24,ZA):NEXT 'Y24
  167. 790 PUT ZT%(ZA,Y1,4), ZR:RETURN 'write the record
  168. 800 ' ** SUBROUTINE TO CREATE A NEW MASTER DATA SET **
  169. 801 ' ** Be sure that 'ZA'=the number of the data set, ZR$=the search item, ZI$(X)=the new data variables **
  170. 805 GOSUB 500:ZZ=1 ' ZR now=the calculated record # in 'ZA' and with ZZ=1 any calls to subroutine at 610 will return from 665.
  171. 810 GOSUB 610 ' check record to see if record already exists at this calculated location.
  172. 820 IF ZL$ <> STRING$(ZSIZE%(ZA,ZTESTFLD%),32) THEN 880 ' if ZL$=blank then no Master exists at this location
  173. 825 ZC=1:ZP=0:ZN=0 ' set header variables
  174. *23 830 IF ZS%(ZA,4)=0 OR ZCLONEIN%=1 THEN GOTO 840 'ZCLONEIN% used by Resize Data Base program that you get when you register
  175. *23 835 FOR ZI=1 TO ZS%(ZA,4):ZH(ZI)=0:ZE(ZI)=0:NEXT
  176. 840 GOSUB 750 ' create the record
  177. 850 ZS%(ZA,6)=ZS%(ZA,6)+1:ZCHGFLAG(ZA)=1 'bump number of records and set the change flag
  178. *12 852 IF ZS%(ZA,1)=1 AND ZFOPEN<>ZA THEN CLOSE ZQ+1:ZF$=CHR$(64+ZT%(ZA,1,3))+":"+LEFT$(ZS$(ZA,1),(LEN(ZS$(ZA,1))-4))+".SRT":OPEN ZF$ FOR APPEND AS ZQ+1:ZFOPEN=ZA 'open the sort key file
  179. *13 852 IF ZS%(ZA,1)=1 AND ZFOPEN<>ZA THEN CLOSE ZQ+1:ZF$=LEFT$(ZS$(ZA,1),(LEN(ZS$(ZA,1))-4))+".SRT":OPEN ZF$ FOR APPEND AS ZQ+1:ZFOPEN=ZA 'open the sort key file
  180. 854 WRITE #ZQ+1,ZR 'append the newly created record # to the report sort file
  181. 860 RETURN
  182. 880 ' ** RECORD ALREADY EXISTS AT THE CALCULATED LOCATION **
  183. 885 IF ZL$=ZR$ THEN BEEP:LOCATE 25,1,0:COLOR 15,0:PRINT ZR$;" Already in the data base - Strike any key to continue";:COLOR 7,0:ZQ$=INPUT$(1):ZV=2:RETURN
  184. 890 IF ZC=0 GOTO 950 ' if ZC>=1 then we are at the head of a master chain
  185. 900 GOSUB 1800:IF ZV>0 THEN RETURN ELSE ZZ=1:GOSUB 610 ' Z1 will= a vacant record number
  186. 905 IF ZC>1 GOTO 920 'if ZC=1 then there are no present secondary masters
  187. 910 ZC=2:ZN=Z1:GOSUB 700 ' update the pointers on the chain head Master
  188. *23 915 ZC=0:ZP=ZR:ZN=0:ZR=Z1:GOTO 830 ' set header variables, GOTO 830 to create the new Master
  189. *28 915 ZC=0:ZP=ZR:ZN=0:ZR=Z1:GOTO 840 ' set header variables, GOTO 840 to create the new Master
  190. 920 Z2=ZR:ZR=ZN ' we got here from 905 when there are already secondary Masters
  191. 925 ZZ=1:GOSUB 610:IF ZL$=ZR$ THEN BEEP:LOCATE 25,1,0:COLOR 15,0:PRINT ZR$;" Already exists in the data base - Strike any key to continue";:COLOR 7,0:ZQ$=INPUT$(1):ZV=2:RETURN
  192. 930 IF ZN=0 GOTO 940
  193. 935 ZR=ZN:GOTO 925 ' read the next secondary Master
  194. 940 ZN=Z1:Z3=ZR:GOSUB 700:ZR=Z2:ZZ=1:GOSUB 610:ZC=ZC+1:GOSUB 700 ' set the pointers on the former last record in the chain and on the head Master record.
  195. *23 945 ZR=Z1:ZN=0:ZP=Z3:ZC=0:GOTO 830 ' create the new Master at 830
  196. *28 945 ZR=Z1:ZN=0:ZP=Z3:ZC=0:GOTO 840 ' create the new Master at 840
  197. 950 GOSUB 1800:IF ZV>0 THEN RETURN ELSE ZZ=1:GOSUB 610:Z2=ZR:ZR=Z1:GOSUB 700 ' read secondary Master at calculated position, find a new vacant record and xfer the secondary Master to it.
  198. 955 Z1=ZR:ZR=ZP:Z3=ZN:ZZ=1:GOSUB 610:ZN=Z1:GOSUB 700 ' read and reset pointers of the previous record for the secondary we just moved
  199. 960 IF Z3=0 GOTO 970
  200. 965 ZR=Z3:ZZ=1:GOSUB 610:ZP=Z1:GOSUB 700 ' reset the pointers on the next record in the chain of the secondary that we just moved
  201. 970 ZR=Z2:ZC=0:ZP=0:ZN=0:GOTO 825 ' set ZR back to the calculated value then GOTO 825 to create the new Master chain head
  202. 975 '
  203. *29
  204. 1000 ' ** SUBROUTINE TO CREATE A DETAIL DATA SET **"
  205. 1001 ' ** ZR$ must= the search item of the Detail's Master so the chain head and end of the Detail chain can be updated
  206. 1002 ' ** It is assumed that the chain head Master has already been read as ZR. ZM=Master set num, ZS=Detail set num. Save ZR as YM **
  207. 1010 YM=ZR:ZA=ZS
  208. 1020 Z6=0
  209. |1025 FOR ZI=2 TO |09
  210. |1030 IF ZS$(ZM,ZI)=ZS$(ZS,1) THEN Z6=ZI-1:ZI=|09
  211. 1035 NEXT:IF Z6=0 THEN BEEP:PRINT ZS$(ZS,1);" DOES NOT MATCH ";ZS$(ZM,1):PRINT "PROGRAMMING ERROR":GOTO 400 ' Z6=which Detail set for the Master
  212. 1040 Z7=ZH(Z6):Z8=ZE(Z6) ' save the existing chain head and end pointers from the Master
  213. 1050 IF ZS%(ZS,1)<>2 THEN BEEP:PRINT "PROGRAMMING ERROR-";ZS$(ZS,1);" ISN'T A DETAIL SET.":GOTO 400
  214. 1060 Z1=ZS%(ZS,8):IF Z1=0 THEN BEEP:LOCATE 25,15,0:COLOR 15,0:PRINT "THIS DATA SET IS FULL - Strike any key to continue";:COLOR 7,0:YQ$=INPUT$(1):RETURN
  215. 1100 Z2=ZR:ZR=Z1:ZZ=1:GOSUB 610:ZS%(ZS,8)=ZF:ZR=Z2  ' read the new Detail to get the pointer to the next vacant Detail for future reference in ZS%(ZS,8)
  216. 1110 IF ZF>ZS%(ZS,2) THEN ZS%(ZA,8)=0
  217. 1115 ZA=ZM:ZR=YM:ZZ=1:GOSUB 610:IF Z7<>0 GOTO 1125
  218. 1120 ZH(Z6)=Z1:ZE(Z6)=Z1:GOSUB 700:ZB=0:ZF=0:ZR=Z1:GOTO 1140
  219. 1125 Z2=ZE(Z6):ZE(Z6)=Z1:ZA=ZM:ZR=YM:GOSUB 700:ZR=Z2 ' set new chain end in Master
  220. 1130 ZA=ZS:ZZ=1:GOSUB 610
  221. 1135 ZF=Z1:GOSUB 700:ZB=Z2 ' set forward pointer for previous chain end data set
  222. 1140 ZA=ZS:ZF=0:ZR=Z1:GOSUB 750  ' write new Detail record
  223. 1145 ZS%(ZA,6)=ZS%(ZA,6)+1 ' add 1 to the active records count
  224. 1150 ZR=YM:RETURN
  225. 1160 '
  226. 1200 ' ** DELETE A MASTER RECORD **
  227. 1201 ' ** ZA must=# of the set, ZR$ must=value of search item. It is assumed that the record has been read
  228. 1205 Y4=ZR:IF ZC=0 THEN GOSUB 500:Y5=ZR
  229. *23 1210 IF ZS%(ZA,4)=0 GOTO 1220
  230. *23 1213 FOR ZI=1 TO ZS%(ZA,4):IF ZH(ZI)<>0 OR ZE(ZI)<>0 THEN BEEP:LOCATE 25,1,0:COLOR 15,0:PRINT "CAN'T DELETE THIS MASTER RECORD AS IT STILL HAS DETAIL DATA. - Strike any key";:COLOR 7,0:ZQ$=INPUT$(1):ZV=1:RETURN
  231. *23 1215 NEXT
  232. 1220 IF ZC=0 GOTO 1240 ' ZC=0 if it is a secondary Master
  233. 1225 IF ZC>1 GOTO 1280 ' if ZC>1 then there are secondary Masters to deal with
  234. 1230 FOR Y11=1 TO ZS%(ZA,7):ZI$(Y11,ZA)=STRING$(ZSIZE%(ZA,Y11),32):NEXT Y11:ZC=0:ZP=0:ZN=0:GOSUB 750:ZS%(ZA,6)=ZS%(ZA,6)-1:ZCHGFLAG(ZA)=1 'set fields blank, update record, subtract 1 from number of records assigned, set change flag
  235. 1235 RETURN
  236. 1240 Y2=ZP:Y3=ZN:ZR=Y2:ZZ=1:GOSUB 610:ZN=Y3:IF Y2=Y5 THEN ZC=ZC-1
  237. 1245 GOSUB 700  ' reset the pointers on the previous record
  238. 1250 IF Y3<>0 THEN ZR=Y3:ZZ=1:GOSUB 610:ZP=Y2:GOSUB 700 ' reset pointers in next record
  239. 1255 IF Y2<>Y5 THEN ZR=Y5:ZZ=1:GOSUB 610:ZC=ZC-1:GOSUB 700 ' reset the number of Masters in the chain head
  240. 1260 ZR=Y4:GOTO 1230
  241. 1280 Y2=ZR:ZR=ZN:Y9=ZN:ZX=ZC:ZZ=1:GOSUB 610:Y3=ZN 'we are removing the chain head that has secondary masters. thus, we move the 1st secondary to the chain head record number
  242. 1285 ZC=ZX-1:ZP=0:ZR=Y2:GOSUB 700 'this moved the 1st secondary Master to the chain head
  243. 1290 IF Y3<>0 THEN ZR=Y3:ZZ=1:GOSUB 610:ZP=Y2:GOSUB 700 'reset pointer on next record
  244. 1295 ZR=Y9:GOTO 1230
  245. *30
  246. 1300 ' ** DELETE A DETAIL RECORD **"
  247. 1301 ' ** assumes that YS=the record number of the Detail record that has previously been read (in ZS), and that YM=the record number of the associated Master record (in ZM).
  248. 1305 ZA=ZS:Z1=YS
  249. 1310 FOR Y11=1 TO ZS%(ZA,7):ZI$(Y11,ZA)=STRING$(ZSIZE%(ZA,Y11),32):NEXT Y11:Z2=ZF:ZF=ZS%(ZA,8):Z3=ZB:ZB=0:GOSUB 750:ZS%(ZA,8)=YS:ZS%(ZA,6)=ZS%(ZA,6)-1
  250. 1311 ' set the record to blanks, save the record # in ZS%(ZA,8) & set forward pointer to next vacant record
  251. 1315 IF Z3=0 THEN GOTO 1340
  252. 1325 ZR=Z3:ZZ=1:GOSUB 610 'read the previous record in the chain
  253. 1330 ZF=Z2:GOSUB 700 'up-date the forward pointer in the previous record in the detail chain
  254. 1340 IF Z2=0 THEN GOTO 1360
  255. 1345 ZR=Z2:ZZ=1:GOSUB 610 'read the next record in the Detail chain
  256. 1350 ZB=Z3:GOSUB 700 'up-date the backward pointer in the next record in the chain
  257. 1360 ' up-date the associated Master if necessary
  258. 1365 IF Z2<>0 AND Z3<>0 THEN RETURN ' the deleted Detail was in the middle of a detail chain
  259. 1370 ZA=ZM:ZR=YM:ZZ=1:GOSUB 610 'read the associated Master
  260. 1375 Z6=0:FOR ZI=2 TO ZS%(ZA,4)+1:IF ZS$(ZM,ZI)=ZS$(ZS,1) THEN Z6=ZI-1:ZI=ZS%(ZA,4)+1
  261. 1380 NEXT:IF Z3=0 THEN ZH(Z6)=Z2
  262. 1385 IF Z2=0 THEN ZE(Z6)=Z3
  263. 1390 GOSUB 700:RETURN 'up-date the chain head and chain ends if the associated Master"
  264. 1395 '
  265. 1500 ' ** SUBROUTINE TO CREATE ZI$(X) FROM Y$(X) **
  266. 1510 ' ** ZA must=the number of the data set
  267. 1520 FOR Z1=1 TO ZS%(ZA,7):ZI$(Z1,ZA)=Y$(Z1,ZA):NEXT 'Z1
  268. 1530 RETURN
  269. 1540 '
  270. 1800 ' ** SUBROUTINE TO LOCATE A VACANT MASTER RECORD **
  271. 1810 Z1=ZR:Z2=ZR:ZV=0:IF ZS%(ZA,6)=ZS%(ZA,2) THEN BEEP:LOCATE 25,15,0:COLOR 15,0:PRINT "DATA SET ";ZS$(ZA,1);" IS FULL - Strike any key to continue";:COLOR 7,0:ZQ$=INPUT$(1):ZV=1:RETURN
  272. 1820 Z1=Z1-1:IF Z1=0 THEN Z1=ZS%(ZA,2) 'search downward for a vacant record
  273. 1830 ZZ=1:ZR=Z1:GOSUB 610:IF ZL$ <> STRING$(ZSIZE%(ZA,ZTESTFLD%),32) THEN 1820 'read the lower record and check for blank search field
  274. 1840 ZR=Z2 'found a blank record
  275. 1850 RETURN
  276. 1860 '
  277. 1981 ' ** THE MAIN PROGRAM FOLLOWS **
  278. 1982 ' ** THE FOLLOWING SUBROUTINES CAN BE CALLED **
  279. 1983 '    500 - TO CALCULATE A RECORD NUMBER
  280. 1984 '    600 - TO DIRECT READ A RECORD
  281. 1985 '    700 - TO UPDATE A RECORD USING Y$(X) BUFFER
  282. 1986 '    750 - TO UPDATE A RECORD USING ZI$(X) BUFFER
  283. 1987 '    800 - TO CREATE A NEW MASTER
  284. *23 1988 '   1000 - TO CREATE A NEW DETAIL DATA SET
  285. 1989 '   1200 - TO DELETE A MASTER RECORD
  286. *23 1990 '   1300 - TO DELETE A DETAIL RECORD
  287. 1991 '   1500 - TO CREATE ZI$(X) FROM Y$(X) BUFFER
  288. 1995 '   1800 - TO LOCATE A VACANT RECORD
  289. 2000 ' *******MAIN PROGRAM******
  290. *31 this line indicates end of .SRC file - do NOT remove it. Copyright 1987 by PRO DEV Software
  291.