Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bien le bonjour,
L'export Excel fournit par Pb en version 10.2.0 build 8075 ne me convient pas du tout : les en-têtes de colonnes ne sont pas ceux "lisibles" par l'utilisateur sur l'interface, mais bien les noms de colonnes en base de données. De plus, lorsque l'on exporte des datawindow composite, il est fréquent que tout ou partie des sous-rapports ne soient pas exportées. Enfin, les computed fields sont ignorés.
J'envisage donc de me faire mon propre export XLS manuel.
-1- J'ai entendu parler d'objets OLE (?) qui permettraient de se connecter à un fichier Excel pour écrire dedans. Pensez-vous que ce genre de choses - que je ne connais absolument pas - soient plus appropriés qu'un simple fichier texte dans lequel j'écrirai des instructions Excel (qu'il me reste encore à identifier) ?
-2- Je voudrais aussi que mes en-têtes de colonnes sous Excel correspondent à mes en-têtes de colonnes visibles par l'utilisateur dans l'application. Je pense qu'avec du Describe() je dois être en mesure d'obtenir mes en-têtes de colonnes, mais je ne vois pas comment déterminer de façon fiable quel en-tête correspond à quelle colonne de données. Voyez-vous une solution ?
Sinon j'envisage tout simplement de transmettre à mon export 2 tableaux : l'un avec les en-têtes de colonnes, et l'autre avec les nom des champs des colonnes de données. C'est vraiment pas une solution idéale, car elle implique un important retravail (des dizaines de datawindows à exporter son concernées), mais ca reste envisageable.
Qu'en pensez-vous ?
Ne vais-je pas réinventer la roue inutilement ?
Hors ligne
il y a des exemples de OLE Excel sur le forum
http://pbadonf.fr/forum/viewtopic.php?pid=1655#p1655
// Connection to Excel objects OLEObject lo_Excel OLEObject lo_Sheet OLEObject lo_Workbook // Hookup to the Excel Document lo_Excel = CREATE OLEObject li_Result = lo_Excel.ConnectToNewObject ( "excel.application" ) IF li_Result < 0 THEN ...error handling goes here END IF // Open the excel file lo_Excel.Application.Workbooks.Open ( ls_destination ) lo_Workbook = lo_Excel.Application.ActiveWorkbook lo_Sheet = lo_Excel.Application.ActiveSheet // Move in the various header stuff that we know about lo_Sheet.Range("Q3").Value = ls_Month lo_Sheet.Range("T3").Value = ls_Year lo_Sheet.Range("AD2").Value = ls_Timebase lo_Sheet.Range("AG2").Value = ls_Workgroup lo_Sheet.Range("AJ2").Value = ls_Cbid lo_Sheet.Range("A7").Value = ls_Firstname lo_Sheet.Range("M7").Value = ls_Lastname lo_Sheet.Range("AD7").Value = ls_PositionNumber IF NOT IsNull ( is_NineEightEighty ) THEN lo_Sheet.Range("AH4").Value = "x" lo_Sheet.Range("AJ16").Value = is_NineEightEighty lo_Sheet.Range("AK17").Value = string ( li_Hours, '000' ) ELSE lo_Sheet.Range("AJ16").Value = "" END IF lo_Workbook.Save() lo_Workbook.Close() lo_Excel.Application.Quit lo_Excel.DisconnectObject()
http://pbadonf.fr/forum/viewtopic.php?pid=6940#p6940
long numcols , numrows , c, r OLEObject xlapp , xlsub int ret // Set the # of columns and rows to process // Currently Set to copy the entire DW numcols = long(dw_1.Object.DataWindow.Column.Count) numrows = dw_1.RowCount() // Create the oleobject variable xlapp xlApp = Create OLEObject // Connect to Excel and check the return code ret = xlApp.ConnectToNewObject( "Excel.Sheet" ) if ret < 0 then MessageBox("La connection à Excel a échoué !",string(ret)) return end if // Open a particular Excel file //xlApp.Application.Workbooks.Open("k:\test-bruno.xls") //,false,true // Make Excel visible xlApp.Application.Visible = true // Resolve the Excel reference once // This technique shortens the script and improves performance xlsub = xlapp.Application.ActiveWorkbook.Worksheets[1] // Loop thru the Datawindow and Excel sheet // The for/next loop copies all rows for each column For c = 1 to numcols For r = 1 to numrows xlsub.cells[r,c] = dw_1.object.data[r,c] Next Next // Save opened file //xlApp.Application.Activeworkbook.Save() // SaveAs a different filename //xlApp.Application.Activeworkbook.SaveAs("c:\file2.xls") // clean up messagebox("Fermeture du document","Avez-vous fini de vous servir du document ?") xlApp.DisConnectObject() Destroy xlapp
Hors ligne
Merci pour ta réponse, mais à vrai dire ce que je souhaite savoir c'est si ça vaut vraiment le coût de passer par ces objects OLE ?
Je suppose que c'est plus "gourmand" que d'écrire directement des instructions dans un fichier texte, et peut-être ya-t-il une limite ? Je souhaite pouvoir écrire des centaines de milliers de lignes si nécessaire. Pb doit certainement utiliser ces objects OLE pour son export XLS, et l'export est refusé si il y a trop de rows à exporter.
Hors ligne
Bonjour,
Et non, l'un des intérêts de passer par ces objets OLE est qu'il n'y a pas de limitation, contrairement à l'export XLS de PB
Hors ligne
Ohhhhh d'accord ! Voilà qui devient très intéressant !
Je vais donc me tourner vers ces objects OLE, comme ça j'en profiterai pour mieux comprendre leur fonctionnement.
Merci pour vos réponses,
je garde le sujet ouvert comme ça - si j'aboutis à quelque chose de pas trop moche - je le partagerai ici.
Hors ligne
Nyphel a écrit:
je ne vois pas comment déterminer de façon fiable quel en-tête correspond à quelle colonne de données. Voyez-vous une solution ?
par défaut, la convention de nommage des textes d'entête est de rajouter _t au nom de la colonne
il suffira de la respecter
Hors ligne
Oui, j'ai respecté cette convention de nommage pour pouvoir disposer d'un système de traduction des labels : si il y a un _t, c'est qu'il faut aller chercher en base de données le texte qui correspond au tag de cette colonne et de cette datawindow.
Toutefois je ne souhaite pas me baser là-dessus pour l'export, car je me suis aperçu que - parfois - cette règle de nommage n'était pas respectée dans d'anciens modules de l'application. De même, je pense qu'au final le mieux est de permettre au développeur de spécifier les colonnes qu'il souhaite exporter, car je sais que - dans notre cas - certaines colonnes sont hors-champ, masquées, ou inutiles. Des fois nous avons même 2 computed fields l'un sur l'autre, dont l'affichage varie selon des expressions... Bref, c'est bien dommage, mais bon...
Merci encore une fois à vous ;)
Hors ligne