Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Logiciels Libres & Open Source Discussion :

Faire une macro copier coller dans une feuille Calc


Sujet :

Logiciels Libres & Open Source

  1. #1
    Futur Membre du Club
    Faire une macro copier coller dans une feuille Calc
    Bonjour tout le monde,
    tout d'abord je suis un tout nouveau inscrit et je ne sais pas quelle est la marche à suivre pour essayer de me faire aider. J'espère que vous aurez pitié de moi car en plus je ne connais rien dans le langage de programmation utilisé dans Calc.
    A tout hasard je vous expose mon problème que j'ai réussi à résoudre en VBA pour Excel. Je voudrais faire la même macro dans Calc. J'ai passé deux jours sur les forums en vain pour trouver une solution.
    Au final je voudrais expédier plusieurs factures faites sur Calc en publipostage avec Writer. Pour cela je pars de la facture type de la feuille(n) de laquelle je copie toutes les valeurs des différentes cellules dans une unique ligne de cette même feuille (avec les formules: =F3,=E5...). Et c'est cette ligne que je veux, au moyen d'une macro, copier puis coller dans une feuille (n+1). A chaque fois que j'ai une nouvelle facture, les valeurs de ces cellules changent et donc je voudrais coller ligne après ligne ces différents enregistrements sans écraser les précédents. Et c'est cette table que j'utiliserai pour faire du publipostage ensuite.
    Exemple: De la facture1 de la feuille1 je transcris dans trois cellules contiguës des valeurs de nom, ville et métier en A1,B1 et B1. Je voudrais copier ces valeurs de la feuille1 et les coller dans la feuille2 en A2,B2 et C2;
    Pour la facture2 j'aurai les mêmes cellules de la feuille1 (A1,B1,C1) avec des valeurs différentes à coller dans la feuille2 mais cette fois-ci en A3,B3 et C4 et ainsi de suite pour les autres factures avec une sauvegarde en fin de saisie.
    J'espère avoir été assez compréhensible. Si ce n'est pas le cas je peux fournir d'autres précisions. Si quelqu'un peut m'aider j'en serais ravi car cela fait plus de trois jours que je galère;
    Je voudrais m'excuser si je ne suis pas au bon endroit pour ce genre de discussion mais je débute dans le forum.
    Merci d'avance pour votre aide.
    Bien cordialement;
    Jacques

  2. #2
    Membre habitué
    Bonjour,

    Voici un programme simple en exemple, de copie de cellules :

    Code oBasic :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    REM  *****  BASIC  *****
     
    Public document as object
    Public a as integer
    Public b as integer
    Public c as integer
    Public d as integer
    Public e as integer
    Public f as integer
    Public g as integer
    Public h as integer
    Public i as integer
     
     
    rem Gestion des variables --------------------------------------------------
    Public col1 as integer		' numéro de la colonne en cours de la première feuille
    Public lig1 as integer		' numéro de la ligne   en cours de la première feuille
    Public col2 as integer		' numéro de la colonne en cours de la deuxième feuille
    Public lig2 as integer		' numéro de la ligne   en cours de la deuxième feuille
    Public compt as integer  	' compteur d'exécution
    Public compt_lig as integer	' compteur de boucles de la fonction while permettant la sortie
    rem ------------------------------------------------------------------------
     
    Sub gestion_compte
    document = ThisComponent
    Feuille1 = document.Sheets.getByIndex(0)
    Feuille2 = document.Sheets.getByIndex(1)
     
    col1 = 1
    lig1 = 1
    col2 = 1
    lig2 = 3
     
    while Feuille1.getCellByPosition(col1,lig1).string = ""
    	lig1 = lig1 + 1
    wend
     
    lig1 = lig1 - 1
    for i = 1 to 20
    compt = 0
    compt_lig = 0
    	while compt < 7
    		if Feuille1.getCellByPosition(col1,lig1).string <> "" then
    			Feuille2.getCellByPosition(col2,lig2).string = Feuille1.getCellByPosition(col1,lig1).string
    			col2 = col2 + 1
    			compt = compt + 1
    			if Feuille1.getCellByPosition(col1,lig1).string = "-- h --" then
    				col2 = col2 + 1
    				compt = compt + 1
    			endif
    			if Feuille1.getCellByPosition(col1,lig1).string = "En traitement" then
    				col2 = col2 - 1
    				compt = compt - 1
    			endif
    		endif
    		lig1 = lig1 + 1
    		compt_lig = compt_lig + 1
    		if compt_lig > 15 then
    			compt = compt + 1
    		endif
    	wend
    	col2 = 1
    	lig2 = lig2 + 1
    next
     
    a = lig2
    lig2_2 = lig2 + 5
     
    for i = 1 to a
    	for col2 = 1 to 7
    		Feuille2.getCellByPosition(col2,lig2_2).string = Feuille2.getCellByPosition(col2,lig2).string
    	next
    	lig2_2 = lig2_2 + 1
    	lig2 = lig2 - 1
    next
    End Sub


    dans lequel, le minimum de commandes à écrire sont les suivantes :

    Code oBasic :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Public document as object
     
    Sub gestion_compte
    document = ThisComponent
     
    End sub

  3. #3
    Futur Membre du Club
    Faire une macro copier coller dans une feuille Calc
    Bonjour Pascaltech,
    un grand merci tout d'abord pour ta rapidité à me répondre. Je vais essayer d''adapter ta macro à mon fichier Calc.
    J'avoue que je ne pensais pas que la macro soit aussi longue pour copier/coller 3 cellules. En fait les 3 cellules étaient un exemple car au maximum j'ai un potentiel de 150 cellules à copier/coller. C'est vrai dans toutes les factures il n'y aura pas toutes les cellules à copier mais cela pourrais arriver. Je vais m'y mettre mardi.
    J'aurais une question subsidiaire concernant les macros en général. En utilisant le gestionnaire (ce n'est peut-être pas le mot approprié) de macro j'ai réussi à faire une macro pour copier/ coller des valeurs de cellules contiguës (provenant d'une formule) dans une autre ligne au moyen d'un collage spécial (texte non formaté). Quand je fais "exécuter" la macro fonctionne, mais dès que je l'associe à un bouton la macro ne fonctionne plus. J'ai l'impression que la copie ne se fait pas et que la macro colle dans la ligne désirée une précédente copie que le presse-papier a gardé en mémoire.
    J'espère ne pas avoir été trop long.
    Un grand merci encore.
    bien cordialement.
    Jacques

  4. #4
    Membre habitué
    Bonjour Jacques,

    Tu dois t'attendre à faire un minimum de manipulations de tes données d'entrée. La stratégie est d'itérer un petit programme afin de répéter certains traitements et ,ainsi, éviter d'écrire un long programme.

    Citation Envoyé par jackouBZH Voir le message
    J'aurais une question subsidiaire concernant les macros en général. En utilisant le gestionnaire (ce n'est peut-être pas le mot approprié) de macro j'ai réussi à faire une macro pour copier/ coller des valeurs de cellules contiguës (provenant d'une formule) dans une autre ligne au moyen d'un collage spécial (texte non formaté). Quand je fais "exécuter" la macro fonctionne, mais dès que je l'associe à un bouton la macro ne fonctionne plus. J'ai l'impression que la copie ne se fait pas et que la macro colle dans la ligne désirée une précédente copie que le presse-papier a gardé en mémoire.
    Tu dois parler de l'enregistreur de macros qui te permet d'enregistrer toutes les actions que tu effectues pendant la phase d'enregistrement et que tu peux reproduire ensuite.

    Peux-tu donner cette macro ici ?

    Bonne journée Pascal.

  5. #5
    Futur Membre du Club
    Suite macro copier/coller
    Bonjour Pascal,
    Après mainte et maintes essai avec des macros piochés dans différents messages du forum (et là je remercie vraiment tous ceux qui animent ces discussions; c'est formidable) j'ai réussi à concocter une macro qui fonctionne (il ya surement des lignes inutiles mais j'ai tellement galéré que je n'ose y toucher). j'ai mis une copie d'écran pour montrer où je récupère les données que j'aurai besoin pour faire du publipostage. Dans les cellules de Q1 à FX1 je récupère sur la facture différentes données par la fonction "= H3 ou = G8.... etc (par exemple) Ensuite la macro fait une copie de ces cellules et fait un collage spécial (texte non formaté) dans les cellules de Q2 à FX2. Ensuite la macro copie ces cellules pour les mettre dans la feuille suivante appelée "PUBLIPOSTAGE" (l'onglet n'apparait peut-être pas dans la copie d'écran) dans la première ligne vide à partir de la colonne A. Ainsi les données se copient au fur et à mesure sans écrasement; Je dispose alors d'une base de données qui sera exploitable pour faire du publipostage avec Writer; Pour l'instant cette macro fonctionne bien. Par contre c'est au niveau du bouton pour lancer la macro qu'il y a un souci. j'ai contourné le problème en assignant la macro "sspresspapieryy" à une forme de dessin (l'ovale rouge dans la facture en coipie d'écran) et cela fonctionne. Bouton et ovale sont assignés à la même macro et cela ne marche pas avec le bouton; l'essentiel c'est que cela fonctionne avec l'ovale; mais j'aimerais comprendre.
    J'ai mis ci-dessous le concoctage de code pour arriver à mes fins tout en ne connaissant pas grand chose en langage de programmation.
    En tout cas un grand merci Pascal.
    bonne fin de journée.
    Cordialement;
    Jacques

    Code oBasic :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    sub sspressepapieryy
    ' sub sspressepapier
     rem--------------------------coeip ligne1  sur ligne 2 feuille1-qui fonctionne------------------------------------------
    '' sub collefeuille1
    rem ----------------------------------------------------------------------
    rem define variables
    dim document   as object
    dim dispatcher as object
    rem ----------------------------------------------------------------------
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
     
    rem ----------------------------------------------------------------------
    dim args1(0) as new com.sun.star.beans.PropertyValue
    args1(0).Name = "ToPoint"
    'args1(0).Value = "$Q$2"
     args1(0).Value = "$Q$1"
     
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())
     
    rem ----------------------------------------------------------------------
    dim args2(0) as new com.sun.star.beans.PropertyValue
    args2(0).Name = "ToPoint"
    'args2(0).Value = "$Q$2:$FX$2"
     args2(0).Value = "$Q$1:$FX$1"
     
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args2())
     
    rem ----------------------------------------------------------------------
    dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
     
    rem ----------------------------------------------------------------------
    dim args4(0) as new com.sun.star.beans.PropertyValue
    args4(0).Name = "ToPoint"
    args4(0).Value = "$Q$2:$Q$2"
     
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args4())
     
    rem ----------------------------------------------------------------------
    dim args5(0) as new com.sun.star.beans.PropertyValue
    args5(0).Name = "ToPoint"
    args5(0).Value = "$Q$2:$FX2"
     
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args5())
     
    rem ----------------------------------------------------------------------
    dispatcher.executeDispatch(document, ".uno<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />asteUnformatted", "", 0, Array())
     
    rem ----------------------------------------------------------------------
    dispatcher.executeDispatch(document, ".uno:Save", "", 0, Array())
     
     
    'end sub
     
     
    rem ----------------------------------------------------------------------
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
     
    rem -----------------------------------------------------------------
    rem------------------sans presse-papier
     Dim oDoc as Object, oRange as Object, aCopier as Object
     
       oDoc = thisComponent
     ' oRange = oDoc.Sheets(0).getCellRangeByName("Q2:FX2") ' la zone à copier
       orange = oDoc.Sheets(4).getCellRangeByName("Q2:FX2")
         oDoc.CurrentController.select(oRange) 'Sélection de la zone
       rem-------------------------
       aCopier = oDoc.CurrentController.getTransferable() 'Copie
    ' aCopier = dispatcher.executeDispatch(document, ".uno<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />asteUnformatted", "", 0, Array())
       rem----------------------------
     
      ThisComponent.Sheets("PUBLIPOSTAGE")'.getCellRangeByName("D6:G11")
       rem--------------------------
      ' Sub TrouverLigneVide()
      	 Dim monDocument As Object
      	 	 Dim maFeuille As Object
        Dim maCellule As Object
        monDocument = ThisComponent
     Dim zoneVide As Variant
     Dim maZone As Object
     	 Dim celluleVide As Integer
    '	 dim dispatcher as object
     
    	 'Je désigne la feuille sur laquelle je travaille
        maFeuille = ThisComponent.getSheets.getByName("PUBLIPOSTAGE")
     
         'Affiche la feuille correspondante au cas où c'est autre feuille qui est affichée à l'écran (FACULTATIF)
        ThisComponent.CurrentController.ActiveSheet = maFeuille
     
         'Je désigne la zonne sur laquelle je cherche une ligne vide de la manière suivante
         'Colonne A qui est ma colonne de référence.
         'Je commence à la ligne A2 (A2 comporte mes titres de mon tableau). donc la recherche commencera à partir de la ligne 3
         'Je termine à A100. Il ne faut pas hésiter à aller plus loin si le nombre de lignes
         'pouvant étre utiliser est supérieur (exemple: A300)	 
     maZone = maFeuille.getCellRangeByName("A2:A400")	
      zoneVide = maZone.queryEmptyCells.RangeAddresses
    	 'Je trouve la dernière ligne utilisée
    	 	 celluleVide = zoneVide(0).StartRow
    	 'J'ajoute 1 pour obtenir la ligne vide
     celluleVide = celluleVide + 1
     Rem-------------------------------------------------------------------------------------------------
    	 'Je vais à la ligne vide de la colonne A et j'insère mon nouvel enregistrement (nom)
     maCellule = maFeuille.getCellRangeByName("A" & celluleVide)
        ' maCellule.String = "nouveau nom"
       ' End sub
       rem----------------------------reprise de sspresses papier
      oRange = oDoc.Sheets(5).getCellRangeByName("A" & cellulevide) 'Première cellule pour recopie de la zone
      oDoc.CurrentController.select(oRange) 'Selection de la cellule
     
       rem------------------------------------------------------
       oDoc.CurrentController.insertTransferable(aCopier) 'Transfert des données
     ' dispatcher.executeDispatch(document, ".uno<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />asteUnformatted", "", 0, Array())
       rem-------------------------------------
    End Sub

  6. #6
    Membre habitué
    Bonsoir,

    Pour être honnête avec toi, je n'utilises pas le service dispatchHelper ; je trouve cela compliqué et abscons.

    J'ai exécuté ton programme, il fonctionne lorsque j'ai le bon nombre d'onglet, mais je n'obtiens pas de copie avec le dispatcher.

    Je reconnais que les début en macro sont difficiles, il y a beaucoup de notions, peu de programmes clairs, des lignes à rallonge. Si tu en as le besoin, appréhende en premier la programmation objet. C'est par le biais ds macros que j'ai acquis la connaissance de ce mode de programmation, à mon petit niveau. Si tu as les concepts, tu peux avancer. Je n'ai pas poussé plus avant sur ce mode de programmation, car il est limité aux documents texte et tableur. Mais c'est un bon outil qui permet de faire bien des choses avec peu de lignes.

    En ce qui me concerne, je n'utilise pas pour le moment la doxa de nommage que l'on retrouve dans ta macro. Je trouve cela surfait, peut-être y viendrais-je si je pousse plus en avant.

    Je regarderai mieux ta macro demain. Je te conseille de mettre ton programme entre [CODE] avec l'icône # sur le haut de ta fenêtre de message.

    Bonne assiduité pour ce soir.

    Voici un programme exemple d'utilisation du service DispatchHelper :

    Code oBasic :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Sub CopierCollerSpecial
    ' J.P Janvier 2015
    Doc = thisComponent
     
    Dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
    Frame = Doc.CurrentController.Frame
     
     
    ' On sélectionne la plage de cellule à copier
    Feuille = Doc.Sheets(0)
    plage = Feuille.getCellRangeByName("A1:A10")
    Doc.CurrentController.Select(plage)
     
     
    ' On utilise un Dispatch pour copier la plage
    Dispatcher.executeDispatch(Frame, ".uno:Copy", "", 0, Array())
     
     
    ' On sélectionne la première cellule de l'endroit où coller
    plage = Doc.Sheets(0).getCellRangeByName("B1")
    Doc.CurrentController.Select(plage)
     
     
    ' on renseigne les arguments pour le coller spécial
    dim args1(5) as new com.sun.star.beans.PropertyValue
     
     
    ' Flags :  A=Tout VSD=Valeurs T=Formats F=Formules VSDT=Valeurs&Formats
    args1(0).Name = "Flags"
    args1(0).Value = "A"
     
     
    'FormulaCommand : 0=aucune 1=addition 2=soustraction 3=multiplication 4=Division
    args1(1).Name = "FormulaCommand"
    args1(1).Value = 1          '1 : on additionne les valeurs de la plage de départ à celle d'arrivée
    args1(2).Name = "SkipEmptyCells"
    args1(2).Value = false
    args1(3).Name = "Transpose"
    args1(3).Value = false
    args1(4).Name = "AsLink"
    args1(4).Value = false
    args1(5).Name = "MoveMode"
    args1(5).Value = 4
    Dispatcher.executeDispatch(Frame, ".uno:InsertContents", "", 0, args1())
    end sub