|
|
' ' Q B a s i c M O N E Y M A N A G E R ' ' Copyright (C) Microsoft Corporation 1990 ' ' The Money Manager is a personal finance manager that allows you ' to enter account transactions while tracking your account balances ' and net worth. ' ' To run this program, press Shift+F5. ' ' To exit QBasic, press Alt, F, X. ' ' To get help on a BASIC keyword, move the cursor to the keyword and press ' F1 or click the right mouse button. '
'Set default data type to integer for faster operation DEFINT A-Z
'Sub and function declarations DECLARE SUB TransactionSummary (item%) DECLARE SUB LCenter (text$) DECLARE SUB ScrollUp () DECLARE SUB ScrollDown () DECLARE SUB Initialize () DECLARE SUB Intro () DECLARE SUB SparklePause () DECLARE SUB Center (row%, text$) DECLARE SUB FancyCls (dots%, Background%) DECLARE SUB LoadState () DECLARE SUB SaveState () DECLARE SUB MenuSystem () DECLARE SUB MakeBackup () DECLARE SUB RestoreBackup () DECLARE SUB Box (Row1%, Col1%, Row2%, Col2%) DECLARE SUB NetWorthReport () DECLARE SUB EditAccounts () DECLARE SUB PrintHelpLine (help$) DECLARE SUB EditTrans (item%) DECLARE FUNCTION Cvdt$ (X#) DECLARE FUNCTION Cvst$ (X!) DECLARE FUNCTION Cvit$ (X%) DECLARE FUNCTION Menu% (CurrChoiceX%, MaxChoice%, choice$(), ItemRow%(), ItemCol%(), help$(), BarMode%) DECLARE FUNCTION GetString$ (row%, col%, start$, end$, Vis%, Max%) DECLARE FUNCTION Trim$ (X$)
'Constants CONST TRUE = -1 CONST FALSE = NOT TRUE
'User-defined types TYPE AccountType Title AS STRING * 20 AType AS STRING * 1 Desc AS STRING * 50 END TYPE
TYPE Recordtype Date AS STRING * 8 Ref AS STRING * 10 Desc AS STRING * 50 Fig1 AS DOUBLE Fig2 AS DOUBLE END TYPE
'Global variables DIM SHARED account(1 TO 19) AS AccountType 'Stores the 19 account titles DIM SHARED ColorPref 'Color Preference DIM SHARED colors(0 TO 20, 1 TO 4) 'Different Colors DIM SHARED ScrollUpAsm(1 TO 7) 'Assembly Language Routines DIM SHARED ScrollDownAsm(1 TO 7) DIM SHARED PrintErr AS INTEGER 'Printer error flag
DEF SEG = 0 ' Turn off CapLock, NumLock and ScrollLock KeyFlags = PEEK(1047) POKE 1047, &H0 DEF SEG
'Open money manager data file. If it does not exist in current directory, ' goto error handler to create and initialize it. ON ERROR GOTO ErrorTrap OPEN "money.dat" FOR INPUT AS #1 CLOSE ON ERROR GOTO 0 'Reset error handler
Initialize 'Initialize program Intro 'Display introduction screen MenuSystem 'This is the main program COLOR 7, 0 'Clear screen and end CLS
DEF SEG = 0 ' Restore CapLock, NumLock and ScrollLock states POKE 1047, KeyFlags DEF SEG
END
' Error handler for program ' If data file not found, create and initialize a new one. ErrorTrap: SELECT CASE ERR ' If data file not found, create and initialize a new one. CASE 53 CLOSE ColorPref = 1 FOR a = 1 TO 19 account(a).Title = "" account(a).AType = "" account(a).Desc = "" NEXT a SaveState RESUME CASE 24, 25 PrintErr = TRUE Box 8, 13, 14, 69 Center 11, "Printer not responding ... Press Space to continue" WHILE INKEY$ <> "": WEND WHILE INKEY$ <> " ": WEND RESUME NEXT CASE ELSE END SELECT RESUME NEXT
'The following data defines the color schemes available via the main menu. ' ' scrn dots bar back title shdow choice curs cursbk shdow DATA 0, 7, 15, 7, 0, 7, 0, 15, 0, 0 DATA 1, 9, 12, 3, 0, 1, 15, 0, 7, 0 DATA 3, 15, 13, 1, 14, 3, 15, 0, 7, 0 DATA 7, 12, 15, 4, 14, 0, 15, 15, 1, 0
'The following data is actually a machine language program to 'scroll the screen up or down very fast using a BIOS call. DATA &HB8,&H01,&H06,&HB9,&H01,&H04,&HBA,&H4E,&H16,&HB7,&H00,&HCD,&H10,&HCB DATA &HB8,&H01,&H07,&HB9,&H01,&H04,&HBA,&H4E,&H16,&HB7,&H00,&HCD,&H10,&HCB
'Box: ' Draw a box on the screen between the given coordinates. SUB Box (Row1, Col1, Row2, Col2) STATIC
BoxWidth = Col2 - Col1 + 1
LOCATE Row1, Col1 PRINT "�"; STRING$(BoxWidth - 2, "�"); "�";
FOR a = Row1 + 1 TO Row2 - 1 LOCATE a, Col1 PRINT "�"; SPACE$(BoxWidth - 2); "�"; NEXT a
LOCATE Row2, Col1 PRINT "�"; STRING$(BoxWidth - 2, "�"); "�";
END SUB
'Center: ' Center text on the given row. SUB Center (row, text$) LOCATE row, 41 - LEN(text$) / 2 PRINT text$; END SUB
'Cvdt$: ' Convert a double precision number to a string WITHOUT a leading space. FUNCTION Cvdt$ (X#)
Cvdt$ = RIGHT$(STR$(X#), LEN(STR$(X#)) - 1)
END FUNCTION
'Cvit$: ' Convert an integer to a string WITHOUT a leading space. FUNCTION Cvit$ (X) Cvit$ = RIGHT$(STR$(X), LEN(STR$(X)) - 1) END FUNCTION
'Cvst$: ' Convert a single precision number to a string WITHOUT a leading space FUNCTION Cvst$ (X!) Cvst$ = RIGHT$(STR$(X!), LEN(STR$(X!)) - 1) END FUNCTION
'EditAccounts: ' This is the full-screen editor which allows you to change your account ' titles and descriptions SUB EditAccounts
'Information about each column REDIM help$(4), col(4), Vis(4), Max(4), edit$(19, 3)
'Draw the screen COLOR colors(7, ColorPref), colors(4, ColorPref) Box 2, 1, 24, 80
COLOR colors(5, ColorPref), colors(4, ColorPref) LOCATE 1, 1: PRINT SPACE$(80) LOCATE 1, 4: PRINT "Account Editor"; COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE 3, 2: PRINT "No� Account Title � Description �A/L" LOCATE 4, 2: PRINT "������������������������������������������������������������������������������" u$ = "##�\ \�\ \� ! " FOR a = 5 TO 23 LOCATE a, 2 X = a - 4 PRINT USING u$; X; account(X).Title; account(X).Desc; account(X).AType; NEXT a
'Initialize variables help$(1) = " Account name | <F2=Save and Exit> <Escape=Abort>" help$(2) = " Account description | <F2=Save and Exit> <Escape=Abort>" help$(3) = " Account type (A = Asset, L = Liability) | <F2=Save and Exit> <Escape=Abort>"
col(1) = 5: col(2) = 26: col(3) = 78 Vis(1) = 20: Vis(2) = 50: Vis(3) = 1 Max(1) = 20: Max(2) = 50: Max(3) = 1
FOR a = 1 TO 19 edit$(a, 1) = account(a).Title edit$(a, 2) = account(a).Desc edit$(a, 3) = account(a).AType NEXT a
finished = FALSE
CurrRow = 1 CurrCol = 1 PrintHelpLine help$(CurrCol)
'Loop until F2 or <ESC> is pressed DO GOSUB EditAccountsShowCursor 'Show Cursor DO 'Wait for key Kbd$ = INKEY$ LOOP UNTIL Kbd$ <> ""
IF Kbd$ >= " " AND Kbd$ < "~" THEN 'If legal, edit item GOSUB EditAccountsEditItem END IF GOSUB EditAccountsHideCursor 'Hide Cursor so it can move 'If it needs to SELECT CASE Kbd$ CASE CHR$(0) + "H" 'Up Arrow CurrRow = (CurrRow + 17) MOD 19 + 1 CASE CHR$(0) + "P" 'Down Arrow CurrRow = (CurrRow) MOD 19 + 1 CASE CHR$(0) + "K", CHR$(0) + CHR$(15) 'Left or Shift+Tab CurrCol = (CurrCol + 1) MOD 3 + 1 PrintHelpLine help$(CurrCol) CASE CHR$(0) + "M", CHR$(9) 'Right or Tab CurrCol = (CurrCol) MOD 3 + 1 PrintHelpLine help$(CurrCol) CASE CHR$(0) + "<" 'F2 finished = TRUE Save = TRUE CASE CHR$(27) 'Esc finished = TRUE Save = FALSE CASE CHR$(13) 'Return CASE ELSE BEEP END SELECT LOOP UNTIL finished
IF Save THEN GOSUB EditAccountsSaveData END IF
EXIT SUB
EditAccountsShowCursor: COLOR colors(8, ColorPref), colors(9, ColorPref) LOCATE CurrRow + 4, col(CurrCol) PRINT LEFT$(edit$(CurrRow, CurrCol), Vis(CurrCol)); RETURN
EditAccountsEditItem: COLOR colors(8, ColorPref), colors(9, ColorPref) ok = FALSE start$ = Kbd$ DO Kbd$ = GetString$(CurrRow + 4, col(CurrCol), start$, end$, Vis(CurrCol), Max(CurrCol)) edit$(CurrRow, CurrCol) = LEFT$(end$ + SPACE$(Max(CurrCol)), Max(CurrCol)) start$ = ""
IF CurrCol = 3 THEN X$ = UCASE$(end$) IF X$ = "A" OR X$ = "L" OR X$ = "" OR X$ = " " THEN ok = TRUE IF X$ = "" THEN X$ = " " edit$(CurrRow, CurrCol) = X$ ELSE BEEP END IF ELSE ok = TRUE END IF
LOOP UNTIL ok RETURN
EditAccountsHideCursor: COLOR colors(7, ColorPref), colors(4, ColorPref) LOCATE CurrRow + 4, col(CurrCol) PRINT LEFT$(edit$(CurrRow, CurrCol), Vis(CurrCol)); RETURN
EditAccountsSaveData: FOR a = 1 TO 19 account(a).Title = edit$(a, 1) account(a).Desc = edit$(a, 2) account(a).AType = edit$(a, 3) NEXT a SaveState RETURN
END SUB
'EditTrans: ' This is the full-screen editor which allows you to enter and change ' transactions SUB EditTrans (item)
'Stores info about each column REDIM help$(6), col(6), Vis(6), Max(6), CurrString$(3), CurrFig#(5) 'Array to keep the current balance at all the transactions REDIM Balance#(1000)
'Open random access file file$ = "money." + Cvit$(item) OPEN file$ FOR RANDOM AS #1 LEN = 84 FIELD #1, 8 AS IoDate$, 10 AS IoRef$, 50 AS IoDesc$, 8 AS IoFig1$, 8 AS IoFig2$ FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
'Initialize variables CurrString$(1) = "" CurrString$(2) = "" CurrString$(3) = "" CurrFig#(4) = 0 CurrFig#(5) = 0
GET #1, 1 IF valid$ <> "THISISVALID" THEN LSET IoDate$ = "" LSET IoRef$ = "" LSET IoDesc$ = "" LSET IoFig1$ = MKD$(0) LSET IoFig2$ = MKD$(0) PUT #1, 2 LSET valid$ = "THISISVALID" LSET IoMaxRecord$ = "1" LSET IoBalance$ = MKD$(0) PUT #1, 1 END IF
MaxRecord = VAL(IoMaxRecord$)
Balance#(0) = 0 a = 1 WHILE a <= MaxRecord GET #1, a + 1 Balance#(a) = Balance#(a - 1) + CVD(IoFig1$) - CVD(IoFig2$) a = a + 1 WEND GOSUB EditTransWriteBalance
help$(1) = "Date of transaction (mm/dd/yy) " help$(2) = "Transaction reference number " help$(3) = "Transaction description " help$(4) = "Increase asset or debt value " help$(5) = "Decrease asset or debt value "
col(1) = 2 col(2) = 11 col(3) = 18 col(4) = 44 col(5) = 55
Vis(1) = 8 Vis(2) = 6 Vis(3) = 25 Vis(4) = 10 Vis(5) = 10
Max(1) = 8 Max(2) = 6 Max(3) = 25 Max(4) = 10 Max(5) = 10
'Draw Screen COLOR colors(7, ColorPref), colors(4, ColorPref) Box 2, 1, 24, 80
COLOR colors(5, ColorPref), colors(4, ColorPref) LOCATE 1, 1: PRINT SPACE$(80); LOCATE 1, 4: PRINT "Transaction Editor: " + Trim$(account(item).Title);
COLOR colors(7, ColorPref), colors(4, ColorPref) LOCATE 3, 2: PRINT " Date � Ref# � Description � Increase � Decrease � Balance " LOCATE 4, 2: PRINT "������������������������������������������������������������������������������"
u$ = "\ \�\ \�\ \�" u1$ = " � � � � � " u1x$ = "�������߳�����߳������������������������߳���������߳���������߳��������������" u2$ = "###,###.##" u3$ = "###,###,###.##" u4$ = " "
CurrTopline = 1 GOSUB EditTransPrintWholeScreen
CurrRow = 1 CurrCol = 1 PrintHelpLine help$(CurrCol) + "| <F2=Save and Exit> <F9=Insert> <F10=Delete>"
GOSUB EditTransGetLine
finished = FALSE
'Loop until <F2> is pressed DO GOSUB EditTransShowCursor 'Show Cursor, Wait for key DO: Kbd$ = INKEY$: LOOP UNTIL Kbd$ <> "" GOSUB EditTransHideCursor
IF Kbd$ >= " " AND Kbd$ < "~" OR Kbd$ = CHR$(8) THEN 'If legal key, edit item GOSUB EditTransEditItem END IF
SELECT CASE Kbd$ 'Handle Special keys CASE CHR$(0) + "H" 'up arrow GOSUB EditTransMoveUp CASE CHR$(0) + "P" 'Down arrow GOSUB EditTransMoveDown CASE CHR$(0) + "K", CHR$(0) + CHR$(15) 'Left Arrow,BackTab CurrCol = (CurrCol + 3) MOD 5 + 1 PrintHelpLine help$(CurrCol) + "| <F2=Save and Exit> <F9=Insert> <F10=Delete>" CASE CHR$(0) + "M", CHR$(9) 'Right Arrow,Tab CurrCol = (CurrCol) MOD 5 + 1 PrintHelpLine help$(CurrCol) + "| <F2=Save and Exit> <F9=Insert> <F10=Delete>" CASE CHR$(0) + "G" 'Home CurrCol = 1 CASE CHR$(0) + "O" 'End CurrCol = 5 CASE CHR$(0) + "I" 'Page Up CurrRow = 1 CurrTopline = CurrTopline - 19 IF CurrTopline < 1 THEN CurrTopline = 1 END IF GOSUB EditTransPrintWholeScreen GOSUB EditTransGetLine CASE CHR$(0) + "Q" 'Page Down CurrRow = 1 CurrTopline = CurrTopline + 19 IF CurrTopline > MaxRecord THEN CurrTopline = MaxRecord END IF GOSUB EditTransPrintWholeScreen GOSUB EditTransGetLine CASE CHR$(0) + "<" 'F2 finished = TRUE CASE CHR$(0) + "C" 'F9 GOSUB EditTransAddRecord CASE CHR$(0) + "D" 'F10 GOSUB EditTransDeleteRecord CASE CHR$(13) 'Enter CASE ELSE BEEP END SELECT LOOP UNTIL finished
CLOSE
EXIT SUB
EditTransShowCursor: COLOR colors(8, ColorPref), colors(9, ColorPref) LOCATE CurrRow + 4, col(CurrCol) SELECT CASE CurrCol CASE 1, 2, 3 PRINT LEFT$(CurrString$(CurrCol), Vis(CurrCol)); CASE 4 IF CurrFig#(4) <> 0 THEN PRINT USING u2$; CurrFig#(4); ELSE PRINT SPACE$(Vis(CurrCol)); END IF CASE 5 IF CurrFig#(5) <> 0 THEN PRINT USING u2$; CurrFig#(5); ELSE PRINT SPACE$(Vis(CurrCol)); END IF END SELECT RETURN
EditTransHideCursor: COLOR colors(7, ColorPref), colors(4, ColorPref) LOCATE CurrRow + 4, col(CurrCol) SELECT CASE CurrCol CASE 1, 2, 3 PRINT LEFT$(CurrString$(CurrCol), Vis(CurrCol)); CASE 4 IF CurrFig#(4) <> 0 THEN PRINT USING u2$; CurrFig#(4); ELSE PRINT SPACE$(Vis(CurrCol)); END IF CASE 5 IF CurrFig#(5) <> 0 THEN PRINT USING u2$; CurrFig#(5); ELSE PRINT SPACE$(Vis(CurrCol)); END IF END SELECT RETURN
EditTransEditItem:
CurrRecord = CurrTopline + CurrRow - 1 COLOR colors(8, ColorPref), colors(9, ColorPref)
SELECT CASE CurrCol CASE 1, 2, 3 Kbd$ = GetString$(CurrRow + 4, col(CurrCol), Kbd$, new$, Vis(CurrCol), Max(CurrCol)) CurrString$(CurrCol) = new$ GOSUB EditTransPutLine GOSUB EditTransGetLine CASE 4 start$ = Kbd$ DO Kbd$ = GetString$(CurrRow + 4, col(4), start$, new$, Vis(4), Max(4)) new4# = VAL(new$) start$ = "" LOOP WHILE new4# >= 999999.99# OR new4# < 0
a = CurrRecord WHILE a <= MaxRecord Balance#(a) = Balance#(a) + new4# - CurrFig#(4) + CurrFig#(5) a = a + 1 WEND CurrFig#(4) = new4# CurrFig#(5) = 0 GOSUB EditTransPutLine GOSUB EditTransGetLine GOSUB EditTransPrintBalances GOSUB EditTransWriteBalance CASE 5 start$ = Kbd$ DO Kbd$ = GetString$(CurrRow + 4, col(5), start$, new$, Vis(5), Max(5)) new5# = VAL(new$) start$ = "" LOOP WHILE new5# >= 999999.99# OR new5# < 0
a = CurrRecord WHILE a <= MaxRecord Balance#(a) = Balance#(a) - new5# + CurrFig#(5) - CurrFig#(4) a = a + 1 WEND CurrFig#(4) = 0 CurrFig#(5) = new5# GOSUB EditTransPutLine GOSUB EditTransGetLine GOSUB EditTransPrintBalances GOSUB EditTransWriteBalance CASE ELSE END SELECT GOSUB EditTransPrintLine RETURN
EditTransMoveUp: IF CurrRow = 1 THEN IF CurrTopline = 1 THEN BEEP ELSE ScrollDown CurrTopline = CurrTopline - 1 GOSUB EditTransGetLine GOSUB EditTransPrintLine END IF ELSE CurrRow = CurrRow - 1 GOSUB EditTransGetLine END IF RETURN
EditTransMoveDown: IF (CurrRow + CurrTopline - 1) >= MaxRecord THEN BEEP ELSE IF CurrRow = 19 THEN ScrollUp CurrTopline = CurrTopline + 1 GOSUB EditTransGetLine GOSUB EditTransPrintLine ELSE CurrRow = CurrRow + 1 GOSUB EditTransGetLine END IF END IF RETURN
EditTransPrintLine: COLOR colors(7, ColorPref), colors(4, ColorPref) CurrRecord = CurrTopline + CurrRow - 1 LOCATE CurrRow + 4, 2 IF CurrRecord = MaxRecord + 1 THEN PRINT u1x$; ELSEIF CurrRecord > MaxRecord THEN PRINT u1$; ELSE PRINT USING u$; CurrString$(1); CurrString$(2); CurrString$(3); IF CurrFig#(4) = 0 AND CurrFig#(5) = 0 THEN PRINT USING u4$ + "�" + u4$ + "�" + u3$; Balance#(CurrRecord) ELSEIF CurrFig#(5) = 0 THEN PRINT USING u2$ + "�" + u4$ + "�" + u3$; CurrFig#(4); Balance#(CurrRecord) ELSE PRINT USING u4$ + "�" + u2$ + "�" + u3$; CurrFig#(5); Balance#(CurrRecord) END IF END IF RETURN
EditTransPrintBalances: COLOR colors(7, ColorPref), colors(4, ColorPref) FOR a = 1 TO 19 CurrRecord = CurrTopline + a - 1 IF CurrRecord <= MaxRecord THEN LOCATE 4 + a, 66 PRINT USING u3$; Balance#(CurrTopline + a - 1); END IF NEXT a RETURN
EditTransDeleteRecord: IF MaxRecord = 1 THEN BEEP ELSE CurrRecord = CurrTopline + CurrRow - 1 MaxRecord = MaxRecord - 1 a = CurrRecord WHILE a <= MaxRecord GET #1, a + 2 PUT #1, a + 1 Balance#(a) = Balance#(a + 1) - CurrFig#(4) + CurrFig#(5) a = a + 1 WEND
LSET valid$ = "THISISVALID" LSET IoMaxRecord$ = Cvit$(MaxRecord) PUT #1, 1 GOSUB EditTransPrintWholeScreen CurrRecord = CurrTopline + CurrRow - 1 IF CurrRecord > MaxRecord THEN GOSUB EditTransMoveUp END IF GOSUB EditTransGetLine GOSUB EditTransWriteBalance END IF RETURN
EditTransAddRecord: CurrRecord = CurrTopline + CurrRow - 1 a = MaxRecord WHILE a > CurrRecord GET #1, a + 1 PUT #1, a + 2 Balance#(a + 1) = Balance#(a) a = a - 1 WEND Balance#(CurrRecord + 1) = Balance#(CurrRecord) MaxRecord = MaxRecord + 1 LSET IoDate$ = "" LSET IoRef$ = "" LSET IoDesc$ = "" LSET IoFig1$ = MKD$(0) LSET IoFig2$ = MKD$(0) PUT #1, CurrRecord + 2
LSET valid$ = "THISISVALID" LSET IoMaxRecord$ = Cvit$(MaxRecord) PUT #1, 1 GOSUB EditTransPrintWholeScreen GOSUB EditTransGetLine RETURN
EditTransPrintWholeScreen: temp = CurrRow FOR CurrRow = 1 TO 19 CurrRecord = CurrTopline + CurrRow - 1 IF CurrRecord <= MaxRecord THEN GOSUB EditTransGetLine END IF GOSUB EditTransPrintLine NEXT CurrRow CurrRow = temp RETURN
EditTransWriteBalance: GET #1, 1 LSET IoBalance$ = MKD$(Balance#(MaxRecord)) PUT #1, 1 RETURN
EditTransPutLine: CurrRecord = CurrTopline + CurrRow - 1 LSET IoDate$ = CurrString$(1) LSET IoRef$ = CurrString$(2) LSET IoDesc$ = CurrString$(3) LSET IoFig1$ = MKD$(CurrFig#(4)) LSET IoFig2$ = MKD$(CurrFig#(5)) PUT #1, CurrRecord + 1 RETURN
EditTransGetLine: CurrRecord = CurrTopline + CurrRow - 1 GET #1, CurrRecord + 1 CurrString$(1) = IoDate$ CurrString$(2) = IoRef$ CurrString$(3) = IoDesc$ CurrFig#(4) = CVD(IoFig1$) CurrFig#(5) = CVD(IoFig2$) RETURN END SUB
'FancyCls: ' Clears screen in the right color, and draws nice dots. SUB FancyCls (dots, Background)
VIEW PRINT 2 TO 24 COLOR dots, Background CLS 2
FOR a = 95 TO 1820 STEP 45 row = a / 80 + 1 col = a MOD 80 + 1 LOCATE row, col PRINT CHR$(250); NEXT a
VIEW PRINT
END SUB
'GetString$: ' Given a row and col, and an initial string, edit a string ' VIS is the length of the visible field of entry ' MAX is the maximum number of characters allowed in the string FUNCTION GetString$ (row, col, start$, end$, Vis, Max) curr$ = Trim$(LEFT$(start$, Max)) IF curr$ = CHR$(8) THEN curr$ = ""
LOCATE , , 1
finished = FALSE DO GOSUB GetStringShowText GOSUB GetStringGetKey
IF LEN(Kbd$) > 1 THEN finished = TRUE GetString$ = Kbd$ ELSE SELECT CASE Kbd$ CASE CHR$(13), CHR$(27), CHR$(9) finished = TRUE GetString$ = Kbd$
CASE CHR$(8) IF curr$ <> "" THEN curr$ = LEFT$(curr$, LEN(curr$) - 1) END IF
CASE " " TO "}" IF LEN(curr$) < Max THEN curr$ = curr$ + Kbd$ ELSE BEEP END IF
CASE ELSE BEEP END SELECT END IF
LOOP UNTIL finished
end$ = curr$ LOCATE , , 0 EXIT FUNCTION
GetStringShowText: LOCATE row, col IF LEN(curr$) > Vis THEN PRINT RIGHT$(curr$, Vis); ELSE PRINT curr$; SPACE$(Vis - LEN(curr$)); LOCATE row, col + LEN(curr$) END IF RETURN
GetStringGetKey: Kbd$ = "" WHILE Kbd$ = "" Kbd$ = INKEY$ WEND RETURN END FUNCTION
'Initialize: ' Read colors in and set up assembly routines SUB Initialize
WIDTH , 25 VIEW PRINT
FOR ColorSet = 1 TO 4 FOR X = 1 TO 10 READ colors(X, ColorSet) NEXT X NEXT ColorSet
LoadState
P = VARPTR(ScrollUpAsm(1)) DEF SEG = VARSEG(ScrollUpAsm(1)) FOR I = 0 TO 13 READ J POKE (P + I), J NEXT I
P = VARPTR(ScrollDownAsm(1)) DEF SEG = VARSEG(ScrollDownAsm(1)) FOR I = 0 TO 13 READ J POKE (P + I), J NEXT I
DEF SEG
END SUB
'Intro: ' Display introduction screen. SUB Intro SCREEN 0 WIDTH 80, 25 COLOR 7, 0 CLS
Center 4, "Q B a s i c" COLOR 15 Center 5, "� � ���� � � ���� � � � � ���� � � ���� ����� ���� �����" Center 6, "��� ��� � � �� � � ����� ��� ��� � � �� � � � � � � �" Center 7, "� � � � � � ��� ���� � � � � ���� � ��� ���� � ��� ���� �����" Center 8, "� � ���� � � ���� � � � � � � � � � ����� ���� � ��" COLOR 7 Center 11, "A Personal Finance Manager written in" Center 12, "MS-DOS QBasic" Center 24, "Press any key to continue"
SparklePause END SUB
'LCenter: ' Center TEXT$ on the line printer SUB LCenter (text$) LPRINT TAB(41 - LEN(text$) / 2); text$ END SUB
'LoadState: ' Load color preferences and account info from MONEY.DAT SUB LoadState
OPEN "money.dat" FOR INPUT AS #1 INPUT #1, ColorPref
FOR a = 1 TO 19 LINE INPUT #1, account(a).Title LINE INPUT #1, account(a).AType LINE INPUT #1, account(a).Desc NEXT a
CLOSE
END SUB
'Menu: ' Handles Menu Selection for a single menu (either sub menu, or menu bar) ' currChoiceX : Number of current choice ' maxChoice : Number of choices in the list ' choice$() : Array with the text of the choices ' itemRow() : Array with the row of the choices ' itemCol() : Array with the col of the choices ' help$() : Array with the help text for each choice ' barMode : Boolean: TRUE = menu bar style, FALSE = drop down style ' ' Returns the number of the choice that was made by changing currChoiceX ' and returns the scan code of the key that was pressed to exit ' FUNCTION Menu (CurrChoiceX, MaxChoice, choice$(), ItemRow(), ItemCol(), help$(), BarMode)
currChoice = CurrChoiceX
'if in bar mode, color in menu bar, else color box/shadow 'bar mode means you are currently in the menu bar, not a sub menu IF BarMode THEN COLOR colors(7, ColorPref), colors(4, ColorPref) LOCATE 1, 1 PRINT SPACE$(80); ELSE FancyCls colors(2, ColorPref), colors(1, ColorPref) COLOR colors(7, ColorPref), colors(4, ColorPref) Box ItemRow(1) - 1, ItemCol(1) - 1, ItemRow(MaxChoice) + 1, ItemCol(1) + LEN(choice$(1)) + 1
COLOR colors(10, ColorPref), colors(6, ColorPref) FOR a = 1 TO MaxChoice + 1 LOCATE ItemRow(1) + a - 1, ItemCol(1) + LEN(choice$(1)) + 2 PRINT CHR$(178); CHR$(178); NEXT a LOCATE ItemRow(MaxChoice) + 2, ItemCol(MaxChoice) + 2 PRINT STRING$(LEN(choice$(MaxChoice)) + 2, 178); END IF
'print the choices COLOR colors(7, ColorPref), colors(4, ColorPref) FOR a = 1 TO MaxChoice LOCATE ItemRow(a), ItemCol(a) PRINT choice$(a); NEXT a
finished = FALSE
WHILE NOT finished
GOSUB MenuShowCursor GOSUB MenuGetKey GOSUB MenuHideCursor
SELECT CASE Kbd$ CASE CHR$(0) + "H": GOSUB MenuUp CASE CHR$(0) + "P": GOSUB MenuDown CASE CHR$(0) + "K": GOSUB MenuLeft CASE CHR$(0) + "M": GOSUB MenuRight CASE CHR$(13): GOSUB MenuEnter CASE CHR$(27): GOSUB MenuEscape CASE ELSE: BEEP END SELECT WEND
Menu = currChoice
EXIT FUNCTION
MenuEnter: finished = TRUE RETURN
MenuEscape: currChoice = 0 finished = TRUE RETURN
MenuUp: IF BarMode THEN BEEP ELSE currChoice = (currChoice + MaxChoice - 2) MOD MaxChoice + 1 END IF RETURN
MenuLeft: IF BarMode THEN currChoice = (currChoice + MaxChoice - 2) MOD MaxChoice + 1 ELSE currChoice = -2 finished = TRUE END IF RETURN
MenuRight: IF BarMode THEN currChoice = (currChoice) MOD MaxChoice + 1 ELSE currChoice = -3 finished = TRUE END IF RETURN
MenuDown: IF BarMode THEN finished = TRUE ELSE currChoice = (currChoice) MOD MaxChoice + 1 END IF RETURN
MenuShowCursor: COLOR colors(8, ColorPref), colors(9, ColorPref) LOCATE ItemRow(currChoice), ItemCol(currChoice) PRINT choice$(currChoice); PrintHelpLine help$(currChoice) RETURN
MenuGetKey: Kbd$ = "" WHILE Kbd$ = "" Kbd$ = INKEY$ WEND RETURN
MenuHideCursor: COLOR colors(7, ColorPref), colors(4, ColorPref) LOCATE ItemRow(currChoice), ItemCol(currChoice) PRINT choice$(currChoice); RETURN
END FUNCTION
'MenuSystem: ' Main routine that controls the program. Uses the MENU function ' to implement menu system and calls the appropriate function to handle ' the user's selection SUB MenuSystem
DIM choice$(20), menuRow(20), menuCol(20), help$(20) LOCATE , , 0 choice = 1 finished = FALSE
WHILE NOT finished GOSUB MenuSystemMain
subchoice = -1 WHILE subchoice < 0 SELECT CASE choice CASE 1: GOSUB MenuSystemFile CASE 2: GOSUB MenuSystemEdit CASE 3: GOSUB MenuSystemAccount CASE 4: GOSUB MenuSystemReport CASE 5: GOSUB MenuSystemColors END SELECT FancyCls colors(2, ColorPref), colors(1, ColorPref)
SELECT CASE subchoice CASE -2: choice = (choice + 3) MOD 5 + 1 CASE -3: choice = (choice) MOD 5 + 1 END SELECT WEND WEND EXIT SUB
MenuSystemMain: FancyCls colors(2, ColorPref), colors(1, ColorPref) COLOR colors(7, ColorPref), colors(4, ColorPref) Box 9, 19, 14, 61 Center 11, "Use arrow keys to navigate menu system" Center 12, "Press Enter to select a menu item"
choice$(1) = " File " choice$(2) = " Accounts " choice$(3) = " Transactions " choice$(4) = " Reports " choice$(5) = " Colors "
menuRow(1) = 1: menuCol(1) = 2 menuRow(2) = 1: menuCol(2) = 8 menuRow(3) = 1: menuCol(3) = 18 menuRow(4) = 1: menuCol(4) = 32 menuRow(5) = 1: menuCol(5) = 41
help$(1) = "Exit the Money Manager" help$(2) = "Add/edit/delete accounts" help$(3) = "Add/edit/delete account transactions" help$(4) = "View and print reports" help$(5) = "Set screen colors"
DO NewChoice = Menu((choice), 5, choice$(), menuRow(), menuCol(), help$(), TRUE) LOOP WHILE NewChoice = 0 choice = NewChoice RETURN
MenuSystemFile: choice$(1) = " Exit "
menuRow(1) = 3: menuCol(1) = 2
help$(1) = "Exit the Money Manager"
subchoice = Menu(1, 1, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice CASE 1: finished = TRUE CASE ELSE END SELECT RETURN
MenuSystemEdit: choice$(1) = " Edit Account Titles "
menuRow(1) = 3: menuCol(1) = 8
help$(1) = "Add/edit/delete accounts"
subchoice = Menu(1, 1, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice CASE 1: EditAccounts CASE ELSE END SELECT RETURN
MenuSystemAccount:
FOR a = 1 TO 19 IF Trim$(account(a).Title) = "" THEN choice$(a) = RIGHT$(STR$(a), 2) + ". ------------------- " ELSE choice$(a) = RIGHT$(STR$(a), 2) + ". " + account(a).Title END IF menuRow(a) = a + 2 menuCol(a) = 19 help$(a) = RTRIM$(account(a).Desc) NEXT a
subchoice = Menu(1, 19, choice$(), menuRow(), menuCol(), help$(), FALSE)
IF subchoice > 0 THEN EditTrans (subchoice) END IF RETURN
MenuSystemReport: choice$(1) = " Net Worth Report " menuRow(1) = 3: menuCol(1) = 32 help$(1) = "View and print net worth report"
FOR a = 1 TO 19 IF Trim$(account(a).Title) = "" THEN choice$(a + 1) = RIGHT$(STR$(a), 2) + ". ------------------- " ELSE choice$(a + 1) = RIGHT$(STR$(a), 2) + ". " + account(a).Title END IF menuRow(a + 1) = a + 3 menuCol(a + 1) = 32 help$(a + 1) = "Print " + RTRIM$(account(a).Title) + " transaction summary" NEXT a
subchoice = Menu(1, 20, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice CASE 1 NetWorthReport CASE 2 TO 20 TransactionSummary (subchoice - 1) CASE ELSE END SELECT RETURN
MenuSystemColors: choice$(1) = " Monochrome Scheme " choice$(2) = " Cyan/Blue Scheme " choice$(3) = " Blue/Cyan Scheme " choice$(4) = " Red/Grey Scheme "
menuRow(1) = 3: menuCol(1) = 41 menuRow(2) = 4: menuCol(2) = 41 menuRow(3) = 5: menuCol(3) = 41 menuRow(4) = 6: menuCol(4) = 41
help$(1) = "Color scheme for monochrome and LCD displays" help$(2) = "Color scheme featuring cyan" help$(3) = "Color scheme featuring blue" help$(4) = "Color scheme featuring red"
subchoice = Menu(1, 4, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice CASE 1 TO 4 ColorPref = subchoice SaveState CASE ELSE END SELECT RETURN
END SUB
'NetWorthReport: ' Prints net worth report to screen and printer SUB NetWorthReport DIM assetIndex(19), liabilityIndex(19)
maxAsset = 0 maxLiability = 0
FOR a = 1 TO 19 IF account(a).AType = "A" THEN maxAsset = maxAsset + 1 assetIndex(maxAsset) = a ELSEIF account(a).AType = "L" THEN maxLiability = maxLiability + 1 liabilityIndex(maxLiability) = a END IF NEXT a
'Loop until <F2> is pressed finished = FALSE DO u1$ = "\ \$$###,###,###.##" u2$ = "\ \+$$#,###,###,###.##"
COLOR colors(5, ColorPref), colors(4, ColorPref) LOCATE 1, 1: PRINT SPACE$(80); LOCATE 1, 4: PRINT "Net Worth Report: " + DATE$; PrintHelpLine "<F2=Exit> <F3=Print Report>"
COLOR colors(7, ColorPref), colors(4, ColorPref) Box 2, 1, 24, 40 Box 2, 41, 24, 80
LOCATE 2, 16: PRINT " ASSETS " assetTotal# = 0 a = 1 count1 = 1 WHILE a <= maxAsset file$ = "money." + Cvit$(assetIndex(a)) OPEN file$ FOR RANDOM AS #1 LEN = 84 FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$ GET #1, 1 IF valid$ = "THISISVALID" THEN LOCATE 2 + count1, 3: PRINT USING u1$; account(assetIndex(a)).Title; CVD(IoBalance$) assetTotal# = assetTotal# + CVD(IoBalance$) count1 = count1 + 1 END IF CLOSE a = a + 1 WEND
LOCATE 2, 55: PRINT " LIABILITIES " liabilityTotal# = 0 a = 1 count2 = 1 WHILE a <= maxLiability file$ = "money." + Cvit$(liabilityIndex(a)) OPEN file$ FOR RANDOM AS #1 LEN = 84 FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$ GET #1, 1 IF valid$ = "THISISVALID" THEN LOCATE 2 + count2, 43: PRINT USING u1$; account(liabilityIndex(a)).Title; CVD(IoBalance$) liabilityTotal# = liabilityTotal# + CVD(IoBalance$) count2 = count2 + 1 END IF CLOSE a = a + 1 WEND IF count2 > count1 THEN count1 = count2 LOCATE 2 + count1, 25: PRINT "--------------" LOCATE 2 + count1, 65: PRINT "--------------" LOCATE 3 + count1, 3: PRINT USING u2$; "Total assets"; assetTotal#; LOCATE 3 + count1, 43: PRINT USING u2$; "Total liabilities"; liabilityTotal#
COLOR colors(5, ColorPref), colors(4, ColorPref) LOCATE 1, 43: PRINT USING u2$; " NET WORTH:"; assetTotal# - liabilityTotal#
DO: Kbd$ = INKEY$: LOOP UNTIL Kbd$ <> ""
SELECT CASE Kbd$ 'Handle Special keys CASE CHR$(0) + "<" 'F2 finished = TRUE CASE CHR$(0) + "=" 'F3 GOSUB NetWorthReportPrint CASE ELSE BEEP END SELECT LOOP UNTIL finished EXIT SUB
NetWorthReportPrint: PrintHelpLine ""
Box 8, 20, 14, 62 Center 10, "Prepare printer on LPT1 for report" Center 12, "Hit <Enter> to print, or <Esc> to abort"
DO: Kbd$ = INKEY$: LOOP WHILE Kbd$ <> CHR$(13) AND Kbd$ <> CHR$(27)
IF Kbd$ = CHR$(13) THEN Box 8, 20, 14, 62 Center 11, "Printing report..." u0$ = " \ \ " u1$ = " \ \ $$###,###,###.##" u2$ = " --------------" u3$ = " =============" u4$ = " \ \+$$#,###,###,###.##" PrintErr = FALSE ON ERROR GOTO ErrorTrap ' test if printer is connected LPRINT IF PrintErr = FALSE THEN LPRINT : LPRINT : LPRINT : LPRINT : LPRINT LCenter "Q B a s i c" LCenter "M O N E Y M A N A G E R" LPRINT : LPRINT LCenter "NET WORTH REPORT: " + DATE$ LCenter "-------------------------------------------" LPRINT USING u0$; "ASSETS:" assetTotal# = 0 a = 1 WHILE a <= maxAsset file$ = "money." + Cvit$(assetIndex(a)) OPEN file$ FOR RANDOM AS #1 LEN = 84 FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$ GET #1, 1 IF valid$ = "THISISVALID" THEN LPRINT USING u1$; account(assetIndex(a)).Title; CVD(IoBalance$) assetTotal# = assetTotal# + CVD(IoBalance$) END IF CLOSE #1 a = a + 1 WEND LPRINT u2$ LPRINT USING u4$; "Total assets"; assetTotal# LPRINT LPRINT LPRINT USING u0$; "LIABILITIES:" liabilityTotal# = 0 a = 1 WHILE a <= maxLiability file$ = "money." + Cvit$(liabilityIndex(a)) OPEN file$ FOR RANDOM AS #1 LEN = 84 FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$ GET #1, 1 IF valid$ = "THISISVALID" THEN LPRINT USING u1$; account(liabilityIndex(a)).Title; CVD(IoBalance$) liabilityTotal# = liabilityTotal# + CVD(IoBalance$) END IF CLOSE #1 a = a + 1 WEND LPRINT u2$ LPRINT USING u4$; "Total liabilities"; liabilityTotal# LPRINT
LPRINT LPRINT u3$ LPRINT USING u4$; "NET WORTH"; assetTotal# - liabilityTotal# LCenter "-------------------------------------------" LPRINT : LPRINT : LPRINT END IF ON ERROR GOTO 0 END IF RETURN END SUB
'PrintHelpLine: ' Prints help text on the bottom row in the proper color SUB PrintHelpLine (help$) COLOR colors(5, ColorPref), colors(4, ColorPref) LOCATE 25, 1 PRINT SPACE$(80); Center 25, help$ END SUB
'SaveState: ' Save color preference and account information to "MONEY.DAT" data file. SUB SaveState OPEN "money.dat" FOR OUTPUT AS #2 PRINT #2, ColorPref
FOR a = 1 TO 19 PRINT #2, account(a).Title PRINT #2, account(a).AType PRINT #2, account(a).Desc NEXT a
CLOSE #2 END SUB
'ScrollDown: ' Call the assembly program to scroll the screen down SUB ScrollDown DEF SEG = VARSEG(ScrollDownAsm(1)) CALL Absolute(VARPTR(ScrollDownAsm(1))) DEF SEG END SUB
'ScrollUp: ' Calls the assembly program to scroll the screen up SUB ScrollUp DEF SEG = VARSEG(ScrollUpAsm(1)) CALL Absolute(VARPTR(ScrollUpAsm(1))) DEF SEG END SUB
'SparklePause: ' Creates flashing border for intro screen SUB SparklePause
COLOR 4, 0 a$ = "* * * * * * * * * * * * * * * * * " WHILE INKEY$ <> "": WEND 'Clear keyboard buffer
WHILE INKEY$ = "" FOR a = 1 TO 5 LOCATE 1, 1 'print horizontal sparkles PRINT MID$(a$, a, 80); LOCATE 22, 1 PRINT MID$(a$, 6 - a, 80);
FOR b = 2 TO 21 'Print Vertical sparkles c = (a + b) MOD 5 IF c = 1 THEN LOCATE b, 80 PRINT "*"; LOCATE 23 - b, 1 PRINT "*"; ELSE LOCATE b, 80 PRINT " "; LOCATE 23 - b, 1 PRINT " "; END IF NEXT b NEXT a WEND END SUB
'TransactionSummary: ' Print transaction summary to line printer SUB TransactionSummary (item) FancyCls colors(2, ColorPref), colors(1, ColorPref) PrintHelpLine "" Box 8, 20, 14, 62 Center 10, "Prepare printer on LPT1 for report" Center 12, "Hit <Enter> to print, or <Esc> to abort"
DO: Kbd$ = INKEY$: LOOP WHILE Kbd$ <> CHR$(13) AND Kbd$ <> CHR$(27)
IF Kbd$ = CHR$(13) THEN Box 8, 20, 14, 62 Center 11, "Printing report..." PrintErr = FALSE ON ERROR GOTO ErrorTrap ' test if printer is connected LPRINT IF PrintErr = FALSE THEN PRINT LPRINT : LPRINT : LPRINT : LPRINT : LPRINT LCenter "Q B a s i c" LCenter "M O N E Y M A N A G E R" LPRINT : LPRINT LCenter "Transaction summary: " + Trim$(account(item).Title) LCenter DATE$ LPRINT u5$ = "--------|------|------------------------|----------|----------|--------------" LPRINT u5$ LPRINT " Date | Ref# | Description | Increase | Decrease | Balance " LPRINT u5$ u0$ = "\ \|\ \|\ \|" u2$ = "###,###.##" u3$ = "###,###,###.##" u4$ = " "
file$ = "money." + Cvit$(item) OPEN file$ FOR RANDOM AS #1 LEN = 84 FIELD #1, 8 AS IoDate$, 10 AS IoRef$, 50 AS IoDesc$, 8 AS IoFig1$, 8 AS IoFig2$ FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$ GET #1, 1 IF valid$ = "THISISVALID" THEN Balance# = 0 MaxRecord = VAL(IoMaxRecord$) CurrRecord = 1 WHILE CurrRecord <= MaxRecord
GET #1, CurrRecord + 1 Fig1# = CVD(IoFig1$) Fig2# = CVD(IoFig2$)
LPRINT USING u0$; IoDate$; IoRef$; IoDesc$; IF Fig2# = 0 AND Fig1# = 0 THEN LPRINT USING u4$ + "|" + u4$ + "|" + u3$; Balance# ELSEIF Fig2# = 0 THEN Balance# = Balance# + Fig1# LPRINT USING u2$ + "|" + u4$ + "|" + u3$; Fig1#; Balance# ELSE Balance# = Balance# - Fig2# LPRINT USING u4$ + "|" + u2$ + "|" + u3$; Fig2#; Balance# END IF CurrRecord = CurrRecord + 1 WEND LPRINT u5$ LPRINT : LPRINT END IF ON ERROR GOTO 0 END IF CLOSE END IF END SUB
'Trin$: ' Remove null and spaces from the end of a string. FUNCTION Trim$ (X$)
IF X$ = "" THEN Trim$ = "" ELSE lastChar = 0 FOR a = 1 TO LEN(X$) y$ = MID$(X$, a, 1) IF y$ <> CHR$(0) AND y$ <> " " THEN lastChar = a END IF NEXT a Trim$ = LEFT$(X$, lastChar) END IF
END FUNCTION
|