Note: You must be running on BP Forms version 3 (Feb 2018) for the functionality described within this document to work.

This section describes a simple test program that is provided with Blue Prairie Forms.  This program  is similar to the provided bpi_simple_test_program but it packages differetn data and presents it within the template using an open office table as well as presenting it as an Open Office chart. This program produces a document called Q0___bpi_simple_test_chart.odt.  This document will, by default, be dropped into the .../queue/bpiform1 directory.  If the phantom is configured and running, it will attempt to deliver the document to a CUPS printer called Q0 on the Open Office Print Server. 

A Sample Program

Blue Prairie Forms in installed with a sample test program that:

  1. Uses a standard template (bpi_simple_test_chart_tpl.odt) provided with Blue Prairie Forms
  2. Requires no external data source
  3. Produces a finished odt document
  4. Is a good example that can be used as a starting point for your own chart integrations

This example program will be installed and tested to verify the stability of the Blue Prairie Forms by your installation technician.  It should be left unaltered as it may be used in the future as a diagnostic test to validate the stability of the installation.  You may make copies of the program for your own experimentation.

   * bpi_simple_test_chart
   * Copyright (c) 2016 by Blue Prairie, Inc.
   * Example program to test a simple form with common form elements
   * 2/4/2018 by Bruce Decker
   * ----------------------------------------------------------------
   * Requires that the form template be placed in the directory indicated
   * below.  This does not actually print the form, it just produces (drops)
   * a finished form into a specified location
   * This example program will:
   * 1) Set some non-repeating tags and values  (see subroutine InitformVars)
   * 2) Set some repeating tags and values using multiValued arrays
   * 3) Call the templating system (see subroutine MakeAndPrint)
   * 4) Write a finished document based on the named template
   * Note: This example does not actually print.  It just creates a document
   * -----------------------------------------------------------------
   pgmId = \bpi_simple_test_chart\
   tag = \\; val = \\
   * Equate some vectors for our associated multiValue arrays
   EQU d.lineNo       TO 1
   EQU d.productLine  TO 2
   EQU d.revenue      TO 3
   EQU d.profit       TO 4
   EQU d.transactions TO 5
   GOSUB ParseSentence; *171212
   GOSUB InitFormVars
   * load the detail array with a simple loop
   totExtPrice = 0
   FOR lineNo = 1 TO 10
     detail< d.lineNo, lineNo> = lineNo                    ;* a line number
     detail< d.productLine, lineNo> = \Line-\:lineNo       ;* word Line- followed by lineNo
     detail< d.revenue, lineNo> = (lineNo*100)             ;* rev is lineNo x 100
     detail< d.profit, lineNo>  = (lineNo*100)*(.10)       ;* profit is 10% of rev
     detail< d.transactions, lineNo> = (lineNo*30)         ; *transaction count 30x lineNo
   NEXT lineNo
   * load footnotes array with static assignment
   footnotes<1,-1> = \This is line 1 of the footnotes array\
   footnotes<1,-1> = \This is line 2 of the footnotes array\
   * Now make the document
   GOSUB MakeAndPrint
   GOTO Exit
   * ------------------------------------------------------------------------------
   * B L U E   P R A I R I E   F O R M S   S U B R O U T I N E S
   * ------------------------------------------------------------------------------
   verbose = 5
   blocks = \\; tags = \\; vals = \\; pos = 0;
   * note that the 4th param is the 'block' specifier.  Since blank these tags are not repeating
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%@PGM%\, pgmId, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%@WHO%\, @WHO, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%@LOGNAME%\, @LOGNAME, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%@USERNO%\, @USERNO, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%port%\, FIELD(OCONV(\\,\U50BB\), SPACE(1), 1), \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%TIME%\, OCONV(TIME(),\MTH\):SPACE(1):OCONV(DATE(),\D2/\), \\, vector, verbose); *|||BPI FORM|||
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%timeDate%\, TIMEDATE(), \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%dayOfWeek%\, OCONV(DATE(), 'DWAMADYL'), \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%powered_by%\, \Powered by Blue Prairie Forms (tm)\, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \\, \%reprint%\, \\, \\, vector, verbose)
   detail = \\
   footnotes = \\
   * reserved for future use
   * now add the detail lines to the blocks/tags/vals arrays with a block name of 'det'.  The template should feed
   * these tags to a one-row table in openOffice.  The first column in the table should be made to contain the plug-in
   * directive "{repeat=tr;block=det}  This will cause the table row to be repeated for the number of multivalues
   * found in these tags.  So, if you have 10 lines represented by 10 multivalues for each of the tags, then the
   * table should be expanded automatically from 1 row as defined in the template to 10 rows (one for each multivalue)
   * because each line in the detail array is represented (properly) as a multivalue.
* Note the numeric tag names (111.111, 222.222), etc. This is not ideal but it is required because the open office
* chart editor does not permit non-numeric values in the chart data. Therefore, we needed to use numeric tag names
* and wanted to choose tag names that would not collide with 'real' data that may have existed within the document.
* We will investigate whether Open Office can be made to accept proper (non numeric) tag names within the chart table
   CALL bpi.set.tagval2(blocks, tags, vals, \mychart\, \%d.lineNo%\, detail<d.lineNo>, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \mychart\, \%d.productLine%\, detail<d.productLine>, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \mychart\, \111.111\, detail<d.revenue>, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \mychart\, \222.222\, detail<d.profit>, \\, vector, verbose)
   CALL bpi.set.tagval2(blocks, tags, vals, \mychart\, \333.333\, detail<d.transactions>, \\, vector, verbose)
   * load footnotes array to tag
   CALL bpi.set.tagval2(blocks, tags, vals, \foot\, \%f.footnotes%\, footnotes, \\, vector, verbose)
   doc.format = \odt\
   pathToBpiForms = "/dbms/BPIFORMS/bpi_forms"; * <--- change to suit your install
   verbose = 5
   GOSUB MoveDetailToArrays
   CALL bpi.xmlencode( tags, tags, \all\, error)
   CALL bpi.xmlencode( vals, vals, \all\, error)
   *make a diag table from tags and vals
   CALL bpi.makediag( blocks, tags, vals, \odt\, diag, status)
   *add the diag table to the tags and vals array
   CALL bpi.set.tagval2( blocks, tags, vals, \\, \%diag%\, diag, \\, vector, verbose)
   GOSUB GetQueue
   *construct the filename of the document
   document_name_make = "%queueName%___bpi_simple_test_chart%copy%.odt"
   tag<2> = \%queueName%\; val<2> = bpiQueueName

   * set variables for the form maker
   params = \odt\
   templatePath = "%pathToBpiForms%/templates/bpi_simple_test_chart_tpl.odt"
   templatePath = CHANGE( templatePath, \%pathToBpiForms%\, pathToBpiForms)

   tempPath = "%pathToBpiForms%/working"
   tempPath = CHANGE( tempPath, \%pathToBpiForms%\, pathToBpiForms)
   * call the form maker
   verbose = 5
   FOR i = 1 TO copies
      IF copies EQ 1 THEN
         copyName = \\
      END ELSE
         copyName = \_\:i
      output_docname = document_name_make
      CALL bpi.tagval( tag, val, output_docname )
      output_docname = CHANGE( output_docname, \%copy%\, copyName)
      outputPath = "%pathToBpiForms%/queue/bpiform1/":output_docname
      outputPath = CHANGE( outputPath, \%pathToBpiForms%\, pathToBpiForms)
      outputPath = CHANGE( outputPath, \%queueName%\, bpiQueueName)
      CRT \Making-> \:outputPath
      CALL bpi.set.tagval2( blocks, tags, vals, \\, \%chartHeading%\, "Revenue, Profit and Volume", \\, vector, verbose)
      CALL bpi.form.make2( templatePath, outputPath, tempPath, params, blocks, tags, vals, verbose, status, message)
      *should now have a completed form at output.path
   NEXT i
   * We would normally grab the current assigned queue from a SP-ASSIGN or SETPTR command
   * but for this test, we'll just use the queue Q0
   bpiQueueName = \Q0\
   pgm = \bpi_simple_test_program\
   sentence = CHANGE( @SENTENCE, SPACE(1), @AM)
   maxSentence = DCOUNT(sentence, @AM)
   start  = @FALSE
   copies = 1
   FOR i = 1 TO maxSentence
       word = sentence<i>
       uc.word = OCONV( word, \MCU\)
       CASE start
          BEGIN CASE
          CASE uc.word[1,2] = \-C\
             copies = OCONV( word, \MCN\)
             IF NOT( copies ) THEN copies = 1
          CASE @TRUE
          END CASE
       CASE word EQ pgm
          start = @TRUE
       CASE @TRUE
       END CASE
    NEXT i


The above program functions similarly to the other 'simple' example programs provided with Blue Prairie Forms.  The main differences are:

  1. The tag names are different
  2. The data values are not masked using MultiValue OCONV functions because Open Office requires raw numbers (without commas, currency symbols, etc.)
  3. 3The tag names of 111.111, 222.222 seem odd and instead we would have preferred to use our normal tagging style (e.g., %tagname% ).  But, because the Open Office chart object allows ONLY numeric data to be added to the chart's data table object for the Y axis values, we had to resort to using numeric tags.  As such, using tag names like a simple '1' could present issues because the tagging engine would attempt to swap all instances of '1' with the tag's value.  Therefore, in our example, we have used the tag names of 111.111, 222.222, etc because we believed that it would be unlikely that these values would exist natually either within the template itself or as values assigned to other tags.

Running the example program

To run the sample, program, simply type bpi_simple_test_chart.  Diagnostic messages will be displayed to the screen and a document will be written to the queue directory declared in the program.  Depending on the specific location of directories in your Blue Prairie Forms installation, you may need to modify certain parts of the test program.  Specifically, the variable pathToBpiForms should be adjusted to fit your installation.

If you wish to run a number of copies of a document to the queue directory, you may add the -c switch followed by the number of copies you wish to create.  For example:

bpi_simple_test_chart -c5

Will generate 5 documents:






Template Highlights

A detailed explanation of the template process is provided in the User Manual.  You can modify the example template but please make a backup of the original template (unchanged) before making modifications.  You can access this template at .../BPIFORMS/bpi_forms/template/bpi_simple_test_chart_tpl.odt

 The Header (for all pages of the template)

The header is much like other test programs

The Body (for page 1)

Page one of the template contains a normal table so that you can see the data values in table form.  Page 2 of the example contains the chart which will use the same data presented in the table but will show a chart-based visualization of that table data.

The body table is the same as the other bpi_simple example templates.  The {repeat} tag (which is clipped in the above image) is actually:


In this example, the block name has changed from the other bpi_simple examples to 'mychart'.  This is purely cosmetic and it really does not matter what the block name is, so long as it matches between the program declared block name and the block name referenced in the template.   In this case, the block name in the program was 'mychart' so this is what we have used in this template.

Tag: 111.111 222.222...

The tag 111.111 does indeed seem odd especially in considering that we normally advise the use of unambiguous tags.  The ONLY reason we have used the tag names 111.111, 222.222 and 333.333 is that the chart object editor does not allow alpha-numeric values to be entered as data values for feeding the chart. 

The Body (for page 2) "The Chart"

Page 2 of the template contains the chart object.  This is standard chart object that can be added to any Open Office template using the standard chart object.


 Note the following

  • The chart was created when the author created the template by simply selecting Insert>Chart from the Open Office menu
  • The chart type was chosen by double-clicking on the inserted chart on the inserted chart and choosing "Chart Type" from the pop-up menu
  • The tag %chartHeading% is showing in the template.  This will be replaced by a value passed to open office using a host-side tag called %chartHeader%
  • The {repeat} tag is showing at the bottom of the chart.  This will be replaced by the %d.productLine% tag's value when the actual data is inserted into the chart at run time.
  • The numbers 222.222 and 333.333 are showing because these are the tag names being used by the template.  These tag names will be replaced with the actual data passed from the MultiValue host at run time.  In the above example, 111.111 has been truncated by Open Office charts to 111.11 however the internally stored value is 111.111.  This is important because 111.111 is far more unlikely to occur in normal data than 111.11.  Don't be fooled by the above image.
  • In the template, only one record is present in the data set (the tag) and this explains why there are only three bars (blue, red and yellow).  When an actual set of data is passed into the chart object at run time, more records will be reflected in the chart.
  • The legend words are "Revenue", "Profit" and "Transactions."  These are hard coded into the chart in this example but just as easily could have been tag/value references passed from the MultiValue host (as we did with %chartHeading%.

Select the Chart

  • Click on the chart and it will be selected
  • Now, right-click and choose 'edit' from the pop-up menu

  • When selected, green anchors will appear in the four corners of the chart.
  • With the green anchors visible, right click on the chart and select 'edit' from the pop-up menu.  A grey border will appear around the chart and the green anchors will turn black.

Edit the Chart

  • Right click on the chart and a pop-up menu will appear with the following options:
  • Insert Titles will allow you to edit the chart's titles.  This is where we inserted the tag %chartHeading% in the example template
  • Chart Type will allow you to change the chart type
  • Data Table is where we will enter tag names to populate the chart

Insert Titles

Note the tag being used in the Title field.  When a tag is used, it will be replaced by the value passed from the multiValue host at run-time

Chart Type

Note: Experiment with the various chart types and options.

Data Table

The data table is where you will enter the repeat tags used

  • The actual values entered into the Y-axis data sets is 111.111 (note the three digits after decimal) even though in the above screen snip, the editor is truncating the display to 111.11.  We recommend using at least three digits after the decimal when forced to used pure numeric tags to lessen the change that a tag might be in conflict with normal data that exists elsewhere naturally in the document.
  • In the example above, we hard-coded the legend text as Revenue, Profit and Transactions.  However these could have been passed by the MultiValue host using normal tags
  • The Category column contains our normal {repeat} tag so that, at run time, additional rows will be inserted into the chart's data table based on data sent from the MultiValue Host.  In the example above, the full text of the Category field is:


repeat=tr   Means that the table row (tr) will be repeated based on the number of data rows from the MultiValue host
block=mychart   specifies that the repeat will be based on the repeating block named 'mychart'
increment=1   (see the repeat tag documentation for a full explanation)
%d.productLine%   This is a tag passed from the MultiValue host that will contain the product line.  This value will be the label of each chart group at run time.


The Result



Congratulations.  Using the same techniques you have used to create documents with tables, you have now created your first chart!