home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / dbase / _base16.zip / CLIPPER.DOC < prev    next >
Text File  |  1994-02-13  |  6KB  |  183 lines

  1. Enhancing your Clipper programs using !STRUCT
  2. ================================================================
  3. !STRUCT allows to export information from you dbf files, and put
  4. it directly into your source code files.  This will save you much
  5. typing, and a lot of debugging headaches.
  6.  
  7. This file provides information on how to enhance your code by:
  8.  
  9.         Using dbcreate()
  10.         Using field declarations
  11.         Accessing database fields by field number
  12.  
  13.  
  14. Using dbcreate()
  15. ================================================================
  16. Clipper 5.0 has a new function called dbcreate(), that allows the
  17. creation of a database file from a structure array.  By using a
  18. structure array:
  19.  
  20.     Your application generate its own dbf files
  21.     File structure updates are easier
  22.     Fields lengths up to 64,000 characters may be used
  23.  
  24. To see what a structure array looks like type:
  25.  
  26.     !STRUCT . -A | MORE
  27.  
  28. To create a program that creates all of your databases, type:
  29.  
  30.     !STRUCT . -A > CREATE.PRG
  31.             │  │ │ └───────── output file name
  32.             │  │ └─────────── redirect output symbol
  33.             │  └───────────── specify array style output
  34.             └──────────────── file specification
  35.  
  36. Then edit CREATE.PRG.  You will a static array created for each
  37. dbf file in you application.
  38.  
  39.     static DBF_TEST := { ;
  40.         {"TEXT"      , 'C',   80, 0 };
  41.     }
  42.  
  43.     static DBF_SAMPLE := { ;
  44.         {"ID_NUM"    , 'C',    6, 0 },;
  45.         {"ID_DATE"   , 'D',    8, 0 },;
  46.         {"ID_AMT"    , 'N',    8, 2 },;
  47.         {"ITEM"      , 'C',   30, 0 };
  48.     }
  49.  
  50. Now add the necessary code to create the databases:
  51.  
  52.     function Initialize()
  53.     if !file("sample.dbf")
  54.         dbcreate("sample", DBF_SAMPLE)
  55.     endif
  56.     if !file("test.dbf")
  57.         dbcreate("TEST", DBF_TEST)
  58.     endif
  59.  
  60. When you need to modify a database in an existing application,
  61. simply edit this file again and change the array information. In
  62. this example I decided to add the new field "extra".  This code
  63. will detect the fact that the actual database file structure
  64. doesn't match the expected database structure, and it updates the
  65. actual file structure.
  66.  
  67.     static DBF_SAMPLE := { ;
  68.         {"ID_NUM"    , 'C',    6, 0 },;
  69.         {"ID_DATE"   , 'D',    8, 0 },;
  70.         {"ID_AMT"    , 'N',    8, 2 },;
  71.         {"ITEM"      , 'C',   30, 0 },;
  72.         {'EXTRA'     , 'C',    8, 0 };
  73.     }
  74.  
  75.     function open_sample()
  76.  
  77.     use sample new
  78.     if len(DBF_SAMPLE) > fcount()
  79.         ? "Updating file structure - Please wait"
  80.         close sample
  81.         erase sample.old
  82.         rename sample.dbf to sample.old
  83.         dbcreate("sample", DBF_SAMPLE)
  84.         use sample new
  85.         append from sample.old
  86.         erase sample.old
  87.     endif
  88.  
  89.  
  90. Using field declarations
  91. ================================================================
  92. To avoid complier warning, field declarations should be used.
  93. The best way of doing this is to create a header file with all
  94. the field names declared in it.
  95.  
  96. You can generate this header file very easily by typing:
  97.  
  98.     !STRUCT . -F > FIELDS.CH
  99.             │  │ │ └───────── output file name
  100.             │  │ └─────────── redirect output symbol
  101.             │  └───────────── specify field declaration output
  102.             └──────────────── file specification (same as *.*)
  103.  
  104. To use the header file, put the include declaration at the top of
  105. the file:
  106.  
  107.     #include "fields.ch"
  108.  
  109.     function main()
  110.     ...
  111.  
  112. Any time a database or field is added, simply generate a new
  113. FIELDS.CH header file.
  114.  
  115.  
  116. Accessing database fields by field number
  117. ================================================================
  118. Clipper 5.0 introduced the fieldget() and fieldput() functions.
  119. Fieldget() and fieldput() allow you to reference database fields
  120. by number, instead of by the name string.  This is useful, if you
  121. wish to pull your field information into an array.
  122.  
  123. The problem with using hard coding numbers to reference fields,
  124. is that it is hard to keep track of which number corresponds to
  125. which field.
  126.  
  127. To generate a header file that redefines each field with a
  128. readable name type:
  129.  
  130.     !STRUCT SAMPLE.DBF -N > DEFINES.CH
  131.  
  132. The utility will create the file DEFINES.CH that will look like
  133. this:
  134.  
  135.     *** SAMPLE ***
  136.     #define SAMPLE_ID_NUMBERS     1  // C,   6, 0
  137.     #define SAMPLE_ID_DATE        2  // D,   8, 0
  138.     #define SAMPLE_ID_AMT         3  // N,   8, 2
  139.     #define SAMPLE_ITEM           4  // C,  30, 0
  140.     #define MAX_SAMPLE            4
  141.  
  142. To get the value of the field ID_NUMBERS type:
  143.  
  144.     #include "defines.ch"
  145.     ? fieldget(SAMPLE_ID_NUMBERS)
  146.  
  147. A more useful example that sucks up the contents of a record into
  148. an array, allows the user to edit the array, and then puts the
  149. contents back into the original record:
  150.  
  151.     #include "defines.ch"
  152.  
  153.     func main()
  154.     local getlist:={}
  155.     local a:={}
  156.  
  157.     use sample
  158.     a:=getrec(MAX_SAMPLE)
  159.     @ 10, 10 get a[SAMPLE_ID_NUMBERS]
  160.     @ 11, 10 get a[SAMPLE_ID_DATE   ]
  161.     @ 12, 10 get a[SAMPLE_ID_AMT    ]
  162.     @ 13, 10 get a[SAMPLE_ITEM      ]
  163.     read
  164.     if lastkey()!=27
  165.         putrec(a, MAX_SAMPLE)
  166.     endif
  167.  
  168.     func getrec(nLast)
  169.     local a[nLast]
  170.     local cnt
  171.     for cnt:=1 to nLast
  172.         a[cnt]:=fieldget(cnt)
  173.     next
  174.     return(a)
  175.  
  176.     func putrec(a, nLast)
  177.     local cnt
  178.     for cnt:=1 to nLast
  179.         fieldput(cnt, a[cnt])
  180.     next
  181.     return nil
  182.  
  183.