REM LEDGER1.BAS REM REM This is a source program in CBASIC version 2 for use under CP/M REM with 32+ K memory and dual floppy discs. Written by Patrick Cun- REM ningham, 235 Sharon Drive, San Antonio, TX 78216. Commercial re- REM production is prohibited. This program will read budget entries REM entered on disc with the BUDGET1.BAS program, sum like entries and REM output updated totals for a given data file. It then stores the REM monthly totals in an annual total file, named TOTALS.Ynn REM FOR I%=1 TO 15 REM a little fancy output PRINT NEXT I% PRINT TAB(10); "This program reads and totals monthly expense entries." PRINT TAB(10); ":::::::::::::::::::::::::::::::::::::::::::::::::::::" FOR I%=1 TO 15 REM more of the same PRINT NEXT I% OPEN.OUT.FILE%=0 REM used in case of iteration 10 INPUT "Do you want an update [U] or disc total entry [D]?";QUES$ IF QUES$="" THEN 10 IF QUES$="U" THEN UPDATE%=-1 : GOTO 10.1 IF QUES$="D" THEN UPDATE%=0 : GOTO 10.1 PRINT "Your response is not recognizeable." : GOTO 10 10.1 INPUT "What expense file are you accessing?"; LINE RESP$ REM REM Now we see if the file name is valid REM IF LEN(RESP$)=0 THEN GOTO 10.1 IF LEN(RESP$)>12 THEN PRINT "** NAME TOO LONG **" : GOTO 10.1 CH.CHAR$= RIGHT$(RESP$,4) CHAR.ONE$=LEFT$(CH.CHAR$,1) IF CHAR.ONE$<>"." THEN PRINT CHR$(07);TAB(20);"INVALID FILE NAME" :\ GOTO 10.1 FILN$ = UCASE$(RESP$) 11 INPUT "Do you want data printed as it is read {Y/N}";LINE RR$ IF RR$="" THEN 11 IF RR$="Y" THEN PRINT.FLAG%=1 : GOTO 12 IF RR$="N" THEN PRINT.FLAG%=0 : GOTO 12 PRINT "Your response is not recognizeable" : GOTO 11 12 IF END # 1 THEN 10 IF UPDATE% OR OPEN.OUT.FILE% THEN GOTO 13.1 REM REM This next routine sets up the annual output file REM INPUT "Does the totals file already exist on the disc {Y/N}?";LINE RS$ IF RS$="" THEN 12 IF RS$="Y" THEN FILE.NEW%=0 : GOTO 13 IF RS$="N" THEN FILE.NEW%=-1 : GOTO 13 PRINT "Your response is not recognizeable" : GOTO 12 13 INPUT "What year is it?"; LINE YEAR$ IF LEN(YEAR$)<>4 THEN 13 OUT.FILE.NAME$ = "EXP"+ YEAR$ +".TOT" IF END # 2 THEN 10 IF FILE.NEW% THEN CREATE OUT.FILE.NAME$ RECL 64 AS 2 IF NOT FILE.NEW% THEN OPEN OUT.FILE.NAME$ RECL 64 AS 2 PRINT "MONTH'S TOTALS TO BE OUTPUT TO FILE ";OUT.FILE.NAME$ OPEN.TWO%=-1 REM REM we now calculate the number of records in either file REM 13.1 OPEN FILN$ RECL 64 AS 1 FALSE%=0 TRUE%=-1 DEF FN.CALCULATE.FILE.NO%(FILE.NAME$,REC.SIZE%,FILE.NUM%,POSITION%) FN.CALCULATE.FILE.NO% = FALSE% FILE.SIZE%=SIZE(FILE.NAME$) IF FILE.SIZE%=0 THEN \ FALSE IF NO FILE RETURN \ ELSE FN.CALCULATE.FILE.NO% = TRUE% IF END # FILE.NUM% THEN 14 POSITION%=INT%(FLOAT(FILE.SIZE%)* 128/REC.SIZE%) PRINT "locating file at end" READ # FILE.NUM%,POSITION%; WHILE TRUE% READ # FILE.NUM%; LINE DUMMY$ POSITION% = POSITION% + 1 WEND 14 PRINT "There are";POSITION%;"entries in this data file." FN.CALCULATE.FILE.NO%=POSITION% RETURN FEND REM end of defined function POSN%=0 FILE.RECORD.LENGTH%=FN.CALCULATE.FILE.NO%(FILN$,128,1,POSN%) CLOSE 1 REM REM We now read in the various expense entries from the disc REM OPEN FILN$ RECL 64 AS 1 DIM EXPENSE(FILE.RECORD.LENGTH%,4) DIM EXPENSE.CAT$(FILE.RECORD.LENGTH%,4) DIM PAYEE$(FILE.RECORD.LENGTH%) DIM DATE%(FILE.RECORD.LENGTH%) FOR I%=1 TO FILE.RECORD.LENGTH% IF END # 1 THEN 25 READ # 1,I%; DATE%(I%), PAYEE$(I%), EXPENSE.CAT$(I%,1),EXPENSE(I%,1),EXPENSE.CAT$(I%,2),EXPENSE(I%,2),EXPENSE.CAT$(I%,3),EXPENSE(I%,3),EXPENSE.CAT$(I%,4),EXPENSE(I%,4) NEXT I% 25 IF PRINT.FLAG%=0 THEN GOTO 26 FOR I%=1 TO FILE.RECORD.LENGTH% PRINT PAYEE$(I%);" "; FOR J%=1 TO 4 PRINT EXPENSE.CAT$(I%,J%);"|";EXPENSE(I%,J%); NEXT J% PRINT NEXT I% 26 REM all data has been read in and printed, if that was desired. PRINT.FLAG%=0 REM we will now sum up like data and output it in readable form DIM CATEGORY.NAME$(19) DIM CATEGORY.CODE$(19) FOR H%=1 TO 19 READ CATEGORY.NAME$(H%),CATEGORY.CODE$(H%) NEXT H% DATA Charity,C,Drugs & Pharmacy,D,Clothing/Garments,G,Food,F,Household/hardware,H,Inventoried(mortgage),I,Insurance,J,Medical,Y,Miscellaneous taxable,M,Miscellaneous non-tax,N,Phone(pers.),P,Phone(business),B,Phone(Special.),R DATA Savings,S,Utility,U,Gas(personal),E,Auto parts(personal),X,Auto repair,W,SALES TAX,T RESTORE MONTH.TOTAL=0.0 DIM CATEGORY.SUM(19) FOR H%=1 TO 19 CATEGORY.TOTAL=0.0 PRINT TAB(20);"............." PRINT TAB(20);CATEGORY.NAME$(H%) PRINT FOR I%=1 TO FILE.RECORD.LENGTH% FOR J%=1 TO 4 WHILE EXPENSE.CAT$(I%,J%)=CATEGORY.CODE$(H%) CATEGORY.TOTAL=CATEGORY.TOTAL+ EXPENSE(I%,J%) IF LEN(PAYEE$(I%))<10 THEN \ PAYEE$(I%)=PAYEE$(I%)+" " PRINT TAB(09); DATE%(I%);TAB(13);":";PAYEE$(I%), PRINT USING "$$####.## ";EXPENSE(I%,J%) GOTO 30 REM logically, we take next I% WEND IF EXPENSE.CAT$(I%,J%+1)="" THEN GOTO 30 NEXT J% 30 NEXT I% CATEGORY.SUM(H%)=CATEGORY.TOTAL IF LEN(CATEGORY.NAME$(H%))<13 THEN \ CATEGORY.NAME$(H%)=CATEGORY.NAME$(H%)+" " PRINT TAB(44);"--------" PRINT "TOTAL FOR ";CATEGORY.NAME$(H%), PRINT USING "$$#####.## ";CATEGORY.SUM(H%) MONTH.TOTAL=MONTH.TOTAL+CATEGORY.TOTAL NEXT H% PRINT PRINT "TOTAL EXPENSES FOR THIS MONTH ARE: "; PRINT USING "$$######.## "; MONTH.TOTAL REM REM We now output the month's totals to the annual totals disc file. REM IF UPDATE% THEN UPDATE%=0 : GOTO 45 40 IF END # 2 THEN 42 OUT.FILE.LENGTH%=FN.CALCULATE.FILE.NO%(OUT.FILE.NAME$,64,2,0) 42 MONTH.CODE$=RIGHT$(FILN$,3) PRINT # 2; "*", MONTH.CODE$,YEAR$ FOR H%=1 TO 19 PRINT # 2; " ", CATEGORY.CODE$(H%),CATEGORY.SUM(H%) PRINT "disc entered:";CATEGORY.NAME$(H%);":";CATEGORY.SUM(H%) NEXT H% PRINT # 2; "=",MONTH.TOTAL PRINT "disc entered total for ";MONTH.CODE$;",";YEAR$ 45 INPUT "Any other files to process{Y/N}?"; RSS$ IF RSS$="" THEN 45 IF RSS$="Y" THEN CLOSE 1 : OPEN.OUT.FILE%=-1 : GOTO 10 IF RSS$="N" THEN 50 PRINT "Your response is not recognizeable" : GOTO 45 50 PRINT TAB(20); "end of this routine." IF OPEN.TWO% THEN CLOSE 2 END REM: Really, isn't Algol much neater?