Programmez Office Excel Avec VBA
Programmez Office Excel Avec VBA
Programmez Office Excel Avec VBA
Vous êtes un utilisateur averti de Word et d'Excel ? Vous avez souvent entendu parler de VBA, ce fameux langage de
programmation qui permet de décupler la puissance de vos logiciels favoris ? Vous êtes tombé juste ! Grâce à VBA
(Visual Basic pour Applications), vous allez pouvoir automatiser plein de choses, et devenir encore plus productif.
Il faut savoir que Visual Basic est décliné en de nombreuses variantes : Il existe Visual Basic "Pur et Dur", qui est un
langage de programmation commercialisé tel quel, et qui est vraiment destiné aux développeurs professionnels. Ensuite,
Microsoft a intégré ce Visual Basic au sein de ses applications phaes : a savoir Office. Aussi, il existe Visual Basic pour
Word, pour Excel, Pour Access, pour PowerPoint et pour Outlook. Pourquoi y a-t-il autant de variantes ? Simplement
parce que chaque programme a ses spécificités : En effet, Word n'a nul besoin d'une commande de création de nouvel
onglet spécifique à Excel, Excel, n'a nul besoin de comamndes Visual Basic permettant de créer un nouveau Courrier
(spécifique à Outlook), et ainsi de suite. Par contre, certaines instructions, comme le MsgBox par exemple, qui permet
d'afficher un court message à l'écran, est, lui, présent dans tous les Visual Basic que vous rencontrerez.
Au début de votre apprentissage, nous allons commencer par aborder les principes de programmation identiques dans
tous les Visual Basic, aussi, peu importe le programme que vous allez utiliser (Word, Excel, Access, Powerpoint ou
Outlook). Cependant, pour des raisons de pédagogie et de pratique, certains chapitres sont plutôt effectués avec Word,
surtout en début d'apprentissage, et, petit à petit, nous allons principalement nous tourner vers Excel, pour étudier son
VBA plus en profondeur. Pourquoi cette préférence ? Simplement parce qu'il s'avère qu'Excel est habituellement le
programme pour lequel on désire le plus vite et le plus possible se tourner vers sa programmation.
Première approche
Que sont les objets ? Exemple du téléphone portable - Qu'entend-on exactement par "Programmation
Orientée Objet" ? ou POO. Tout vous est expliqué
Qu'est-ce qu'un programme et à quoi sert-il ? - Un peu de théorie avant de commencer
Votre première macro Excel - Avant de vous plonger dans les arcanes de la programmation avancée
(VBA EXCEL)
Attacher une macro à une icône d'une barre d'outils - Afin de pouvoir appeler votre macro d'un
simple clic plutôt que d'aller dans Outils/Macros/Macros
Les variables et les constantes
Les tableaux
Utilisation de la fonction InputBox et du & (Et commercial)
Calcul mental - Ou comment partir d'un petit programme pour en faire un gros
Les boucles
Les boucles DO, LOOP, WHILE et UNTIL
Affichage d'un certain nombre de fois "Bonjour" à l'écran (Do While, Until, Loop, TypeText,
TypeParagraph)
Chaînes de caractères
Traitement de chaînes de caractères (Left, Right, Mid, Len, Chr)
1
Comptage du nombre de voyelles d'une phrase
Réécriture d'une phrase à l'envers
Par exemple, éviter un message d'avertissement lorsque vous effacez une feuille de calcul dans
EXCEL :
Application.DisplayAlerts = False
ActiveWindow.SelectedSheets.Delete
Application.DisplayAlerts = True
Quelle est la différence entre Sheets et WorkSheets ? En fait, Sheets contient toutes les feuilles,
même les graphiques ou les Macros Excel 4 (En fait, tout ce que vous pouvez insérer quand vous
cliquez avec le bouton droit sur un onglet et que vous choisissez "Insérer..."). Tandis que
WorkSheets ne parcourt QUE les feuilles "Normales"
Sub Feuille()
For Ctr = 1 To Sheets.Count
MsgBox Sheets(Ctr).Name
Next
End Sub
Sub FeuilleTravail()
For Ctr = 1 To Worksheets.Count
MsgBox Worksheets(Ctr).Name
Next
End Sub
Gestion des fonctions intégrées d'Excel dans VBA - Il est très possible d'écrire des fonctions
intégrées d'Excel dans des cellules depuis VBA, encore faut il avoir une syntaxe correcte.
Gestion des plages de cellules - S'y déplacer, aller a ses limites, compter ses cellules, lignes,
colonnes (CurrentRegion et consorts)
Créez votre premier complément Excel .XLA - Mettez à disposition vos procédures et fonctions à
toute votre entreprise
Calculez les notes sans les extrêmes - Vous avez déjà vu les compétitions sportives à la télé ? Les
juges notent, mais on exclut les notes les plus hautes et les plus basses
2
Sélection de cellules - Comment sélectionner la première ou la dernière cellule, ou ligne ou colonne
d'un tableau donné
Ecriture, sélection, déplacement dans les cellules - Cette section explique comment écrire quoi que
ce soit dans la ou les cellules de votre choix, qu'il s'agisse de la feuille courante ou d'une autre, d'un
autre classeur, ou même d'un calcul
Gestion des onglets - Comment les déplacer, supprimer, renommer...
Les événements de feuilles et de classeurs - Ou l'art de savoir non seulement ce que Visual Basic va
faire, mais QUAND il va le faire
Les autres événements - On peut demander à VBA d'exécuter quelque chose à une heure précise, ou
dans quelques muinutes, ou lorsqu'on fait Edition/Annuler
Où les macros sont-elles stockées ? - Il est bien de savoir quels sont les endroits possibles pour
ranger ses macros, car ça va déterminer quand elles seront utilisables
3
Raccourcis clavier
On peut assigner des raccourcis clavier aux macros. Pour ce faire, allez dans le menu
Outils/Macros/Macros, choisissez la macro qui vou intéresse, et cliquez sur le bouton "Options", en
bas à droite. Assignez une lettre minuscule, par exemple s. Cliquez sur OK, et Annuler (car il n'y a
pas de bouton OK). Maintenant, lorsque vous appuyez sur CTRL s, Excel exécute la macro au lieu
d'enregistrer le classeur (CTL s étant le raccourci de Fichier/Enregistrer). Vous l'avez donc
"Supplanté". La plupart des lettres et chiffres sont déjà utilisés par Excel en fait. Pour éviter
l'écrasement, lorsque vous attribuez un raccourci clavier à une macro, utilisez une lettre
MAJUSCULE, par exemple S. Comme ça, CTRL s, ce sera "Enregistrer", et CTRL SHIFT s, ce sera
l'appel à votre macro. Attention : il n'y a pas moyen facile d'avoir la liste de tous vos raccourcis
claviers assignés aux macros, ce qui fait que si vous attribuez le même raccourci clavier à deux
macros différentes, Excel ne donnera PAS de message d'erreur, mais lorsque vous utiliserez votre
raccourci clavier, ce sera la macro la première dans l'ordre alphabétique qui sera exécutée !
Les macros complémentaires - Enrichissez Excel grâce à des outils pointus et puissants qui ne sont
pas installés par défaut
Création de ses propres fonctions - Bien qu'il existe des centaines de fonctions Excel (Romain, Max,
Min, Somme, ...), vous avez la possibilités de créer vos propres fonctions personnelles
(CalculeSurface, TransformeMilesKMH, MultiplieParTrois, etc...)
Traduction des fonctions Français>Anglais - Dans Excel, on peut écrire =SOMME(A1:A6), mais
quand on fait appel à une fonction Excel en VBA, on doit utiliser l'expression anglaise... C'est
comme ça. C'est en cela que cette liste va vous être utile
Formules et valeurs : Comment insérer des formules ou des valeurs avec des références absolues ou
relatives dans les cellules ?
Utilisation dans VBA des fonctions Excel : Somme, Moyenne, Max, Min, etc. Il est possible de les
utiliser en programmation grâce à WorkSheetFunction
Création d'une petite application (recherche des diviseurs d'un nombre) - Utilisation des boîtes de
dialogues personnalisées pour un cas concret
Conseils d'optimisation - Si votre code se comporte mal, ou est particulièrement lent, il est temps de
penser à l'optimiser
Le saviez-vous ? Lorsque vous allez dans Outils/Macros complémentaires et que vous cochez la case
"Utilitaires d'analyse", ça ajoute un complément "FuncRes.XLA", que vous pouvez voir dans
l'environnement VBA (Alt-F11), mais il est protégé par mot de passe. Celui ci est : Wildebeest!!
Mais il n'y a pas de module VBA visible... c'est magique... Ce mot de passe est le même pour tous les
compléments XLA disponibles.
4
VBA Word seulement
Apprenez a faire votre première MacroWord - a vec l'enregistreur de macro bien pratique (VBA
WORD)
Exécutez du code VBA WORD lors d'événements tels que Print ou Save Comment créer des
événements non inclus à la base dans Word
Pourrissez la vie des spammeurs - Les spammeurs recherchent les adresses e-mails sur tout le web.
Ce petit programme vous aide à générer une immense page HTML pleine d'adresses e-mails
invalides
Sub ListeDesImprimantesInstallees()
For Ctr = 0 To Application.Printers.Count - 1
Debug.Print Application.Printers(Ctr).DeviceName
Next
End Sub
Ecrire dans le bloc-notes depuis Excel. On lance l'application Notepad.exe, et on y écrit abc. Ensuite
on sauvegarde et on ferme : (Attention : ca ne marche pas avec la touche F5 dans l'éditeur VBA,
mais seulement en lançans la macro depuis Outils/Macros/Macros :
Sub EcrireBlocNote()
' Lancement du bloc-notes :
AppActivate Shell("Notepad.exe", vbNormalFocus)
' Ecrire abc dans le bloc-notes
SendKeys "abc"
' CTRL S pour sauver :
SendKeys "^s"
SendKeys "D:\Atelier\teste.txt"
' Comme si on cliquait sur OK :
SendKeys "{ENTER}"
' Quitter le bloc notes avec ALT F4 :
SendKeys "%{F4}"
End Sub
Utilisez l'assistant : Ce petit personnage sur votre programme Office (Le petit trombonne ou le petit
Einstein). On peut leur faire dire ce qu'on veut :
5
Sub UtiliserAssistant()
With Assistant.NewBalloon
.BalloonType = msoBalloonTypeNumbers
.Icon = msoIconTip
.Button = msoButtonSetOK
.Heading = "Astuces pour travailler en
sécurité"
.Labels(1).Text = "Enregistrez souvent
(CTRL S)"
.Labels(2).Text = "Installez un pare feu"
.Labels(3).Text = "Fermez Windows
correctement"
.Show
End With
End Sub
Les raccourcis clavier - Comment appeler une macro avec une touche, utilisation de
Application.OnKey
Le panneau de configuration (Application.International) - Il peut être très intéressant de connaître le
séparateur décimal (Point ou virgule), les séparateurs de date (point ou /), etc
L'explorateur d'objets - Les propriétés, méthodes, constantes sont innombrables dans Excel. Voyez
ici une vue panoramique de l'explorateur d'objets
Accès à la base de registre - Si vous voulez sauvegarder des informations générales sur la
configuration de votre programme
Les macros complémentaires : Emplacement, utilisation
si vous voulez afficher le contenu d'une variable, ou bien "Vide" si sa valeur est nulle il suffit de
faire :
Nz(LaVariable, "vide")
Les fonctions de conversions de type : Integer, Single, String, Texte, Monnaie, Booléen...
Interaction avec Access : Notamment accès depuis Excel à des .MDB d'Access via DAO,
Importation...
Créer automatiquement un raccourci sur le bureau
Conversion de nombres décimaux en binaires, et de binaires en nombres décimaux
Extraction d'une chaîne de caractères dans une autre chaîne
Calcul de temps pour des heures supérieures à 24 heures
6
Exécutez une procédure à une heure précise
Admettons que vous ouvriez une feuille Excel qui restera ouverte toute la journée, mais qu'à 16:00,
Excel doit vous rappeler que vous avez rendez-vous chez le coiffeur :
Rendez-vous dans la macro qui s'exécute automatiquement à l'ouverture de votre classeur (Besoin
d'aide ?)
Créez ensuite un nouveau module dans lequel vous créez la macro Dentiste. Elle s'exécutera une
heure après que le fichier se soit ouvert :
Sub Coiffeur()
MsgBox "N'oubliez pas votre rendez-vous chez le coiffeur"
End Sub
Exportation de données Access dans Excel, et envoi par e-mail - Ou comment créer un fichier Excel
avec des données en provenance de tables ACcess, en utilisant Outlook
Envoyez des E-Mails en série - Une base de données Access, Outlook, et c'est parti !
Listes de diffusion - Accédez à Outlook depuis Access via VBA
Pilotez Word depuis Excel - Attention : Pour utilisateurs de VBA confirmés seulement ! C'est ce
qu'on appelle l'OLE automation
Pilotez PowerPoint depuis Excel - Ou n'importe quel autre programme d'Office
Utilisation de For ... Each - Cette instruction de permet de parcourir une collection d'objets
simplement
Céation de ses propres collections - Les Collections sont plus souples et plus puissantes que les
tableaux
Les modules de classe - Property Get, Let, Set, comment ça marche ?
Création de ses propres types - Suivis des tableaux de types, et collections de types personnalisés
Fonctions personnalisées prêtes à l'emploi - Apprenez comment créer des fonctions personnalisées
vraiment pratique, et améliorez celles qui sont ici pour votre propre emploi
Récupérer le numéro de série du disque dur - Pour par exemple empêcher le piratage d'un
programme
7
Afficher la résolution de l'écran
Boîtes de dialogues personnalisées - Boutons, listes déroulantes, zones de textes, dans une feuille de
calcul
Utilisation de boîtes de dialogues personnalisées - Il est parfois bien pratique de créer des boîtes de
dialogues personnalisées. Exemple : Outils/Solveur est un bon exemple de boîte de dialogue
personnalisée
Les objets de la boîte à outils pour les boîtes de dialogues personnalisées - Zones d'édition, listes
déroulantes, boutons, etc.
Boîtes de dialogues personnalisées : Création, utilisation, UserForm, Show, Zones d'édition
Boîtes de dialogues intégrées : comment faire apparaître par exemple la boîte Fichier/Ouvrir par
exemple. Choix d'un fichier de manière conviviale, GetSaveAsFileName
Petite astuce pour demander à une Macro d'attendre 4 secondes avant de continuer :
Application.Wait Now + TimeValue("0:00:04")
MsgBox "Terminé"
8
Microsoft Excel
Excel est le très puissant et convivial tableur de Microsoft. C'est grâce à lui que des milliers
d'entreprises s'appuient pour faire leurs comptes, statistiques, listes, et autres graphiques et
tableaux. Adoré par les uns pour sa puissance, détesté par les autres pour son apparente
complexité, Excel devient votre plus fidèle allié pour peu que vous vous initiez à ses finesses. Avec
un minimum de maîtrise, vous serez à même de concevoir, trier, mettre en page de grandes listes de
n'importe quoi, établir des factures, créer de splendides graphiques qui reflètent l'état de santé de
votre entreprise, et des milliers d'autres choses que vous pouvez à peine imaginer... Avec Excel, le
seul problème, c'est que vous risquez de ne bientôt plus pouvoir faire une addition à la main !
Je me suis amusé à programmer des petites puces de couleur qui se déplacent aléatoirement dans leur
zone. Arriveront-elles à empiéter sur le territoire des autres puces en passant par le milieu ? C'est ici,
ça ne sert à rien, mais c'est rigolo !
1. Ouvrez Excel. Vous êtes dans la cellule A1 d'un nouveau classeur. C'est très bien
2. Faites Outils/Macros/NouvelleMacro
3. Nom de la macro : BeauTemps (PAS D'ESPACE entre Beau et Temps)
4. Enregistrer la macro dans : Ce classeur
5. Cliquez sur OK
ATTENTION : Maintenant, vous êtes en train d'enregistrer votre macro. C'est comme
si vous étiez dans un studio d'enregistrement, LA MOINDRE CHOSE que vous faites,
ne fut-ce que de cliquer dans une autre cellule que A1 sera enregistré. Donc : Dès
maintenant, vous faites EXACTEMENT ce qui suit.
6. Ecrivez Il y a du soleil
7. Cliquez sur le petit V, à gauche de la barre de formule, pour valider votre texte (à la place
d'appuyer sur ENTER)
8. Faites Outils/Macros/Arrêter l'enregistrement
Voilà. Vous pouvez respirer, la macro est terminée ! Nous allons maintenant passer à l'exécution de
la macro :
9
Etape 2: Exécution de la macro BeauTemps
Et voilà : Si tout s'est bien passé, vous devriez voir apparaître en B2 Il y a du soleil
Si vous avez eu un problème quelconque, je vous conseille de quitter Excel, ne pas sauvegarder
votre document, revenir dans Excel, et recommencer intégralement le tout depuis le point 1 de
l'étape 1.
Si tout s'est bien passé, passons à l'étape 3, à quoi cette macro ressemble-t-elle ?
'
ActiveCell.FormulaR1C1 = "Il y a du soleil"
End Sub
Voilà à quoi ressemble votre macro BeauTemps : Toutes les macros commencent par Sub
NomDeLaMacro, et se terminent par End Sub. C'est une règle. Les lignes qui commencent par une
apostrophe (') en vert sont des commentaires, ce sont simplement des lignes qui sont ignorées par
Visual Basic. Et pour écrire du texte dans une cellule, vous le voyez vous même : C'est
ActiveCell.FormulaR1C1 = "Un texte quelconque"
Maintenant que vous êtes arrivés ici, passons à l'étape suivante qui consite à modifier une macro
existante
10
Etape 4 : Modification d'une macro existante
Admettons que notre macro BeauTemps ne doit pas afficher Il y a du soleil, mais plutôt Le ciel est
bleu. C'est très simple :
Si tout s'est bien passé, vous devriez voir Le ciel est bleu dans la cellule C3.
Continuons notre petit bonhomme de chemin, et créons une macro de toutes pièces nous même
Imaginons une macro qui s'appelle Ski, qui qui affiche J'aime les sports d'hiver
End Sub
4. Maintenant, dans cette procédure, ajoutez la ligne de commande suivante pour écrire
J'aime les sports d'hiver : activeCell.FormulaR1C1 = "J'aime
les sports d'hiver"
5. Voici le résultat que vous devez obtenir :
Sub BeauTemps()
'
' BeauTemps Macro
' Macro enregistrée le 16.12.2000 par Michel
'
11
'
ActiveCell.FormulaR1C1 = "Le ciel est bleu"
End Sub
Sub Ski()
ActiveCell.FormulaR1C1 = "J'aime les sports d'hiver"
End Sub
Nous allons tester cette macro : Cliquez dans une cellule quelconque encore vide (D4 par exemple),
et faites Outils/Macros, et cliquez 2 fois sur Ski. Normalement, vous devriez voir apparaître dans la
cellule D4 J'aime les sports d'hiver
Vous voilà maintenant initié au grand monde de la parogrammation visual basic pour Excel.
Nous allons compléter le tout par un petit exercice pratique : Nous allons créer une macro toute
simple qui efface toute la feuille de calcul, et qui se positionne sur la cellule A1, comme on
effacerait un tableau noir. Avant de commencer cette macro, il faut identifier les étapes.
D'abord, "Salissez" un peu votre feuille de calcul : Ecrivez du texte dans certaines cellules, coloriez
en d'autres en différentes couleurs... Attention donc, je vous rappelle que pour effacer la coloration
d'une cellule, la touche DELETE ne fonctionne pas, il faut faire Edition/Effacer/Tout.
Bien. Maintenant que votre feuille est "Salie", faisons une répétition générale de ce que doit faire la
macro :
Normalement, vous devriez être dans la cellule A1 d'une feuille immaculée... Resalissez cette pauvre
feuille (Ecrivez du texte et coloriez quelques cellules). Après cela, nous allons faire la même chose
que tout à l'heure, mais en enregistrant la macro qui va faire toutes ces étapes. C'est parti :
12
Voilà. La macro est fin prête. Resalissez encore une fois la feuille (vous commencez à avoir
l'habitude), et faites Outils/Macros, et cliquez 2 fois sur EffacerTout... Si tout se passe comme prévu,
la feuille doit s'effacer automatiquement, et vous devriez vous retrouver sur A1...
Je pense que vous savez comment faire pour aller visualiser cette macro qui doit ressembler
exactement à ceci :
Sub EffacerTout()
'
' EffacerTout Macro
' Macro enregistrée le 16.12.2000 par Michel
'
'
Cells.Select
Selection.Clear
Range("A1").Select
End Sub
Aménageons-là : Supprimez les commentaires (qui ne nous servent pas à grand chose...
L'enregistreur de macros fait parfois de l'excès de zèle):
Sub EffacerTout()
Cells.Select
Selection.Clear
Range("A1").Select
End Sub
Et indentez le code. Indenter signifie simplement mettre tout ce qui est entre Sub EffacerTout et End
Sub en retrait, pour faciliter la lisibilité. Pour l'instant, vous pouvez ne pas comprendre l'utilité, mais
par la suite, vous verrez que c'est très pratique :
Sub EffacerTout()
Cells.Select
Selection.Clear
Range("A1").Select
End Sub
Et voilà... Sans être des pros de VBA, vous pouvez déjà deviner pas mal de choses. Allez, je ne vous
donne pas la solution, à votre avis, quel signifie Cells.Select ? et Selection.Clear ? Et
Range("A1").Select ? C'est facile, n'est ce pas !...
13
Que sont les objets ? Exemple du téléphone portable
VBA est un langage orienté objets. C'est à dire qu'il fonctionne avec des objets qui ont des
propriétés et des méthodes. Pour mieux comprendre, faisons un rapprochement avec un téléphone
portable. C'est un objet. Cet objet à plusieurs propriétés : Par exemple, il est noir. On dit que sa
propriété Couleur = Noir. On l'écrirait : TéléphonePortable.Couleur = Noir. Si on voulait
l'afficher avec un MsgBox, on dirait
Nous pourrions imaginer que nous pouvons repeindre ce téléphone., en rose par exemple. Nous
dirions alors :
Maintenant, nous imaginons que nous avons beaucoup de propriétés pour notre téléphone portable :
La couleur, La marque, Le poids, Le Style d'ouverture, S'il est étanche... Voici comment nous le
construirions :
L'une de ces propriétés est utilisée plus fréquemment que les autres. Par exemple, la couleur. Alors,
dans ce cas, si nous le savons, au lieu d'écrire
14
TéléphonePortable.Couleur =
ActiveCell.Value = "Bonjour"
"Gris"
Nous pourrions nous permettre d'écrire
TéléphonePortable = "Gris" Activecell = "Bonjour"
Ce téléphone portable a certaines propriétés, mais il possède également d'autres objets : Comme par
exemple l'antenne, ou les touches, ou même la batterie. Ce sont des objets qui tout en faisant partie
intégrante du téléphone portable sont malgré tout des objets "indépendants". On pourrait avoir un
téléphone noir, mais avec une antenne grise par exemple. Nous dirions alors :
Tout ce dont nous venons de parler sont des propriétés. Maintenant, il y a des méthodes. Ce sont des
actions. C'est bien beau d'avoir un téléphone portable, mais s'il ne peut rien faire, ce n'est pas très
intéressant. Par exemple, nous avons la possibilité de l'allumer. On dirait alors :
On ne dit pas TéléphonePortable.Allume = Quelque chose. On dit juste Allume, c'est tout. On dit
que Allume est une méthode de TéléphonePortable. Maintenant, on peut bien entendu imaginer une
propriété Allumé, comme ceci :
Maintenant, le plus intéressant avec un téléphone portable est de pouvoir appeler quelqu'un. Nous
allons utiliser une méthode Appelle, comme ceci :
C'est bien joli... Mais QUI doit-il appeler ? Et bien nous avons besoin d'un paramètre, c'est le numéro
de téléphone à appeler :
15
Et, nous avons d'autres possibilités quand nous appelons.
- Nous pouvons indiquer le préfixe 079, ou pas, ça dépend,
- Nous pouvons même faire un préfixe international : 0041 par exemple,
- et nous laissons sonner un certain nombre de coups.
Appelle est donc une méthode avec plusieurs paramètres. Nous l'appelons comme ceci :
On n'est pas obligé de dire a quoi correspondent les paramètres, même si c'est plus clair de les
mettre. La ligne suivante fonctionne ausi bien :
Dans le cas ou le préfixe est "par défaut" 079, c'est à dire que si on nme le précise pas c'est ce qu'il
fait, et que le 0041 est aussi "par défaut", alors, on peut se permettre de les omettre, il en tiendra
compte, mais il faut mettre les virgules pour préciser quels paramètres on désire vraiment préciser :
Pareil pour le nombre de coups. Si, par défaut, il laisse sonner 5 coups avant de raccrocher, et que
c'est justement ce qu'on veut, alors, on peut l'omettre, et il ne faut pas mettre de virgule si les
paramètres sont à la fin de la ligne :
TéléphonePortable.Appelle , , "555.666", 17
16
De la même façon qu'on peut avoir plsieurs feuilles de calcul sous Excel, vous pouvez avoir
plusieurs téléphones portables. Si vous ne le précisez pas, le téléphone portable actuellement dans
votre poche (Activé) est utilisé.
On pourrait vouloir repeindre le téléphone portable qui se trouve dans la chambre. On dirait comme
ceci :
On a la possiblité de raccourcir cette syntaxe. Par exemple, en donnant un petit nom à son téléphone
de la chambre. Par exemple, au bureau, vous pourriez dire à votre secrétaire:
"Pouvez-vous me composer le 55.66.77.88, avec le téléphone portable qui se trouve dans ma veste
grise ?"
De la même façon que dans le langage courant, vous ne dites pas : Mon téléphone portable est noir,
Mon téléphone portable à une antenne de 5 centimètres, Mon téléphone portable pèse 160
grammes... Non, vous dites : Mon téléphone portable est noir, a une antenne de 5 centimètres, et
pèse 160 grammes.
17
TéléphonePortable("CeluiDuTravail"
) .Value = "Salut"
.Couleur = Noir .Font.UnderLine = True
.Antenne.Longueur = 5 .Orientation = xlVertical
.Poids = 160 End With
End With
Calcul mental
Version 1: Il s'agit de choisir un nombre au hasard :
Option Explicit
' Affichage d'un message de bienvenue et d'un message d'au revoir
Sub CalculMentalV1()
MsgBox "Bienvenue dans le programme de calcul mental"
MsgBox "Merci d'avoir joué"
End Sub
Sub CalculMentalV2()
Dim Nombre1
Randomize ' Cette instruction permet simplement d'assurer qu'à
chaque lancement du programme,
' Le nombre aléatoire sera toujours différent
MsgBox "Bienvenue dans le programme de calcul mental"
Nombre1 = Rnd
MsgBox Nombre1
MsgBox "Merci d'avoir joué"
End Sub
En fait, il faut le transformer d'un nombre au hasard entre 0 et 1 en nombre au hasard entre 1 et
100 (100 par exemple)
Sub CalculMentalV3()
Dim N1
Randomize
MsgBox "Bienvenue dans le programme de calcul mental"
N1 = Rnd ' 0.9963265412 - Nombre au hasard entre 0 et 1
N1 = N1 * 100 ' 99.63265412 - Le même nombre * 100
N1 = N1 + 1 ' 100.63265412 - Le même nombre + 1 (sinon ce serait
un nombre au hasard entre 0 et 99)
18
N1 = Int(Hasard) ' 100 ' On supprime toutes les décimales pour
avoir un nombre entier
MsgBox N1
MsgBox "Merci d'avoir joué"
End Sub
Il est possible de compresser la génération du nombre aléatoire en une seule ligne de code qui est
plus difficile à comprendre mais qui permet un programme plus compact
Sub CalculMentalV4()
Dim N1
Randomize
MsgBox "Bienvenue dans le programme de calcul mental"
N1 = Int((100 * Rnd) + 1)
MsgBox N1
MsgBox "Merci d'avoir joué"
End Sub
En fait, ce n'est pas un seul nombre que nous avons besoin, mais 2
Sub CalculMentalV5()
Dim N1, N2
Randomize
MsgBox "Bienvenue dans le programme de calcul mental"
N1 = Int((100 * Rnd) + 1)
N2 = Int((100 * Rnd) + 1)
MsgBox "N1 égale " & N1
MsgBox "N2 égale " & N2
MsgBox "Merci d'avoir joué"
End Sub
Sub CalculMentalV6()
Dim N1, N2
Randomize
MsgBox "Bienvenue dans le programme de calcul mental"
N1 = Int((100 * Rnd) + 1)
N2 = Int((100 * Rnd) + 1)
' Utilisation astucieuse des & :
Reponse = InputBox("Combien font " & N1 & " + " & N2 & " ?")
MsgBox "Merci d'avoir joué"
End Sub
Et maintenant, on vérifie si l'utilisateur a entré la bonne réponse : Cette version dit que
l'utilisateur a entré une fausse réponse même si elle est correcte Je pense que c'est parce que N1
et N2 n'ont pas été déclarés en INTEGER
19
Sub CalculMentalV7()
Dim N1, N2
Dim Reponse ' Stockage de la réponse de l'utilisateur
Randomize
MsgBox "Bienvenue dans le programme de calcul mental"
N1 = Int((100 * Rnd) + 1)
N2 = Int((100 * Rnd) + 1)
Reponse = InputBox("Combien font " & N1 & " + " & N2 & " ?")
If Reponse = N1 + N2 Then
MsgBox "Bonne réponse !"
Else
MsgBox "Désolé... la bonne réponse était " & N1 + N2
End If
MsgBox "Merci d'avoir joué"
End Sub
Sub CalculMentalV8()
' Déclaration des variables correctement
Dim N1 As Integer
Dim N2 As Integer
Dim Reponse ' Stockage de la réponse de l'utilisateur
Randomize
MsgBox "Bienvenue dans le programme de calcul mental"
N1 = Int((100 * Rnd) + 1)
N2 = Int((100 * Rnd) + 1)
Reponse = InputBox("Combien font " & N1 & " + " & N2 & " ?")
If Reponse = N1 + N2 Then
MsgBox "Bonne réponse !"
Else
MsgBox "Désolé... la bonne réponse était " & N1 + N2
End If
MsgBox "Merci d'avoir joué"
End Sub
Maintenant, ce n'est pas un calcul qu'il faut proposer à l'utilisateur, mais 4 : Si on n'utilise pas de
boucle For To Next, on obtient le programme suivant qui ressemble à un mammouth : (Et
encore... on n'a que 4 calculs...)
Sub CalculMentalV9()
Dim N1 As Integer
Dim N2 As Integer
20
MsgBox "Bienvenue dans le programme de calcul mental"
21
Sub CalculMentalV12()
' *******************************
' * Déclaration des variables : *
' *******************************
Dim N1 As Integer ' Premier des deux nombre au hasard
Dim N2 As Integer ' Second des deux nombres au hasard
Dim Reponse As Integer ' Réponse proposée à chaque fois par le
joueur
Dim Compteur As Integer ' Compteur de questions
Dim Score As Integer ' Contiendra le score du joueur (nombre de
réponses correctes)
' ***************************
' *Démarrage du programme : *
' ***************************
Score = 0 ' D'entrée son score est de zéro.
Randomize ' Permet d'assurer que les nombres seront toujours
différents à chaque tirage au sort
MsgBox "Bienvenue dans le programme de calcul mental"
' ***********************
' * Boucle principale : *
' ***********************
For Compteur = 1 To 4 ' Il est facile de remplacer 4 par un autre
nombre...
N1 = Int((100 * Rnd) + 1) ' Génération d'un nombre au hasard N1
N2 = Int((100 * Rnd) + 1) ' Génération d'un nombre au hasard N2
Reponse = InputBox("Combien font " & N1 & " + " & N2 & " ?")
' Si le joueur répond correctement :
If Reponse = N1 + N2 Then
MsgBox "Bonne réponse !"
Score = Score + 1 ' On augmente son score s'il répond bien
Else ' Sinon...
' Sinon, son score ne bouge pas...
MsgBox "Désolé... la bonne réponse était " & N1 + N2
End If
Next ' Fin du For
' **********************
' * Fin du programme : *
' **********************
MsgBox "Merci d'avoir joué. Votre score est de " & Score & " sur
4."
End Sub
Tout programme est améliorable à l'infini. Essayez donc ces quelques améliorations :
22
TRES FACILE
- A la place d'addictions, faire des soustractions, ou des multiplications
FACILE
Demander au joueur son nom, pour personnaliser le message de conclusion :
"Roger, votre score est de 3 sur 4"
FACILE
- Demander au joueur à la base combien d'additions il veut (3, 4, 50 ?)
FACILE
- Demander la difficulté voulue au joueur (Des additions jusqu'à 100 comme ici, ou 500, ou 10000 ?)
ASSEZ FACILE
- Faire des commentaires suivant le score :
"Score de 1 sur 4, Roger, vous êtes NUL !"
Ou
"Score de 4 sur 4, Marcel, vous êtes un génie !"
ASSEZ FACILE
- Afficher les résultats successifs des additions dans Word avec Selection.TypeText et
TypeParagraph
DIFFICILE
- Demander à l'utilisateur s'il veut faire des additions, des soustractions ou des multiplications avant
de commencer le jeu
23
Si vous ne déclarez pas vos variables, elles seront automatiquement Variant.
Il est souvent plus judicieux de les déclarer d'un certain type particulier, d'une
part pour la clarté du code, et d'autre part pour optimiser l'espace mémoire
nécessaire.
Type de données Taille d'enregistrement en octets
Byte 1 0 à 255
Boolean 2 True ou False
Integer 2 -32 768 à 32 767
Long 4 -2 147 483 648 à 2 147 483 647
Single 4 -3,402823E38 à -1,401298E-45 pour les valeurs nég
Double 8 -1,79769313486231E308 à -4,94065645841247E-3
valeurs positives
Currency 8 -922 337 203 685 477,5808 à 922 337 203 685 477
Decimal 14 +/-79 228 162 514 264 337 593 543 950 335 sans s
séparateur décimal ; le plus petit nombre différent de
Date 8 1er janvier 100 au 31 décembre 9999
Object 4 Toute référence à des données de type Object
String (longueur variable) 10 + longueur de la chaîne 0 à environ 2 milliards
String (longueur fixe) Longueur de la chaîne 1 à environ 65 400
Variant (nombres) 16 Toute valeur numérique, avec la même plage de val
Variant (caractères) 22 + longueur de la chaîne Même plage de valeurs qu'une donnée de type Strin
24
Plus compliqué : utilisation de guillemets en cas de constante textuelle :
ActiveCell.Formula = "=LEFT(" & """" & "abricot" & """" & ")"
On peut utiliser cette technique pour obtenir en VBA le résultat d'une fonction intégrée d'Excel :
Range("IV65536").FormulaLocal = "=ROMAIN(22)"
MsgBox ActiveCell.Value
Range("IV65536").Clear
MsgBox WorksheetFunction.Roman(22)
Ou la valeur résultante :
MsgBox ActiveCell.Value
ou
MsgBox ActiveCell
25
3 cellules plus haut, même colonne :
ActiveCell.FormulaR1C1 = "=Roman(R[-3]C[0])"
A B C D E
1
Préno
2 Janvier Février Mars
ms
Marce
3 3 3 7
l
4 Louis 4 1 9
5 René 7 4 9
TOTA =SOMME(C3 =SOMME(D3 =SOMME(
6
UX :C5) :D5) E3:E5)
7
8
9
1 Préno
Avril Mai
0 ms
1 Marce
4 8
1 l
1
Louis 2 5
2
1
René 1 3
3
1 TOTA =SOMME(C1 =SOMME(D1
4 UX 1:C13) 1:D13)
1
5
26
Nous allons utiliser CurrentRegion pour sélectionner les tableaux en entier. Constatez qu'il y a deux
tableaux distincts, car séparés par 3 lignes vides.
Si on utilise n'importe laquelle des cellules entre B2 et E6, CurrentRegion nous renverra les mêmes
résultats. Je rappelle que CurrentRegion désigne le tableau, et qu'on peut y accéder par la
combinaison de touches CTRL * (Cliquez dans C5 par exemple, et appuyez sur CTRL * pour vous
en assurer - Utilisez le * de votre pavé numérique, sinon c'est CTRL SHIFT 3)
Attention :
Range("A7").CurrentRegion.Select
C'est la plage A2:E7 qui va être sélectionnée ! En effet, si on est sur une cellule qui touche le
tableau, le tableau est sélectionné PLUS la ligne et/ou la colonne qui contient la cellule dans laquelle
on était pour exécuter la macro !
On est pas obligé de sélectionner le CurrentRegion : On peut très bien le traiter "à distance" :
MsgBox Range("C2").CurrentRegion.Address
Va afficher
$B$2:$E$6
Aurait renvoyé ... $B$3... A cause de cette satanée cellule vide ! En fait VBA fonctionne comme si
vous aviez travaillé "A la main". Essayez :
27
3. Appuyez sur CTRL *
4. Appuyez sur CTRL Flèche en bas
Pour simplifier la suite de ce didacticiel, admettons que cette cellulke soit remplie, histoire d'avoir
des tableaux bien carrés (ou rectangulaires...) ce qui est le plus souvent le cas lors d'une utilisation
courante d'Excel.
Et attention : J'ai pris une cellule plus centrale que E2... ou plutôt une cellule qui ne se trouve pas à
la première ligne, car si on est sur la ligne du haut de notre tableau et qu'on fait End(xlUp) - soit
CTRL Flèche en haut, il ne reste pas sur la première ligne, mais il remonte au dessus du tableau... Ou
plutôt il remonte jusqu'é ce qu'il ne puisse plus remonter (c'est notre cas : ligne 1), ou alors il
remonte jusque sur la dernière ligne du tableau précédent :
MsgBox Range("D10").End(xlUp).End(xlToLeft).Address
Renverrait ...$D$6 ! Eh oui !
On peut maintenant connaître le nombre de lignes et de colonnes de notre tableau (on doit réutiliser
notre bon vieux CurrentRegion):
MsgBox Range("D4").CurrentRegion.Columns.Count
4
MsgBox Range("D4").CurrentRegion.Rows.Count
5
Ainsi que le nombre de cellules :
MsgBox Range("D4").CurrentRegion.Cells.Count
20 (4 X 5 évidemment ...)
28
Et si à la place du numéro de colonne, nous avons besoin de la lettre, il faut utiliser une astuce :
MsgBox Chr(Range("D4").End(xlToLeft).Column + 64)
Soit le code ASCII de la lettre B (66)
Pour suivre cet article et le trouver intéressant, une bonne aisance avec VBA est indispensable
Les macros (Sub et Function) peuvent se placer dans le classeur actuel, ou dans Perso.XLS, afin
de les avoir à disposition tout le temps. Perso.XLS est systématiquement chargé à chaque
démarrage d'Excel, mais il existe une autre technique, ce sont les compléments. Les compléments
sont des classeurs Excel masqués qui peuvent contenir des UserForms, des modules dans lesquels
on peut avoir des prodécures et des fonctions.
Les programmeurs d'Excel, chez Microsoft, ont décidé de ne pas mettre à disposition tous les outils
d'Excel directement dans les menus. En effet, s'ils l'avaient fait, Excel mettrait 10 minutes à se
lancer.
Une partie des fonctionnalités d'Excel se trouvent dans des compléments (*.XLA - eXceL Additive).
Par exemple, le solveur, outil qui se trouvait autrefois par défaut dans le menu Outils d'Excel, n'est
maintenant plus accessible qu'au travers du complément Solver.XLA. Ce qui est une bonne chose,
car qui utilise cet outils, a part quelques scientifiques très pointus ? (Le solveur est un outil
mathématique permettant de résoudre des équations à plusieurs inconnues, mais le sujet de cet article
n'est pas d'apprendre à l'utiliser)
Actuellement, lorsque vous allez dans le menu Outils, vous constatez que "Solveur" n'est pas
présent.
Maintenant, lorsque vous cliquez sur le menu Outils, vous trouverez le sous-menu Solveur.
Si vous quittez Excel, et que vous le rouvrez, le solveur sera toujours a disposition sans avoir besoin
de nouveau de cocher la case.
29
Vous constatez qu'il y a plein de compléments dans Outils/Macros complémentaires. Ce qu'il y a de
bête, c'est que ce n'est pas la peine d'appuyer sur F1 en sélectionannt une macro complémentaire,
l'aide d'Excel ne renseigne pas sur son contenu !
Par exemple, j'ai appris que pour arrondir un montant à 5 centimes à l'aide d'une fonction, les
fonctions ARRONDI ne peuvent pas le faire. Mais il existe une fonction
ARRONDI.AU.MULTIPLE qui permet de le faire facilement. Cette fonction n'apparaîtra dans la
liste des fonctions que si vous cochez la macro complémentaire Utilitaires d'analyse.
C'est parti !
IMPORTANT : Suivez les instructions suivantes le plus précisément possible pour bien
comprendre ! Commencez par carrément fermer Excel pour être certain de commencer sans
rien d'ouvert dans Excel.
Nous allons créer une macro Soleil qui va simplement afficher "Il fait beau", qui va se trouver dans
un module d'un complément CompTest.XLA.
1. Lancez Excel
2. Vous avez un classeur vierge sous les yeux : "Classeur1"
3. Allez dans VBA
4. Créez un nouveau module dans ce classeur
5. Créez la macro suivante :
Sub Soleil()
MsgBox "Il fait beau"
End Sub
6. Revenez dans Excel
7. Allez dans le menu Outils/Macros/Macros
8. (Constatez que Soleil est présent dans la liste des macros)
9. Exécutez-là
10. Allez dans le menu Fichier/Enregistrer
11. Comme nom de fichier écrivez CompTest
12. Type de fichier : Choisissez "Macro complémentaire Microsoft Office Excel" (Tout en bas)
13. Constatez que le chemin d'accès en haut de la boîte de dialogue vous redirige vers
l'emplacement par défaut des macros complémentaires créées par les utilisateurs :
C:\Documents and Settings\VotreNom\Application Data\Microsoft\
Macros complémentaires
14. Cliquez sur Enregistrer
C'est ici qu'il faut bien suivre !
15. Fermez "Classeur1" - car c'est bien Classeur1 qui est sur votre écran : Ca ferme votre
complément CompTest.XLA (Oui je sais c'est bizarre)
16. Vous êtes dans votre Excel tout gris
17. Menu Fichier : dans la liste des derniers fichiers utilisés, il y a CompTest.XLA. Cliquez
dessus pour l'ouvrir
30
18. Constatez que le classeur est masqué, comme s'il n'avait rien ouvert - Et si vous allez dans le
menu Fenêtre/Afficher, vous constaterez que même là vous ne pouvez pas afficher
ComptTest.XLA.
19. Allez dans le menu Outils/Macros
20. Constatez que très étrangement, la macro Soleil n'existe pas. MAIS : Dans la zone "Nom de
la macro", tout en haut, écrivez soleil, et cliquez sur exécuter : Il l'exécute !!! La macro est
bel et bien là, mais le classeur et ses macros sont fortement cachés.
21. Allez dans VBA, constatez que CompTest.XLA est bien actif, et sa macro soleil bien visible.
22. Revenez dans Excel
23. Quittez Excel
24. Rouvrez Excel
25. Nous sommes bien d'accord que maintenant, Soleil n'est plus disponible. Testez
(Outils/Macros/macros, Ecrivez Soleil et Exécuter) : Il ne donne pas d'erreur, mais il croit
que vous voulez créer une macro Soleil dans un module de ce nouveau classeur qui est
apparu par défaut à l'ouverture d'Excel
26. Re-quittez Excel, et Rouvrez le encore une fois, ne sauvegardez rien du tout
27. Dans la pratique, il ne s'agit pas d'ouvrir le complément CompTest.XLA de manière
traditionnelle, mais comme ceci :
28. Allez dans le menu Outils/Macros complémentaires
29. Cochez la case CompTest.XLA. Comment sait-il que vous avez précédemment créé ce
complément ? Parce que à l'étape 13, il vous a "imposé" un chemin d'accès vers lequel Excel
sait que des macros complémentaires des utilisateurs se trouvent.
30. OK
31. A ce stade, à chaque démarrage d'Excel, CompTest.XLA sera chargé à chaque démarrage
d'Excel, mais le classeur sera masqué (En fait, un .XLA possède-t-il même un classeur ?) Et
les macros seront disponibles, mais invisibles dans Outils/Macros/Macros. Pour tester,
maintenant que la case est cochée :
32. Fermez et rouvrez Excel
33. Menu Outils/Macros/Macros. Ecrivez Soleil et cliquez sur Exécuter : La macro s'exécute
Evolution du complément
Attention maintenant si vous désirez ajouter d'autres macros dans votre complément. Admettons que
vous désiriez ajouter la macro suivante :
Sub Pluie()
MsgBox "Il Pleut"
End Sub
Si vous l'ajoutez et que vous retournez dans Excel et que vous allez dans le menu
Fichier/Enregistrer, il va vous enregistrer le classeur visible à l'écran, mais en tout cas pas
CompTest.XLA !
Pour enregistrer les modifications apportées à votre compléments, vous DEVEZ le faire DEPUIS
l'environnement VBA (CTRL S, ou fichier/Enregistrer CompTest.XLA.
31
J'insuste bien sur ce point car quand on crée des macros dans des classeurs standards .XLS, on peut
enregistrer son classeur indifféremment dans l'environnement VBA ou dans Excel, les modules,
macros, feuilles et classeur seront tout enregistré en même temps, dans un même fichier.
Function MonNom()
MonNom = "Michel Defawes"
End Function
Alors que les macros Sub n'apparaissent pas dans Outils/Macros/Macros, votre fonction apparaîtra
dans le menu Insertion/Fonction (Et pour répondre à une interrogation que pourraient poser les
connaisseurs : non, ça n'a rien à voir avec les éventuels Private ou Public qu'on pourrait ajouter
avant)
Il est possible de créer des macros qui s'exécutent automatiquement à chaque ouverture de
CompTest.XLA. C'est à dire en fait à chaque ouverture d'Excel, pour autant qu'on ait coché la case
correspondante dans Outils/Macros complémentaires.
32
12. Dans la liste vde droite, choisssez Uninstall
13. Et, bien entendu, quand vous voulez que du code soit exécuté une seule fois lors du
chargement du complément (quand on coche la case, et qu'on clique sur OK), c'est AddInstall
Et faites quelques tests : Quittez Excel, rouvrez Excel, cochez et décochez la case de votre
complément CompTest.XLA, et regardez si vous obtenez bien les messages correspondants.
Vous avez déjà vu les compétitions sportives ou les juges doivent voter ? On retire les extrêmes,
respectivement les notes les plus hautes et les plus basses.
Vous pouvez télécharger le classeur Excel qui contient les fonctions de cette rubrique ici.
Voici un petit exemple. Soit une compétition de plongeon, les juges donnent les notes suivantes :
33
La note la plus haute VALIDE est 9
La note la plus basse VALIDE est 7.5
La moyenne des notes valides est 8 + 9 + 7.5 + 8.5 + 9 = 42. 42
: 5 = 8.4
Ce qui serait extrêmement sympathique, c'est d'avoir une série de fonctions personnalisées qui
permettent de calculer ces valeurs, comme ceci :
A B
1 Juge belge 9.5
2 Juge suisse 8
Juge
3 9
allemand
Juge
4 9.5
suédois
Juge
5 7
autrichien
6 Juge grec 7.5
Juge
7 8.5
danois
Juge
8 9
hollandais
MEILLE
=SansExtremeMeilleu
9 URE
r(B1:B8)
NOTE :
1 PIRE =SansExtremePire(B1:
0 NOTE : B8)
1 MOYEN =SansExtremeMoyenn
1 NE : e(B1:B8)
A B
1 Juge belge 9.5
2 Juge suisse 8
3 Juge allemand 9
4 Juge suédois 9.5
5 Juge autrichien 7
6 Juge grec 7.5
7 Juge danois 8.5
8 Juge hollandais 9
34
MEILLEURE
9 9
NOTE :
10 PIRE NOTE : 7.5
11 MOYENNE : 8.4
Function SansExtremeMeilleur()
End Function
Notre fonction a besoin d'un paramètre particulier : c'est la plage de cellules qui contient les valeurs
à juger. Ca se dit comme ceci :
Le fait d'écrire LesNotes as Range (LesNotes est une variable-paramètre sortie de mon imaginsation, qui est
définie comme une variable de type "Range", c'est à dire une plage de cellules ) permet de parcourir la plage de
cellules. Dans notre exemple, la cellule B9 renverrait 9, parce que c'est la 3ème cellule du Range :
(C'est à dire la note du juge allemand)
LesNotes.Count
Maintenant, pour connaître la meilleure note de manière absolue, on peut utiliser la fonction d'Excel
bien connue : MAX. Et pour l'utiliser au sein de VBA, on va utiliser l'objet WorkSheetFunction,
comme ceci :
Maintenant donc, toujours dans la cellule B9, dans notre exemple, le résultat serait 9.5. Bon,
évidemment, c'est nul... on aurait tout aussi bien fait d'écrire directement =MAX(B1:B8) ! Il s'agit
toujours d'éliminer les extrêmes.
Voici maintenant, pour s'approcher du but, une autre manière de repérer la meilleure note est de faire
une boucle comme ceci :
35
Function SansExtremeMeilleur(LesNotes As Range)
' On commence par initialiser une variable à 0 :
LaMeilleureNote = 0
' On parcourt la plage de cellule de la 1ère à la dernière
cellule :
For Ctr = 1 To LesNotes.Count
' Si la note actuelle est plus grande que "LaMeilleureNote"
' Et lors du premier tour de boucle, ça va forcément être le
' Cas puisque "LaMeilleureNote" vaut 0), alors,
"LaMeilleureNote"
' devient la note actuelle (dans notre exmeple 9.5)
If LesNotes(Ctr) > LaMeilleureNote Then
LaMeilleureNote = LesNotes(Ctr)
End If
' Ensuite on repart dans la boucle avec la 2ème note, et si la
' 2ème est plus grande que 9.5, "LaMeilleureNote" va prendre la
valeur
' de la 2ème note, mais ce n'est pas le cas (la 2ème vaut 8 dans
notre
' exemple). En fait, tout au long de la boucle, le 9.5 ne sera
' jamais détrôné...
Next
' ... et donc le résultat de la fonction sera ... 9.5 :
SansExtremeMeilleur = LaMeilleureNote
End Function
Toute cette complication pour avoir un résultat comparable à la fonction MAX ! Quelle injustice !!!
Mais en fait, maintenant, il n'y a plus grand chose à modifier pour la faire fonctionner correctement :
il faut éliminer les plus grandes notes, c'est à dire les notes égales à
WorksheetFunction.Max(LesNotes). Et ceci est assez simple, on va rajouter une 2ème
condition :
36
Et maintenant, le résultat est bien ... 9 !
La fonction inverse, c'est à dire SansExtremePireNote est tellement facile à créer que je crois qu'elle
se passe de commentaire :
La moyenne des notes intemédiaires ? Cette fois, il s'agit d'exclure les notes les plus hautes ET les
plus basses, et de compter les notes intermédiaires (Dans notre exemple, il nous en reste 5 sur 8)
37
calculer
' la moyenne, comme à l'école :
SansExtremeMoyenne = TotalNote / NombreNote
End Function
Sélection de cellules
Soit le tableau suivant :
Il peut être fort pratique de connaître d'un seul coup d'un seul : la première
ligne qui compose le tableau, la dernière cellule, la dernière colonne, etc. Voici
quelques "recettes de cuisine".
Tout d'abord, il faut savoir ou le tableau commence. En l'occurence, il commence en C2, pas en A1.
Pour sélectionner le tableau, on écrit :
ActiveSheet.UsedRange.Select
Ce qui aura pour effet de sélectionner C2:E7. Attention : UsedRange prend en compte TOUTES les
cellules utilisées. Le tableau suivant :
38
va poser problème. En effet
ActiveSheet.UsedRange.Select
Va sélectionner B2:F20. Vous avez compris la nuance ? Pour pouvoir sélectionner le premier tableau
dans ce cas-ci, on aurait recours à CurrentRegion, mais il faut connaître au moins une cellule faisant
partie du tableau.
ActiveSheet.Range("E12").CurrentRegion.Select
Sélectionnerait D10:F14. Selon la cellule spécifiée, le CurrentRegion sélectionne tel ou tel tableau
de la feuille.
Pour le bien-être de la démonstration, nous allons admettre que notre feuille active ne contient que le
tableau décrit au début de la page, ce qui nous permettre d'utiliser UsedRange en toute quiétude.
39
Voici toutes les sélections intéressantes en rapport avec ce tableau :
Toutes les sélections commencent avec ActiveSheet.UsedRange, c'est pourquoi je les ai mises
en petit.
ActiveSheet.UsedRange.Select
Tout le tableau sauf la ligne de titre (C3:E7). Tout l'astuce consiste à commencer à la ligne 2 du
tableau (Ligne3 en fait), jusqu'au nombre de Lignes (Rows.Count):
ActiveSheet.UsedRange.Rows("2:"
&
ActiveSheet.UsedRange.Rows.Count).Select
ActiveSheet.UsedRange.Rows(1).Select
ActiveSheet.UsedRange.Rows(1).EntireRow.Select
Toutes les lignes complètes composant le tableau (Ligne 2 jusqu'à la ligne 7):
ActiveSheet.UsedRange.EntireRow.Select
Toutes les colonnes complètes composant le tableau (Colonne C jusqu'à la E). EntireColumn est le
pendant de EntireRow, on l'aura compris :
ActiveSheet.UsedRange.EntireColumn.Select
Toutes les lignes complètes composant le tableau, sauf la ligne de titre (Ligne 3 jusqu'à la ligne 7).
Voir la sélection de tout le tableau sauf la première ligne.
Rows("2:" &
ActiveSheet.UsedRange.
ActiveSheet.UsedRange.Rows.Count).EntireRow.Select
La première colonne complète (Colonne C). On prend l'EntireColumn de la première cellule en haut
à gauche de notre UsedRange.
ActiveSheet.UsedRange.Cells(1, 1).EntireColumn.Select
La dernière colonne complète (Colonne E). Même chose, mais on prend la cellule tout en haut de la
colonne N° Columns.Count
40
Cells(1,
ActiveSheet.UsedRange.
ActiveSheet.UsedRange.Columns.Count).EntireColumn.Select
Dernière ligne : Pas toute la ligne, mais uniquement C7:E7 (dans la limite du UsedRange donc)
ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Select
Dernière ligne complète. Cette fois grace à EntireRow, on peut sélectionner toute la ligne 7
ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).EntireRow.Sele
ct
Nouvelle ligne : (C8:E8) C'est comme la sélection de la dernière ligne, mais on ajoute + 1
ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count + 1).Select
Rows(ActiveSheet.UsedRange.Rows.Count +
ActiveSheet.UsedRange.
1).EntireRow.Select
ActiveSheet.UsedRange.Cells(1, 1).Select
ActiveSheet.UsedRange.Cells(1, ActiveSheet.UsedRange.Columns.Count).Select
Cellule en Bas à gauche (Dernier nom : C7): Cette fois, c'est le comptage des lignes avec
Rows.Count
ActiveSheet.UsedRange.Cells(ActiveSheet.UsedRange.Rows.Count, 1).Select
Cellule en bas à droite (Dernière ville : E7) : Combinaison possible de Rows et Columns.Count. Ne
vous laissez pas troubler par l'apparente complexité du Cells().
Cells(ActiveSheet.UsedRange.Rows.Count,
ActiveSheet.UsedRange.
ActiveSheet.UsedRange.Columns.Count).Select
Premier nom (Colonne de gauche): (C3). Cells(2,1) = Cells(Ligne, Colonne). Il s'agit bien de la
2ème ligne du UsedRange, et pas de la feuille complète, ce qui explique pourquoi nous sommes sur
la ligne 3 et pas la 2.
ActiveSheet.UsedRange.Cells(2, 1).Select
41
Premier prénom : Même principe, mais le 2ème 2 signifie 2ème colonne, toujours du UsedRange,
donc.
ActiveSheet.UsedRange.Cells(2, 2).Select
ActiveSheet.UsedRange.Cells(2, ActiveSheet.UsedRange.Columns.Count).Select
Cellule une ligne plus bas, colonne la plus a gauche (Nouveau nom : C8) : Cette fois, c'est le nombre
de lignes + 1 qui nous intéresse.
ActiveSheet.UsedRange.Cells(ActiveSheet.UsedRange.Rows.Count + 1, 1).Select
Cellule une ligne plus bas, colonne la plus a droite (Nouvelle ville : E8) : Le nombre de colonnes et
le nombre de lignes + 1 nous intéresse.
Cells(ActiveSheet.UsedRange.Rows.Count + 1,
ActiveSheet.UsedRange.
ActiveSheet.UsedRange.Columns.Count).Select
Nouveau prénom (juste en dessous du dernier prénom - 2ème colonne : D8). Le ",2" considère la
combientième colonne nous intéresse. Si on avait mis ",18", il aurait sélectionné la 18ème colonne
de notre UsedRange, et malgré que la 18ème colonne est bien trop à droite, il l'aurait quand même
sélectionnée sans faire d'erreur.
ActiveSheet.UsedRange.Cells(ActiveSheet.UsedRange.Rows.Count + 1, 2).Select
Vous pourriez, à titre d'exercice, essayer de sélectionner tout le tableau sauf la denière colonne, ou
tout le tableau sauf la première ni la dernière ligne, ou que la 4ème ligne...
Sub Test()
Cells(4, 2) = "Tralala"
End Sub
Ecrit Tralala dans la 4ème ligne, 2ème colonne de la feuille courante du classeur courant. En d'autres
mots dans la cellule B4.
42
En fait, Cells est un membre de Application, mais lorsqu'il s'agit de l'objet Application, nul besoin de
le préciser. La procédure suivante fait exactement la même chose :
Sub Test()
Application.Cells(4, 2) = "Tralala"
End Sub
Nous aurions pu également préciser que Tralala est bien le CONTENU de la cellule, en effet, si nous
avions écrit GREEN à la place de Tralala, on pourrait imaginer qu'Excel allait reconnaître qu'il s'agit
non pas d'écrire GREEN, mais de mettre le texte, ou même la couleur de fond de la cellule en Vert.
Le code suivant donne encore une fois exactement le même résultat :
Sub Test()
Application.Cells(4, 2).Value = "Tralala"
End Sub
En fait, la propriété Value ne doit pas obligatoirement se préciser, car Excel imagine
(intelligemment) que nous voulons nous occuper du contenu.
Ainsi, grâce à cette méthode, nous avons la possibilité de remplir une grande zone, avec l'instruction
de programmation For To Next, comme ceci :
Sub Test()
Dim Ctr As Integer
For Ctr = 1 To 10
Cells(Ctr, 1) = "ca marche"
Next
End Sub
Qui nous permet de remplir les cellules de A1 jusqu'à A10 avec le texte "ca marche"
Si vous avez un peu de peine avec la logique pure et dure de programmation (Structures If .. Then ..
Else, For .. To .. Next, Do .. Loop, etc.), qui finalement n'ont pas grand chose à voir avec Excel, je
vous conseille de commencer par le commencement, et cliquer ici pour avoir les notions de
programmation de base.
Utilisation de Range
Une autre manière de placer du texte ou du chiffre dans une cellule particuière est la méthode
Range :
43
Et, comme plus haut, nous pouvons omettre le Mot Application. En fait, Application veut
simplement dire que c'est l'application courante (Excel) qui reçoit les instructions
La même technique nous permet de remplir une plage de cellules plus simplement qu'avec For To
Next :
De cette manière, il est possible d'attribuer une valeur à une cellule particulière qui fait partie d'une
plage de cellule, sans recourir à ActiveCell. Dans l'exemple qui précède, nous attribuons la même
valeur à plusieurs cellules, mais voici la manière d'attribuer une valeur à la 3ème cellule d'une
plage :
Range("A5:A10")(3) = "Trois"
Ecrit Trois dans la 3ème cellule a partir de la première cellule sélectionnée. La première est donc
A5, la 2ème A6, et la 3ème A7. Excel écrit donc dans A7.
De cette manière, avec une simple boucle, on peut écrire les chiffres de 1 à 5 respectivement dans
A5, A6, A7, A8 et A9, comme ceci :
Sub test()
For Ctr = 1 To 5
Range("A5:A10")(Ctr) = Ctr
Next
End Sub
Comme je le disais, Excel se doute bien que c'est la valeur (le contenu) de la cellule que vous
voulons changer. C'est pourquoi il nous autorise à nous en passer. Si nous avions voulu changer la
couleur du texte pour le mettre en rouge (Le code du rouge est 255), nous aurrions écrit ceci :
Application.Range("A5").Font.color = 255
La procédure suivante Ecrit "Tomate" dans la cellule B5, et en plus, l'écrit en Rouge
44
Sub LaTomateRouge()
Application.Range("B6").Font.Color = 255
Application.Range("B6").Value = "Tomate"
End Sub
Remarque : avec Cells, présenté plus haut, on peut également définir autre chose que le contenu,
comme la couleur de caractère, avec l'instruction
Grace à la propriété Interior, nous avons la possibilité de définir les couleurs de fond des cellules. Le
plsu simple étant d'utiliser la fonction RGB (Red (Rouge) , Green (Vert) , Blue (Bleu)). Red, Green
et Blue étant des valeurs comnprises entre 0 (valeur nulle) à 255 (valeur maximum). Par exemple
255,0,0 donne du rouge vif. 0,0,0 donne noir, 255,255,255 donne blanc.
Nous allons dans l'exemple qui suit faire un tableau de récapitulation des couleurs qui écrit les
valeurs RGB et colore la cellule voisine de cette couleur :
Sub TableauDeCouleur()
Dim MaSelection As Object
Set MaSelection = Range("A1:A17")
Cells.Clear
Numero = 0
45
For Ctr = 0 To 255 Step 16
Numero = Numero + 1
MaSelection(Numero).Offset(0, 0) = "RGB (0, 0, " & Ctr & ")"
MaSelection(Numero).Offset(0, 1).Interior.Color = RGB(0, 0,
Ctr)
MaSelection(Numero).Offset(0, 2) = "RGB (0, " & Ctr & " , 0)"
MaSelection(Numero).Offset(0, 3).Interior.Color = RGB(0, Ctr,
0)
MaSelection(Numero).Offset(0, 4) = "RGB (" & Ctr & " , 0, 0)"
MaSelection(Numero).Offset(0, 5).Interior.Color = RGB(Ctr, 0,
0)
MaSelection(Numero).Offset(0, 6) = "RGB (" & Ctr & ", " & Ctr &
", 0)"
MaSelection(Numero).Offset(0, 7).Interior.Color = RGB(0, Ctr,
Ctr)
MaSelection(Numero).Offset(0, 8) = "RGB (" & Ctr & ", 0, " &
Ctr & ")"
MaSelection(Numero).Offset(0, 9).Interior.Color = RGB(Ctr, 0,
Ctr)
MaSelection(Numero).Offset(0, 10) = "RGB (" & Ctr & ", " & Ctr
& ", 0)"
MaSelection(Numero).Offset(0, 11).Interior.Color = RGB(Ctr,
Ctr, 0)
MaSelection(Numero).Offset(0, 12) = "RGB (" & Ctr & ", " & Ctr
& ", " & Ctr & ")"
MaSelection(Numero).Offset(0, 13).Interior.Color = RGB(Ctr,
Ctr, Ctr)
Next
Cells.EntireColumn.AutoFit
End Sub
Ca doit s'écrire en 2 lignes (Je n'ai pas trouvé le moyen de le compresser en une seule ligne). Dans
l'exemple, on écrit "Autre Classeur, Autre feuille", dans la cellule B11, de l'onglet Janvier, du
classeur déjà ouvert AutreFichier.xls :
46
Windows("AutreFichier.xls").Activate
Sheets("Janvier").Range("B11") = "Autre classeur, Autre feuille"
Voici le code généré automatiquement par l'enregistreur de Macros. Il s'agit d'ouvrir le fichier, se
placer dans le bon onglet, la bonne cellule, et d'y écrire un texte :
Workbooks.Open Filename:="D:\Atelier\vbatest.xls"
Sheets("Janvier").Select
Range("A18").Select
ActiveCell.FormulaR1C1 = "Un texte"
ActiveWorkbook.Save
ActiveWindow.Close
Il peut fréquemment arriver qu'on veuille traiter l'ensemble de la sélection courante (Plage de cellule
sélectionnée au clavier ou à la souris juste avant d'exécuter la macro)
L'exemple suivant montre comment remplir une sélection, aussi grande soit-elle avec une
numérotation comme ceci:
AB C D
11 2 3 4
25 6 7 8
1 1 1
39
0 1 2
Sub Comptage()
Dim Cellule As Object
For Each Cellule In Selection
Ctr = Ctr + 1
Cellule = Ctr
Next
End Sub
L'astuce ici, consiste à utiliser For Each. En effet, sans ce For Each, on aurait été embêté. Nous
aurions pu dire :
Sub Comptage2()
Selection = "xxx"
End Sub
47
Mais le problème est ici que C'est xxx qui est écrit dans chacune des cellules... Ce qui n'est pas ce
qu'on veut.
Sub Comptage3()
Selection(1) = 10
Selection(2) = 20
End Sub
Mais dans ce cas, autre problème : On ne sait pas jusqu'ou on doit compter...
On a encore un tour dans notre sac : La propriété Count de Selection, qui nous permet de compter le
nombre de cellules sélectionnées :
Sub Comptage4()
MsgBox Selection.Count
End Sub
Et finalement, nous pourrions effectuer le comptage proposé au début de cette page comme ceci :
Sub Comptage5()
For Ctr = 1 To Selection.Count
Selection(Ctr) = Ctr
Next Ctr
End Sub
C'est pareil...
ATTENTION : Si vous essayez d'exécuter cette macro alors que vous avez sélectionné à la souris
(A l'aide de CTRL) des plages différentes, ça ne fonctionnera plus
Désactivation de l'écran
Lorsqu'on exécute une macro assez longue, il est souvent préférable de ne pas voir le déroulement de
la macrosous ses yeux. D'une part, ce n'est pas très confortable pour la personne qui utilise votre
macro de voir tout ce qui se passe à grande vitesse, et d'autre part, paradoxalement, ça ralentit
l'exécution de la macro. Justement, dans l'exemple précédent, nous avons une macro qui remplit une
plage de cellules avec des chiffres. Quand vous l'avez testée, si vous aviez sélectionné une plage
assez étendue de cellules, vous avez sans doute remarqué que les chiffres n'apparaissaient pas
comme ça, d'un bloc, mais s'inscrivaient les uns après les autres dans les cellules.
Voici les deux lignes de code à rajouter afin que l'on ne voit pas l'exécution de la macro petit à petit,
mais le résultat final qui apparait instantanément quand la macro a fini son travail :
48
Sub Comptage()
' Désactivation de la mise à jour de l'écran :
Application.ScreenUpdating = False
Dim Cellule As Object
For Each Cellule In Selection
Ctr = Ctr + 1
Cellule = Ctr
Next
' Réactivation de l'écran :
Application.ScreenUpdating = False
End Sub
Cells.Select
La méthode Offset permet d'accéder à une cellule ou une plage de cellules située à un certain endroit
(en haut, en bas, à gauche ou a droite d'une certaine cellule). La syntaxe théorique est :
Par exemple :
Range("C6").Offset(0, 1) = 44
Ecrit 44 dans la cellule 0 lignes plus bas et 1 colonne plus à droite de la cellule C6 : Donc 44 dans la
cellule D6.
49
Il est possible d'utiliser des chiffres négatifs pour écrire plus en haut ou plus à gauche :
Range("C6").Offset(-3, -2) = 55
Ecrit 55 3 lignes plus haut, et 2 colonnes plus à gauche que C6 (Donc dans la cellule A3).
A B
1 4
2 2
3 7
4 9
5 5
Dans les cellules de B1 à B5, il s'agit d'écrire, par programmation "Grand" si la chiffre à droite est
plus grand que 5, sinon, écrire "Petit", comme ceci :
A B
1 4 Petit
2 2 Petit
3 7 Grand
4 9 Grand
5 5 Petit
Marche à suivre :
1. Sélectionner la liste des chiffres sans savoir la taille de la colonne, mais en sachant qu'elle
commence à A1 (Range("A1").CurrentRegion)
2. Assigner cette région (A1:A5) à une variable-objet Espace simplement pour éviter d'avoir à
écrire Range("A1").CurrentRegion à tout bout de champ
3. Assigner à la variable NombreCellule le nombre de cellules Espace.Count que
comprend la sélection Range("A1").CurrentRegion (Sinon, cette zone
CurrentRegion va s'agrandir dynamiquement au fur et à mesure qu'on va écrire Grand ou
Petit dans la 2ème colonne... ben oui...)
4. Démarrer une boucle For Ctr = 1 To NombreCellule qui va parcourir les cellules
Espace(Range("A1").CurrentRegion) une par une afin d'écrire à chaque fois dans
la cellule voisine de droite "Grand" ou "Petit" (Espace(Ctr).Offset(0, 1)
="Grand/Petit")
50
Sub UtilisationOffset()
Dim Espace As Object
Dim Ctr
Dim NombreCellule As Integer
Il est bien clair qu'il s'agit ici d'un exemple servant à illustrer la méthode Offset. Dans la pratique,
sans la moindre programmation, on aurait pu tout simplement utiliser la fonction Si, comme ceci :
A B
1 4 =SI(A1>5;"Grand";"Petit")
Cette façon de faire aurait présenté l'avantage d'être dynamique (Si on change la valeur de A1, B1 se
modifie en conséquence), au contraire de la programmation utilisant OffSet qui a fixé une fois pour
toutes les valeurs de la colonne B (A moins qu'on réexécute la macro).
Nous allons essayer l'exercice suivant : Il s'agit de placer une bordure noire tout autour du tableau.
En fait, plutôt de colorer toutes les cellules adjacentes en noir, comme ceci :
A B C D E F G H I
1
2
3 X 5 5
4 6 E 11
5 ii 11 k
6 m a b
7
8
9
51
Après l'exécution de la macro :
A B C D E F G H I
1
2
3 X 5 5
4 6 E 11
5 ii 11 k
6 m a b
7
8
9
L'idée est dond que lorsque on se trouve dans une cellule quelconque située entre C3 et E6, et qu'on
exécute la macro, la bordure noire est affichée comme dans cet exemple. Attention : Si le tableau se
trouve collé contre la gauche ou en haut de la feuille de calcul, la macro se plante, puisqu'elle ne peut
pas colorer les cellules avant la colonne A, ni avant la ligne 1. On voit que la macro est séparée en 4
parties distinctes : Bordure du HAUT, DROITE; GAUCHE et BAS. Fonctionnement :
1. Je déclare LaBase comme String. Cette variable contiendra tour à tour B2, F2 et B7
(Leas adresses des 3 coins depuis lesquels on va partir pour colorer les bordures) :
LaBase = LaPlace.Cells(1, 1).Offset(-1, -1).Address
LaPlace.Cells(1, 1) renvoie C3, et grace à Offset(-1, -1), nous avons B2
(cellule de départ)
2. Je déclare LaPlace comme Object. Je l'initialise avec le tableau : Set LaPlace =
ActiveCell.CurrentRegion (Pour raccourcir mes lignes de code : C'est plus
commode)
3. Je fixe une fois pour toutes les longueurs et largeur de ma sélection, pour être certain qu'elles
ne varient pas lorsque je vais commencer à colorer les pourtours : NbColonne =
LaPlace.Columns.Count et NbLigne = LaPlace.Rows.Count
4. J'exécute les 4 boucles For To Next qui vont colorer les 4
côtés : For Ctr = 0 To NbColonne + 1
NbColonne contient 3, je vais donc de 0 à (3+1), donc : 0,1,2,3,4 : Ces chiffres sont
l'Offset (Déplacement) vers la droite: Je me décale d'1, puis 2, puis 3, puis 4 colonnes vers
la droite en démarrant de B2 (LaPlace.Cells(1, 1).Offset(-1, -
1).Address). Je colorie en noir la cellule en cours, et c'est peut être la ligne de code la
plus difficile à comprendre :
Range(LaBase).Offset(0, Ctr).Interior.Color = RGB(0, 0, 0)
Sub BordureNoire()
' Déclaration des variables
Dim LaBase As String ' Tour à tour les 4 coins
Dim LaPlace As Object ' Tableau de base (CurrentRegion)
52
Dim NbLigne As Integer ' Nombre de lignes du tableau
Dim NbColonne As Integer ' Nombre de colonnes du tableau
53
Gestion des onglets
Les onglets sont le synonymes de feuilles. Dans un classeur (Fichier .XLS), il
doit au moins y en avoir 1, et au maximum 255. On peut confondre les objets
Sheets et WorkSheets. Apparemment, ce sont les mêmes objets, qui se
comportent de la même manière. Pour éviter les confusions, utilisons Sheets
dans tous les cas de figure.
Les onglets existants dans le classeurs sont numérotés de 1 à Sheets.Count, et peuvent être accédés
par leur nom ou leur numéro d'ordre :
On utilise la méthode Delete pour effacer les onglets. Admettons que je veuille effacer l'onglet
nommé "Onglet inutile", j'écris :
Sheets("Onglet inutile").Delete
Afin d'éviter le message d'erreur sempiternel d'Excel "Attention, les feuilles sélectionnées vont être
effacées", j'envoie la touche ENTER à l'aide de Sendkeys, comme ceci :
SendKeys ("{ENTER}")
Sheets("Onglet inutile").Delete
Evidemment, si l'onglet "Onglet inutile" n'existe pas, Excel renvoie une erreur. Erreur que nous
contournons en lui demandant de ne pas y prêter attention, et de simplement finir la procédure sans
rien effacer :
54
Finalement on a la procédure propre suivante :
Sub EffacerOnglet()
On Error Resume Next
SendKeys ("{ENTER}")
Sheets("Onglet inutile").Delete
End Sub
Dans l'exemple précédent, nous avons effacé un onglet en utilisant son nom. Ceci dit, les onglets
sont numérotés de 1 à Sheets.Count. Ce qui nous permet de tous les effacer sans connaître leur nom
Un classeur doit contenir au moins un onglet (une feuille de calcul). Ainsi, le code suivant génère
une erreur :
Sheets.Count contient le nombre d'onglets actuellement existants dans votre classeur. Avec le For To
Next, on se déplace d'onglet en onglet, et on efface tout sauf le dernier, pour éviter l'erreur (S'il y a
10 onglets, on se déplace du numéro 1 jusqu'au numéro 10 - 1 (9))
Une solution plus élégante serait d'effacer tous les onglets sauf justement celui sur lequl on se trouve
:
Sub EffacementTouteFeuille()
For Ctr = Sheets.Count To 1 Step -1
If Sheets(Ctr).Name <> ActiveSheet.Name Then
Sheets(Ctr).Delete
End If
Next
End Sub
Parce qu'a chaque tour de boucle, on efface chaque fois une feuille, et Sheets.Count devient chaque
fois plus petit. Au bout d'un moment, VBA ne trouve plus les feuilles. C'est subtil !
55
Création d'onglets
Sheets.Add
Le simple fait d'écrire Sheets.Add ajoute un onglet juste avant l'onglet actif, dont le nom est FeuilX,
X étant un nombre imprévisible (5 si c'est la 5ème fois qu'on crée un onglet, même si on a déjà
effacé les 4 précédents).
On peut connaître immédiatement le nom de l'onglet qu'on vient de créer, en une seule ligne :
MsgBox Sheets.Add.Name
Sheets.Add OngletAvantLequelLaNouvelleFeuilleDoitEtreInsérée ,
OngletAPRESLequelLaNouvelleFeuilleDoitEtreInsérée ,
NombreDeFeuillesAInsérer,
GenreDeFeuilleMaisCeNestPasTrèsIntéressant
Il est donc possible, avec le 1er paramètre, d'insérer une nouvelle feuille à un endroit précis.
L'exemple suivant insére la nouvelle feuille avant la première :
Sheets.Add Worksheets(1)
Sheets.Add , Worksheets(WorkSheets.Count)
Sheets.Add , Worksheets(WorkSheets.Count), 3
Sheets.Add.Name = "Nouveau"
Une autre manière de faire, en utilisant une variable-objet (L'avantage est qu'on peut donner un ou
plusieurs paramètres à Add):
56
Copier les onglets
La copie d'onglets se passe exactement de la même manière que la création d'onglets, sauf qu'on
utilise Copy à la place de Add
Sheets("Ici").Copy
Sheets("Ici").Move, Worksheets(WorkSheets.Count)
ActiveSheet.Name = "test"
Lorsqu'il s'agit de créer un onglet, c'est simple, mais si tout à coup vous deviez créer 12 onglets : De
janvier à Décembre, vous devez faire 12 fois la manoeuvre de création d'un nouvel onglet, suivi du
re-nommage de celui-ci. Je vous propose ici de créer une macro qui crée les onglets voulus à partir
d'une plage de cellules (CurrentRegion), comme ceci :
A
1 Janvier
2 Février
3 Mars
4 Avril
Imaginez que vous êtes actuellement dans la cellule A2 (Ou A1, A3 ou A4, ou même que vous ayez
sélectionné A1:A4, peu importe), et que voudriez, par la simple exécution d'une macro, créer les
onglets Janvier, Février, Mars et Avril, dans cet ordre, sans toucher aux onglets existants, mais en les
plaçants après les onglets déjà existants. Il faut donc :
57
On commence :
Création d'un tableau de texte (Dim Tableau() As String) que nous redimensionnons
(ReDim) en le nombre de cellules (CurrentRegion.Count) que contient notre sélection
Dim Tableau() As String
ReDim Tableau(1 To ActiveCell.CurrentRegion.Count)
J'ai été obligé de faire 2 boucles, car avec une seule boucle, j'ai eu des problèmes techniques de
récupération de ActiveCell.CurrentRegion.Count. En effet, à chaque création de nouvel
onglet, Excel active cet onglet automatiquement, ce qui fait qu'évidemment,
ActiveCell.CurrentRegion.Count ne contient plus qu'une cellule, puisque cette fonction
ne marche que si on est dans une cellule qui fait partie d'un groupe de cellules, alors évidemment,
quand on crée un nouvel onglet, si Excel l'active automatiquement. il n'y a plus de CurrentRegion
qui tienne.. C'est pourquoi j'ai contourné le problème en "Fixant" le contenu des cellules de ce
CurrentRegion dans un tableau (Tableau 1 to ActiveCell.CurrentRegion(Ctr)), comme ça, Excel peut
changer de feuille active tant qu'il veut, je m'en fiche, j'ai stocké à part ma précieuse liste de mois.
Sub CreationOnglet()
ActiveCell.CurrentRegion.Select
Dim Tableau() As String
ReDim Tableau(1 To ActiveCell.CurrentRegion.Count)
58
Sheets.Add , Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = Tableau(Ctr)
Next
End Sub
Sub TriNomsOnglets()
On Error Resume Next
Dim I As Integer, J As Integer
For I = 1 To Sheets.Count
For J = I To Sheets.Count
If UCase(Sheets(J).Name) < UCase(Sheets(I).Name) Then
Sheets(J).Move Sheets(I)
End If
Next J
Next I
End Sub
59
Les événements de feuilles et de classeurs
Il est possible de déclencher du code Visual Basic dès qu'il se passe quelque chose
de spécial (Fermeture d'un classeur, changement d'onglet, ...). Il peut se passer des
choses (des événements) au niveau d'une feuille, ou du classeur entier
Introduction - A lire avant d'aller plus loin pour comprendre ce qu'est un événement de feuille ou de
classeur
Quand voulez-vous qu'il se passe quelque chose ? - Ce document ne va pas vous aider à savoir
quoi programmer, mais va vous préciser QUAND vous voulez que Visual Basic se "réveille"
Ordre d'exécution des procédures - Pour se démêler les idées et bien se rendre compte que parfois,
plusieurs procédures vont automatiquement, logiquement s'enchaîner les unes aux autres
Evénements de feuille - La liste exhaustive de TOUS les événements de feuille sont ici, ainsi que
leur explication et leurs paramètres
Evénements de classeur - La liste exhaustive de TOUS les événements de classeur sont ici, ainsi
que leur explication et leurs paramètres
Tous les événements s'appellent comme suit : Par exemple, imaginons que nous voulions exécuter la
procédure AllonsY à 17 heures 15 précises. Pour ce faire, il faut exécuter la macro test à 17 heures
14,, aattendre une minute devant son écran. Après une minute d'attente, vous aurez un message "Il
est dix-sept heures quinze !"
Sub Test()
Application.OnTime ("17:15:00"), "AllonsY"
End Sub
Sub AllonsY()
MsgBox "Il est dix-sept heures quinze !"
End Sub
- Application.OnKey
- Application.OnTime
- Application.OnRepeat
60
- Application.OnUndo
- Application.OnWindow
OnKey
Quand on presse sur une touche, ou une combinaison de touches. Ca complète d'ailleurs de façon
plus exhaustive la fonction existante qui permet d'assigner l'appel d'une macro à CTRL-X (X étant
une lettre ou un chiffre) - Voyez cela dans Outils/Macros/Macros, choisissez la macro que vous
désirez exécuter avec CTRL-M par exemple, et cliquez sur Options, écrivez M, et Ok. Chaque fois
que vous ferez CTRL M, cette macro s'exécutera. Ici, l'avantage de OnKey, c'est que ça ne s'arrête
pas à CTRL-QuelqueChose. Attention donc aux conflits : On peut très bien définir CTRL-M
appelle une certaine macro, et définir également CTRL-M avec OnKey. Je n'ai pas testé comment
Excel gère cette situation.
Exemple 1 : Quand on appuie sur a, quelle que soit le classeur, feuille et la cellule dans laquelle on
est, la procédure AllonsY sera exécutée (Excel affichera OK à chaque fois qu'on pressera sur a).
Attention : Il faut qu'on appuie sur a directement. Si on se trouve dans une cellule et qu'on veut
écrire abricot, on ne pourra pas, car on aura sans arrêt OK qui va s'afficher à la place de a. Mais par
contre, on pourra écrire sans problème banane, car ce n'est pas la première lettre du mot.
Sub Test2()
Application.OnKey "a", "AllonsY"
End Sub
Sub AllonsY()
MsgBox "ok"
End Sub
Attention : Une fois que la procédure Test2 a été lancée, elle a assigné une fois pour toutes AllonsY
à chaque frappe de la lettre a. C'est à dire qu'a partir de maintenant, on ne peut plus s'en débarasser
jusqu'à ce qu'on ferme Excel et qu'on le rouvre. Le seul fait de fermer le classeur dans lequel se
trouve Test2 ne désactive pas le OnKey, et quelque soit le classeur dans lequel on se trouve ensuite,
Excel ira jusqu'à Rouvrir dans notre dos le classeur ou se trouve Test2 pour pouvoir l'exécuter.
Et ca va même plus loin : Même si on modifie la procédure OnKey pour dire que ce n'est plus a,
mais b qui est capturé, alors a ET b appelleront la procédure AllonsY, même si a n'a plus rien a voir
la dedans... Etrange... Comme si c'était une procédure résident en mémoire de manière indécrottable.
Exemple 2 :
Exemple 3 :
61
Liste des raccouris clavier
Chacun de ces raccouris peut-être accompagné d'une touche de contrôle : SHIFT, ALT et CTRL
"%{F4}" = ALT F4
"+a" = SHIFT a
Pour plus d'informations, cherchez SendKeys dans l'aide Visual Basic pour Excel
62
F13 {F13}
F14 {F14}
F15 {F15}
F16 {F16}
ATTN {BREAK}
ENTRÉE (Enter, Return) {ENTER}ou ~
ÉCHAP (Esc, Escape) {ESC}
INSERTION (Ins, Insert) {INSERT} ou {INS}
Divers
IMPR. ÉCRAN (Print Screen) {PRTSC}
TAB (Tabulation) {TAB}
AIDE {HELP}
OnTime
Sub Test()
Application.OnTime ("17:15:00"), "AllonsY"
End Sub
Sub AllonsY()
MsgBox "Il est dix-sept heures quinze !"
End Sub
Sub Test()
Application.OnTime Now + TimeValue("00:00:05"), "AllonsY"
MsgBox "Youpi..."
End Sub
Sub AllonsY()
MsgBox "Tralala"
End Sub
Si on lance Test, nous aurons d'abord l'affichage "Youpi...", et APRES avoir cliqué sur OK, on
aura "Tralala"
63
OnRepeat
Cet événement permet de programmer ses macros de manière à ce que l'utilisateur puisse utiliser de
manière transparente la commande Edition/Répéter. En effet cette commande fonctionne avec toutes
les fonctions intégrées d'Excel, mais ne permet pas de répéter correctement une macro que l'on vient
d'exécuter.
Sub AllonsY()
ActiveCell = "Tagada"
Application.OnRepeat "Réécrire Tagada s'il vous plaît ",
"Recommencer"
End Sub
Lorsqu'on exécute cette macro, on écrit donc Tagada dans la cellule courante. On peut bien entendu
cliquer ensuite dans une autre cellule, et relancer la même macro. Mais justement, le comble du
confort est de pouvoir élégamment utiliser Edition/Répéter une fois qu'on est dans une autre cellule
pour réexécuter AllonsY.
Dans cet exemple, Dès qu'on exécute AllonsY, On écrit Tagada, et quand on va ensuite dans le menu
Edition, on trouve juste en dessous de Annuler : "Réécrire Tagada S'il vous plaît". Si on clique
dessus, Excel va exécuter mla macro Recommencer (Si elle existe, sinon, il y a une erreur). Dans
Recommencer, nous pourrions avoir le code suivant :
Qui est en fait une copie conforme de AllonsY. Donc en fait, mis a part pour peut-être certaines
macros qui ne peuvent s'exécuter qu'une seule fois, et que quand on leur demande de se répéter, il
faut effectivement appeler du code différent, on peut quand même dire que dans la plupart des cas,
ce sera la même chose qui sera exécutée. ALors, on peut tout à fait imaginer que OnRepeat réappelle
simplement la macro dans laquelle nous sommes. Résumons donc
Sub AllonsY()
ActiveCell = "Tagada"
Application.OnRepeat "Réécrire Tagada s'il vous plaît ",
"Recommencer"
End Sub
Sub Recommencer()
ActiveCell = "Tagada"
End Sub
En :
64
Sub AllonsY()
ActiveCell = "Tagada"
Application.OnRepeat "Réécrire Tagada s'il vous plaît ",
"Allonsy"
End Sub
OnUndo
Cet événement fonctionnement exactement comme OnRepeat, sauf que cette fois, bien sûr, c'est la
fonction d'annulation qui est intéressée. Ici, la tâche du programmeur est plus complexe. En effet,
pour la fonction de répétition, il suffit de répéter indéfiniment la dernière action. Dans le cas d'une
annulation, il y a le concept de multi-annulation qui entre en ligne de compte. Ce qui fait que lors de
mes tests, la fonction d'annulation se comporte correctement jusqu'au moment ou je redéfinis cette
fonction d'annulation. Dans ce cas, les annulations précédentes, gérées par Excel ne sont plus
disponibles. Le menu Edition contient en première ligne "Impossible d'annuler".
OnWindow
Sub CaMarche()
Application.OnWindow = "Test1000"
End Sub
Sub Test1000()
MsgBox "ok"
End Sub
65
Il est même possible de restreindre les fenêtres non pas à l'ensemble des fenêtres d'Excel, mais
seulement aux fenêtres émanent d'un seul classeur. Il ne s'agit pas des différentes feuilles, mais des
différentes fenêtres qu'on peut obtenir avec Fenêtre/Nouvelle Fenêtre, ou
Fenêtre/Réorganiser/Mosaïque. Exemple :
ThisWorkbook.Windows(1).OnWindow = "Test1001"
Selon les cas, les macros peuvent être stockées à tel ou tel endroit, selon
l'usage que l'on veut en faire. En fait, il est très intéressant de savoir où les
macros sont stockées dans le cas où on emporte un classeur sur disquette
(les macros vont-êlles suivre ?), ou qu'on envoie un fichier .XLS par E-Mail
(Même commentaire), ou si on désire qu'une ou plusieurs Macros ne soient
utilisable qu'avec tel ou tel fichier. Dans tous les cas, quel que soit l'endroit ou
on désire enregistrer ou écrire la macro, il FAUT que le fichier dans lequel on
veut la mettre soit ouvert (Qu'il soit automatiquement ouvert, masqué ou non,
peu importe, mais ouvert de toutes façons).
Vous allez rapidement vous rendre compte que ce n'est pas évident de s'y
retrouver avec tous ces fichiers et ces dossiers. En plus, selon la version de
Windows et d'Office que vous avez, les références peuvent également
changer. Vous voilà prévenus...
Le fait de stocker une macro dans le classeur courant la rendre accessible seulement lorsque vous
êtes dans ce classeur. Attentioin toutefois, si vous avez plusieurs classeurs ouverts et que la macro se
touve dans Classeur1, et que en fait vous êtes dans classeur2, alors, avec Outils/Macros/Macros,
vous aurez Accès aux macros de Classeur1.
Attention Toutefois (C'est compliqué) : admettons que vous êtes dans le classeur Classeur1.XLS, et
que vous enregistrez une Macro "Macro1" dans ce calsseur Classeur1.XLS, et que vous attachez
cette macro à une icône d'une barre d'outils personnalisée que vous avez créé préalablement (avec
Affichage/Barre d'outils/Personnaliser), vous pourriez imaginer que si vous enregistrez
Classeur1.XLS et que vous fermez Excel, quand vous allez revenir dans Excel, soit la barre d'outils
personnalisée que vous aviez créé quand vous étiez dans Classeur1.XLS aura disparu, soit, si elle n'a
pas disparu, l'icône qui appelle une macro de Classeur1.XLS ne fonctionnera plus tant que vous
n'ouvrez pas Classeur1 ... ET BIEN NON : Excel, dès que vous cliquerez sur le bouton qui appelle
Macro1 de Classeur1.XLS, ouvrira (discrètement) Classeur1.XLS pour récupérer et exécuter
Macro1. Bien entendu, si entretemps vous avez supprimé Classeur1, ou déplacé, ou renommé, alors
évidemment, Excel vous dira qu'il ne trouve plus la macro !
66
Donc méfiez-vous des barres d'outils qui appellent des macros "locales" au classeur dans lequel vous
êtes ! Dans ce cas de figures, moi, je trouve que ce serait bien d'afficher automatiquement la barre
d'outils du classeur local lors de l'ouverture. Voici un exemple de code utilisant les procédures
auto_open() et auto_close() pour montrer ou masquer une barre d'outils qui s'appellerait
MacrosLocales, et qui contiendrait des boutons qui appellent des macros se trouvant dans l'actuel
fichier XLS :
Sub auto_open()
CommandBars("MacrosLocales").Visible = True
End Sub
Sub auto_close()
CommandBars("MacrosLocales").Visible = False
End Sub
Le classeur de macros personnelles s'appelle en réalité PERSO.XLS. C'est un nom de fichier réservé.
Il s'agit d'un fichier masqué qui est créé dès la première fois qu'on enregistre une macro dans le
classeur de macros personnelles. PERSO.XLS s'enregistre automatiquement dans le dossier de
démarrage par défaut d'Excel. Dans le chapitre suivant j'en dis plus sur le dossier de démarrage par
défaut, notamment comment le troiuver.
Voici la marche à suivre pour créer le classeur de macros PERSO.XLS : Il suffit d'enregistrer une
macro idiote dedans :
Voilà. Maintenant, vous SAVEZ que PERSO.XLS existe, et qui se trouve dans le dossier de
démarrage par défaut d'Excel. Pour le trouver, cliquez sur le bouton Démarrer de Windows,
Rechercher/Fichiers ou Dossiers, et recherchez PERSO.XLS sur tout votre ordinateur. Vous verrez
ainsi ou il se trouve. Retenez-le, ça pourra vraiment vous être utile
67
PERSO.XLS ne commence a exister qu'a partir du moment ou on y installa la première macro. Il est
placé dans ce qu'Excel appelle un "Dossier de démarrage". C'est quoi ? Et bien, Excel va ouvrir
automatiquement tous les fichiers .XLS qui sont dans ce dossier à chaque ouverture d'Excel. S'il y a
50 fichiers .XLS, Excel les ouvre les 50.
Et ou est placé de dossier de démarrage ? Ce n'est pas très clair : On aurait bien aimé le savoir en
allant dans Outils/Options, mais rien. En fait, dans Outils/Options, on trouve bien un endroit "Autre
dossier de démarrage", mais ce n'est pas celui-là. Nous allons donc ruser. Je vous ai dit que
PERSO.XLS existait à partir du moment ou on créait une première macro. Marche à suivre :
A partir de maintenant, à chaque ouverture d'Excel, il va continuer a vous afficher une feuille de
calcul blanche, mais, en plus, il va ouvrir PERSO.XLS en tant que Fichier masqué ! C'est à dire que
vous ne le verrez pas, mais il est bien présent. Pour s'en convaincre, faites Outils/Macros/Macros.
Dans la liste, vous devriez constater la macro PERSO.XLS!MacroGenerale. Ca veut dire que
MacroGenerale se trouve effectivement bien dans PERSO.XLS.
Si vous voulez faire plus de tests, essayez de quitter Excel, et d'aller détruire PERSO.XLS dans
l'explorateur Windows. Quand vous reviendrez dansExcel, MacroGenerale aura disparu.
Un autre test consisterait à rendre visible PERSO.XLS. Il suffit d'aller dans Fenêtre/Afficher, et de
demander l'affichage de PERSO.XLS. Vous verrez un simple fichier vide, mais qui contient
MacroGenerale. ATTENTIOn : Si vous faites ce test, ne sauvegardez pas votre PERSO.XLS, parce
qu'il serait sauvegardé en Affiché, et pas Masqué, ce qui lui fait perdre tout son intérêt. On n'a pas
besoin de le VOIR, on a besoin qu'il nous mette discrètement ses macros à disposition tout le temps.
68
Dans un classeur .XLS se trouvant dans le dossier de démarrage par défaut
d'Excel
Il existe un endroit sur votre disque dur qui est le dossier de démarrage par défaut d'Excel. Ce
dossier de démarrage peut changer avec les versions d'Excel et de Windows. Avant Windows 2000,
il me c'était un dossier qui s'appelait XLOUVRIR, et qui est un sous dossier qui se trouve dans le
dossier d'installation d'Office. Avec Windows 2000, ce dossier se trouve plutôt dans les données de
configuration personnelle (Dans mon cas : C:\Documents and Settings\NomDeMonOrdinateur\
Application Data\Microsoft\Office\XLSTART).
En deux mots, pour retrouver ou se trouve votre dossier de démarrage par défaut, il suffit de
rechercher PERSO.XLS (Voir chapitre précédent)
Allez dans Outils/Options/General : Dans la zone "Autre dossier de démarrage", vous pouvez
spécifier un nom de dossier (pas un nom de fichier, mais bien de dossier. Exemple : d:\docs\Config\
Excel). Tous les fichiers .XLS qui se trouvent dans ce dossier seront chargés au démarrage d'Excel,
qu'ils soient masqués ou pas
S'il n'y a aucun fichier, alors, un classeur vide apparaître simplement au démarrage d'Excel. S'il y en
a un, il prend la place de ce classeur vide, et s'il y en à plus, ils sont chargés les uns derrière les
autres.
Une astuce intéressante consisterait à sauvegarder un fichier .XLS masqué dans cet autre dossier de
démarrage, et d'y installer des macros. Dans le cas ou vous avez un fichier .XLS masqué dans ce
dossier, Excel vous donnera encore un classeur vide au démarrage d'Excel (pour vous éviter d'avoir
un Excel tout gris sans classeur visible pour travailler au démarrage)
Ce dossier pourrait sembler faire double emploi avec le dossier de démarrage par défaut d'Excel,
mais en fait, on pourrait imaginer que votre dossier de démarrage par défaut se trouve sur votre
ordinateur, et personne n'y a accès à part vous, et l'autre dossier de démarrage pourrait se trouver sur
un lecteur de disque réseau, partageable avec tout un groupe d'utilisateurs.
Bon, maintenant, une question qui peut surgir, c'est "Que se passe-t-il si dans le dossier de
démarrage par défaut et dans l'autre dossier de démarrage, il y a 2 fois le même nom de fichier ?". Je
n'en sais rien... Je n'ai pas testé...
Classeur.XLT (eXceL Template) est un nom réservé qui désigne le classeur par défaut qui est ouvert
quand vous ouvrez Excel. A la base, ce classeur n'existe pas, mais si vous le créez
(Fichier/Enregistrer Sous, Type de Fichier : Modèle, Nom ; Classeur.XLT, Emplacement : Le même
que Perso.XLS, ou l'autre dossier de démarrage), alors, chaque fois que vous allez ouvrir Excel, ce
sera simplement une copie de ce classeur qui va être ouverte. Attention : a partir du moment ou
69
Classeur.XLT existe, on ne peut plus utiliser Outils/Options/Général/Nombre de feuilles par
nouveau classeur. Ce sera le nombre de feuilles de Classeur.XLT.
Les modèles de classeur doivent se trouver dans un dossier de démarrage (XLOUVRIR, XLSTART,
ou l'autre dossier de démarrage défini par l'utilisateur). Dans ce cas, les macros seront disponibles
dès qu'on ouvrira un classeur basé sur ce modèle (Fichier/Nouveau/Choisir le modèle en question)
Une macro complémentaire est un simple fichier Excel, qui ne possède pas de feuille visible,
particulièrement conçu pour stocker des macros VBA. Pour plus d'informations sur les macros
complémentaires existantes, cliquez ici.
Vous puvez mettre ou non une coche en face de cette macro complémentaire testcomplement.xla.
Qu'est ce que ça signifie, cette coche ?
Ici, ce n'est pas un choix, c'est une implication. Lorsque vous créez des barres d'outils
personnalisées, celles-ci sont stockées sous forme de fichier binaire dans un fichier .XLB (eXcel
Bar). Ce ou ces fichiers sont stockés dans le dossier de démarrage par défaut d'Excel. Ce sont des
fichiers qu'on ne peut pas modifier comme ça. Pour voir le contenu, il faut d'abord créer une barre
d'outils personnalisée, y attacher une ou plusieurs macros qui viennent d'endroits difféents, et ensuite
visualiser le fichier résultant .XLB dans un éditeur de texte, tel que NotePad, par simple curiosité.
70
Les macros complémentaires
Les macros complémentaires existantes
La macro complémentaire, comme son nom l'indique, est une macro additionnelle, qu'on peut ou pas
charger à l'ouverture d'Excel. Ce sont des fichiers .XLA (eXceL Additive) qui contiennent des
procédures et des fonctions VBA qui sont parfois utiles. Il existe déjà une pléiade de ces macros
complémentaires que l'on peut charger ou décharger en mettant les coches en regard des macros
complémentaires voulues dans le menu Outils/Macros Complémentaires.
Exemple : Dans la liste des fonctions d'Excel, vous allez trouver des centaines de fonctions
(Insertion/Fonction), et parmi elles, plusieurs fonctions puissantes qui permettent d'arrondir des
nombres à un certain nombre de décimales (ARRONDI), ou encore un arrondissement qui va vers le
haut (9.14 arrondi à 10), grâce à la fonction PLAFOND, ou l'inverse, grâce à PLANCHER. Mais
vous ne trouverez aucune fonction d'arrondissement à 5 centimes (4.67 s'arrondissant à 4.65), car
Excel étant un logiciel américain, ils n'ont généralement que faire d'une telle fonction.
Mais comme ici, en Europe, nous en avons besoin, ils ont implantés cette fonction dans une Macro
Complémentaire, qui s'appelle "Utilitaire d'Analyse", et qui contient une grande collection de
fonctions bien utile, dont cette fameuse fonction d'arrondissement qui s'appelle
ARRONDI.AU.MULTIPLE. Marche à suivre :
3. Retournez dans Insertion/Fonction, et constatez que cette fonction est maintenant existante. On
l'utilise comme ceci : =ARRONDI.AU.MULTIPLE(23.47; 0.05). Le résultat sera 23.45
Vous avez maintenant accès à toutes les fonctions de Utilitaire d'Analyse, même quand vous
quitterez Excel et que vous y reviendrez. En fait jusqu'au moment ou vous enlevez la coche.
Ne cochez pas toutes les macros complémentaires sans rasion, car plus il y en a, plus le lancement
d'Excel sera lent, et plus il consommera de mémoire. Ce qui explique l'utilité de la notion de Macro
Complémentaire.
Voyez également le chapitre Créations de ses propres fonctions, qui contient la manière de créer ses
propres fonctions, et de les rendre disponibles via une macro complémentaire que vous aurez-créé
vous même
71
Exercice de style : Téléchargement et utilisation d'une Macro
Complémentaire
Changement au sein d'Excel des paramètres régionaux
Comme n'importe qui peut créer des macros complémentaires et les mettre à disposition de tout un
chacun, certains développeurs ne se privent pas. Voici l'histoire :
- Lorsque vous utilisez Excel, selon la machine sur laquelle vous êtes, vous devez utiliser le point ou
la virgule pour séparer les chiffres des décimales, ou encore, c'est $ ou FF, ou CHF quand on
demande un format monétaire, ou même c'est parfois l'année qui s'écrit sur 2 chiffres, alors qu'on
l'aimerait sur 4 chiffres. Pour changer tout ça, vous savez certainement que ce n'est pas dans Excel
que ça se passe, mais dans Windows : Démarrer/Paramètres/Panneau de configuration, et cliquez 2
fois sur Paramètres régionaux. Un développeur VBA Excel à eu la judicieuse idée de mettre au point
une commande de Menu directement dans Excel qui permettrait de changer ces paramètres (Sans
quitter Excel, donc, ce qui est déjà fort pratique), mais en plus, de donner la possibilité de changer
ces paramètres d'affichage uniquement pour la session Excel en cours, ou pour tous les programmes
Windows (Access par exemple), alors que Démarrer/Paramètres/Paramètres régionaux ne donne pas
cette alternative. Il a donc installé le code VB nécessaire à ce petit plus dans un fichier .XLA, et il va
suffire de le télécharger, de l'installer et de l'activer pour s'en servir. Marche à suivre :
1. Ecrivez une date quelconque dans la cellule B2 par exemple : 01.01.98, et faites ENTER
Je ne sais pas comment la date s'écrit : admettons que vous voyez affiché : 01.01.1998.
Supposons que vous ne voulez voir que 2 chiffres pour l'année :
2. Faites Outils/Paramètres régionaux/Application Excel en cours (Ce qui est en rouge est une
NOUVELLE commande que vous venez d'installer, justement ...)
72
3. Dans la boîte de dialogue qui apparait, dans la zone "Style de date courte", écrivez jj.MM.aa
à la place de jj.MM.aaaa, faites OK
Voilà... Si ça c'est bien passé, votre date écrite avec l'année en 4 chiffres dans la cellule B2 s'est
maintenant affichée en 2 chiffres. Ce changement, si l'on en croit le menu, ne s'est effectué que dans
Excel, actuellement, et effectivement, j'ai testé : Quand on quitte Excel et qu'on revient dans le
même fichier, la date s'écrit à nouveau comment avant notre intervention. Il s'agit donc bien d'un
additif qu'un programmeur dont nous ne connaissons pas l'identité a créé pour nous. C'est à dire que
je suis incapable de vous dire comment il a fait son programme (le code VB qu'il a créé est protégé
par mot de passe), je ne sais absolument pas pourquoi il faut également copier avec le XLA
ParamReg.EXE... En fait c'est une "boîte noire". Et si ça créer des problèmes sur notre ordinateur,
c'est à nos risques et périls. Nous sommes tous bien au courant que personne, ni moi, ni le
programmeur ne prend AUCUNE part d'une quelconque responsabilité en cas de problèmes, même
si ça plante complètement votre PC... Mais qui n'essaie rien n'a rien... Il faut parfois savoir faire
confiance.
Si vous avez bien réussi l'exercice précédent, je vais vous donner d'autres macros complémentaires.
Celle qui suit permet, pour les programmeurs VBA qui utilisent énormément de procédures et
fonctions dans chaque classeur XLS, de répertorier, de manière résumée, en tableau, toutes les
procédures et fonctions du classeur Actif :
Voilà, maintenant, lorsque vous êtes dans un fichier Excel qui comprend pas mal de macros, il vous
suffit maintenant pour avoir la liste résumée de celles-ci d'aller dans Outils/Macros/Liste des
procédures, et cochez à choix feuille active ou nouvelle feuilles, c'est selon. Je vous laisse tester
l'utilisation que vous pouvez avoir d'une telle macro. Référez vous au fichier RTF joint dans le ZIP
pour de plus amples informations données directement par son auteur.
73
Création de ses propres fonctions
Quand une procédure commence par Sub, c'est une simple procédure, mais quand on remplace
Procedure par Function, il s'agit alors d'une fonction qui se rajoute dans la liste des fonctions
intégrées d'Excel.
Par exemple, imaginons une fonction qui calcule la surface d'un rectangle si on lui donne comme
paramètre la longueur et la largeur, de manière à ce qu'on puisse l'appeler de cette manière :
=SurfaceRectangle(4; 6)
Le résultat doit bien être 30, et la cellule dans laquelle vous étiez doit bien afficher
=SurfaceRectangle(5; 6)
Vous venez d'enrichir Excel d'une fonction de plus. Cette fonction, tout comme les procédures peut-
être stockée à différents endroits. Pourquoi pas l'isntaller dans un fichier Macro Complémentaire ?
Nous allons Créer la fonction SurfaceRectangle, dans un module installé dans un fichier Macro
complémentaire XLA appelé MesFonctions.XLA, (Mes fonctions personnelles) installé dans le
dossier de démarrage d'Excel. Marche à suivre :
2. Fichier/Propriétés : Titre : Mes fonctions personnelles. Commentaires : Liste des fonctions que
j'ai créé moi-même
74
3. Fichier/Enregistrer sous : MesFonctions. Type de fichier : Macro complémentaire Microsoft
Excel (*.xla) (Constatez qu'il va spontanément se placer dans le dossier de démarrage automatique
des macros complémentaires), et OK
Constatez que dans la barre de titre, il s'agit toujours de Classeur1, et pas de MesFonctions. Un
fichier.xla ne comporte pas de feuille. C'est vraiment un simple ensemble de fonctions en format
binaire. Attention, il y a un petit phénomène : Bien que nous venons de créer MesFonctions.xla,
même si nous ne l'avons pas fermé, il n'est pas là... du tout... Pour s'en convaincre, allez dans
Outils/Macros/Visual Basic Editor, et dans la partie de gauche, vous ne voyez normalement pas
"VBA Project (MesFonctions.xla)". Mais... Quittez VBA, et faites Fichier/Cliquez dans la liste des
derniers fichiers sauvegardés sur "MesFonctions.XLA", et maintenant, et seulement maintenant, si
vous allez dans Outils/Macros/Visual Basic Editor, vous voyez, sur la gauche : "VBA Project
(MesFonctions.xla)".
4. Faites donc Fichier, et dans la liste des derniers fichiers, cliquez sur MesFonctions.XLA (pour le
"rouvrir"...)
6. Sur la gauche, cliquez avec le bouton droit de la souris sur VBA Project (MesFonctions.xla), et
choisissez Insertion/Module
10. Fermez la feuille Excel, et s'il vous demande d'enregistrer, répondez non (ça n'a plus rien a voir
avec le XLA)
Il n'y a plus aucun classeur ouvert, mais MesMacros.XLA est encore là. Si vous retournez
maintenant dans Visual Basic, vous allez voir dans la partie de gauche qu'il est encore présent.
Maintenant, si vous allez dans Visual Basic, MesMacros.XLA a disparu. Pour le faire réapparaître,
il faut explicitement l'ouvrir avec le menu Fichier/Ouvrir. Comme c'est fastidieux, nous allons
demander à ce qu'il soit ouvert à chaque démarrage d'Excel
75
12. Outils/Macros Complémentaires, et cochez la case "Mes fonctions personnelles"
Constatez que ce sont les renseignements donnés à l'étape 2 qui apparaissent au lieu du nom du
fichier
13. Faites OK
Et voilà. Pour la tester, écrivez dans n'importe quelle cellule : =SurfaceRectangle(8; 4),
vous devriez voir 32
ATTENTION : Comme il s'agit d'une fonction dans un fichier séparé, les feuilles de calculs les
utilisant ne fonctionneront que chez vous. Si vous envoyez un classeur avec cette fonction à
quelqu'un d'autre, il faudra également lui envoyer MesFonctions.XLA, qu'il l'installe dans son
dossier de démarrage des XLA, et qu'il l'active avec Outils/Macros Complémentaires.
76
Formules et valeurs
Il est possible avec VBA d'assigner des valeurs fixes dans les cellules, mais
également des formules, avec des références relatives ou absolues. Cette
page a été crée pour Excel 2003, version française.
A B
1 2
2 3
3 4
4 5
5
6
7
Une rreur survient. On pourrait trouver ça normal, mais vous allez voir qu'avec VBA, un certain
jonglage linguistique est nécessaire !
Pour assigner une formule à une cellule, on peut l'écrire comme ceci :
Range("B7") = "=sum($A$1:$A$4)"
ou
Range("B7") = "=SuM(A1:A4)"
Mais pas
Range("B7") = "=SOMME(A1:A4)"
77
Si on voulait la valeur fixe et pas la formule dans B7, on aurait écrit :
Range("B7") = Application.WorksheetFunction.Sum(Range("A1:A4"))
Mais ce n'est pas le sujet de cette page. Cliquez ici pour plus d'infos sur WorkSheetFunction.
Si on désire absolument insérer une formule en langage d'installation d'Excel (Français donc dans
notre cas), il est nécessaire d'utiliser la propriété FormulaLocal :
Range("B7").FormulaLocal = "=SOMME(A1:A4)"
L'instruction suivante génère une erreur #Nom? :
Range("B7") = "=SOMME(A1:A4)"
Lors de la lecture d'une cellule qui contient une fonction, selon la propriété utilisée, nous obtenons
des notations différentes. Admettons notre tableau :
A B
12
23
34
45
5
6
=SOMME(A1:
7
A4)
Msgbox Range("B7") 14
Msgbox Range("B7").Value 14
Msgbox =SUM(R[-6]C[-
Range("B7").FormulaR1C1 1]:R[-3]C[-1])
Msgbox =SOMME(L(-6)C(-
Range("B7").FormulaR1C1Local 1):L(-3)C(-1))
Msgbox Range("B7").Formula =SUM(A1:A4)
Msgbox =SOMME(A1:A4)
78
Range("B7").FormulaLocal
Msgbox Range("B7") 14
Msgbox
14
Range("B7").Value
Msgbox
=SUM(R1C1:R4C
Range("B7").FormulaR1
1)
C1
Msgbox
=SOMME(L1C1:L
Range("B7").FormulaR1
4C1)
C1Local
Msgbox =SUM($A$1:$A$
Range("B7").Formula 4)
Msgbox
=SOMME($A$1:$
Range("B7").FormulaLo
A$4)
cal
---
Par exemple, nous aimerions connaître la somme d'une plage de cellules dans VBA, sans pour autant
écrire cette somme dans une cellule :
Sub FonctionExcel()
MsgBox Application.WorksheetFunction.Sum(Range("A1:A3,A5"))
End Sub
Cette fonction va afficher la somme des cellules A1 jusqu'à A3 ainsi que A5.
Constatez que :
Somme est écrit en anglais sinon ça ne fonctionne pas : La traduction de toutes les fonctions
Français/anglais est ici
C'est une virgule qu'il y a entre A3 et A5 car si vous mettez un poiunt virgule, ça ne
fonctionne pas.
79
Création d'une application : Les diviseurs
Nous allons, pour cet exemple imaginer une petite application qui va
s'intégrer à Excel, et qui va nous permettre de calculer les diviseurs d'un
nombre. Avant d'aller plus loin, il est nécessaire de bien comprendre le
fonctionnement de la recherche des diviseurs d'un nombre. Aussi, avant
d'aller plus loin, rafraîchissez-vous la mémoire avec cette page de
programmation en Word.
Sub DiviseurOptimise()
Dim QuelNombre As Long
Dim Ctr As Long
QuelNombre = Val(InputBox("Quel nombre voulez-vous analyser ?"))
For Ctr = 2 To QuelNombre / 2
If QuelNombre Mod Ctr = 0 Then
MsgBox Ctr & " est diviseur de " & QuelNombre
End If
Next Ctr
End Sub
Qui n'est pas très convivial, avouons-le, en véritable application Excel. En effet, nous ne pouvons
pas simplement transformer ce programme en fonction personnalisée de type Function
ChercheDiviseur(), puisque nous ne recherchons pas un seul résultat à mettre dans une seule
cellule, mais bien toute une colonne de longueur variable de résultats.
80
Et, quand on clique
sur "Chercher les
diviseurs", on a
carrément une boîte
de dialogue
personnalisée,
comme ceci :
Dans cette boîte de dialogue, nous avons 2 zones sélecteur de référence , sous 2 étiquettes
("Ou se trouve le nombre à analyser" et "Ou placer les diviseurs") , et un bouton OK. La bôite de
dialogue est elle même titrée (Détermination des diviseurs). Donc, quand tout sera fini, nous
pourrons donner l'exemple suivant :
1. Cliquez dans A1
2. Ecrivez 1000
3. Faites Outils/Options/Chercher les diviseurs
4. Cliquez dans la zone "Ou se trouve le nombre à analyser", et cliquez sur A1
5. Cliquez dans la zone "Ou placer les diviseurs", et cliquez sur B1
Voici le résultat de la boîte de dialogue :
6. Cliquez sur OK
C'est tout. Si tout s'est bien passé, vous devriez obtenir ceci :
A B
1 1000 2
2 4
3 5
4 8
5 10
6 20
7 25
8 40
9 50
10 100
81
11 125
12 200
13 250
14 500
On commence
Création de la boîte de dialogue en elle-même
Et ces propriétés :
82
5. Dans la feuille des propriétés, définissez Name = FeuilleDiviseur, et Caption =
Détermination des diviseurs
6.
7. Cliquez sur le sélecteur de références du haut, et dans la feuille des propriétés, donnez lui
le Name = REDNombre
RED est simplement les initiales de Reference zone d'EDition (mais on aurait pu appeler
cette zone ChouFleur, çaurait été bien aussi...)
8. le sélecteur de références du bas doit avoir le Name = REDDestination
9. Le bouton OK soit s'appeler Name = BDCOK
BDC = Bouton De Commande
A ce stade, "L'interface Utilisateur est terminée". Reste maintenant à savoir comment faire pour faire
fonctionner tout ça !
Nous allons commencer créer la commande "Chercher les diviseurs", du menu Outils. Juste avant ça,
il faut que nous créions une petite macro qui se contente d'afficher notre boîte de dialogue
personnalisée dont le nom est, je le rappelle, "FeuilleDiviseur".
83
Création du sous-menu, et affectation de la macro
Si vous cliquez sur OK, il ne se passe rien (La boîte de dialogue ne se ferme même pas). C'est
normal, on ne lui a encore rien demandé. Pour l'instant, on peut juste constater que les zones se
remplissent correctement quand on clique dans les différentes cellules de votre feuille de calcul.
C'est maintenant, justement à l'appui de cette touche OK que le miracle va devoir se produire : Le
programme doit extraire le nombre inscrit dans la zone Feuil1!$A$1 (puisque c'est ce qu'on a choisi),
et renvoyer les diviseurs du nombre qui s'y trouve dans la cellule Feuil1!$B$1 (puisque c'est là qu'on
les veut), et les cellules plus bas (B2, B3, B4, etc. si nécessaire)
84
1. Allez dans l'environnement VBA
2. Cliquez 2 fois sur FeuilleDiviseur dans l'explorateur de projets, pour faire apparaître votre
boîte de dialogue en mode création
3. Cliquez 2 fois sur le bouton OK
Vous devriez arriver dans une nouvelle feuille avec le code suivant :
Private Sub BDCOK_Click()
End Sub
4. Copiez le code suivant qui est le code définitif de calcul des diviseurs, et de leur bon
placement :
Range(REDNombre) doit vous rappeler Range("G41") par exemple. Simplement, ce n'est pas
une référence de type G41 ou A89, mais c'est la référence qui se trouve dans le sélecteur de
référence REDNombre ("Ou se trouve le nombre à analyser"). Dans notre cas, ce sera Feuil1!$A$1
85
Et le Offset (je rappelle que Offset signifie Déplacement), permet d'écrire les différents diviseurs les
uns en dessous des autres. Si Ctr2 vaut 5 (Nous serions donc au 5ème diviseur de notre nombre), et
bien Range(REDDestination).Offset(5, 0) signifierait un déplacement de 5 cellules
plus bas que REDDestination !
C'est fini ! OUF ! Vous pouvez tester, ça marche. Le mode d'emploi ? tout en début de page,
cherchez "Donc, quand tout sera fini, nous pourrons donner l'exemple suivant"
Lorsque vous commencerez à écrire des applications "sérieuses", ou le temps d'exécution devient
important, il peut être judicieux d'optimiser votre code. Bon, s'il s'agit d'une macro qui s'exécute
en une seconde, est-il bien nécessaire de se casser la tête pour savoir comment réduire son temps
d'exécution à 2 dixièmes de secondes ? Par contre, une macro très touffue peut demander
plusieurs minutes, voire plusieurs heures pour s'exécuter : alors si c'est possible de diviser son
temps d'exécution par 2, 3 ou même 100, pourquoi s'en priver ?
Si quand vous exécutez une macro qui effectue automatiquement des modifications dans des
cellules, vous constatez une lenteur étrange, c'est vraissemblablement parce que votre
classeur contient de nombreuses formules, et à chaque changement quelconque d'une cellule,
Excel recalcule tout. AUssi, il est sage de mettre avant toute macro l'instruction de blocage
du recalcul automatique :
Application.Calculation = xlCalculationManual
Pensez à le remettre à automatique juste avant la fin de la macro :
Application.Calculation = xlCalculationAutomatic
On peut demander le calcul de tout le classeur :
Application.Calculate
Une seule Feuille :
ActiveSheet.Calculate
Ou même une plage de cellules :
Range("F2:F8").Calculate
Egalement pour des questions de vitesse d'exécution, il est conseillé de sésactiver le
rafraîchissement de l'écran avant la macro, et réactiver après :
Application.ScreenUpdating = False
' Faire plein de choses qui affectent le contenu des
cellules
Application.ScreenUpdating = True
Il arrive que la macro s'interrompe pour vous demander une confirmation : par exemple si
vous fermez le classeur courant, Excel va vous demander si vous voulez l'enregistrer. Pour ne
pas être ralenti par ces confirmation, utilisons DisplayAlerts qui va choisir à notre place
86
l'option par défaut (Dans ce cas : Oui on veut enregistrer) :
Application.DisplayAlerts = False
ActiveWorkbook.Close
Application.DisplayAlerts = True
On peut avoir quelques problèmes inhérents à la manière qu'a choisi l'utilisateur d'afficher les
formules. Aussi, il semble sage d'imposer le style d'écriture voulu au début de chaque macro :
Application.ReferenceStyle = xlA1
(Affichera =SOMME(A1:A4) par exemple)
Ou
Application.ReferenceStyle = xlR1C1
(Affichera alors =SOMME(L(-6)C(-1):L(-3)C(-1))
87