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