home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 4 / AACD04.ISO / AACD / Programming / CanDo / Decks3 / Bill-it / Databases.case < prev    next >
Encoding:
Text File  |  1994-04-28  |  11.5 KB  |  222 lines

  1. BILL-IT AND DATABASES DOCUMENTATION
  2.  
  3. by Miles Goodhew, Desktop Utilities, March/April 1994
  4. for AustBBS Desktop Utilities CanDo User Group Disk 4
  5.  
  6.  
  7. This tutorial attempts to explain the concept of databases for application
  8. in CanDo.  There are several "serious" database concepts and methods that I
  9. have left out, but they're not of much relevance here.  For all you could
  10. want to know about database programming see CanDo Tutorials (from Rush
  11. Software or Desktop Utilities) pp.48-63, and general references such as
  12. Capron's "Computers:  Tools for an information age" pp.448-473.
  13.  
  14. The case study refers to the Bill-it program, which provides a facility for
  15. generating and tracking invoices.
  16.  
  17. --------------------------------------------------------------------------
  18.  
  19. What is a Database?
  20.  
  21.     A Database is quite simply a collection of information.  This
  22. information is organied to allow easy access for operations such-as adding,
  23. sorting and searching, etc.  A database consists of a number of records.
  24.  
  25. --------------------------------------------------------------------------
  26.  
  27. Records
  28.  
  29.     These show up in most higher-level languages, such-as the Pascal/Modula/Oberon
  30. family and in C as the STRUCT datatype.  A record is a structured or compound
  31. data type that incorporates several other pieces of information, which can
  32. be any type at all.
  33.  
  34.     To explain this, take an example:  A small business operates a database
  35. which has records for each of the employees.  The information stored for
  36. each employee is:  Name, age, wage, and address (which corresponds to a
  37. record structure consisting of a string, two numbers and another string).
  38. So in their CanDo program, they have an array of records as their database.
  39. Each record consists of a name string, age number, wage number and address
  40. string.  e.g.:
  41.  
  42.         For 42-year old Fred Smith of No.1 Credibility Street, Bruce,
  43. A.C.T.  26xx, who's paid $230 per week:
  44.  
  45.         Let Database[1].Name = "Fred Smith"
  46.         Let Database[1].Age  = 42
  47.         Let Database[1].Wage = 230
  48.         Let Database[1].Addr = "1 Credibility Street, Bruce, A.C.T. 26xx"
  49.  
  50.         Example1 - An example of a record - the "Database" name is, of
  51. course, not required - it could quite easily be "Employees".  In this
  52. example, a new record has been created (or an old one overwritten) at
  53. location 1 of the database array.
  54.  
  55.     As you can see from this, all the information in the database is
  56. identical in structure , even though each record may have different
  57. information within it.
  58.  
  59. --------------------------------------------------------------------------
  60.  
  61. That's all good and well, but what can it do for me?
  62.  
  63.     Most people view databases as (like the example above) lists of
  64. employees, or catalogues of objects, etc.  What many people don't know at
  65. first is that all sorts of information can be stored as a database.  One
  66. popular application is in ordering or invoicing programs.
  67.  
  68.     Invoices and order forms often consist of several lines of identically
  69. formatted information (e.g.  Stock no., quantity, description, price/unit,
  70. total price).  These lines lend themselves quite well to being stored as
  71. records in a database (a unique database for each order form or invoice.
  72. Although all of the databases have the same record structure).
  73.  
  74. --------------------------------------------------------------------------
  75.  
  76. Forms
  77.  
  78.     Database forms, much like their paper namesakes are a collection of
  79. fields that need to be filled by the user.  Usually fields have a logical
  80. input focus flow from one to another, and the last one usually "commits" a
  81. record to the database.
  82.  
  83. ==========================================================================
  84.  
  85. A Case Study
  86.  
  87. Several users have approached us with queries about making databases or
  88. making invoicing-type programes.  As you might have noticed from the above
  89. (very brief!) explanation, it's not just some simple tip that can be relayed
  90. over the phone.  I also happens that our invoicing program is a little
  91. temperamental, so I thought I might as well write another invoicing program,
  92. and hit two or three birds with the one stone.
  93.  
  94. --------------------------------------------------------------------------
  95.  
  96.     What should it do?
  97.  
  98. Well, the screen layout consists of three main sections:
  99.     1) Entry fields for information unique to each invoice (Name, date, etc.)
  100.     2) A group of fields for entry of multiple lines of order information
  101. (product code, description, quantity, etc.)
  102.     3) A list-box containing the all the lines of order information.
  103.  
  104.     The essential operaton is as follows:
  105.     · Input focus flows from the first of the unique fields through to the
  106. last of the "multipe-entry" fields, and then jups back to the first of the
  107. "multiple-entry" fields (N.B.  NOT the unique fields).
  108.     · As return is hit in various fields, values are calculated and
  109. inserted into other fields (e.g.  an item total is calculated from that
  110. item's price and quantity).  When return is pressed in the final field, all
  111. the "multiple-entry" fields are copied into a database (array of records),
  112. and typed into the list box.
  113.     · Clicking on a line in the list-box "edits" that line by copying the
  114. corresponding databse element to the input fields, and selecting the first
  115. "multipe-entry" field for user input.  Then when return is pressed again in
  116. the final field, the values are copied back to the database and the list
  117. refreshed.
  118.     · The List refresh erases the list's document, and types in information
  119. from the database (formatting numbers, etc as it goes).  As it types each
  120. line, it also keeps a running total of the prices and tax components.  When
  121. it's finished going through the database, the totals are calculated and
  122. printed at the bottom of the screen.
  123.     · There are menu items to let you load or save and invoice, to get a
  124. new invoice, or to quit the program.  There's also an edit menu, which
  125. allows you to cut copy, pase and delete lines from the list-box (and their
  126. corresponding database entries).
  127.  
  128. --------------------------------------------------------------------------
  129.  
  130.     How is it done?
  131.  
  132.      The central information store of this program is a record called
  133. CurrRcpt, which has entries for all the unique input fields, as well as an
  134. array called "Items".  The Items array's elements are records which in-turn
  135. have elements for each of the "Multiple-entry" fields (make sense? - have a
  136. look at figure 2).  It's important to note that the lines of the list-box
  137. correspond to the elements of the Items database array (i.e.  line 1 is
  138. element 1, line 2 is element 2, etc.).  So whenever the user clicks on a
  139. line, the returned number is the index (i) to use for
  140. SeDBObjects(CurrRcpt.items[i]) (that is - "put the selected record into the
  141. edit fields").
  142.  
  143.     Unfortunately CanDo only allows for one group of database objects on a
  144. card at one time.  This poses a problem, as the two groups of input fields
  145. (the "Unique" and "Multiple entry" groups) need to be accessed in different
  146. ways and at different times.  For example, you wouldn't want each element
  147. in the Items array to include a copy of the "Unique" invoice information.
  148. Similarly, you wouldn't want the CurrRcpt variable to include, at the
  149. top-level, a copy of the most recently selected item from the list.  So,
  150. only one of the groups can be named as database objects.  I decided that,
  151. as they were used most often, the "multiple entry" fields would be database
  152. objects (i.e.  their names start with "."), and would thus be able to use
  153. the get and set DBObjects commands.  For the "Unique" fields, I made two
  154. new scripts to get and set their values to/from the unique information in
  155. the invoice (these scripts are used within the load and save operations).
  156.  
  157.     Loading and saving of the database is simplicity itself, thanks to
  158. CanDo's LoadVariable and SaveVariable commands.  There is a little
  159. complexity in the load and save routines, as if the user requests to Quit,
  160. Load or clear the invoice when the current recieipt has been edited since it
  161. was last saved, then the program queries the user that this s what they
  162. really want to do.  You've probably seen this is many other programs
  163. ("Document blah has been edited, really quit?"), it involved keeping track
  164. of an "Edited" flag or "Dirty Bit".  This flag is set (assigned a TRUE
  165. value) whenever the user's actions modify the data in memory (e.g.  adding
  166. or changing an invoiced item, etc.).  The flag is cleared (assigned a FALSE
  167. value) whenever the user loads, saves or clears an invoice (Of course, if
  168. the invoice had been edited, then the load or clear operations would have
  169. first produced the "Are you sure" confirmation).
  170.  
  171.     You might have noticed that there is not element in the CurrRcpt
  172. variable for the invoice number.  This is because the invoice number is
  173. saved as part of the filename (and ONLY as part of the filename).  Why?  -
  174. because this then allows a user to re-index the invoice simply by renaming
  175. it.  The Save function generates the filename by taking the value from the
  176. invoice number field, and appending it to the invoicee's name (Note the use
  177. of the "||" operator).  The Load function extracts the second "word" of the
  178. filename (using "." as the word separator) as the invoice number.
  179.  
  180. --------------------------------------------------------------------------
  181.  
  182.     What can be added from here?
  183.  
  184. * Printing - This is easily achieved by writing to the "PRT:" device.  That
  185. is, execute OpenFile, with filename "PRT:", ioflag of WRITEONLY, and
  186. accessflag of NEWFILE (The buffer name can be anything - "Printer" is
  187. fairly easy to remember, though).  Having opened the printer device, you
  188. now use one of the FileWrite commands to send the information out
  189. (FileWriteLine would probably be best).  The format of what you print is
  190. entirely up to you (that's something outside the scope of this article).
  191. For style hints, try examining a few invoices you might have received.
  192. Having printed out all the information you feel necessary, you then close
  193. the printer file (using "Close <buffername>").  If you find it easier to
  194. get the layout of the invoice in a document, then you can print it by using
  195. the SaveDocument command, and the "PRT:" device (Don't forget to specify
  196. ASCII filetype!).  Using the document approach is simpler from a
  197. programmer's perspective, but it has the slight drawbacks of consuming a
  198. bit more memory and time.
  199.  
  200. * "Auto stocknumbers" - That is:  When a stocknumber is entered, the
  201. invoicing program fills the description and price fields accordingly.  This
  202. is a little more complex than printing, but nevertheless the method is
  203. still fairly clear.
  204.     The easiest way of doing this is create a directory for stock item
  205. records.  Each file in this directory has a stocknumber for its name, and
  206. consists of a single record with entries for description, price and taxrate
  207. (or whatever you want).  So, when the user enters a stocknumber, and hits
  208. return, the rpogram loads-in the relevant file, and copies the information
  209. from the file to the display fields (i.e.  description, taxrate, etc.).
  210.     If the program can't find a given stocknumber then it assumes that
  211. this is a new stocknumber, and remembers this by setting a variable (say
  212. "NewStockNumber") to true.  Then, when the user hits return in the final
  213. entry field, the "Commit" script can check this variable, and save the
  214. relevant information to the new stocknumber.
  215.     If you need to modify your stock item information at-least
  216. semi-regularly, then you'll need to implement some sort of stock-item
  217. modification functionality.  However, I'll leave this up to you, as you
  218. should have learnt enough thoughout this tutorial to be able to do this
  219. yourself.  The only hints I can offer are:  it will probably involve
  220. another card, and some input fields similar to the "multiple-entry" ones
  221. mentioned previously.
  222.