HOWTO développement Sashipa

 

 Imprimer des listes avancées.

Vous souhaitez associer un état à un formulaire listForm pour imprimer une liste.

 

Dans cette page nous décortiquons l'exemple fourni par l'application DemoContact. Cet état a de spécifique qu'il contient deux niveaux de listes. Commençons par la vue générale :

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

    <caption>Imprimer les contacts (adresses)</caption>

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

  </printReport>

On définit ici une feuille A4 orientée en portrait. On lui met un en-tête (qui apparaîtra sur chaque page) et un corps contenant les données.

 

Voyons le contenu de l'en-tête :

  <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>(adresses)</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>

Cet en-tête affichera le titre (type='title') de la liste en centré. Ce titre est calculé dynamiquement à chaque génération de l'état, en fonction du filtre de la listForm. A droite du titre on aura le numéro de page ainsi que le nombre de pages (type='pageNumeroOnCount'). On rajoute un libellé "(adresses)" sous le titre. Puis on tire un trait sur toute la largeur.

Notez que quand la largeur des éléments n'est pas spécifiée, c'est celle de la zone affichable de la page qui est prise par défaut.

 

Nous pouvons passer au contenu de l'élément (pageContent), qui est le corps de la page proprement dit. En voici la vue d'ensemble :

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

        ... serieDrawFigure ...

        <printerDataSource mode='dispatchParentValues' />

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

Le contenu de notre page est une liste (listDistribution), ce qui signifie que les dessins générés par le serieDrawFigure pour chaque ligne de donnée, seront positionnés à la suite les uns des autres, en ordonnées.

Nous remarquons l'attribut removeFirstChildY='yes' qui signifie que l'ordonnée du premier dessin de chaque page sera ignorée (l'ordonnée du serieDrawFigure sert à espacer les lignes mais le premier dessin de chaque page sera néanmoins collé en haut).

La source de donnée n'est pas redéfinie : c'est celle du listForm appelant qui sera utilisée. Ceci n'est possible que parceque toutes les instanceColumns que nous utilisons dans notre serieDrawFigure sont déjà présentes comme colonnes de la listForm. De cette manière, la requête ne sera pas rejouée lors de la génération de l'état.

 

Voyons maintenant le serieDrawFigure qui créera un dessin pour chaque ligne de donnée.

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

    <!-- Champs de l'enregistrement -->

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

      <!-- Nom, Prenom -->
      <serieDrawFigure x='0' locations='relativeHorizontal' maxWidth='371'>
        <defaultFont name='arial' style='boldItalic' size='10' />
        <!-- ContactNom -->
        <textDrawFigure maxWidth='186'>
          <instanceColumn schemaColumn='tblContact_Contactnom' />
        </textDrawFigure>
        <!-- ContactPrenom -->
        <textDrawFigure x='4' maxWidth='181'>
          <instanceColumn schemaColumn='tblContact_Contactprenom' />
        </textDrawFigure>
      </serieDrawFigure>

      <!-- TelPortable -->
      <textDrawFigure x='371' maxWidth='130' halign='right'>
        <instanceColumn schemaColumn='tblContact_Telportable' />
        <font name='arial' style='italic' size='10' />
        <tiedText type='before'>
          <condition type='notNull' />
          <text>Portable : </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>

Le serieDrawFigure principal contient trois éléments : un serieDrawFigure enfant, la sous-liste des adresses, et un segment (lineDrawFigure) pour séparer les enregistrements. On remarque que le changement de page peut avoir lieu au milieu du dessin d'un même enregistrement (atomic='no') - ce qui est plus sage, au cas où une personne aurait une sous-liste d'adresses qui dépasserait une page.

Le serieDrawFigure principal positionne ses enfants les uns en dessous des autres (locations='relativeVertical'), en fonction de la hauteur de chacun. Le serieDrawFigure enfant positionne en revanche ses enfants en coordonnées absolues, ce qui permet de répartir les champs aux mêmes ordonnées et que ceux-ci aient les mêmes abscisses sur les différentes lignes.

Dernière chose : on associe un texte qui apparaîtra devant (tiedText type='before') le téléphone portable. Et uniquement si ce dernier existe (condition type='notNull').

 

Le serieDrawFigure que nous venons d'observer est un exemple classique pour une liste à un niveau. Nous allons y associer un l'élément listDistributionDrawFigure qui dessinera une sous-liste dans chaque ligne de donnée. Je met ici l'intégralité du code :

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

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

          <!-- IsProfessionnelle -->
          <textDrawFigure x='0' maxWidth='36'>
            <instanceColumn schemaColumn='tblContactadresse_Isprofessionnelle' />
            <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>

          <!-- AdresseRue -->
          <textDrawFigure x='36' maxWidth='194'>
            <instanceColumn schemaColumn='tblContactadresse_Adresserue' />
          </textDrawFigure>

          <!-- AdresseCP -->
          <textDrawFigure x='230' maxWidth='40'>
            <instanceColumn schemaColumn='tblContactadresse_Adressecp' />
          </textDrawFigure>

          <!-- AdresseVille -->
          <textDrawFigure x='270' maxWidth='130'>
            <instanceColumn schemaColumn='tblContactadresse_Adresseville' />
          </textDrawFigure>
        </serieDrawFigure>

        <printerDataSource>
          <selectQueryBuilder db='dbDemoContact' type='list'>
            <castFilterSet autoCastFilter='no'>
              <fkCastFilter>
                <instanceFk schemaFk='fk_tblContactadresse_tblContact' />
              </fkCastFilter>
            </castFilterSet>
            <selectStatementBuilder>
              <instanceColumnList>
                <instanceColumn schemaColumn='tblContactadresse_Isprofessionnelle' />
                <instanceColumn schemaColumn='tblContactadresse_Adresserue' />
                <instanceColumn schemaColumn='tblContactadresse_Adressecp' />
                <instanceColumn schemaColumn='tblContactadresse_Adresseville' />
              </instanceColumnList>
            </selectStatementBuilder>
            <fromStatementBuilder>
              <mainInstanceTable schemaTable='tblContactadresse' />
            </fromStatementBuilder>
          </selectQueryBuilder>
        </printerDataSource>

      </dataRecordPrinter>

    </listDistribution>
  </listDistributionDrawFigure>

On observe que l'on connait déjà la plupart des éléments : c'est une listDistribution construite comme la principale. La seule nouveauté, c'est la source de données qui est une selectQueryBuilder. Cette dernière construira une requête dynamiquement. Ceci est nécessaire pour que la requête générée soit filtrée sur la clef primaire du contact en train d'être dessiné.

Remarque : actuellement ce type d'état n'est pas super optimisé par le moteur Melba puisque une requête sera jouée pour chaque ligne de contact, pour chercher les adresses du contact. Cet état exécutera autant de requêtes qu'il y a de contacts à afficher !!

 

© Copyright 2003 Sashipa-Melba Team. Ce document de la technologie Sashipa-Melba est sous licence GNU FDL Vous pouvez le copier et modifier librement les copies tant que cette mention apparaît clairement.