Macros

From The Document Foundation Wiki
< Macros‎ | Base
Jump to: navigation, search

Comment simuler des sous-rapports avec libreoffice-report-builder ?

Cet article traite du problème des sous-rapports dans LibreOffice.
Quand on fait ses rapports avec l'extension libreoffice-report-builder, la difficulté rencontrée avec cet outil puissant est qu'il ne gère pas les sous-rapports et les différentes solutions à ce problème proposées sur Internet ne sont pas satisfaisantes.
Le problème rencontré par beaucoup de personnes dans des logiciels de facturation par exemple est : comment afficher le montant total de chaque TVA, comme illustré ci-dessous.

Capture rapport resultat.png

Pour obtenir cela, on commence par construire notre rapport comme d'habitude avec l'extension libreoffice-report-builder.
Les champs dans l'en-tête idFacture et dans la section Détail proviennent d'une requête qui contient les données des clients, les lignes des données des factures et les montants totaux sont calculés en utilisant une fonction d'accumulation dans l'extension libreoffice-report-builder. Il y a un critère de regroupement par idFacture.
C'est tout pour notre rapport.

Capture rapport edition.png

Ce rapport est ouvert en cliquant sur le bouton d'impression du formulaire suivant:

Capture formulaire facture.png

L'astuce consiste simplement à recopier le contenu du sous-formulaire qui contient le coût total par taxe (ce qui est facile à calculer avec une requête et encore plus facile à afficher dans un sous-formulaire) dans le pied de page de groupe idFacture en utilisant des champs d'étiquette.
Voici les macros qui font ceci :

REM  *****  BASIC  *****
Option Explicit

REM Copyright (C) 2015 P. « James00cat » M. <darthcat at free point fr>
REM This program is free software: you can redistribute it and/or modify
REM it under the terms of the GNU General Public License as published by
REM the Free Software Foundation, either version 3 of the License, or
REM (at your option) any later version.

REM This program is distributed in the hope that it will be useful,
REM but WITHOUT ANY WARRANTY; without even the implied warranty of
REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
REM GNU General Public License for more details.

REM You should have received a copy of the GNU General Public License
REM along with this program.  If not, see <http://www.gnu.org/licenses/>.

Sub btnPrint(oEv as object)
        REM tableau de propriétés du rapport
        dim aProp(2) as new com.sun.star.beans.PropertyValue
        dim oReportsDocuments as object
        dim oReportDesign as object
        dim oResultSet as object
        dim i as integer
        dim j as integer
        REM les positions sont indiquées dans le concepteur de rapports en cm, ici : *1000
        REM les origines sont à partir des bords de section et de page
        dim posY as integer
        const ORIG_POS_Y_TAX_AMOUNT = 500 REM origine des positions des montants des taxes
        const ORIG_FOOTER_HEIGHT = 2000
        const TXT_CTL_HEIGHT = 500 REM hauteur des etiquettes et champs
        const LEFT_MARGIN = 1000
        const VAT_LBL_WIDTH = 4100
        const VAT_LBL_POSX = 10600
        const VAT_TOTAL_AMOUNT_LBL = 1800
        const VAT_TOTAL_AMOUNT_POSX = 14900
        
        if not oEv.source.model.parent.IsNew then
                aProp(0).Name = "ActiveConnection"
                aProp(0).Value = ThisComponent.DrawPage.Forms.GetByIndex(0).ActiveConnection
                aProp(1).Name = "Hidden"
                aProp(1).Value = true
                aProp(2).Name = "OpenMode"
                aProp(2).Value = "openDesign"
                oReportsDocuments = ThisDatabaseDocument.ReportDocuments
                oReportDesign = oReportsDocuments.loadComponentFromURL("Facture", "", 0, aProp())        
                
                with oReportDesign.groups.getbyindex(0).footer
                        REM effacement des données d'un ancien "sous-rapport" (étiquettes libelleTVAi et montantTotalTVAi)
                        REM en supprimant les objets par indices décroissants pour éviter le problème d'index hors limite.
                        for i = .count - 1 to 0 step -1
                                if instr(.getbyindex(i).name, "libelleTVA") or   instr(.getbyindex(i).name, "montantTotalTVA") then
                                        .remove(.getbyindex(i))
                                end if
                        next i
                        
                        REM remise des _totaux_ à leur position d'origine
                        .getbyindex(0).positionY = ORIG_POS_Y_TAX_AMOUNT + 500
                        for i=1 to 3
                                .getbyindex(i).positionY = ORIG_POS_Y_TAX_AMOUNT + 1000
                        next i
                        
                        REM remise à sa taille d'origine de la hauteur du pied de groupe
                        .height = ORIG_FOOTER_HEIGHT
                        
                        REM sélection de la facture affichée dans le formulaire
                        oReportDesign.filter = "idFacture = " + oEv.source.model.parent.GetByName("txtIdFacture").value
                        
                        REM récupération du jeu de résultats du sous-formulaire de taxes
                        oResultSet = oEv.source.model.parent.GetByName("SFTaxes").createResultSet()
                        
                        if not isnull(oResultSet) then
                                oResultSet.beforefirst()
                                j = 0
                                posY = ORIG_POS_Y_TAX_AMOUNT
                                while oResultSet.next
                                        REM augmentation de la hauteur du pied de page de groupe
                                        .height = .height + TXT_CTL_HEIGHT
                                        REM décalage des totaux vers le bas
                                        for i=0 to 3
                                                .getbyindex(i).positionY = .getbyindex(i).positionY + TXT_CTL_HEIGHT
                                        next i
                                        
                                        REM position = marge + positionX
                                        addFixedText(oReportDesign, "libelleTVA" + j, VAT_LBL_WIDTH, 500, LEFT_MARGIN + VAT_LBL_POSX, posY, 0, 150, "Total " + oResultSet.getstring(4))
                                        addFixedText(oReportDesign, "montantTotalTVA" + j, VAT_TOTAL_AMOUNT_LBL, 500, LEFT_MARGIN + VAT_TOTAL_AMOUNT_POSX, posY, 1, 150, _
                                                                                               format(oResultSet.getfloat(3), "0.#0 €"))
                                        
                                        j = j + 1
                                        posY = posY + TXT_CTL_HEIGHT
                                wend
                        endif
                end with
                
                aProp(1).Value = false REM propriete hidden
                aProp(2).Value = "open" REM propriete OpenMode
                oReportsDocuments.loadComponentFromURL("Facture", "", 23, aProp())
        end if
End Sub

REM le type float est single en Basic!!!
sub addFixedText(oReport as object, sName as string, iWidth as integer, iHeight as integer, iPosx as integer, iPosY as integer, iParaAdjust as integer, fCharWeight as single, sLabel as string)
        dim oFixedText as object
        
        oFixedText = oReport.createinstance("com.sun.star.report.FixedText")
        with oFixedText
                .name = sName
                .width = iWidth
                .height = iHeight
                .positionX = iPosx
                .positionY = iPosy
                .ParaAdjust = iParaAdjust
                .CharWeight = fCharWeight
                .Label = sLabel
        end with
        oReport.groups.getbyindex(0).footer.add(oFixedText)
end sub

Les techniques utilisées ici permettent de faire des rapports dynamiques avec libreoffice-report-builder car elles donnent accès aux composants du rapport et permettent d'en créer de nouveaux, de les supprimer et de les déplacer le cas échéant.