home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource1 / chint / useful33.hnt < prev    next >
Encoding:
Text File  |  1993-11-02  |  9.1 KB  |  215 lines

  1. This useful hint outlines how to set up for just about any sort of labels.
  2.  
  3. It can handle the situation where "half labels" appear at the top and bottom
  4. of the sheet of labels.  It can also handle the case where the number of
  5. labels per sheet does not divide exactly into the number on lines per sheet,
  6. and of course standard tractor feed labels are also supported.
  7.  
  8.  
  9. 1) Create a function file, LABELS.FUN and add the following code to it.
  10.  
  11. #define MAXLABELSPERPAGE  20  /* Maximun labels in the first column */
  12.  
  13. int labelLines[MAXLABELSPERPAGE+1];
  14.  
  15. void setupForLabels(void)
  16. /*
  17.   A call to this procedure will n2eed to be added to a custom report skeleton.
  18.   This is where all the label dimensions and spacing are determined.
  19. */
  20. {
  21.   int i, j, gap, adjustBy, orphanLines;
  22.   int linesPerLabel, linesPerSheet, labelsPerPage;
  23.  
  24.   num_across[1] = ival(GET_NUM_ACROSS);
  25.   gap = space_across[1] - width_across[1];
  26.   space_across[1] = ival(GET_WIDTH);
  27.   width_across[1] = space_across[1] - gap;
  28.   headerstruct[PGHDR] = ival(GET_TOP_MARGIN);
  29.   headerstruct[PGFTR] = ival(GET_BOTTOM_MARGIN);
  30.   labelsPerPage = ival(GET_NUM_LABELS);
  31.  
  32.   linesPerSheet = pagelength - headerstruct[PGHDR] - headerstruct[PGFTR];
  33.   linesPerLabel = linesPerSheet / labelsPerPage;
  34.   orphanLines = linesPerSheet % labelsPerPage;
  35.   bandlinestruct[1].d = linesPerLabel;
  36.  
  37.   if (orphanLines <= (labelsPerPage/2))
  38.     adjustBy = 1;
  39.   else {
  40.     adjustBy = -1;
  41.     linesPerLabel++;
  42.     orphanLines = labelsPerPage - orphanLines;
  43.   }
  44.  
  45.   for (i=1; i<=MAXLABELSPERPAGE; i++) {
  46.     if (i <= labelsPerPage)
  47.       labelLines[i] = linesPerLabel;
  48.     else
  49.       labelLines[i] = 0;
  50.   }
  51.  
  52.   if (orphanLines != 0) {
  53.     bandlinestruct[1].d++;
  54.     j = labelsPerPage / orphanLines;
  55.     if (adjustBy > 0) {
  56.       for (i=labelsPerPage; i >= (labelsPerPage-orphanLines+1); i--)
  57.         labelLines[i-(i-1)*j] += adjustBy;
  58.     }
  59.     else {
  60.       for (i=1; i<=orphanLines; i++)
  61.         labelLines[i+(i-1)*j] += adjustBy;
  62.     }
  63.   }
  64. }
  65.  
  66. bool labelLineOK(int labelLineNo)
  67. /*
  68.   This function is passed a label line number, and using the global page line
  69.   number counter, "lineno", determines if the label being printed can print
  70.   on the line passed (based on hte number of lines per label established by
  71.   the calculations in setupForLabels).
  72. */
  73. {
  74.   int i, lno;
  75.  
  76.   i = 1;  lno = lineno - headerstruct[PGHDR];
  77.   while ((lno > labelLines[i]) && (i < MAXLABELSPERPAGE)) {
  78.      lno -= labelLines[i];
  79.      i++;
  80.    }
  81.    return(labelLineNo == lno);
  82. }
  83.  
  84.  
  85. 2) Create a custom report skeleton.  This is necessary because you need to
  86.    insert a call to the "setupForLabels()" function into the
  87.    "initializeReport()" function in the standard report skeleton.  The reason
  88.    the function call must be inserted at this point (rather than using a
  89.    compute field on the filter for example), is that it must be done after
  90.    the report's "allocate" routine has been run.  This because of the
  91.    internal variables that are altered by "setupForLabels".
  92.  
  93.    Copy the standard report skeleton to a skeleton for labels
  94.  
  95.        COPY DBCREP.SKL LABELS.SKL
  96.  
  97.    Now edit LABELS.SKL and at the begininig of the "initializeReport()"
  98.    function add the line "setupForLabels();"
  99.  
  100.         void initializeReport(void)
  101.         {
  102.           ...
  103.  
  104.           setupForLabels();                        /* <-- Insert this line */
  105.           clrscr();
  106.           screenSave = deltas;
  107.           deltas     = 0;
  108.           okStatus   = True;
  109.           ...
  110.  
  111.  
  112. 3) The third step is to design a report filter, LABELREP.DS.  Make sure you
  113.    use exactly the same the filter variable names that have already used in
  114.    the code for "setupForLabels()".
  115.  
  116.    The filter needs to prompt the user for :--
  117.  
  118.      number of lines per sheet of labels               - GET_NUM_LINES
  119.      number of lines in any "half label" at the top    - GET_TOP_MARGIN
  120.      number of lines in any "half label" at the bottom - GET_BOTTOM_MARGIN
  121.      number of labels in the first column of the sheet - GET_NUM_LABELS
  122.      number of labels across the page                  - GET_NUM_ACROSS
  123.      total width of each label in characters           - GET_WIDTH
  124.  
  125.    The filter should also have a compute field to set the report page length
  126.    to what ever the user has specified in "GET_NUM_LINES".  That is the
  127.    "Compute Expression" should be :  pagelength = ival(GET_NUM_LINES).
  128.  
  129.    You may also want to use other filter fields like selecting (and setting),
  130.    the output device, and setting up variables to specify the range of labels
  131.    that are to be printed.
  132.  
  133.  
  134. 4) When designing the report specify the filter screen (LABELREP.DS),
  135.    mentioned in step 3 (use Filter/Specify).
  136.  
  137.    Make sure you add the function file name, "LABELS.FUN" to the list of
  138.    include files for the report (use Universal/Include Files).
  139.  
  140.    When you design the labels they should be in band one as the code in
  141.    "setupForLabels()" assumes this (references to num_across[1],
  142.    space_across[1], width_across[1] and bandlinestruct[1].d).
  143.  
  144.    You should design the labels with one or two blank lines before you start
  145.    placing the fields.  This is because there may be a need to cater for
  146.    labels that are not of a standard length.  For example, if you purchase
  147.    "8 up" laser labels on A4 (70 line) paper then some simple arithmetic
  148.    leads to the discovery that you will need 8.75 lines per label!!  The
  149.    "setupForLabels()" function caters for this by giving some labels one
  150.    more line that others.  This is why is it not advisable to print any
  151.    data on the first line of the label.
  152.  
  153.    You need to select "Labels/Number Across" and should specify the maximum
  154.    number of labels across the page that you permit on the filter screen,
  155.    (that is, if your validation for GET_NUM_ACROSS is "!{} <= 5" then you
  156.    should specify 5 labels across in the report (note that you may first need
  157.    to select "Universal/Page/Width" to increase the page width to accomadate
  158.    the label dimensions you desire).  You will also probably want to use the
  159.    "Labels/Width", "Labels/Seperation" and "Labels/Orientation" items.
  160.  
  161.    You may also want to utilise the "Labels/Pack" facility.  If you do so
  162.    then the first blank line or two, (mentioned above), of your label should
  163.    have a "." or "-"  at the first position.  This will stop the "Pack"
  164.    algorithm moving these line(s) to the bottom of the label.
  165.  
  166.    After the lines where data is printed on the label you will need to add
  167.    a number of blank lines, this is to cater for labels of different lengths,
  168.    so add enough lines to cater for the maximum length label you think your
  169.    program might have to deal with.  For each blank line select "Line
  170.    Condidtion" and use the "labelLineOK(line)" (from the LABELS.FUN file) as
  171.    the condition.  The "line" passed to "labelLineOK()" is the name of an
  172.    internal variable in the report skeleton in the function where the call
  173.    to "labelLineOK()" will be generated.
  174.  
  175.    The last situation that needs to be dealt with is when the label sheet has
  176.    part of a label at the top and/or bottom of the sheet.  For example "7 up"
  177.    laser labels on A4 paper (70 lines), are usually all 9 lines per label.
  178.    This means that there are 7 full labels with 7 lines over.  The 7 extra
  179.    lines are usually put at the top and bottom of the page.  DataBoss will
  180.    handle these as the page header and page footer.
  181.  
  182.    Add as many blank lines to both the "Page Header" and "Page Footer" as
  183.    you think your program may need to deal with (worst case).  Each blank
  184.    line must have a "Line Condition" attached so that when you don't want
  185.    headers and footers the blank lines can be suppressed.  The line condition
  186.    for a blank line in the header is :--
  187.  
  188.       headerstruct[PGHDR] >= line     /* see above for explanation of line */
  189.  
  190.    The line condition for a blank line in the footer is :--
  191.  
  192.       headerstruct[PGFTR] >= line     /* see above for explanation of line */
  193.  
  194.  
  195. 5) The final step is to generate the label printing report using the custom
  196.    LABELS.SKL skeleton file, (just change the skeleton name on the report
  197.    GENERATE form), and then compile and test your program.
  198.  
  199.    NOTE : Just because a sheet of labels has a half label at the top and
  200.           bottom of the sheet does not necessarily mean that you need to
  201.           specify a top and bottom margin when printing labels.
  202.  
  203.           The reason is that the whole point of adding the half labels was
  204.           that laser printers could not print near the edge of the page,
  205.           (often you will find that they can only print on 64 lines).  This
  206.           means that even though the piece of paper has 70 lines on it as
  207.           far as the laser printer is concerned it only has 64.  You don't
  208.           need to specify a top and bottom margin because they are implicit
  209.           to the printers physical capability.
  210.  
  211.    NOTE : This problem, the laser printers inability to print on all lines,
  212.           usually means that it is not possible to print on some label
  213.           stationary when using the standard printer setup of 6 lines per
  214.           inch.  Keep this in mind when purchasing your labels!!
  215.