creapage.net

HOWTO - Sashipa development

 How to print lists.

You wish to make a print report list for a listForm.

In this page we explain an example of the DemoContact application. This report contains two list levels. We begin by a general skeleton:

  <printReport name='PRtblContact_ListAddresss'>
    <pageFormat format='A4' orientation='portrait' />
    <pageImageableArea x='47' y='50' w='501' h='742' relativeLocation='yes' />

    <caption>Print contacts (and addresses)</caption>

    ... pageHeader ...
    
    ... pageContent ...

  </printReport>

We define an A4 page, with a portrait orientation. We specify a page header (that appears on each printed page) and a body contains data.

Here is the header code:

  <pageHeader height='35'>
    <serieDrawFigure locations='absolute'>
      <defaultFont name='arial' style='bold' size='10' />
      <defaultColor r='14' g='28' b='78' />
      <defaultSubDrawFigureAttributes maxHeight='11' />

      <predefinedDrawFigure type='title' halign='center' maxHeight='14'>
        <font name='arial' style='bold' size='11' />
      </predefinedDrawFigure>
      <predefinedDrawFigure type='pageNumeroOnCount' halign='right'>
        <font name='arial' style='plain' size='9' />
      </predefinedDrawFigure>
      <staticTextDrawFigure y='14' halign='center' maxHeight='14'>
        <text>(addresses)</text>
        <font name='arial' style='bold' size='11' />
      </staticTextDrawFigure>

      <lineDrawFigure x='0' y='34' maxHeight='1'>
        <color r='a' g='14' b='3c' />
      </lineDrawFigure>
    </serieDrawFigure>
  </pageHeader>

This header will display the title (type='title') on the center. This title is built on each report building. On the right there is the page numero and the number of pages (type='pageNumeroOnCount'). We add a label "(addresses)" under the title. Then we draw a segment for separating header and page body.

NB: when element width isn't specified the report manager takes pageImageableArea.width as default value.

Now we can see the page body (pageContent). Here is the skeleton:

  <pageContent removeFirstChildY='yes'>
    <listDistribution>
      <dataRecordPrinter>

        ... serieDrawFigure ...

        <printerDataSource mode='dispatchParentValues' />

      </dataRecordPrinter>
    </listDistribution>
  </pageContent>

The content of our page is a list (listDistribution). That means drawings that are generated for each data row, will be located vertically one after others.

We remark the attribute removeFirstChildY='yes'. It means that the 'y' of the first drawing of each page will be ignored. ('y' is used to keep a gap between each row, but the first row is stick to the top.

The data source isn't redefined. So the listForm query will be used. It's possible because all printed instanceColumns are displayed in the listForm too. When the print report uses the listForm query, the report doesn't run any query and data rows are taken in the buffer.

Now we can see the serieDrawFigure that will create a figure for each data row:

  <serieDrawFigure locations='relativeVertical' atomic='no'>
    <defaultFont name='arial' style='plain' size='10' />

    <!-- Record fields -->

    <serieDrawFigure y='10' locations='absolute'>
      <defaultSubDrawFigureAttributes y='0' maxHeight='26' />

      <!-- Name, First name -->
      <serieDrawFigure x='0' locations='relativeHorizontal' maxWidth='371'>
        <defaultFont name='arial' style='boldItalic' size='10' />
        <!-- Contact name -->
        <textDrawFigure maxWidth='186'>
          <instanceColumn schemaColumn='tblContact_Contactname' />
        </textDrawFigure>
        <!-- Contact first name -->
        <textDrawFigure x='4' maxWidth='181'>
          <instanceColumn schemaColumn='tblContact_Contactfirstname' />
        </textDrawFigure>
      </serieDrawFigure>

      <!-- Cellular -->
      <textDrawFigure x='371' maxWidth='130' halign='right'>
        <instanceColumn schemaColumn='tblContact_Cell' />
        <font name='arial' style='italic' size='10' />
        <tiedText type='before'>
          <condition type='notNull' />
          <text>Cell: </text>
        </tiedText>
      </textDrawFigure>
    </serieDrawFigure>
    
    ... listDistributionDrawFigure ...

    <!-- End of record : draw a line -->
    <lineDrawFigure y='5' maxHeight='1'>
      <color r='77' g='99' b='ff' />
    </lineDrawFigure>

  </serieDrawFigure>

The main serieDrawFigure contains three elements: a child serieDrawFigure, an addresses sub-list (listDistributionDrawFigure) and a segment (lineDrawFigure) for separating records. Page breaks can happen into the drawing (atomic='no') - it's safe, in order to allow addresses sub-list bigger than a page.

The main serieDrawFigure locates its sub-drawFigures vertically one after others (locations='relativeVertical'), and takes care to height of each one. The child serieDrawFigure locates its sub-drawFigures in absolute locations. So sub-drawFigures can have a common 'y' value, and keeps the same 'x' value on each row.

Last remark: a text is attached to the Cellular drawFigure. The text will appear before (tiedText type='before') the value, and only when the value exists (condition type='notNull').

We just have seen a classic one-level print report list. Now we are going to see the listDistributionDrawFigure element that draws a sub-list of Addresses in each Contact row. I put here the whole of the code:

  <listDistributionDrawFigure x='100' y='0'>
    <listDistribution>

      <dataRecordPrinter>
        <serieDrawFigure locations='absolute' atomic='yes'>
          <defaultSubDrawFigureAttributes y='4' maxHeight='26' />

          <!-- IsProfessional -->
          <textDrawFigure x='0' maxWidth='36'>
            <instanceColumn schemaColumn='tblContactaddress_Isprofessional' />
            <tiedText type='replace'>
              <condition type='equals'>
                <internationalValue>Y</internationalValue>
              </condition>
              <text>[Prof]</text>
            </tiedText>
            <tiedText type='replace'>
              <condition type='equals'>
                <internationalValue>N</internationalValue>
              </condition>
              <text />
            </tiedText>
          </textDrawFigure>

          <!-- AddressStreet -->
          <textDrawFigure x='36' maxWidth='194'>
            <instanceColumn schemaColumn='tblContactaddress_Addressstreet' />
          </textDrawFigure>

          <!-- AddressPostcode -->
          <textDrawFigure x='230' maxWidth='40'>
            <instanceColumn schemaColumn='tblContactaddress_Addresspostcode' />
          </textDrawFigure>

          <!-- AddressCity -->
          <textDrawFigure x='270' maxWidth='130'>
            <instanceColumn schemaColumn='tblContactaddress_Addresscity' />
          </textDrawFigure>
        </serieDrawFigure>

        <printerDataSource>
          <selectQueryBuilder db='dbDemoContact' type='list'>
            <castFilterSet autoCastFilter='no'>
              <fkCastFilter>
                <instanceFk schemaFk='fk_tblContactaddress_tblContact' />
              </fkCastFilter>
            </castFilterSet>
            <selectStatementBuilder>
              <instanceColumnList>
                <instanceColumn schemaColumn='tblContactaddress_Isprofessional' />
                <instanceColumn schemaColumn='tblContactaddress_Addressstreet' />
                <instanceColumn schemaColumn='tblContactaddress_Addresspostcode' />
                <instanceColumn schemaColumn='tblContactaddress_Addresscity' />
              </instanceColumnList>
            </selectStatementBuilder>
            <fromStatementBuilder>
              <mainInstanceTable schemaTable='tblContactaddress' />
            </fromStatementBuilder>
          </selectQueryBuilder>
        </printerDataSource>

      </dataRecordPrinter>

    </listDistribution>
  </listDistributionDrawFigure>

We already know most of elements. It's a listDistribution built like the main listDistribution. The only news is the data source, that is a selectQueryBuilder. The selectQueryBuilder will build a query dynamically for each Contact row. For each Contact row, the built query will be filtered on the primary key of Contact.

Remark: currently two-levels print reports hasn't good performance because the Melba engine will run one query for each main row.

© Copyright 2003 Sashipa-Melba Team. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License as much as this note clearly appears.