Macro tableur

Introduction aux macros et au BASIC initiation aux macros avec Calc

Les macros permettent d’automatiser simplement des séquences de commandes, mais aussi de programmer des comportements complexes et spécifiques. Trois exemples pour comprendre, du très simple au (relativement) compliqué.

Ce tutoriel est proposé sous Calc, mais les macros sont utilisables de façon équivalente avec les autres outils de la suite bureautique LibreOffice / Apache OpenOffice. Toutefois, l’enregistreur de macros n’est apparemment disponible qu’avec Calc et Writer.


Nous proposons cette formation professionnelle : Formation aux macros tableur avec LibreOffice Calc


Une macro simple : automatiser des séquences de commandes

Principe :
- appliquer un style précis, le "gras rouge souligné",
- aller dans le menu Outils / Macros / Enregistrer une macro,
- apparaît un bouton "Terminer l’enregistrement". Tout ce qui est fait jusqu’à la pression du bouton est enregistré,
- sur une case contenant du texte, "mettre le fond en rouge", "souligner" (Ctrl+U), "mettre en gras" (Ctrl+G), puis "Terminer l’enregistrement",
- on peut alors enregistrer la macro, dans un module précis, et lui attribuer un nom,
- pour exécuter la macro sur une nouvelle case, faire Outils / Macros / Exécuter la macro,
- enfin, sélectionner les modules où la macro est enregistrée, puis la macro. Ça devrait marcher.

Premier pas en BASIC : afficher un texte dans une boîte de dialogue

Une macro est un morceau de code en langage BASIC, qui a pour but d’exécuter une tâche précise. On ne s’en rend pas compte quand on utilise l’enregistreur, mais le résultat est le même (l’enregistreur se contente de générer automatiquement le code BASIC correspondant à la séquence donnée par l’utilisateur).

Programmation d’une macro très simple

- Faire Outils / Macros / Gérer les macros / LibreOffice Basic... (ou OOo Basic...),
- dans la barre en haut à gauche (là où est le focus), donner un nom à la macro et sélectionner "Nouveau". Noter le classement en module,
- cela ouvre l’IDE (Integrated Development Environment ou Environnement de développement intégré) pour faire des macros. La syntaxe est :

Sub NomMacro
        <espace vide>
End Sub

Les commentaires commencent par REM ou ’ et permettent de saisir des informations qui ne seront pas interprétées. Cela est indispensable pour permettre de suivre le déroulement du programme pour un programmeur.

Programmer l’exemple suivant :

Sub MaMacro
        MsgBox "Hello World!", 16, "Hello!"
End Sub

MsgBox : fonction pour afficher une boîte de dialogue, trois arguments :

  1. le texte à afficher dans la boîte,
  2. le type de la boîte, somme de puissance de 2 (ici, 16 = boîte d’alerte),
  3. le titre de la boîte.

On enregistre, puis on valide tout.
Ensuite, faire Outils / Macros / Exécuter la macro. On choisit alors la macro qui est classée dans le module que l’on a demandé au début. Cela devrait marcher.

Automatiser l’appel de la macro avec un bouton dans le menu
- Faire Outils / Macros / Gérer les macros,
- assigner,
- choisir l’onglet Menus et rajouter une entrée pour la macro que l’on veut. Tester.

Automatiser l’appel de la macro avec un raccourci clavier
- Faire Outils / Personnaliser...,
- aller dans l’onglet "Clavier".

Automatiser l’appel de la macro avec un bouton sur la feuille
- Aller dans l’onglet “Contrôles de formulaire”,
- dessiner un bouton,
- faire un clic droit, puis “Contrôle”,
- assigner la macro à "Pendant le déclenchement",
- cliquer sur l’icône “(Dés)activer le mode Conception”,
- enfin cliquer sur le bouton pour tester.

Programmation BASIC : un jeu du nombre mystérieux.

Principe du jeu : l’ordinateur calcule un nombre entre 0 et X (X au choix). En un nombre limité de coups (paramétrable), l’humain doit deviner le numéro, l’ordinateur ne lui disant que "le nombre mystérieux est supérieur à celui-là" ou "le nombre mystérieux est inférieur à celui-là" (ou "Perdu" ou "Gagné").

Nous aurons besoin de deux macros. Une macro pour initialiser la partie (tirant au sort un nombre en fonction de la difficulté donnée, remettant le compteur de coups restants au maximum). Pour cela, nous aurons besoin (cf. le document joint) :
- en position C1, la difficulté (le X de "entre 0 et X"),
- en position C2, le nombre d’essais autorisés,
- en position C3, le nombre mystérieux, calculé par l’ordinateur (dans un vrai jeu, on ne l’affichera pas, évidemment),
- en position C4, le nombre de coups restants, réinitialisé en début de partie.

La seconde macro vérifiera une entrée de l’utilisateur, la comparera avec le nombre mystérieux, affichera le résultat en conséquence. Elle devra aussi gérer la victoire ou la défaite du joueur (les deux conduisant à une réinitialisation du jeu, c’est-à-dire à un rappel de la première macro).
Nous aurons besoin, en position D7, de la proposition du joueur.

Nous assignerons chaque macro à un bouton sur la grille.

La première macro doit être étudiée soigneusement et expliquée par l’enseignant. La deuxième devrait être plus facile, même si elle fait beaucoup plus de choses. Notez que le code est commenté et indenté pour plus de lisibilité. Copié dans l’éditeur BASIC de LibreOffice / Apache OOo, le code est automatiquement coloré en fonction de la syntaxe.

Première macro : initialisation

Sub JNM
        ' Le jeu du nombre mystérieux : initialisation
        ' Déclaration des variables : Dim MaVariable as Type
        ' Le nombre mystérieux, un entier
        Dim iNombMyst as Integer
        ' Les accès aux documents / cases du tableau : des objets
        Dim oDocument As Object, oSheet As Object, oNM As Object, oDiff As Object, oRestant As Object

       
        ' On récupère le contexte du document actuel et de la feuille1
        ' c'est le genre de ligne à copier-coller
        oDocument=ThisComponent
        oSheet=oDocument.Sheets.getByName("Feuille1")

        ' On récupère les paramètres dans les cases de la feuille
        oDiff=oSheet.getCellByPosition(2,0)

        ' On calcule le nombre mystérieux
        iNombMyst = Int(Rnd * oDiff.getValue())
        ' On le stocke dans une case, mais chut ! ne pas le dire à l'utilisateur.
        oNM=oSheet.getCellByPosition(2,2)
        oNM.setValue(iNombMyst)
        ' Coups restants : (ré)initialisation
        oRestant=oSheet.getCellByPosition(2,3)
        ' Ici, on enchaîne les commandes pour gagner de la place
        ' c'est équivalent à :
        ' oEssai = oSheet.getCellByPosition(2,1) ' On récupère l'objet en case C2
        ' iEssai = oEssai.getValue()             ' on récupère la valeur de l'objet précédent
        ' oRestant.setValue(iEssai)              ' on l'assigne en case C4
        oRestant.setValue(oSheet.getCellByPosition(2,1).getValue())
        ' On réutilisera cette astuce par la suite pour éviter d'avoir à manipuler trop de variables
End Sub

Deuxième macro : un tour de jeu

Sub Jouer
        ' Une partie de nombre mystérieux.
        Dim iNombMyst as Integer, iProp as Integer
        Dim oRestant as Object, oDocument As Object, oSheet As Object
        ' On récupère le contexte du document actuel et de la feuille1
        oDocument=ThisComponent
        oSheet=oDocument.Sheets.getByName("Feuille1")
       
        ' On récupère les paramètres dans les cases de la feuille
        ' Nombre de coups restants
        oRestant=oSheet.getCellByPosition(2,3)
       
        ' Nombre mystérieux
        iNombMyst=oSheet.getCellByPosition(2,2).getValue()
        iProp=oSheet.getCellByPosition(3,6).getValue()
       
        ' Début du test :
        ' on enlève un coup
        oRestant.setValue(oRestant.getValue() - 1)
        ' on compare ce que l'utilisateur a mis avec le nombre mystérieux
        If iProp = iNombMyst Then
                MsgBox "Vous avez gagné !!", 1, "Gagné :)"
                ' On réinitialise
                JNM
        ElseIf iProp < iNombMyst Then
                MsgBox "Le nombre mystérieux est plus grand que ça", 1, ""
                if oRestant.getValue() = O Then
                        MsgBox "Plus de coups restants, vous avez perdu", 1, "Perdu :("
                        ' On réinitialise le jeu en appelant la macro précédente
                        JNM
                EndIf               
        Else ' Plus qu'un choix possible...
                MsgBox "Le nombre mystérieux est plus petit que ça", 1, ""
                if oRestant.getValue() = O Then
                        MsgBox "Plus de coups restants, vous avez perdu", 1, "Perdu :("
                        ' On réinitialise le jeu en appelant la macro précédente
                        JNM
                EndIf
        EndIf
End Sub