home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MADTRB36.ZIP / STARTER.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-02-09  |  19.1 KB  |  535 lines

  1. (***************************************************************)
  2. (*                                                             *)
  3. (*        FILER A LA PASCAL DATA BASE SOURCE CODE FILE         *)
  4. (*                                                             *)
  5. (*        (C) 1985 by  John M. Harlan                          *)
  6. (*                     24000 Telegraph                         *)
  7. (*                     Southfield, MI. 48034                   *)
  8. (*                                                             *)
  9. (*     The FILER GROUP of programs is released on a "FREE      *)
  10. (*     SOFTWARE" basis.  The recipient is free to examine      *)
  11. (*     and use the software with the understanding that if     *)
  12. (*     the FILER GROUP of programs prove to be of use and      *)
  13. (*     value,  a contribution to the author is encouraged.     *)
  14. (*                                                             *)
  15. (*     While reasonable effort has been made to ensure the     *)
  16. (*     reliability of the FILER GROUP of programs, no war-     *)
  17. (*     ranty is given. The recipient uses the programs at      *)
  18. (*     his own risk  and in no event shall the author be       *)
  19. (*     liable for damages arising from their use.              *)
  20. (*                                                             *)
  21. (*                                                             *)
  22. (***************************************************************)
  23.  
  24.  
  25. program starter; { ONE OF THE FILER GROUP OF PROGRAMS }
  26. {  A GENERALIZED FRAMEWORK FOR A CUSTOMIZED OUTPUT REPORT  }
  27. {  STARTER.PAS  VERSION 2.0 }
  28. {  INCLUDE FILES : STARTER1.PAS }
  29. {  NOV 15, 1984 }
  30.  
  31. { Formatted 2/7/86 by Doug Stevens using Pformat and the Turbo
  32.   editors global search/replace. Original version was 100%
  33.   upper case and very hard to read. }
  34.  
  35. label QUIT;
  36.  
  37. type
  38.   Range          = array[1..256] of char;
  39.   String60       = string[60];
  40.   String20       = string[20];
  41.   NameStr        = string[12];
  42.  
  43. var
  44.   filerecchgd      : boolean;
  45.   fileexists       : boolean;
  46.   recaddedtofile   : boolean;
  47.   exitflag         : boolean;
  48.  
  49.   ch               : char;
  50.  
  51.   filename       : string[6];
  52.   filedate,
  53.   currdate       : string[8];
  54.   sourcename     : string[14];
  55.   ans            : String60;
  56.   message        : String60;
  57.   prevcontents   : String60;
  58.  
  59.   w,x,z, code, len,
  60.   maxnbrrec, nbrrecused, rcdlen,
  61.   blockingfactor, fieldperrecord,
  62.   datarecord, diskrecord, precbyte,
  63.   diskrecnowinmem, nbrdiskrecused,
  64.   lastrecused, first,
  65.   ascii,page,line,pagefulllinecount          :    integer;
  66.  
  67.   numvalue                                   :    real;
  68.  
  69.   labellength, datalen, dataform,
  70.   labelposn, dataposn, row,
  71.   column, fieldnbr                  :    array[1..32] of integer;
  72.   lbl                               :    array[1..384] of char;
  73.   getdata                           :    Range;
  74.   asciifield                        :    array[1..32] of String60;
  75.   numfield                          :    array[1..32] of real;
  76.   subtotal                          :    array[1..32] of real;
  77.   grandtotal                        :    array[1..32] of real;
  78.  
  79.   source                            :    file;
  80. {================================================================}
  81. {        BINARY CODED DECIMAL TO INTEGER FUNCTION                }
  82. {================================================================}
  83. function BcdToInt (cha : char) : integer;
  84. begin
  85.   BcdToInt := ord(cha) - trunc(ord(cha)/16)*6;
  86. end;
  87. {================================================================}
  88. {             CHARACTER TO INTEGER FUNCTION                      }
  89. {================================================================}
  90. function ChrToInt(var charray : Range; start, len : integer)  : integer;
  91. var
  92.   code, result : integer;
  93.   workstring   : string[10];
  94. begin
  95.   workstring := '';
  96.   for result := 0 to len-1  do
  97.     begin
  98.       if charray[start + result ] = ' ' then
  99.         workstring := workstring + '0'
  100.       else workstring := workstring + charray[start+result];
  101.     end;
  102.   val(workstring,result,code);
  103.   ChrToInt := result;
  104. end;
  105. {================================================================}
  106. {               GET DATA FROM ARRAY PROCEDURE                    }
  107. {================================================================}
  108. procedure GetDataFromArray(var message : String60; z : integer);
  109. var w :  integer;
  110. begin
  111.   message := '';
  112.   for w := precbyte+dataposn[z] to precbyte+dataposn[z+1]-1 do
  113.     message := message + getdata[w];
  114. end;
  115. {================================================================}
  116. {               TIDE (EDIT BACKWARDS) PROCEDURE                  }
  117. {================================================================}
  118. procedure Tide( var message : String60);
  119. var w  :  integer;
  120. begin
  121.   for w := length(message) downto 1 do
  122.     begin
  123.       if message[w] in [',', '$', '+'] then
  124.         begin
  125.           delete(message,w,1);
  126.           message := ' ' + message;
  127.         end;
  128.     end;
  129. end;
  130. {===============================================================}
  131. {                      FUNCTION EDITNBR                         }
  132. {===============================================================}
  133. function EditNbr(x: real; y,z: integer; dollar: char ) : String20;
  134.  
  135. var
  136.   numstring : string[24];
  137.  
  138. begin    { CONVERT THE REAL NUMBER TO A STRING VALUE }
  139.   str(x:18:z,numstring);
  140.   if z = 0 then z := 16  { FIRST POSSIBLE COMMA LOCATION  }
  141.   else z := pos('.',numstring)-3;  {    DITTO             }
  142.  
  143.   while z > 1 do  {  INSERT COMMAS/SPACES IN THE NUMBER  }
  144.     begin
  145.       if numstring[z-1] in [' ','-'] then
  146.         insert(' ',numstring,z)
  147.       else insert(',',numstring,z);
  148.       z := z -3 ;  {  COMMAS OCCUR EVERY THIRD CHARACTER  }
  149.     end;
  150.  
  151.   {  FIND THE FIRST NON SPACE CHARACTER IN THE NUMBER }
  152.   z := 0;
  153.   repeat
  154.     z := z + 1;
  155.  until numstring[z] <> ' ';
  156.  
  157.   { DELETE ANY SPACE FOLLOWING A MINUS SIGN }
  158.   if numstring[z] = '-' then
  159.     begin
  160.       if numstring[z+1] = ' ' then delete(numstring,z+1,1);
  161.       if dollar = '$' then insert('$',numstring,z+1);
  162.     end
  163.  
  164.   { ADD THE $/SPACE CHARACTER TO THE BEGINNING OF THE NUMBER }
  165.   else numstring[z-1] := dollar;
  166.  
  167.   { REPLACE THE NUMBER WITH A FIELD OF '<' IF IT IS TOO BIG  }
  168.   z := length(numstring)-y;
  169.   if numstring[z-1] = '-' then
  170.       for z := y downto 0 do numstring[z] := '<'
  171.   else
  172.     begin
  173.       if numstring[z] in ['0'..'9',',','-','.'] then
  174.           for z := y downto 0 do numstring[z] := '<';
  175.     end;
  176.   EditNbr := copy(numstring,z+1,y);
  177.  
  178. end;
  179. {================================================================}
  180. {               STRING TO REAL NUMBER PROCEDURE                  }
  181. {================================================================}
  182. procedure StringToReal(var source:String60;var numb:real;var code:integer);
  183. var
  184.   w  :  integer;
  185.   condition  :  boolean;
  186. begin
  187.   w := 1;
  188.   numb := 0;
  189.   condition := true;
  190.   Tide(source); { ELIMINATE PUNCTUATION }
  191.   repeat  { UNTIL CONDITION = FALSE }
  192.     if source[w] = ' ' then delete(source,1,1)
  193.     else condition := false;
  194.     if length(source) = 0 then
  195.       begin
  196.         source := '0';
  197.         condition := false;
  198.       end;
  199.   until condition = false;
  200.   if length(source) = 1 then condition := true;
  201.   while condition = false do
  202.     begin
  203.       if source[w] = ' ' then
  204.         begin
  205.           condition := true;
  206.           w := w-2;
  207.         end;
  208.       if length(source) = w then
  209.         begin
  210.           condition := true;
  211.           w := w-1;
  212.         end;
  213.       w := w + 1;
  214.     end;
  215.   source := copy(source,1,w);
  216.   val( source,numb,code );
  217. end;
  218. {================================================================}
  219. {           CALCULATE DISKRECORD & PRECBYTE PROCEDURE            }
  220. {================================================================}
  221. procedure Calculate;
  222.   begin
  223.     diskrecord := trunc((datarecord-1)/blockingfactor)*2+7;
  224.     precbyte := ((datarecord-1) mod blockingfactor)*rcdlen;
  225.   end;
  226. {================================================================}
  227. {                   GET DATA RECORD PROCEDURE                    }
  228. {================================================================}
  229. procedure GetDataRec;
  230.   begin
  231.     Calculate;
  232.     if diskrecord <> diskrecnowinmem then
  233.       begin
  234.         if filerecchgd = true then
  235.           begin
  236.             if diskrecnowinmem > nbrdiskrecused then
  237.               begin                 { GET NEXT AVAILABLE RECORD }
  238.                 Seek(source,nbrdiskrecused+2);
  239.                 nbrdiskrecused := diskrecnowinmem;
  240.               end
  241.             else
  242.               begin
  243.                 Seek(source,diskrecnowinmem);
  244.               end;
  245.             blockwrite(source,getdata,2);  {SAVE CHANGED DATA}
  246.             filerecchgd := false;
  247.           end;
  248.                                     
  249.         if diskrecord <= nbrdiskrecused then
  250.           begin
  251.             Seek(source,diskrecord);
  252.             blockread(source,getdata,2);         {  RECORD DATA  }
  253.          end
  254.         else FillChar(getdata[1],256,' '); {SPACES FOR EMPTY REC }
  255.  
  256.        diskrecnowinmem := diskrecord;
  257.       end;
  258.   end;
  259. {===============================================================}
  260. {                       FUNCTION EXIST                          }
  261. {===============================================================}
  262. function Exist(filename : NameStr) : boolean;
  263. var
  264.   fil    :  file;
  265.   status : Integer;
  266. begin
  267.   Assign(fil,filename);
  268.   {$I-}
  269.   reset(fil);
  270.   {$I+}
  271.   Exist := (IOResult = 0);
  272. {$I-} Close(fil); status := IOResult; {$I+} (* Required by Turbo 3.x *)
  273. end;                                        (* Added by Doug Stevens *)
  274. {================================================================}
  275. {           READ RECORD AND PLACE DATA IN ARRAYS                 }
  276. {================================================================}
  277. procedure MoveRecordDataToArray;
  278.   begin
  279.     Calculate;
  280.     GetDataRec;
  281.     for z := 1 to fieldperrecord do
  282.       begin
  283.         GetDataFromArray(asciifield[z],z);
  284.         if dataform[z] <> ascii then
  285.           begin
  286.             StringToReal(asciifield[z],numfield[z],code);
  287.           end
  288.         else numfield[z] := 0;
  289.       end;
  290.   end;
  291. {================================================================}
  292. {           FUNCTION GET NUMBER IN GETDATA FIELD ( Z )           }
  293. {================================================================}
  294. function FnbrInFld(z : integer) : real;
  295. var
  296.   realval : real;
  297.   begin
  298.     GetDataFromArray(ans,z);
  299.     if dataform[z] <> ascii then
  300.       StringToReal(ans,realval,code)
  301.     else realval := 0;
  302.     FnbrInFld := realval;
  303.   end;
  304. {================================================================}
  305. {                  INITIALIZE FILER FILE                         }
  306. {================================================================}
  307. procedure Initialize;
  308.   label QUIT;
  309.  
  310. begin
  311. {STARTSTART:}
  312.   repeat
  313.     ClrScr; exitflag := FALSE;
  314.     GotoXY(1,22);
  315.     write('START A LA PASCAL');    { ENTER YOUR REPORT NAME HERE }
  316.     GotoXY(1,23);
  317.     write('ENTER SOURCE FILE NAME : ');
  318.     readln(sourcename);
  319.     x := pos('.',sourcename);
  320.     if x <> 0 then sourcename := copy(sourcename,1,x-1);
  321.     if sourcename = 'END' then
  322.       begin                     { Quick and dirty exit. }
  323.         exitflag := TRUE;
  324.         goto QUIT;
  325.       end;
  326.     sourcename := sourcename + '.DAT';
  327.     fileexists := Exist(sourcename);
  328.   until fileexists = true;
  329.   write('ENTER CURRENT DATE (MM/DD/YY) : ');
  330.   readln( currdate );
  331.   if length(currdate) = 0 then currdate := '  /  /  ';
  332.   Assign( source, sourcename );
  333.   reset( source );
  334.   Seek(source,1);
  335.   blockread( source,getdata,1 );
  336.   blockread( source,lbl,3 );
  337.   filename := 'XXXXXX';
  338.   for x := 1 to 6 do
  339.     filename[x] := getdata[x];
  340.   maxnbrrec := ChrToInt(getdata,7,4);
  341.   nbrrecused := ChrToInt(getdata,11,4);
  342.   rcdlen := ChrToInt(getdata,15,3);
  343.   blockingfactor := ChrToInt(getdata,18,2);
  344.   fieldperrecord := ChrToInt(getdata,20,2);
  345.   filedate := '  /  /  ';
  346.   Move(getdata[22],filedate[1],8);
  347.  
  348. {================================================================}
  349. {  GET LABEL LENGTH, DATA LENGTH & DATA FORM INFO                }
  350. {================================================================}
  351.  
  352. labelposn[1] := 1;
  353. dataposn[1] := 1;
  354.  
  355. for x := 1 to fieldperrecord do
  356.   begin
  357.     labellength[x] :=  BcdToInt(getdata[32+x]);
  358.     datalen[x]     :=  BcdToInt(getdata[64+x]);
  359.     dataform[x]    :=  ord(getdata[96+x])-48;
  360.     labelposn[x+1] :=  labelposn[x] + labellength[x];
  361.     dataposn[x+1]  :=  dataposn[x] + datalen[x];
  362.   end;
  363.  
  364. {================================================================}
  365. {           TRANSLATE REPORT STRUCTURE                           }
  366. {================================================================}
  367.  
  368.   blockread(source,getdata,1);  { SCREEN INFORMATION }
  369.       { ESTABLISH VALUE OF DATAFORM[Z] FOR ASCII INFORMATION }
  370.       if getdata[1] = 'S' then ascii := 9 else ascii := 15;
  371.   for x := 1 to fieldperrecord do
  372.     begin
  373.       w := x*4+1;
  374.       row[x]       := BcdToInt(getdata[w]);
  375.       column[x] := BcdToInt(getdata[w+1])*10+trunc(BcdToInt(getdata[w+2])/10);
  376.       {FIELDNBR[X]  := BCDTOIN(GETDATA[W+3]);} { not implemented }
  377.     end;
  378. {================================================================}
  379. {          INITIALIZE VARIABLES FOR ENTRY INTO FILER             }
  380. {================================================================}
  381.   datarecord := nbrrecused;
  382.   Calculate;
  383.   diskrecnowinmem := diskrecord -1; { ENSURE DISK READ FIRST TIME}
  384.   filerecchgd := false;      { ENSURE NO WRITE BEFORE FIRST READ }
  385.   lastrecused := 0;               { SET LAST RECORD USED TO ZERO }
  386.   nbrdiskrecused := diskrecord;     { ESTABLISH MAX DISK REC NBR }
  387.   recaddedtofile := false; { FLAG TO INDICATE CHANGE IN FILE SIZE}
  388. QUIT:
  389. end;  { INTIIALIZE PROCEDURE }
  390. {================================================================}
  391. {                      PROCEDURE NEWPAGE                         }
  392. {================================================================}
  393. procedure NewPage;
  394. begin
  395.   write(Lst,^l);      { FORMFEED COMMAND }
  396.   line := 1;
  397. end;
  398. {================================================================}
  399. {                 PROCEDURE PAGE TITLE                           }
  400. {================================================================}
  401. procedure PageTitle;
  402. begin
  403.   writeln(Lst,'                   SAMPLE REPORT TITLE               ');
  404.   write(Lst,currdate,'                                            ');
  405.   writeln(Lst,'       PAGE ',page);
  406.   writeln(Lst);
  407.   writeln(Lst);
  408.   page := page +1;
  409.   line := line +4;      { FOUR LINES IN THIS REPORT TITLE }
  410. end;
  411. {================================================================}
  412. {                 PROCEDURE DATA HEADING                         }
  413. {================================================================}
  414. procedure DataHeading;
  415. begin
  416.   writeln(Lst,'      NAME                   COMPANY       ACCOUNT 1    ACCOUNT 2');
  417.   writeln(Lst,'=================================================================');
  418.   writeln(Lst);
  419.   line := line +3;         { THREE LINES IN THIS HEADING }
  420. end;
  421. {================================================================}
  422. {                 PROCEDURE PRINT SUB TOTALS                     }
  423. {================================================================}
  424. procedure PrintSubTotals;
  425. begin
  426.   writeln(Lst,'                                        ============   ==========');
  427.   write(Lst,'SUB TOTAL :                               ');
  428.   ans := EditNbr(subtotal[9],10,2,'$');   { SUB TOTAL FOR ACCOUNT 1 }
  429.   write (Lst,ans);
  430.   ans := EditNbr(subtotal[10],13,1,' ');   { SUB TOTAL FOR ACCOUNT 2 }
  431.   writeln(Lst,ans);
  432.   writeln(Lst);
  433.  
  434.   for x := 1 to 31 do                          { ZERO ALL SUBTOTALS }
  435.     subtotal[x] := 0;
  436.  
  437.   line := line + 3;         { THREE LINES PRINTED IN THIS SUB TOTAL }
  438.  
  439.   if line > pagefulllinecount - 3 then
  440.     begin
  441.       NewPage;
  442.       PageTitle;
  443.     end;
  444. end;
  445. {================================================================}
  446. {                 PROCEDURE PRINT GRAND TOTALS                   }
  447. {================================================================}
  448. procedure PrintGrandTotals;
  449. begin
  450.   writeln(Lst,'                                        ============   ==========');
  451.   write(Lst,'GRAND TOTAL :                          ');
  452.   ans := EditNbr(grandtotal[9],13,2,'$');   { SUB TOTAL FOR ACCOUNT 1 }
  453.   write (Lst,ans);
  454.   ans := EditNbr(grandtotal[10],13,1,' ');   { SUB TOTAL FOR ACCOUNT 2 }
  455.   writeln(Lst,ans);
  456. end;
  457.  
  458.  
  459.  
  460. {================================================================}
  461. {                  OUTPUT CODE GOES HERE                         }
  462. {================================================================}
  463. begin
  464.  
  465.   Initialize;                   { ID AND READ IN FILE PARAMETERS }
  466.   if exitflag then goto QUIT;
  467.   page := 1;                             { INITIALIZE FOR REPORT }
  468.   line := 1;
  469.   pagefulllinecount := 60;
  470.   datarecord := 1;                      { SET UP SUB TOTAL TEST }
  471.   MoveRecordDataToArray;
  472.   prevcontents := asciifield[1];
  473.   for x := 1 to 31 do                { CLEAR SUB & GRAND TOTALS }
  474.     begin
  475.       subtotal[x] := 0;
  476.       grandtotal[x] := 0;
  477.     end;
  478.  
  479.   PageTitle;                       {  PRINT TITLE ON TOP OF PAGE }
  480.  
  481.   DataHeading;                              { PRINT DATA HEADING }
  482.  
  483.  
  484.   {==============================================================}
  485.   {                 PROCESS BODY OF REPORT                       }
  486.   {==============================================================}
  487.  
  488.   for datarecord := 1 to nbrrecused do
  489.     begin
  490.       MoveRecordDataToArray;
  491.       {========================================}
  492.       {   CHECK TO SEE IF SUB TOTAL IS REQD    }
  493.       {========================================}
  494.       if asciifield[1] <> prevcontents then
  495.         begin
  496.           prevcontents := asciifield[1];
  497.           PrintSubTotals;
  498.         end;
  499.       {========================================}
  500.       {       WRITE LINE OF DATA HERE          }
  501.       {========================================}
  502.       write(Lst,asciifield[1],' ',asciifield[2],' ');
  503.       ans := EditNbr(numfield[9],10,2,'$');   {  ACCOUNT REC }
  504.       write(Lst,ans);
  505.       ans := EditNbr(numfield[10],13,1,' '); {  AMT PAST DUE }
  506.       writeln(Lst,ans);
  507.       {=======================================}
  508.       {   UPDATE SUB TOTALS & GRAND TOTALS    }
  509.       {=======================================}
  510.       for x := 1 to 31 do
  511.         begin
  512.           subtotal[x] := subtotal[x] + numfield[x];
  513.           grandtotal[x] := grandtotal[x] + numfield[x];
  514.         end;
  515.       {=======================================}
  516.       {   INCREMENT LINE AND CHECK FOR EOP    }
  517.       {=======================================}
  518.       line := line + 1;
  519.       if line > pagefulllinecount then
  520.         begin
  521.           NewPage;
  522.           PageTitle;
  523.           DataHeading;
  524.         end;
  525.     end;  { FOR DATARECORD := 1 TO  }
  526.  
  527.   PrintSubTotals;
  528.   PrintGrandTotals;
  529.  
  530. {================================================================}
  531. {                    END PROGRAM                                 }
  532. {================================================================}
  533. QUIT:
  534. end.
  535.