Extensions development vfp

From Apache OpenOffice Wiki
Revision as of 19:58, 29 November 2007 by FOXIL (Talk | contribs)

Jump to: navigation, search

Visual Foxpro est une base de donnée de Microsoft. En plus de cette fonction, c'est aussi un bon langage de programmtion. On peut travailler soit en procédural soit en orienté objet (et on peut mixer les deux).

Une des forces de VFP (outre la puissance de sa base) est son intégration dans le Microsoft Office. On peut se servir de Word et d'Excel pour créer des états complexes ou plus jolis (agréables à lire) que le simple gestionnaire d'état. Mais cela devient de plus en plus compliqué et ... on peut faire la même chose avec Open Office 2.3 ....

Le premier listing ci-dessous contient des classes qui vont faciliter l'interface entre VFP et 00. On démarre avec la classe VFP_OO qui contient les propriétés et méthodes de base : ouverture d'un document, enregistrement, impression, etc ... Cette classe est sous-classée en

 - vfp_oo_writer : qui contient des propriétés et des méthodes propre à Writer : insertion de texte, gestion des polices, des paragraphes ...
 - vfp_oo_calc   : qui contient des propriétés et des méthodes propre à Calc : création de feuille, sélection de cellule, ....

Quelques petites classes utilitaires sont aussi présentes comme oo_police pour la gestion des polices de caractère et oo_paragraphe pour la gestion des marges.

Ensuite vous verrez deux petits programmes de test pour vous montrer comment utiliser les classes.

Ces sources peuvent être téléchargées librement à partir du site www.atoutfox.org dans la zone 'contributions' : piloter oo à partir de VFP. lib_automation_vfp_oo.prg contient les classes; test_oo et test_oo_calc sont les deux programmes de test.

Je voudrais détailler un point technique : si on a une propriété 'toto', la méthode 'toto_assign' de la même classe sera AUTOMATIQUEMENT lancée chaque fois que l'on tentera de modifier la valeur de toto (inversement on a une méthode toto_access qui est lancée chaque fois que l'on tente de lire la propriété). Cette façon de faire est utilisée pour simplifier les modifications simples d'une seul paramètres. Par exemple on pourra écrire :

 oo.paragraphe.marge_gauche = 1000
 oo.paragraphe.marge_droite = 2000
 oo.paragraphe.retrait_ligne1 = 1000
 oo.paragraphe.faire()

mais si on a que la marge gauche à modifier, on n'écrira qu'une seule ligne :

 oo.paragraphe.a_marge_gauche = 1500

et la méthode _assign correspondante mettra à jour la propriété marge_gauche et lancera la méthode faire.

Voici les listings (je ne sais pas si on peut inclure des pièces jointes ici !)

LIBRAIRIE DE CLASSES :

* J. MAURICE jsm.maurice@wanadoo.fr www.atoutfox.org * (et aussi www.aedtf.org !!) * librairie de classes pour l'automation d'OpenOffice 2.0 * à partir de VFP (Visual FoxPro). Version du jme 26/11/2007 * Ces classes sont issues de nombreuses contributions en particulier * celles de Ted ROCHE. * Le livre Programmation OpenOffice.org 2 macros et API aux éditions * Eyrolles auteurs : Bernard MARCILLY et Laurent Godard m'a été d'un * très grand secours. * un remerciement spécial à * Bernard MARCILLY, un des auteurs du livre qui m'a défriché le terrain * Laurent Godard, l'autre auteur du livre qui m'a aidé à créer la rubrique * dans wiki.services.openoffice.org * Cesar CHALOM pour ses liens * Olivier HAMOU * ... * les sites suivants sont aussi dignes d'intéret : * http://www.oooforum.org/forum/viewtopic.phtml?p=28389#28389 * * dans tout ce qui suit OO veut dire OpenOffice 2 * Ce document comprend d'abord quelques définitions, puis une série de petites * classes correspondant plus à une structure C qu'à une vraie classe (mais elles * peuvent avoir quelques méthodes) et enfin les classes utilisables par le programmeur. * Ces classes respectent un peu la hierarchie d'OO : une classe de base contient * les propriétés et les méthodes communes à chaque document OO (c'est vfp_oo); elle * est sous classée en vfp_oo_writer pour manipuler le traitement de texte; puis * en vfp_oo_calc pour manipuler le tableur, ... * Liste des classes et de leurs méthodes ** Classe: OO_POLICE basée sur Custom ** 226 .init ** 231 .faire ** 264 .a_nom_assign ** 278 .a_taille_assign ** 289 .a_gras_assign ** 303 .a_italique_assign ** 314 .a_souligne_assign ** ** Classe: OO_PARAGRAPHE basée sur Custom ** 344 .init ** 349 .alignement ** 367 .faire ** ** Classe: PARAMETRES_IMPRIMANTE basée sur Custom ** ** Classe: PARAMETRES_IMPRESSION basée sur custom ** ** Classe: VFP_OO basée sur custom ** 460 .init ** 502 .destroy ** 517 .nouveau_document ** 551 .ouvrir_document ** 591 .enregistrer_document ** 617 .enregistrer_copie_document ** 644 .fermer_document ** 668 .imprimer_document ** 723 .informations_document ** 747 .OOoOpenURL ** 777 .OOoPropertyValue ** 797 .OOoCreateStruct ** 822 .OOoConvertToURL ** ** Classe: VFP_OO_WRITER basée sur vfp_oo ** 845 .init ** 857 .destroy ** 869 .nouveau_document_texte ** 908 .ouvrir_document_texte ** 960 .objets_doc ** 970 .enregistrer_copie_document ** 995 .informations_document ** 1009 .debut_texte ** 1013 .ajouter_texte ** 1017 .nouveau_paragraphe ** 1023 .appliquer_police ** 1030 .police ** ** Classe: VFP_OO_CALC basée sur vfp_oo ** 1072 .init ** 1081 .destroy ** 1093 .nouveau_tableur ** 1114 .ouvrir_tableur ** 1151 .maj_infos_tableur ** 1173 .enregistrer_copie_document ** 1198 .informations_document ** 1212 .selection_feuille ** 1271 .ajouter_feuille ** 1308 .cellule_coord_alpha_vers_num ** 1335 .cellule_coord_num_vers_alpha ** 1369 .texte_dans_cellule ** 1382 .valeur_dans_cellule ** 1395 .formule_dans_cellule ** 1408 .date_dans_cellule ** 1442 .lire_une_cellule *OO_automation/sdk/docs/common/ref/com/sun/star/text/ControlCharacter.html #DEFINE PARAGRAPH_BREAK 0 && nouveau paragraphe #DEFINE LINE_BREAK 1 && nouvelle ligne dans un paragraphe #DEFINE HARD_HYPHEN 2 && tiret insécable #DEFINE SOFT_HYPHEN 3 && tiret conditionnel #DEFINE HARD_SPACE 4 && espace insécable #DEFINE APPEND_PARAGRAPH 5 && ajoute un nouveau paragraphe #DEFINE COLOR_WHITE 16777215 #DEFINE COLOR_BLACK 0 * OO_automation/sdk/idl/com/sun/star/awt/FontWeight.idl : graisse des caractères #DEFINE GRAISSE_DONTKNOW 0.000000 && graisse par défaut #DEFINE GRAISSE_THIN 50.000000 && caractères fin (moitié de la graisse normale) #DEFINE GRAISSE_ULTRALIGHT 60.000000 && caractères ultra fins (60% de la graisse normale) #DEFINE GRAISSE_LIGHT 75.000000 && caractères fins (3/4 de la graisse normale) #DEFINE GRAISSE_SEMILIGHT 90.000000 && 90% de la graisse normale #DEFINE GRAISSE_NORMAL 100.000000 && graisse normale #DEFINE GRAISSE_SEMIBOLD 110.000000 && demi gras (110% de la graisse normale) #DEFINE GRAISSE_BOLD 150.000000 && gras #DEFINE GRAISSE_ULTRABOLD 175.000000 && très gras #DEFINE GRAISSE_BLACK 200.000000 && ultra gras * OO_automation/sdk/idl/com/sun/star/awt/FontUnderline.idl : soulignement #DEFINE SOULIGN_NONE 0 && pas de soulignement #DEFINE SOULIGN_SINGLE 1 && ligne simple #DEFINE SOULIGN_DOUBLE 2 && ligne double #DEFINE SOULIGN_DOTTED 3 && pointillé #DEFINE SOULIGN_DONTKNOW 4 && inconnu (??!!??) #DEFINE SOULIGN_DASH 5 && tirets #DEFINE SOULIGN_LONGDASH 6 && tirets longs #DEFINE SOULIGN_DASHDOT 7 && tiret point #DEFINE SOULIGN_DASHDOTDOT 8 && tiret point point #DEFINE SOULIGN_SMALLWAVE 9 && petite vague #DEFINE SOULIGN_WAVE 10 && vague #DEFINE SOULIGN_DOUBLEWAVE 11 && double vague #DEFINE SOULIGN_BOLD 12 && ligne grasse #DEFINE SOULIGN_BOLDDOTTED 13 && points gras #DEFINE SOULIGN_BOLDDASH 14 && tirets gras #DEFINE SOULIGN_BOLDLONGDASH 15 && long tirets gras #DEFINE SOULIGN_BOLDDASHDOT 16 && tiret point gras #DEFINE SOULIGN_BOLDDASHDOTDOT 17 && tiret point point en gras #DEFINE SOULIGN_BOLDWAVE 18 && vague grasse * OO_automation/sdk/idl/com/sun/star/awt/FontWidth.idl #DEFINE LARGEUR_DONTKNOW 0.000000 && largeur inconnue (par défaut ?) #DEFINE LARGEUR_ULTRACONDENSED 50.000000 && condensé (50%) #DEFINE LARGEUR_EXTRACONDENSED 60.000000 && condensé (60%) #DEFINE LARGEUR_CONDENSED 75.000000 && condensé (75%) #DEFINE LARGEUR_SEMICONDENSED 90.000000 && semi-condensé (90%) #DEFINE LARGEUR_NORMAL 100.000000 && normal #DEFINE LARGEUR_SEMIEXPANDED 110.000000 && semi-expansé (110%) #DEFINE LARGEUR_EXPANDED 150.000000 && expansé (150%) #DEFINE LARGEUR_EXTRAEXPANDED 175.000000 && extraexpansé (175%) #DEFINE LARGEUR_ULTRAEXPANDED 200.000000 && ultra-expansé (200%) * OO_automation/sdk/idl/com/sun/star/awt/Fontslant.idl *!* published enum FontSlant ATTENTION énumération et non constantes *!* { *!* /** specifies a font without slant. */ *!* NONE, *!* /** specifies an oblique font (slant not designed into the font). */ *!* OBLIQUE, *!* /** specifies an italic font (slant designed into the font). */ *!* ITALIC, *!* /** specifies a font with an unknown slant. */ *!* DONTKNOW, *!* /** specifies a reverse oblique font (slant not designed into the font). */ *!* REVERSE_OBLIQUE, *!* /** specifies a reverse italic font (slant designed into the font). */ *!* REVERSE_ITALIC #DEFINE ITALIC_DROIT 0 && pas d'italique #DEFINE ITALIC_OBLIQUE 1 && italique si la police ne l'accepte pas (non utilisé ici) #DEFINE ITALIC_ITALIC 2 && italique (à condition que la police l'accepte) #DEFINE ITALIC_INCONNU 3 && comme son nom l'indique !! (non utilisé ici) #DEFINE ITALIC_OBLIQUE_INVERSE 4 && italique inverse (penchée à gauche) si la police && ne l'accepte pas (non utilisé ici) #DEFINE ITALIC_INVERSE 5 && italique inverse (penchée à gauche si la police && l'accepte (non utilisé ici * OO_automation/sdk/idl/com/sun/star/style/ParagraphAdjust.idl *!* published enum ParagraphAdjust ATTENTION énumération et non constantes *!* // value com::sun::star::style::ParagraphAdjust::LEFT *!* /** adjusted to the left border *!* LEFT, *!* // value com::sun::star::style::ParagraphAdjust::RIGHT *!* /** adjusted to the right border *!* RIGHT, *!* // value com::sun::star::style::ParagraphAdjust::BLOCK *!* /** adjusted to both borders / stretched, except for last line *!* BLOCK, *!* // value com::sun::star::style::ParagraphAdjust::CENTER *!* /** adjusted to the center *!* CENTER, *!* // value com::sun::star::style::ParagraphAdjust::STRETCH *!* /** adjusted to both borders / stretched, including last line *!* STRETCH *!* } #DEFINE ALIGNEMENT_GAUCHE 0 && paragraphe cadré à gauche #DEFINE ALIGNEMENT_DROIT 1 && paragraphe cadré à droite #DEFINE ALIGNEMENT_JUSTIFIE_BEAU 2 && paragraphe justifié sauf la dernière && ligne qui reste à gauche #DEFINE ALIGNEMENT_CENTRE 3 && paragraphe centré #DEFINE ALIGNEMENT_JUSTIFIE 4 && paragraphe justifié y compris la dernière ligne #DEFINE avec_ww .T. && si cette constante est définie, on affiche des messages * d'erreur avec WAIT WINDOW. Si vous mettez la ligne en commentaire et que vous * recompilez, aucun message n'est affiché en cas d'erreur * ATTENTION : NE METTRE AUCUN CODE EXECUTABLE APRES UN DEFINE CLASS ''' DEFINE CLASS oo_police AS Custom''' && jme 04/11/2007 * paramètres d'une police de caractères * je suis obligé de renommer les constantes car dans OO on peut avoir deux constantes * de même nom dans deux fichiers de déclaration différents mais pas dans VFP * notes à propos des propriétés a_nom, a_taille, a_gras, a_italique et a_souligne (dans * lesquelles le a_ veut dire 'automatique' : il y a une méthode assign sur chacune * de ces propriétés et donc, si on a un seul paramètre à modifier, la simple mise à jour * de la propriété va bien être reportée sur le texte. Pour les autres propriétés, il * faut mettre à jour les propriétés puis lancer la méthode faire(). nom = "Courier New" && cette police a des caractères de taille fixe; il est donc * très facile de faire des documents avec des colonnes (facture, ...) alors que si * on utilise une police proportionnelle cela devient un cauchemar. taille = 12 gras = .F. italique = .F. souligne = .F. couleur_texte = color_black couleur_fond = color_white * une autre possibilité pour paramétrer la police est d'utiliser les propriétés * a_nom, a_taille, a_gras, a_italique, a_souligne ci-dessous. Sur chacune de * ces propriétés il y a une méthode _assign qui lance la méthode This.faire; donc * lorsqu'on a beaucoup de paramètres à changer, on peut mettre à jour les * propriétés nom, taille, ... puis lancer la méthode This.faire(); mais si * on ne veut changer qu'une seule valeur, il est plus simple de faire une * simple assignation sur les propriétés a_nom, ... a_nom = "Courier New" a_taille = 12 a_gras = .F. a_italique = .F. a_souligne = .F. curseur_ecriture = NULL && pointeur sur le curseur d'écriture. * c'est sur ce curseur que vont être appliqué la police et ses caractéristiques. * il n'y a pas de méthode DESTROY dans cette classe PROCEDURE init && jme 26/11/2007 LPARAMETERS pocurseur This.curseur_ecriture = m.pocurseur ENDPROC PROCEDURE faire( ) * This.curseur_ecriture : curseur d'écriture sur lequel on doit paramétrer * la police. On commence par mettre à jour les propriétés de cette classe puis * on appelle cette méthode pour les appliquer au curseur pointé par * This.curseur_ecriture. * pour l'instant, je ne sais pas vérifier si l'objet passé est * correct. S'il y a un problème, on ne fait rien (sauf faire * un wait window si la compilation se fait avec avec_ww = .T. IF ISNULL(This.curseur_ecriture) #IFDEF avec_ww WAIT WINDOW "paramétrage de la police OO impossible:"+ CHR(13)+ ; "curseur d'écriture NULL" NOWAIT #ENDIF ELSE TRY WITH This.curseur_ecriture .CharFontName = This.nom .CharHeight = This.taille .CharColor = This.couleur_texte .CharBackColor = This.couleur_fond .CharWeight = IIF( This.gras, GRAISSE_BOLD, GRAISSE_NORMAL) .CharPosture = IIF( This.italique, ITALIC_ITALIC, ITALIC_DROIT) .CharUnderline = IIF( This.souligne, SOULIGN_SINGLE, SOULIGN_NONE) ENDWITH && This.curseur_ecriture CATCH #IFDEF avec_ww WAIT WINDOW "problème lors du paramétrage de la police OO" NOWAIT #ENDIF ENDTRY ENDIF && ISNULL(This.curseur_ecriture) ENDPROC && faire HIDDEN PROCEDURE a_nom_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_nom * une méthode HIDDEN n'est pas accessible par les heritiers de cette classe ni * du public (elle n'est seulement accessible que de l'intérieur de la classe * où elle est définie) LPARAMETERS pcnouval IF This.nom <> m.pcnouval STORE m.pcnouval TO This.a_nom, This.nom This.faire() ENDIF ENDPROC && procedure a_nom_assign HIDDEN PROCEDURE a_taille_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_taille LPARAMETERS pnnouval IF This.taille <> m.pnnouval STORE m.pnnouval TO This.a_taille, This.taille This.faire() ENDIF ENDPROC && procedure a_taille_assign HIDDEN PROCEDURE a_gras_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_gras * une méthode HIDDEN n'est pas accessible par les heritiers de cette classe ni * du public (elle n'est seulement accessible que de l'intérieur de la classe * où elle est définie) LPARAMETERS plnouval IF This.gras <> m.plnouval STORE m.plnouval TO This.gras, This.a_gras This.faire() ENDIF ENDPROC && procedure a_gras_assign HIDDEN PROCEDURE a_italique_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_italique LPARAMETERS plnouval IF This.italique <> m.plnouval STORE m.plnouval TO This.italique, This.a_italique This.faire() ENDIF ENDPROC && procedure a_italique_assign HIDDEN PROCEDURE a_souligne_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_souligne * une méthode HIDDEN n'est pas accessible par les heritiers de cette classe ni * du public (elle n'est seulement accessible que de l'intérieur de la classe * où elle est définie) LPARAMETERS plnouval IF This.souligne <> m.plnouval STORE m.plnouval TO This.souligne, This.a_souligne This.faire() ENDIF ENDPROC && procedure a_souligne_assign ENDDEFINE && oo_police '''DEFINE CLASS oo_paragraphe AS Custom''' && jme 04/11/2007 * paramètres d'un paragraphe. Toutes les valeurs sont en 1/100mm * (centième de millimètre) marge_gauche = 0 && 1000 = 1cm retrait_ligne1 = 0 marge_droite = 0 hauteur_avant = 0 hauteur_apres = 0 gdcj = ALIGNEMENT_GAUCHE && alignement par défaut du paragraphe curseur_ecriture = NULL && pointeur sur le curseur d'écriture. * c'est sur ce curseur que vont être appliqué les paramètres du paragraphe a_marge_gauche = 0 && il y aune méthode _assign a_retrait_ligne1 = 0 a_marge_droite = 0 * il n'y a pas de méthode DESTROY dans cette classe PROCEDURE init LPARAMETERS pocurseur This.curseur_ecriture = m.pocurseur ENDPROC PROCEDURE alignement( pcalign AS String) * NOTE test : cette méthode a le même nom qu'une des propriétés ! IF "CENTR" $ UPPER(m.pcalign) This.gdcj = ALIGNEMENT_CENTRE ELSE IF "DROIT" $ UPPER(pcalign) This.gdcj = ALIGNEMENT_DROIT ELSE IF "JUSTI" $ UPPER(m.pcalign) This.gdcj = ALIGNEMENT_JUSTIFIE_BEAU ELSE This.gdcj = ALIGNEMENT_GAUCHE ENDIF && "JUSTI" $ UPPER(m.pcalign) ENDIF && "DROIT" $ UPPER(pcalign) ENDIF && "CENTR" $ UPPER(m.pcalign) This.faire() ENDPROC && alignement PROCEDURE faire( ) * This.curseur_ecriture : curseur d'écriture sur lequel on doit paramétrer * le paragraphe. On commence par mettre à jour les propriétés de cette classe puis * on appelle cette méthode pour les appliquer au curseur pointé par * This.curseur_ecriture. * pour l'instant, je ne sais pas vérifier si l'objet passé est * correct. S'il y a un problème, on ne fait rien (sauf faire * un wait window si la compilation se fait avec avec_ww = .T. IF ISNULL(This.curseur_ecriture) #IFDEF avec_ww WAIT WINDOW "paramétrage du paragraphe OO impossible:"+ CHR(13)+ ; "curseur d'écriture NULL" NOWAIT #ENDIF ELSE TRY WITH This.curseur_ecriture .ParaLeftMargin = This.marge_gauche .ParaFirstLineIndent = This.retrait_ligne1 .ParaRightMargin = This.marge_droite .ParaTopMargin = This.hauteur_avant .ParaBottomMargin = This.hauteur_apres .ParaAdjust = This.gdcj IF INLIST(This.gdcj, ALIGNEMENT_JUSTIFIE, ALIGNEMENT_JUSTIFIE_BEAU) IF This.gdcj = ALIGNEMENT_JUSTIFIE_BEAU .ParaLastLineAdjust = ALIGNEMENT_GAUCHE ELSE .ParaLastLineAdjust = ALIGNEMENT_JUSTIFIE ENDIF && This.alignement = ALIGNEMENT_JUSTIFIE_BEAU ENDIF && INLIST(This.gdcj, ALIGNEMENT_JUSTIFIE, ALIGNEMENT_JUSTIFIE_BEAU) ENDWITH && This.curseur_ecriture CATCH #IFDEF avec_ww WAIT WINDOW "problème lors du paramétrage du paragraphe OO" NOWAIT #ENDIF ENDTRY ENDIF && ISNULL(This.curseur_ecriture) ENDPROC && faire HIDDEN PROCEDURE a_marge_gauche_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_marge_gauche * quand on a qu'une seule valeur à changer il est plus facile de * mettre à jour a_marge_gauche qui aura un effet immédiat que d'écrire * deux lignes de programme LPARAMETERS plnouval IF This.marge_gauche <> m.plnouval STORE m.plnouval TO This.marge_gauche, This.a_marge_gauche This.faire() ENDIF ENDPROC && procedure a_marge_gauche_assign HIDDEN PROCEDURE a_marge_droite_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_marge_droite LPARAMETERS plnouval IF This.marge_droite <> m.plnouval STORE m.plnouval TO This.marge_droite, This.a_marge_droite This.faire() ENDIF ENDPROC && procedure a_marge_droite_assign HIDDEN PROCEDURE a_retrait_ligne1_assign * cette méthode est lancée automatiquement (suffixe _assign) chaque fois * que l'on modifie la valeur de This.a_retrait_ligne1 LPARAMETERS plnouval IF This.retrait_ligne1 <> m.plnouval STORE m.plnouval TO This.retrait_ligne1, This.a_retrait_ligne1 This.faire() ENDIF ENDPROC && procedure a_retrait_ligne1_assign ENDDEFINE && oo_paragraphe DEFINE CLASS parametres_imprimante AS Custom marge_haute = 1 marge_basse = 1 marge_gauche = 1 marge_droite = 1 nom_imprimante = "" orientation = 1 && 1 portrait, 2 paysage ENDDEFINE && parametres_imprimante AS Custom DEFINE CLASS parametres_page AS Custom * définition des paramètres de la page * les valeurs sont en centièmes de millimètre * les paramètres modifiés sont ceux du style standard marge_haute = 1000 marge_basse = 1000 marge_gauche = 1000 marge_droite = 1000 orientation = 1 && 1 portrait, 2 paysage page = NULL && pointeur sur le document sf = NULL && pointeur sur la famille de styles standard = NULL && pointeur sur le style standard PROCEDURE init LPARAMETERS pocurseur This.page = m.pocurseur This.faire() ENDPROC PROCEDURE faire( ) * This.page : objet que l'on doit paramétrer * On commence par mettre à jour les propriétés de cette classe puis * on appelle cette méthode pour les appliquer au document pointé par * This.page. * pour l'instant, je ne sais pas vérifier si l'objet passé est * correct. S'il y a un problème, on ne fait rien (sauf faire * un wait window si la compilation se fait avec avec_ww = .T. * les valeurs sont en centièmes de millimètres IF ISNULL(This.page) #IFDEF avec_ww WAIT WINDOW "paramétrage de la page OO impossible:"+ CHR(13)+ ; "document NULL" NOWAIT #ENDIF ELSE TRY This.sf = This.page.StyleFamilies.getByName("PageStyles") This.standard = This.sf.getByName("Standard") IF ISNULL( This.standard) #IFDEF avec_ww WAIT WINDOW "paramétrage de la page OO impossible:"+ CHR(13)+ ; "style standard NULL" NOWAIT #ENDIF ELSE WITH This.standard .LeftMargin = This.marge_gauche .RightMargin = This.marge_droite .TopMargin = This.marge_haute .BottomMargin = This.marge_basse .IsLandscape = IIF(This.orientation=2, .T., .F.) ENDWITH && This.standard ENDIF && ISNULL( This.standard) CATCH #IFDEF avec_ww WAIT WINDOW "problème lors du paramétrage de la page OO" NOWAIT #ENDIF ENDTRY ENDIF && ISNULL(This.page) ENDPROC && faire ENDDEFINE && parametres_page AS Custom DEFINE CLASS parametres_impression AS custom * cette classe ne contient que des propriétés. A priori elle ne peut * être utilisée que par la classe VFP_OO et ses descendantes nombre_copie = 1 impression_dans_un_fichier = .F. fichier_impression = "" && par exemple SYS(5)+CURDIR()+ "essai.prn" previsualisation = .F. && non encore utilisé ordre_des_pages = .T. && si plusieurs exemplaires : .T. on imprime d'abord * le document n° 1, puis le document n° 2 etc ... .F. : on imprime toutes les * pages 1, puis toutes les pages 2, etc ... attente_fin = .T. && par défaut on attend que l'impression soit mise dans * la file d'attente (le spool) avant de continuer pages = "" && liste des pages à imprimer. Vide si on imprime tout * sinon quelque chose comme "3;5;7-11" : impression des pages 3, 5 et de toutes celles * comprises entre 7 et 11 *!* DIMENSION paramimp(5) && tableau de paramètres pour OO obsolete ENDDEFINE && parametres_impression AS custom DEFINE CLASS vfp_oo AS custom * cette classe contient les propriétés et les méthodes communes à tous les * types de document OpenOffice. Elle va être, éventuellement, sous-classée * pour construire les classes correspondant au Writer (traitement de texte), * à Calc (feuille de calcul), à Draw (dessin) et à Impress (présentation) oo_est_installe = .F. && .T. si OpenOffice est installé gestionnaire_de_services = NULL && pointeur sur le ServiceManager d'OO doc = NULL && pointeur sur le document OO bureau = NULL && pointeur sur le 'bureau' d'OO (oo desktop fichier_courant = "" && nom complet du fichier en cours de traitement imprimante = NULL && pointeur sur la classe parametres_imprimante impression = NULL && pointeur sur la classe parametres_impression cst_paragraph = NULL && essai abandon_document = .F. && pour les tests : si .T. on ne sauvegarde pas le document dans le destroy erreur = -1 && -1 non encore initialisé * -2 OO n'est pas installable -3 échec du createobject, -4 impossible de créer le bureau * -10 structure UNO impossible à créer, -11 paramètre invalide * -13 impossible de fermer le document * -20 impossible de créer le docuemnt, -21 impossible de lire le document * -30 et -31 Impossible de créer le pointeur sur le texte * -32 Impossible de créer le curseur d'insertion texte PROTECTED PROCEDURE init * à l'init on vérifie si openoffice est installé * une méthode PROTECTED est accessible par toutes les méthodes de la classe où * elle est définie mais aussi des méthodes des sous-classes mais pas du public This.imprimante = NEWOBJECT("parametres_imprimante") This.impression = NEWOBJECT("parametres_impression") TRY This.gestionnaire_de_services = CREATEOBJECT( "com.sun.star.ServiceManager" ) IF ISNULL(This.gestionnaire_de_services) #IFDEF avec_ww WAIT WINDOW "erreur instanciation OO" NOWAIT #ENDIF This.erreur = -3 ELSE This.erreur = 1 ENDIF && ISNULL(This.gestionnaire_de_services) CATCH #IFDEF avec_ww WAIT WINDOW "Impossible d'instancier OO" NOWAIT #ENDIF This.erreur = -2 ENDTRY * on va maintenant ouvrir le bureau d'OO * note je ne sais pas si on doit avoir un bureau par document * ou un bureau par instance d'OO (donc a priori un seul). pour * tester je vais en créer qu'un seul donc ici dans l'init IF This.erreur = 1 TRY This.bureau = ; This.gestionnaire_de_services.createInstance( "com.sun.star.frame.Desktop" ) COMARRAY( This.bureau, 10 ) &&The array is a zero-based array and is passed by reference This.erreur = 2 && ok CATCH #IFDEF avec_ww WAIT WINDOW "impossible d'instancier le bureau OO" NOWAIT #ENDIF This.bureau = NULL This.erreur = -4 ENDTRY ENDIF && This.erreur = 1 ENDPROC && init PROTECTED PROCEDURE destroy * une méthode PROTECTED est accessible par toutes les méthodes de la classe où * elle est définie mais aussi des méthodes des sous-classes mais pas du public IF !ISNULL(This.doc) AND This.doc.isModified AND This.abandon_document=.F. * si on n'a pas de nom de fichier quand on sort, on en créer un automatiquement IF EMPTY(This.fichier_courant) This.fichier_courant = "OOO_OO_"+ SYS(2015) ENDIF && EMPTY(This.fichier_courant) This.enregistrer_document() ENDIF && This.doc.isModified This.doc = NULL This.bureau = NULL This.gestionnaire_de_services = NULL ENDPROC PROCEDURE nouveau_document( pctypdoc AS String) * on crée un nouveau document dont le type est contenu dans pctypdoc * nouveau texte : pctypdoc = "private:factory/swriter" * nouveau tableur : pctypdoc = "private:factory/scalc" * nouveau dessin : pctypdoc = "private:factory/sdraw" * nouvelle présentation : pctypdoc = "private:factory/simpress" * nouvelles formules mathématiques : pctypdoc = "private:factory/smath" IF This.erreur >=0 AND !EMPTY(m.pctypdoc) * on ne crée pas de nouveau document s'il y en a déjà un actif IF ISNULL(This.doc) This.erreur = 0 This.OOoOpenURL( m.pctypdoc ) IF ISNULL(This.doc) This.erreur = -20 #IFDEF avec_ww WAIT WINDOW "Impossible de créer un nouveau document" NOWAIT #ENDIF ELSE This.erreur = 2 && document ok This.abandon_document=.F. && on met .T. quand on ne veut pas que le * document soit enregistrer dans le destroy event; il faut donc * bien penser à la remettre à faux lors de la création d'un nouveau * document ENDIF && ISNULL(This.doc) ELSE #IFDEF avec_ww WAIT WINDOW "Création nouveau document impossible" + CHR(13)+ ; "un autre existe déjà" NOWAIT #ENDIF ENDIF && ISNULL(This.doc) ENDIF && This.erreur =2 ENDPROC PROCEDURE ouvrir_document( pcfichier AS String) * pcfichier est un nom de fichier 00 au format Windows ("c:\toto\tata\tutu.odt") LOCAL ARRAY lttab(1) LOCAL lcurl IF This.erreur<2 OR EMPTY(m.pcfichier) This.erreur = -11 && paramètre invalide #IFDEF avec_ww WAIT WINDOW "Il faut indiquer le nom du fichier à ouvrir" NOWAIT #ENDIF ELSE * on demande à VFP de vérifier que le fichier existe bien avant de l'ouvrir IF ADIR(lttab, m.pcfichier) > 0 This.erreur = 0 && on raz l'erreur éventuelle This.doc = NULL lcurl = This.OOoConvertToURL( m.pcfichier ) This.OOoOpenURL( m.lcurl ) IF ISNULL( This.doc) This.erreur = -21 #IFDEF avec_ww WAIT WINDOW "Impossible d'ouvrir le fichier" + CHR(13)+ ; m.pcfichier NOWAIT #ENDIF ELSE This.erreur = 2 && document ok This.abandon_document=.F. && on met .T. quand on ne veut pas que le * document soit enregistrer dans le destroy event; il faut donc * bien penser à la remettre à faux lors de l'ouverture d'un nouveau * document ENDIF && ISNULL( This.doc) ELSE This.erreur = -20 #IFDEF avec_ww WAIT WINDOW "Le fichier" + CHR(13)+ m.pcfichier+ CHR(13)+ ; "n'existe pas"NOWAIT #ENDIF ENDIF && ADIR(lttab, m.pcfichier) > 0 ENDIF && EMPTY(pcfichier) ENDPROC && ouvrir_texte PROCEDURE enregistrer_document( pcnomfichier AS String) && vfp_oo * attention, si vous travaillez sur un document TOTO et que vous * l'enregistrez sous le nom TATA, vous travaillerez dorénavant sur TATA * pcnomfichier contient un nom de fichier (avec éventuellement un chemin) * au format Windows * on ne peut pas exporter en PDF avec storeasurl() IF PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) This.fichier_courant = m.pcnomfichier ENDIF && PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) * on pourrait tester si le document a été modifié avec la propriété * This.doc.isModified (cette propriété est en lecture/écriture) IF EMPTY( JUSTPATH(This.fichier_courant)) * on ne peut pas sauvegarder un document SANS lui donner le chemin complet ! This.fichier_courant = SYS(5)+ CURDIR()+ This.fichier_courant ENDIF && EMPTY( JUSTPATH(This.fichier_courant)) LOCAL lcurl, lcext LOCAL ARRAY lcparam(1) lcext = JUSTEXT(This.fichier_courant) * on veut prévenir l'opérateur s'il écrase une version précédente du document * (même si c'est le même fichier; si c'est trop perturbant on peut supprimer * cette option ou effacer le fichier destinataire avant de faire l'enregistrement) lcparam(1) = This.OOoPropertyValue( "Overwrite", .F. ) lcurl = This.OOoConvertToURL( This.fichier_courant) This.doc.storeAsURL( m.lcurl, @ lcparam) ENDPROC && enregistrer_document PROCEDURE enregistrer_copie_document( pcnomfichier AS String) * on veut créer une copie du document courant (on crée un fichier * sur le disque mais on continue de travailler sur le document courant) * pcnomfichier contient un nom de fichier (avec éventuellement un chemin) * au format Windows * attention la méthode storeToURL est différente de storeAsURL * avec cette méthode on pourrait exporter en PDF, mais, comme les paramètres * dépendent du type de document, on va faire une méthode héritée dans * vfp_oo_writer pour un document texte et dans vfp_oo_calc pour une feuille de calcul. IF PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) *!* IF This.fichier_courant <> m.pcnomfichier jme 18/11/2007 test annulé IF EMPTY( JUSTPATH(m.pcnomfichier)) * on ne peut pas sauvegarder un document SANS lui donner le chemin complet ! pcnomfichier = SYS(5)+ CURDIR()+ m.pcnomfichier ENDIF && EMPTY( JUSTPATH(m.pcnomfichier)) LOCAL lcurl LOCAL ARRAY lcparam(1) * on veut prévenir l'opérateur s'il écrase une version précédente du document * (même si c'est le même fichier; si c'est trop perturbant on peut supprimer * cette option) lcparam(1) = This.OOoPropertyValue( "Overwrite", .T. ) lcurl = This.OOoConvertToURL( m.pcnomfichier ) This.doc.storeToURL( m.lcurl, @ lcparam) *!* ENDIF && This.fichier_courant <> m.pcnomfichier ENDIF && PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) ENDPROC && enregistrer_document PROCEDURE fermer_document LOCAL llok llok = .T. IF This.doc.isModified llok = IIF( INLIST( MESSAGEBOX("Le document" + CHR(13)+ This.fichier_courant + ; CHR(13)+ "n'a pas été enregistré." + CHR(13)+ "Voulez-vous l'enregistrer ?", ; 4+32, "ATTENTION", 60000), -1,6), .T., .F.) ENDIF && This.doc.isModified IF m.llok = .T. TRY This.doc.close(.T.) This.abandon_document=.T. && on ne veut pas enregistrer dans le destroy This.doc = NULL This.erreur = 1 CATCH This.erreur = -13 && impossible de fermer le document #IFDEF avec_ww WAIT WINDOW "Impossible de fermer le document" NOWAIT #ENDIF ENDTRY ENDIF && m.llok = .T. ENDPROC && fermer_document() PROCEDURE imprimer_document * ATTENTION : il faut normalement 5 paramètres pour piloter l'impression. Ces * 5 paramètres sont mémorisés dans l'instance de parametres_impression pointée * par This.impression. Lorsqu'un paramètre est vide (comme filename si on * imprime sur l'imprimante ou pages si on veut tout imprimer), il ne doit PAS * être transmis. La dimension du tableau transmis à OO est donc variable et * dépend du nombre de paramètres utiles. *!* ci dessous un bout de code pour imprimer les propriétés de printer et leur valeur *!* loprinter = This.doc.printer *!* lnaccu = ALEN(loprinter) *!* SET TEXTMERGE TO essai_printer.txt ADDITIVE NOSHOW *!* SET TEXTMERGE ON *!* \<<DATE()>> <<TIME()>> *!* lcaccu = "" *!* FOR m.lni = 1 TO m.lnaccu *!* *lcaccu = m.lcaccu+loprinter(m.lni).name+ CHR(13) *!* IF VARTYPE(loprinter(m.lni).value) <> "O" *!* \ <<loprinter(m.lni).name>> : <<loprinter(m.lni).value>> *!* ELSE *!* \ <<loprinter(m.lni).name>> : objet *!* ENDIF && VARTYPE(loprinter(m.lni).value) <> "O" *!* ENDFOR &&* m.lni = 1 TO m.lnaccu *!* SET TEXTMERGE OFF *!* SET TEXTMERGE TO WITH This.impression DO CASE CASE .impression_dans_un_fichier AND EMPTY(.pages) * impression de tout le document dans un fichier LOCAL ARRAY loparam(4) loparam(4) = This.OOoPropertyValue( "FileName", .fichier_impression) CASE .impression_dans_un_fichier AND !EMPTY(.pages) * impression d'une liste de pages du document dans un fichier LOCAL ARRAY loparam(5) loparam(5) = This.OOoPropertyValue( "FileName", .fichier_impression) loparam(4) = This.OOoPropertyValue( "Pages", .pages) CASE !.impression_dans_un_fichier AND EMPTY(.pages) * impression de tout le document sur l'imprimante LOCAL ARRAY loparam(3) CASE !.impression_dans_un_fichier AND !EMPTY(.pages) * impression d'une liste de pages du document sur l'imprimante LOCAL ARRAY loparam(4) loparam(4) = This.OOoPropertyValue( "Pages", .pages) ENDCASE loparam(1) = This.OOoPropertyValue( "CopyCount", .nombre_copie) && faut expliquer ? * Collate : si plusieurs exemplaires : .T. on imprime d'abord le document n° 1, * puis le document n° 2 etc ... .F. : on imprime toutes les pages 1, puis toutes * les pages 2, etc ... loparam(2) = This.OOoPropertyValue( "Collate", .ordre_des_pages) loparam(3) = This.OOoPropertyValue( "Wait", .attente_fin) ENDWITH && This.impression This.doc.Print( @loparam) ENDPROC && imprimer_document PROCEDURE informations_document LOCAL lcfichier, loinfos, lodate IF !ISNULL(This.doc) lcfichier = This.doc.location loinfos = This.doc.documentInfo lodate = loinfos.CreationDate = MESSAGEBOX("document :"+ m.lcfichier+ CHR(13)+ ; "auteur: "+ m.loinfos.Author+ CHR(13)+ ; "création: "+ STR(m.lodate.Day,2)+"/"+ TRANSFORM(m.lodate.Month, "@L 99")+ ; "/"+ STR(m.lodate.Year,4)+ CHR(13), 0, "informations") ENDIF && !ISNULL(This.doc) ENDPROC && informations_document ********************************************************* * ci-dessous : toutes les méthodes 'utilitaires' ********************************************************* * ben, pour l'instant, il y en a plus !! ********************************************************* * ci-dessous : toutes les méthodes OO utilisées ci-dessus ********************************************************* * HIDDEN : la méthode ne peut être appelée que depuis cette classe. Même * les sous-classes de vfp_oo ne peuvent pas y accéder. PROTECTED PROCEDURE OOoOpenURL( pcURL ) * Ouvre ou crée un document à partir de son URL. * Pour créer un nouveau document, l'URL est : * private:factory/sdraw pour un nouveau document de dessin * private:factory/swriter pour un nouveau document texte * private:factory/scalc pour un nouveau classeur de feuilles de calcul * private:factory/simpress && pour un nouveau document de présentation *!* * LOCAL oPropertyValue *!* * oPropertyValue = OOoCreateStruct( "com.sun.star.beans.PropertyValue" ) *!* * LOCAL ARRAY aNoArgs[1] *!* * aNoArgs[1] = oPropertyValue *!* * aNoArgs[1].Name = "ReadOnly" *!* * aNoArgs[1].Value = .F. *!* * These two lines replace the alternate version above, *!* * which are left commented for the insight they provide. LOCAL ARRAY aNoArgs[1] * grossièrement : on crée une structure contenant la propriété 'hidden' * initialisée à .F. et dont l'adresse est dans le premier élément de anoargs aNoArgs[1] = This.OOoPropertyValue( "Hidden", .F. ) This.doc = This.bureau.LoadComponentFromUrl( m.pcURL, "_blank", 0, @aNoargs ) * Make sure that arrays passed to this document are passed zero based and through * reference * COMARRAY indique à VFP que tous les tableaux passés à this.doc doivent être * basés sur 0 (le premier élément a pour indice 0 et non 1) et être passés par * référence. Toutefois, malgré cette instruction (bug ?) les tableaux doivent être * précédés par @ si on veut que VFP les passe par référence. COMARRAY( This.doc, 10 ) ENDPROC FUNCTION OOoPropertyValue( cName, uValue, nHandle, nState ) * Create a com.sun.star.beans.PropertyValue struct and return it. * créer une structure du type com.sun.star.beans.PropertyValue et * retourne un pointeur * la structure utilisée par OO ne peut pas être créée directement en VFP * on va donc demander à OO de la créer pour nous LOCAL oPropertyValue oPropertyValue = This.OOoCreateStruct( "com.sun.star.beans.PropertyValue" ) oPropertyValue.Name = m.cName oPropertyValue.Value = m.uValue * si on a des paramètres supplémentaires, on les traite IF TYPE([nHandle])="N" oPropertyValue.Handle = m.nHandle ENDIF IF TYPE([nState])="N" oPropertyValue.State = m.nState ENDIF RETURN m.oPropertyValue ENDFUNC FUNCTION OOoCreateStruct( cTypeName AS String) * fonction pour créer n'importe quel type de structure UNO * on l'a fait créer par OO LOCAL oStruct oStruct = .NULL. TRY oStruct = This.gestionnaire_de_services.Bridge_GetStruct( m.cTypeName ) CATCH WAIT WINDOW "impossible de créer la structure" TIMEOUT 2 oStruct = NULL This.erreur = -10 && structure UNO impossible à créer ENDTRY * dans les exemples lus, il semble qu'il pouvait y avoir un problème si certaines * variables globales étaient déjà mises à jour. Pour l'instant, je supprime * cette partie *!* IF ISNULL( m.oStruct ) *!* * on n'a pas réussi à créer la structure, on essaie de corriger un problème *!* * et de recommencer *!* =__OOoReleaseCachedVars() *!* oServiceManager = OOoGetServiceManager() *!* oStruct = oServiceManager.Bridge_GetStruct( cTypeName ) *!* ENDIF && ISNULL( m.oStruct ) RETURN m.oStruct ENDFUNC && OOoCreateStruct( cTypeName ) FUNCTION OOoConvertToURL( cFilename AS String) * convertit un nom de fichier Windows en un nom OO * le nom doit commencer par "/" et il faut changer les \ en / RETURN "file://" + IIF(ASC(m.cFilename)=47, "", "/")+ ; CHRTRAN( m.cFilename, "\", "/" ) ENDFUNC ENDDEFINE && vfp_oo DEFINE CLASS vfp_oo_writer AS vfp_oo && jme 04/11/2007 * cette classe contient les propriétés et les méthodes propres au * document Writer (traitement de texte) d'openOffice texte = NULL && pointeur sur le texte du document cuecr = NULL && curseur écriture cureel = NULL && curseur visible (le clignotant) font = NULL && pointeur sur la classe police paragraphe = NULL && pointeur sur la classe paragraphe page = NULL && pointeur sur la classe parametres_page * erreur = -1 && -1 non encore initialisé * -30 et -31 Impossible de créer le pointeur sur le texte * -32 Impossible de créer le curseur d'insertion texte PROTECTED PROCEDURE init * à l'init on vérifie si openoffice est installé DODEFAULT() IF This.erreur = 2 * initialisation propre au Writer *!* This.font = NEWOBJECT("oo_police") && quand on ne met pas de module, jme 26/11/2007 *!* * VFP cherche dans les classes de base (mais oo_police n'y est pas) puis *!* * dans le programme courant *!* This.paragraphe = NEWOBJECT("oo_paragraphe", This.cuecr) && idem ENDIF && This.erreur = 2 ENDPROC && init PROTECTED PROCEDURE destroy IF !ISNULL(This.doc) AND This.abandon_document=.F. AND This.doc.isModified * si on n'a pas de nom de fichier quand on sort, on en créer un automatiquement IF EMPTY(This.fichier_courant) This.fichier_courant = "OOO_WRITER_"+ SYS(2015) ENDIF && EMPTY(This.fichier_courant) This.enregistrer_document() ENDIF && This.doc.isModified This.doc = NULL DODEFAULT() ENDPROC PROCEDURE nouveau_document_texte * on crée un nouveau document texte IF This.erreur =2 * on ne crée pas de nouveau document s'il y en a déjà un actif IF ISNULL(This.doc) This.nouveau_document( "private:factory/swriter" ) IF ISNULL(This.doc) * il n'y a rien à faire ici, l'erreur a déjà été donnée ELSE This.texte = This.doc.Text && pointeur sur le texte du document * note le texte est le contenu du document. D'autres pointeurs * existent pour l'en-tête, le pied de page, etc .... IF ISNULL(This.texte) This.erreur = -30 #IFDEF avec_ww WAIT WINDOW "Impossible de créer le pointeur sur le texte" NOWAIT #ENDIF ELSE This.cuecr = This.texte.createTextCursor() IF ISNULL(This.cuecr) This.erreur = -32 #IFDEF avec_ww WAIT WINDOW "Impossible de créer le curseur d'insertion texte" NOWAIT #ENDIF ELSE This.erreur = 2 && tout va bien This.objets_doc() ENDIF && ISNULL(This.cuecr) ENDIF && ISNULL(This.texte) ENDIF && ISNULL(This.doc) ELSE #IFDEF avec_ww WAIT WINDOW "Création nouveau document impossible" + CHR(13)+ ; "un autre existe déjà" NOWAIT #ENDIF ENDIF && ISNULL(This.doc) ENDIF && This.erreur =2 ENDPROC PROCEDURE ouvrir_document_texte( pcfichier AS String) * pcfichier est un nom de fichier document text au format Windows LOCAL ARRAY lttab(1) LOCAL lcurl IF EMPTY(m.pcfichier) This.erreur = -11 && paramètre invalide WAIT WINDOW "Il faut indiquer le nom du fichier à ouvrir" NOWAIT ELSE IF ADIR(lttab, m.pcfichier) > 0 This.erreur = 0 && on raz l'erreur éventuelle This.doc = NULL lcurl = This.OOoConvertToURL( m.pcfichier ) This.OOoOpenURL( m.lcurl ) IF ISNULL( This.doc) This.erreur = -21 #IFDEF avec_ww WAIT WINDOW "Impossible d'ouvrir le fichier" + CHR(13)+ ; m.pcfichier NOWAIT #ENDIF ELSE This.texte = This.doc.Text && pointeur sur le texte du document * note le texte est le contenu du document. D'autres pointeurs * existent pour l'en-tête, le pied de page, etc .... IF ISNULL(This.texte) This.erreur = -31 #IFDEF avec_ww WAIT WINDOW "Impossible de créer le pointeur sur le texte" NOWAIT #ENDIF ELSE This.cuecr = This.texte.createTextCursor() IF ISNULL(This.cuecr) This.erreur = -32 #IFDEF avec_ww WAIT WINDOW "Impossible de créer le curseur d'insertion texte" NOWAIT #ENDIF ELSE This.erreur = 2 && tout va bien This.objets_doc() ENDIF && ISNULL(This.cuecr) ENDIF && ISNULL(This.texte) ENDIF && ISNULL( This.doc) ELSE This.erreur = -20 #IFDEF avec_ww WAIT WINDOW "Le fichier" + CHR(13)+ m.pcfichier+ CHR(13)+ ; "n'existe pas"NOWAIT #ENDIF ENDIF && ADIR(lttab, m.pcfichier) > 0 ENDIF && EMPTY(pcfichier) ENDPROC && ouvrir_texte PROTECTED PROCEDURE objets_doc * met à jour les pointeurs et les paramètres utilisés pour manipuler le texte This.font = NEWOBJECT("oo_police", "", "", This.cuecr) && quand on ne met pas de module, * VFP cherche dans les classes de base (mais oo_police n'y est pas) puis * dans le programme courant This.paragraphe = NEWOBJECT("oo_paragraphe", "", "", This.cuecr) && idem * This.font sert pour la gestion des polices de caractères * This.paragraphe sert pour la gestion des paragraphes This.page = NEWOBJECT("parametres_page", "", "", This.doc) * This.page sert à gérer les valeurs de marge haute, marge basse, gauche et * droite de la page. ENDPROC && objets_doc PROCEDURE enregistrer_copie_document( pcnomfichier AS String) && vfp_oo_writer * on veut créer une copie du document texte courant (on crée un fichier * sur le disque mais on continue de travailler sur le document courant) * pcnomfichier contient un nom de fichier (avec éventuellement un chemin) * au format Windows * on va créer systématiquement un export PDF IF PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) IF EMPTY( JUSTPATH(m.pcnomfichier)) * on ne peut pas sauvegarder un document SANS lui donner le chemin complet ! pcnomfichier = SYS(5)+ CURDIR()+ m.pcnomfichier ENDIF && EMPTY( JUSTPATH(m.pcnomfichier)) DODEFAULT( m.pcnomfichier) LOCAL lcurl LOCAL ARRAY lcparam(2) * on veut prévenir l'opérateur s'il écrase une version précédente du document * (même si c'est le même fichier; si c'est trop perturbant on peut supprimer * cette option ou supprimer le PDF avant de lancer cette méthode) lcparam(2) = This.OOoPropertyValue( "Overwrite", .T. ) lcparam(1) = This.OOoPropertyValue( "FilterName", "writer_pdf_Export") * il faut enlever l'éventuelle extension du nom du fichier pour la remplacer par .pdf lcurl = This.OOoConvertToURL( JUSTPATH(m.pcnomfichier)+ "\"+ JUSTSTEM(m.pcnomfichier)+ ".pdf") This.doc.storeToURL( m.lcurl, @ lcparam) ENDIF && PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) ENDPROC && enregistrer_document PROCEDURE informations_document LOCAL lcfichier, loinfos, lodate IF !ISNULL(This.doc) lcfichier = This.doc.location loinfos = This.doc.documentInfo lodate = loinfos.CreationDate = MESSAGEBOX("document :"+ m.lcfichier+ CHR(13)+ ; "auteur: "+ m.loinfos.Author+ CHR(13)+ ; "création: "+ STR(m.lodate.Day,2)+"/"+ TRANSFORM(m.lodate.Month, "@L 99")+ ; "/"+ STR(m.lodate.Year,4)+ CHR(13)+ ; "nombre de mots: "+ ALLTRIM(STR(This.doc.WordCount,6)), 0, "informations") ENDIF && !ISNULL(This.doc) ENDPROC && informations_document PROCEDURE debut_texte This.cuecr.gotoStart(.F.) ENDPROC PROCEDURE ajouter_texte( pctexte AS String) This.texte.insertString( This.cuecr, m.pctexte, .F.) ENDPROC && ajouter_texte PROCEDURE nouveau_paragraphe && insertion d'un nouveau paragraphe * à l'endroit du curseur d'écriture * "com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK" This.texte.insertControlCharacter(This.cuecr, PARAGRAPH_BREAK, .F.) ENDPROC && nouveau_paragraphe PROCEDURE appliquer_police && applique la police définie dans la * classe police This.font.curseur_ecriture = This.cuecr This.font.faire() ENDPROC && appliquer_police PROCEDURE police( pcnompolice AS String, ; pntaille AS Number, plgras AS Logical, plsouligne AS Logical) IF PCOUNT()>0 AND !ISNULL(m.pcnompolice) AND !EMPTY(m.pcnompolice) This.font.nom = m.pcnompolice ENDIF IF PCOUNT()>1 AND !ISNULL(m.pntaille) AND BETWEEN(m.pntaille, 2, 99) This.font.taille = m.pntaille ENDIF IF PCOUNT()>2 AND !ISNULL(m.plgras) This.font.gras = m.plgras ENDIF IF PCOUNT()>3 AND !ISNULL(m.plsouligne) This.font.souligne = m.plsouligne ENDIF This.font.curseur_ecriture = This.cuecr This.font.faire() ENDPROC && police ENDDEFINE && vfp_oo_writer DEFINE CLASS vfp_oo_calc AS vfp_oo && jme 07/11/2007 * cette classe contient les propriétés et les méthodes propres au * document Writer (traitement de texte) d'openOffice nombre_feuilles = 0 && nombre de feuilles DIMENSION feuilles(1,3) && tableau contenant les noms des feuilles (col 1), * leur ordre de création (colonne 2) et leur position (colonne 3) (les valeurs * pour l'ordre et la position commencent à 0 et non 1) * la 2éme feuille créée peut bien être déplacée à la 5éme position par exemple. feuille_active = 0 && ordre de la feuille active coord_cellule_alpha = "" && coordonées d'une cellule au format "A5" ou "BA15" DIMENSION coord_cellule(2) && 1: numéro de la ligne où est la cellule ( à partir de 0); * 2: numéro de la colonne où est la cellule ( à partir de 0) une_cellule = NULL && pointeur sur une structure représentant une cellule une_cellule_valeur = 0 && valeur numérique d'une cellule une_cellule_texte = "" && texte contenu dans une cellule une_cellule_formule = "" && formule contenue dans une cellule une_cellule_date = {} && date contenue dans une cellule coord_region_alpha = "" && coordonnées d'une région au format "A5:Z10" DIMENSION coord_region(4) && 1: ligne du coin en haut à gauche, 2 colonne de ce coin; * 3 ligne du coin en bas à droite, 4 colonne de ce coin PROTECTED PROCEDURE init * à l'init on vérifie si openoffice est installé DODEFAULT() IF This.erreur = 2 * initialisation propre à Calc STORE 0 TO This.coord_cellule, This.coord_region ENDIF && This.erreur = 2 ENDPROC && init PROTECTED PROCEDURE destroy IF !ISNULL(This.doc) AND This.doc.isModified AND This.abandon_document=.F. * si on n'a pas de nom de fichier quand on sort, on en créer un automatiquement IF EMPTY(This.fichier_courant) This.fichier_courant = "OOO_CALC_"+ SYS(2015) ENDIF && EMPTY(This.fichier_courant) This.enregistrer_document() ENDIF && This.doc.isModified This.doc = NULL DODEFAULT() ENDPROC PROCEDURE nouveau_tableur * on crée un nouveau document de calcul IF This.erreur =2 * on ne crée pas de nouveau document s'il y en a déjà un actif IF ISNULL(This.doc) This.nouveau_document( "private:factory/scalc" ) IF ISNULL(This.doc) * il n'y a rien à faire ici, l'erreur a déjà été donnée ELSE This.maj_infos_tableur() This.erreur = 2 && ok ENDIF && ISNULL(This.doc) ELSE #IFDEF avec_ww WAIT WINDOW "Création nouveau document impossible" + CHR(13)+ ; "un autre existe déjà" NOWAIT #ENDIF ENDIF && ISNULL(This.doc) ENDIF && This.erreur =2 ENDPROC PROCEDURE ouvrir_tableur( pcfichier AS String) * pcfichier est un nom de fichier document Calc (au format Windows) LOCAL ARRAY lttab(1) LOCAL lcurl IF EMPTY(m.pcfichier) This.erreur = -11 && paramètre invalide WAIT WINDOW "Il faut indiquer le nom du fichier à ouvrir" NOWAIT ELSE * on demande à VFP de vérifier l'existence du fichier (c'est pour faciliter * la gestion de l'erreur, je ne sais pas ce que fait OO si le fichier * n'existe pas) IF ADIR(lttab, m.pcfichier) > 0 This.erreur = 0 && on raz l'erreur éventuelle This.doc = NULL lcurl = This.OOoConvertToURL( m.pcfichier ) This.OOoOpenURL( m.lcurl ) IF ISNULL( This.doc) This.erreur = -21 #IFDEF avec_ww WAIT WINDOW "Impossible d'ouvrir le fichier" + CHR(13)+ ; m.pcfichier NOWAIT #ENDIF ELSE This.maj_infos_tableur() This.erreur = 2 && ok ENDIF && ISNULL( This.doc) ELSE This.erreur = -20 #IFDEF avec_ww WAIT WINDOW "Le fichier" + CHR(13)+ m.pcfichier+ CHR(13)+ ; "n'existe pas"NOWAIT #ENDIF ENDIF && ADIR(lttab, m.pcfichier) > 0 ENDIF && EMPTY(pcfichier) ENDPROC && ouvrir_texte PROTECTED PROCEDURE maj_infos_tableur * met à jour les propriétés nombre_feuilles, et feuilles avec * le nombre de feuilles leurs nom, position et ordre LOCAL lnaccu, lni, lnmax, lo1feuille STORE This.doc.Sheets.Count TO This.nombre_feuilles, lnaccu DIMENSION This.feuilles(m.lnaccu,3) lnmax = m.lnaccu -1 FOR m.lni = 0 TO m.lnmax lnaccu = m.lni + 1 * lo1feuille = This.doc.Sheets( m.lni) lo1feuille = This.doc.getSheets().getByIndex( m.lni ) This.feuilles( m.lnaccu, 1) = lo1feuille.Name && nom de la feuille This.feuilles( m.lnaccu, 2) = m.lnaccu * la troisième feuille créée a pu être déplacée à la 1ère position par * l'opérateur; la 3éme colonne du tableau contient donc la position de * la feuille et non son ordre de création. This.feuilles( m.lnaccu, 3) = lo1feuille.getRangeAddress().Sheet ENDFOR &&* m.lni = 0 TO m.lnmax This.feuille_active = This.doc.currentController.activeSheet ENDPROC && maj_infos_tableur PROCEDURE enregistrer_copie_document( pcnomfichier AS String) && vfp_oo_calc * on veut créer une copie du tableur courant (on crée un fichier * sur le disque mais on continue de travailler sur le document courant) * pcnomfichier contient un nom de fichier (avec éventuellement un chemin) * au format Windows * on va créer systématiquement un export PDF IF PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) IF EMPTY( JUSTPATH(m.pcnomfichier)) * on ne peut pas sauvegarder un document SANS lui donner le chemin complet ! pcnomfichier = SYS(5)+ CURDIR()+ m.pcnomfichier ENDIF && EMPTY( JUSTPATH(m.pcnomfichier)) DODEFAULT( m.pcnomfichier) LOCAL lcurl LOCAL ARRAY lcparam(2) * on veut prévenir l'opérateur s'il écrase une version précédente du document * (même si c'est le même fichier; si c'est trop perturbant on peut supprimer * cette option ou supprimer le PDF avant de lancer cette méthode) lcparam(2) = This.OOoPropertyValue( "Overwrite", .T. ) lcparam(1) = This.OOoPropertyValue( "FilterName", "calc_pdf_Export") * il faut enlever l'éventuelle extension du nom du fichier pour la remplacer par .pdf lcurl = This.OOoConvertToURL( JUSTPATH(m.pcnomfichier)+ "\"+ JUSTSTEM(m.pcnomfichier)+ ".pdf") This.doc.storeToURL( m.lcurl, @ lcparam) ENDIF && PCOUNT() = 1 AND ! EMPTY(m.pcnomfichier) ENDPROC && enregistrer_document PROCEDURE informations_document LOCAL lcfichier, loinfos, lodate IF !ISNULL(This.doc) lcfichier = This.doc.location loinfos = This.doc.documentInfo lodate = loinfos.CreationDate = MESSAGEBOX("document :"+ m.lcfichier+ CHR(13)+ ; "auteur: "+ m.loinfos.Author+ CHR(13)+ ; "création: "+ STR(m.lodate.Day,2)+"/"+ TRANSFORM(m.lodate.Month, "@L 99")+ ; "/"+ STR(m.lodate.Year,4)+ CHR(13)+ ; "nombre de feuilles: "+ ALLTRIM(STR(This.nombre_feuilles,6)), 0, "informations") ENDIF && !ISNULL(This.doc) ENDPROC && informations_document PROCEDURE selection_feuille(luparametre) * si luparametre est une chaîne de caractères, on recherche la feuille qui porte * ce nom. Si c'est une valeur numérique, on cherche la feuille de ce rang (ordre * visible commençant à 1 et non ordre de création) * oSheet = oDoc.getSheets().getByIndex( 0 ) ' get the zero'th sheet * oSheet = oDoc.getSheets().getByName( "Sheet3" ) ' get by name IF PCOUNT() > 0 IF VARTYPE(m.luparametre)=="C" AND !EMPTY(m.luparametre) * on cherche le feuille qui porte le nom passé en paramètre IF This.doc.getSheets().hasByName( m.luparametre) This.feuille_active = NULL This.feuille_active = This.doc.getSheets().getByName( m.luparametre ) IF ISNULL(This.feuille_active) #IFDEF avec_ww WAIT WINDOW "La feuille" + CHR(13)+ m.luparametre+ CHR(13)+ ; "est impossible à atteindre" NOWAIT #ENDIF ELSE This.doc.currentController.activeSheet = This.feuille_active ENDIF && ISNULL(This.feuille_active) ELSE #IFDEF avec_ww WAIT WINDOW "La feuille" + CHR(13)+ m.luparametre+ CHR(13)+ ; "n'existe pas" NOWAIT #ENDIF ENDIF && This.doc.getSheets().hasByName( "Sheet3" ) ELSE IF VARTYPE(m.luparametre)=="N" OR VARTYPE(m.luparametre)=="I" IF BETWEEN(m.luparametre, 1, This.nombre_feuilles) This.feuille_active = NULL This.feuille_active = This.doc.getSheets().getByIndex( m.luparametre -1) IF ISNULL(This.feuille_active) #IFDEF avec_ww WAIT WINDOW "La feuille n° " + STR(m.luparametre)+ CHR(13)+ ; "est impossible à atteindre" NOWAIT #ENDIF ELSE This.doc.currentController.activeSheet = This.feuille_active ENDIF && ISNULL(This.feuille_active) ELSE #IFDEF avec_ww WAIT WINDOW "numéro de feuille hors limites" NOWAIT #ENDIF ENDIF && BETWEEN(m.luparametre, 1, This.nombre_feuilles) ELSE #IFDEF avec_ww WAIT WINDOW "paramètre incorrect" NOWAIT #ENDIF ENDIF && VARTYPE(m.luparametre)=="N" ENDIF && VARTYPE(m.luparametre)=="C" ELSE #IFDEF avec_ww WAIT WINDOW "Il me faut le nom de la feuille" + CHR(13)+ ; "ou son numéro d'ordre" NOWAIT #ENDIF ENDIF && PCOUNT() > 0 ENDPROC && selection_feuille PROCEDURE ajouter_feuille( lnposition AS Number, lcnom AS String) * On ajoute la feuille de nom lcnom à la position lnposition. * lnposition compris entre 1 (et non 0) et This.nombre_feuilles + 1 * NOTE : je met beaucoup de tests mais c'est pour faciliter le déboguage IF PCOUNT()=2 AND BETWEEN(m.lnposition, 1, This.nombre_feuilles+1) AND ; !EMPTY(m.lcnom) IF This.doc.getSheets().hasByName( m.lcnom) * une feuille porte déjà ce nom #IFDEF avec_ww WAIT WINDOW "Une feuille porte déjà le nom" + CHR(13)+ m.lcnom NOWAIT #ENDIF ELSE LOCAL lofeuille lofeuille = This.feuille_active This.feuille_active = NULL This.doc.getSheets().insertNewByName(m.lcnom, m.lnposition-1) IF This.doc.getSheets().hasByName( m.lcnom) This.feuille_active = This.doc.getSheets().getByName( m.lcnom) IF ISNULL( This.feuille_active) This.feuille_active = m.lofeuille ENDIF && ISNULL( This.feuille_active) ELSE This.feuille_active = m.lofeuille ENDIF && This.doc.getSheets().hasByName( m.lcnom) This.doc.currentController.activeSheet = This.feuille_active ENDIF && This.doc.getSheets().hasByName( m.lcnom) ELSE #IFDEF avec_ww WAIT WINDOW "Au moins un paramètre incorrect" NOWAIT #ENDIF ENDIF && PCOUNT()=2 AND BETWEEN(m.lnposition, 1, This.nombre_feuilles+1) AND ENDPROC && ajouter_feuille *!* coord_cellule_alpha = "" && coordonées d'une cellule au format "A5" ou "BA15" *!* DIMENSION coord_cellule(2) && 1: numéro de la ligne où est la cellule ( à partir de 0); *!* * 2: numéro de la colonne où est la cellule ( à partir de 0) PROCEDURE cellule_coord_alpha_vers_num( m.lccoord AS String) * dans OO.Calc, une cellule peut être accédée par deux types de coordonnées équivalentes : * le texte "A1" ou "AA5" ou par ses numéros de ligne/ numéros de colonne. * "A1" équivaut à 0,0 IF PCOUNT()=1 AND !EMPTY(m.lccoord) This.coord_cellule_alpha = ALLTRIM(m.lccoord) ENDIF && PCOUNT()=1 AND !EMPTY(m.lccoord) LOCAL lnligne, lnaccu, lncolonne, lccar, lnlong STORE 0 TO lncolonne, lnligne lnaccu = 1 lnlong = LEN(This.coord_cellule_alpha) lccar = LEFT(This.coord_cellule_alpha,1) DO WHILE ISALPHA(m.lccar) lncolonne = m.lncolonne * 26 + (ASC(m.lccar)-64) lnaccu = m.lnaccu + 1 lccar = IIF(m.lnaccu<=m.lnlong, SUBSTR( This.coord_cellule_alpha, m.lnaccu,1), "") ENDDO && ISALPHA(SUBSTR( This.coord_cellule_alpha, m.lnaccu,1)) * normalement, lccar contient le premier chiffre DO WHILE ISDIGIT(m.lccar) lnligne = m.lnligne * 10 + (ASC(m.lccar)-48) lnaccu = m.lnaccu + 1 lccar = IIF(m.lnaccu<=m.lnlong, SUBSTR( This.coord_cellule_alpha, m.lnaccu,1), "") ENDDO && ISALPHA(SUBSTR( This.coord_cellule_alpha, m.lnaccu,1)) This.coord_cellule(1)= m.lnligne - 1 This.coord_cellule(2)= m.lncolonne - 1 ENDPROC && cellule_coord_alpha_vers_num PROCEDURE cellule_coord_num_vers_alpha( lnligne AS Number, lncol AS Number) * lnligne et lncol commence à 0 (et non 1) * dans OO.Calc, une cellule peut être accédée par deux types de coordonnées équivalentes : * le texte "A1" ou "AA5" ou par ses numéros de ligne/ numéros de colonne. * "A1" équivaut à 0,0 IF PCOUNT()=2 This.coord_cellule(1)= m.lnligne This.coord_cellule(2)= m.lncol ENDIF && PCOUNT()=2 LOCAL lnli, lnco, lnaccu, lcresult lcresult = "" lnco = This.coord_cellule(2) DO CASE CASE m.lnco >= 702 * le résultat a 3 lettres lnaccu = INT(m.lnco / 702) lcresult = m.lcresult + CHR(64+ m.lnaccu) lnco = m.lnco - m.lnaccu*702 lnaccu = INT(m.lnco / 26) lcresult = m.lcresult + CHR(65+ m.lnaccu) lnco = m.lnco - m.lnaccu*26 lcresult = m.lcresult + CHR(65+m.lnco) CASE m.lnco >= 26 lnaccu = INT(m.lnco / 26) lcresult = m.lcresult + CHR(64+ m.lnaccu) lnco = m.lnco - m.lnaccu*26 lcresult = m.lcresult + CHR(65+m.lnco) CASE m.lnco >= 0 lcresult = m.lcresult + CHR(65+m.lnco) ENDCASE * maintenant que l'on a les lettres, on fait les chiffres, c'est plus simple This.coord_cellule_alpha = m.lcresult+ ALLTRIM(STR(This.coord_cellule(1)+1,6)) ENDPROC && cellule_coord_num_vers_alpha PROCEDURE texte_dans_cellule( pctext AS String, pnligne AS Number, pncol AS Number) * si on ne transmet qu'un seul paramètre, on travaille sur la cellule courante IF PCOUNT()=3 This.coord_cellule(1)= m.pnligne This.coord_cellule(2)= m.pncol ENDIF && PCOUNT()=3 This.une_cellule_texte = m.pctext * attention, dans getCellPosition le 1ere paramètre est la colonne, le 2éme la ligne *This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)).setString( m.pctext ) This.une_cellule = This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)) This.une_cellule.setString( m.pctext ) ENDPROC && texte_dans_cellule PROCEDURE valeur_dans_cellule( pnvaleur AS Number, pnligne AS Number, pncol AS Number) * si on ne transmet qu'un seul paramètre, on travaille sur la cellule courante IF PCOUNT()=3 This.coord_cellule(1)= m.pnligne This.coord_cellule(2)= m.pncol ENDIF && PCOUNT()=3 This.une_cellule_valeur = m.pnvaleur * attention, dans getCellPosition le 1ere paramètre est la colonne, le 2éme la ligne *This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)).setValue( m.pnvaleur ) This.une_cellule = This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)) This.une_cellule.setValue( m.pnvaleur ) ENDPROC && valeur_dans_cellule PROCEDURE formule_dans_cellule( pctext AS String, pnligne AS Number, pncol AS Number) * si on ne transmet qu'un seul paramètre, on travaille sur la cellule courante IF PCOUNT()=3 This.coord_cellule(1)= m.pnligne This.coord_cellule(2)= m.pncol ENDIF && PCOUNT()=3 * attention, dans getCellPosition le 1ere paramètre est la colonne, le 2éme la ligne This.une_cellule_formule = m.pctext *This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)).setFormula( m.pctext ) This.une_cellule = This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)) This.une_cellule.setFormula( m.pctext ) ENDPROC && texte_dans_cellule PROCEDURE date_dans_cellule( pudate, pnligne AS Number, pncol AS Number) * si on ne transmet qu'un seul paramètre, on travaille sur la cellule courante IF PCOUNT()=3 This.coord_cellule(1)= m.pnligne This.coord_cellule(2)= m.pncol ENDIF && PCOUNT()=3 * attention, dans getCellPosition le 1ere paramètre est la colonne, le 2éme la ligne LOCAL lddate, lcaccu, loformat, lolocal, lnformatdate lcaccu = VARTYPE(m.pudate) IF m.lcaccu=="T" lddate = TTOD(m.pudate) ELSE IF m.lcaccu=="D" lddate = m.pudate ELSE lddate = DATE() ENDIF && m.lcaccu=="D" ENDIF && VARTYPE(m.pudate)=="T" This.une_cellule_date = m.lddate * on détaille les calculs pour faciliter le set step on * DTOC ne convient pas car OO veut une date à l'américaine ... *lcaccu = DTOC(m.lddate) lcaccu = TRANSFORM( MONTH(m.lddate), "@L 99")+"/"+ ; TRANSFORM( DAY(m.lddate), "@L 99")+"/"+ STR(YEAR(m.lddate),4) This.une_cellule = This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)) This.une_cellule.setFormula( m.lcaccu) * dans les quelques lignes ci-dessous, je recopie bêtement l'exemple; j'ai pas tout compris. loformat = This.doc.getNumberFormats() lolocal = This.OOoCreateStruct( "com.sun.star.lang.Locale" ) * com.sun.star.util.NumberFormat.DATE = 2 lnformatdate = loformat.getStandardFormat( 2, lolocal) && 2 = date This.une_cellule.NumberFormat = m.lnformatdate ENDPROC && date_dans_cellule PROCEDURE lire_une_cellule( pnligne AS Number, pncol AS Number) * lit le contenu d'une cellule * mais comment savoir le type de donnée ? * si c'est une valeur numérique, string et formula contiennent le STR(valeur)! * si on ne transmet pas de paramètre, on travaille sur la cellule courante IF PCOUNT()=2 This.coord_cellule(1)= m.pnligne This.coord_cellule(2)= m.pncol This.une_cellule = This.feuille_active.getCellByPosition( This.coord_cellule(2), This.coord_cellule(1)) ENDIF && PCOUNT()=3 This.une_cellule_valeur = This.une_cellule.value && valeur numérique de la cellule This.une_cellule_texte = This.une_cellule.string && texte contenu dans la cellule This.une_cellule_formule = This.une_cellule.formula && formule contenue dans la cellule *!* une_cellule_date = {} && date contenue dans une cellule LOCAL lnaccu lnaccu = 0 && pour le set step on ENDPROC && lire_une_cellule ENDDEFINE && vfp_oo_calc

TEST_OO.PRG :

* J. MAURICE jsm.maurice@wanadoo.fr * programme permettant de tester la librairie lib_automation_vfp_oo.prg * version du 26/11/2007 PUBLIC looo LOCAL lcaccu WAIT WINDOW "début" NOWAIT NOCLEAR looo = NEWOBJECT("vfp_oo_writer", "lib_automation_vfp_oo.prg") WAIT WINDOW "nouveau document" NOWAIT NOCLEAR looo.nouveau_document_texte() IF m.looo.erreur>1 WAIT WINDOW "insertion texte" NOWAIT NOCLEAR looo.abandon_document=.T. looo.debut_texte() looo.ajouter_texte("première ligne créée automatiquement depuis VFP"+CHR(10)) looo.nouveau_paragraphe() looo.ajouter_texte("deuxième ligne "+ DTOS(DATE())+ " "+ TIME()) *!* looo.informations_document() looo.nouveau_paragraphe() looo.font.taille = 16 looo.font.gras = .T. looo.appliquer_police() looo.ajouter_texte("ceci devrait être dans une taille 16"+ CHR(10)) looo.nouveau_paragraphe() looo.font.gras = .F. looo.font.taille = 8 looo.font.souligne = .T. looo.font.nom = "Impact" looo.appliquer_police() looo.ajouter_texte("police Impact, taille 8 non gras, souligné") looo.nouveau_paragraphe() looo.ajouter_texte("nouveau") looo.police("Courier New", 10, .F., .F.) looo.ajouter_texte(" texte avec ") looo.police("Courier New", 16, .F., .F.) looo.ajouter_texte("changement de ") looo.police("", 9, .F., .T.) looo.ajouter_texte("police") looo.ajouter_texte(".") looo.nouveau_paragraphe() looo.police("Times New Roman", 12, .F., .F.) looo.ajouter_texte("et retour à la normale") looo.nouveau_paragraphe() FOR m.i = 8 TO 24 STEP 2 looo.police("Times New Roman", m.i, .F., .F.) looo.ajouter_texte("Times "+ STR(m.i,3)+", ") ENDFOR &&* m.i = 1 TO 10 looo.nouveau_paragraphe() FOR m.i = 8 TO 24 STEP 2 looo.police("Courier New", m.i, .F., .F.) looo.ajouter_texte("Courier "+ STR(m.i,3)+", ") ENDFOR &&* m.i = 1 TO 10 * lorsque l'on veut changer qu'un seul parametre, il est plus * facile d'utiliser les propriétés a_nom, a_taille, a_gras * a_souligne, a_italique qui possèdent des méthodes _assign * ex: si on ne change que la taille : looo.nouveau_paragraphe() looo.police("Courier New", 12, .F., .F.) looo.ajouter_texte("Courier : avec les assign") looo.nouveau_paragraphe() FOR m.i = 8 TO 24 STEP 2 looo.font.a_taille = m.i looo.ajouter_texte("Courier assign"+ STR(m.i,3)) looo.nouveau_paragraphe() ENDFOR &&* m.i = 8 TO 24 STEP 2 looo.nouveau_paragraphe() looo.police("Courier New", 12, .F., .F.) looo.ajouter_texte("gestion des paragraphes") looo.nouveau_paragraphe() FOR m.i = 0 TO 3000 STEP 500 looo.paragraphe.marge_gauche = m.i looo.paragraphe.faire() looo.ajouter_texte("marge gauche"+ STR(m.i,6)) looo.nouveau_paragraphe() ENDFOR looo.nouveau_paragraphe() looo.paragraphe.marge_gauche = 0 looo.ajouter_texte("ceci est un paragraphe aligné à gauche") looo.paragraphe.alignement("gauche") looo.nouveau_paragraphe() looo.font.a_italique = .T. looo.ajouter_texte("ceci est un paragraphe aligné à droite") looo.paragraphe.alignement("droite") looo.nouveau_paragraphe() looo.font.a_italique = .F. looo.ajouter_texte("ceci est un paragraphe centré") looo.paragraphe.alignement("centré") looo.nouveau_paragraphe() lcaccu = "ceci est un paragraphe que l'on va tenté de justifier. " looo.ajouter_texte(m.lcaccu+" Remarquez son retrait de première ligne !."+m.lcaccu) looo.ajouter_texte(m.lcaccu+m.lcaccu+m.lcaccu+"1234") looo.paragraphe.retrait_ligne1 = 1000 && 1 cm looo.paragraphe.alignement("justifié") looo.abandon_document=.T. WAIT WINDOW "impression du document" NOWAIT * ATTENTION : on imprime dans un fichier mais il faut tout de même qu'une * imprimante soit connectée. je regarde le problème. looo.impression.pages = "" looo.impression.fichier_impression = SYS(5)+CURDIR()+"essai_oo.prn" looo.impression.impression_dans_un_fichier = .T. looo.imprimer_document() WAIT WINDOW "enregistrement du document" NOWAIT NOCLEAR lcaccu = SYS(5)+CURDIR()+"essai_"+DTOS(DATE())+"_"+ CHRTRAN(TIME(), ":", "")+".swx" *!* lcaccu = "essai_"+DTOS(DATE())+"_"+ CHRTRAN(TIME(), ":", "") looo.enregistrer_document(m.lcaccu) *!* lcaccu = "copie_"+DTOS(DATE())+"_"+ CHRTRAN(TIME(), ":", "") lcaccu = SYS(5)+CURDIR()+"copie_"+DTOS(DATE())+"_"+ CHRTRAN(TIME(), ":", "")+".swx" looo.enregistrer_copie_document(m.lcaccu) looo.fermer_document() WAIT WINDOW "document fermé" NOWAIT && TIMEOUT 2 WAIT CLEAR ELSE looo = NULL ENDIF && m.looo.erreur>1 TEST_OO_CALC.PRG : PUBLIC looo SET DATE FRENCH WAIT WINDOW "début" NOWAIT NOCLEAR looo = NEWOBJECT("vfp_oo_calc", "lib_automation_vfp_oo.prg") WAIT WINDOW "ouvrir document" NOWAIT NOCLEAR looo.ouvrir_tableur("d:\mau\profess9\open_office\test\test_calc.ods") IF m.looo.erreur>1 WAIT WINDOW "tableur ouvert" NOWAIT NOCLEAR looo.abandon_document=.T. * looo.informations_document() looo.selection_feuille(2) looo.selection_feuille("SYBIC") *!* WAIT WINDOW "enregistrement du document" NOWAIT NOCLEAR *!* lcaccu = SYS(5)+CURDIR()+"essai_"+DTOS(DATE())+"_"+ CHRTRAN(TIME(), ":", "")+".swx" *!* looo.enregistrer_document(m.lcaccu) looo.ajouter_feuille( 1, "PAPOUCHE") looo.texte_dans_cellule("chatte", 0,2) looo.valeur_dans_cellule(123, 0,3) looo.date_dans_cellule( DATE(),0,4) looo.lire_une_cellule(0,3) * looo.fermer_document() * WAIT WINDOW "document fermé" TIMEOUT 2 WAIT CLEAR ELSE looo = NULL ENDIF && m.looo.erreur>1 Tous les programmes ci-dessus sont librement utilisables.

Personal tools