Polycopié

Transcription

Polycopié
Révision Excel – Boîte de dialogue : La société RidoConf
Objectifs : Révisions Excel, Insertion d’objets dans une feuille, Boîtes de dialogues
L'entreprise RidoConf est une SARL Spécialisée :
- dans la vente de tissus d'ameublement et de linge de maison
- dans la confection sur mesure de voilages et de doubles rideaux
Le coût de confection des rideaux est fonction du type de tissu, du modèle de rideau souhaité,
des dimensions de la fenêtre et de l'ampleur désirée (coefficient applicable à la largeur réelle
permettant d'envisager plusieurs type de plis). Pour fixer leur choix, les clients souhaitent
disposer des coûts correspondants à plusieurs hypothèses de réalisation.
Il vous est demandé de réaliser un modèle Excel permettant de proposer et remettre
immédiatement au client les éléments du coût correspondant aux différentes hypothèses
envisagées lors de sa visite. Ces hypothèses limitées aux choix du tissu et du modèle de
confection sont appelées propositions.
A partir des caractéristiques de la fenêtre à équiper - hauteur et largeur -, il est possible
d'envisager les différentes hypothèses de réalisation en fonction :
-
de l'ampleur désirée (coefficient entre 1 et 3)
de l’ourlet (entre 0 à 20% de longueur en plus)
du modèle de rideau souhaité
de la référence du tissu
Le modèle conditionne le coût horaire de la façon et la durée moyenne du travail par mètre
carré confectionné. Chaque type de tissu d'ameublement comporte une référence, un nom, une
largeur, trois prix dégressifs au mètre : prix1: achats <5mètres ; prix2 entre 5 et 10 mètres ;
prix3 achats >= 10 mètres(Cf. tableau Tissu). Chaque modèle est caractérisé par un numéro,
un nom et une estimation du temps de travail par mètre carré réalisé(Cf. tableau Modèle). La
façon exprime pour un code donné le coût horaire de travail(Cf. Tableau Façon). Chaque
proposition comporte : un numéro, la date, le coût du tissu, de la façon et le coût total.
1°) Réaliser un modèle sous Excel en utilisant les fonctions Recherche(H ou V) ou Index et
Equiv.
2°) Modifier le modèle initial de façon à ce que tous les choix du client se fassent dans une
boîte de dialogue.
G. Mauffrey
Introduction à la programmation VBA
page 1/51
Annexe 1 – Données Tissus, Modèles, Façon
1 Tissu
Référence
24
47
70
93
116
181
246
311
376
441
506
520
534
548
562
Nom
Venise
Suisse
Miami
Wallis
Tahiti
Agadir
Madras
Tabriz
Corfou
Hébrides
Majorque
Annaba
Korogo
Hawai
Roma
2
Largeur
120 cm
140 cm
90 cm
90 cm
120 cm
240 cm
140 cm
140 cm
90 cm
240 cm
90 cm
120 cm
90 cm
90 cm
240 cm
Prix1
15,00 €
17,00 €
12,00 €
10,00 €
18,00 €
21,00 €
20,00 €
26,00 €
15,00 €
26,00 €
9,00 €
12,00 €
15,00 €
10,00 €
25,00 €
Prix2
12,50 €
15,00 €
12,00 €
8,00 €
15,00 €
18,00 €
15,00 €
25,00 €
14,00 €
20,00 €
8,00 €
10,00 €
12,00 €
10,00 €
22,00 €
Heures façon/Modèle de rideau
Nom
Heure/M²
Numéro
15
Provençal
1,25 H
104
Bonne femme
1,50 H
193
Brise Bise
1,00 H
282
Louis XV
2,00 H
371
Régence
1,30 H
460
Empire
2,20 H
549
Campagnard
1,80 H
638
Droit
0,80 H
Prix3
10,00 €
12,00 €
10,00 €
8,00 €
12,00 €
15,00 €
14,00 €
22,00 €
12,00 €
15,00 €
7,00 €
8,00 €
12,00 €
10,00 €
21,00 €
Code façon
57
35
79
13
35
101
79
57
Coût Façon
Code façon
Prix
13
12,00 €
35
12,50 €
57
14,00 €
79
14,50 €
101
17,50 €
G. Mauffrey
Introduction à la programmation VBA
page 2/51
Annexe 2 – A propos du modèle de facturation
La démarche à suivre pour la facturation est composée de deux étapes :
1. Calcul du prix du tissu :
1.1. Une fois le tissu choisi (donc la largeur définie), déterminer le nombre de largeurs de
tissu (‘lés’) nécessaires pour couvrir la largeur de la fenêtre (ne pas oublier de tenir
compte de l’ampleur). On pourra éventuellement tenir compte d’un ourlet fixe (p.e.
10cm) sur chaque lé, ou le prendre en tant que pourcentage en plus (de 0 à 20%).
1.2. En déduire le métrage de tissu nécessaire et éventuellement la chute (tissu inutilisé)
1.3. En déduire le prix global du tissu
2. Calcul de la façon :
2.1. Déterminer la surface utile, c’est à dire la surface de tissu à travailler (donc sans les
chutes).
2.2. En fonction du modèle choisi, déterminer le temps nécessaire et le code façon.
2.3. En déduire le coût de la façon.
3. Le prix à facturer est la somme du prix du tissu et du coût de la façon.
Fonctions Excel utilisées : Recherche ou Rechercheh ou Recherchev, Index, Indirect,
Arrondi.sup.
Rappel : dans un modèle sous tableur les données doivent être séparées des équations, aucune
constante ne doit apparaître dans les équations.
G. Mauffrey
Introduction à la programmation VBA
page 3/51
Annexe 3 – Création et utilisation d'une boîte de dialogue
Nous allons indiquer ici comment créer et utiliser une boîte de dialogue identique à celle ci :
La création se fait en Visual Basic, dans le menu "Affichage-Barres d'outil" sélectionner la
barre Visual Basic, puis cliquer sur Visual Basic Editor, il apparaît alors une nouvelle fenêtre
:
Dans le menu insertion choisir UserForm, la fenêtre devient alors :
G. Mauffrey
Introduction à la programmation VBA
page 4/51
Il apparaît trois fenêtres : une fenêtre contenant l'objet (la boîte de dialogues), une fenêtre
décrivant les propriétés de l'objet, et une boîte à outils permettant d'ajouter des contrôles à la
boîte de dialogue.
Dans la fenêtre Propriétés, on peut modifier le titre (‘caption’) de la boîte de dialogue et son
nom de façon à lui associer un identificateur plus "parlant" (par défaut le nom est ‘Userform +
un numéro’) par exemple ‘Choix’.
1) Ajout d'une liste déroulante à la boîte de dialogue
Dans la boîte à outil choisir l'objet "Zone de liste modifiable", le dessiner sur la boîte de
dialogue, lui donner un nom par exemple Maliste1. La façon la plus simple de mettre cette
liste déroulante en relation avec la feuille de calcul est d'utiliser les propriétés de l'objet :
•
La propriété "RowSource" correspond à la zone de la feuille contenant la liste des
éléments parmi lesquels l'utilisateur doit faire son choix : indiquer ici le nom de cette
zone, (à condition bien sû de l'avoir nommée).
2) Insertion d'un compteur et d'une zone de texte associée
Dans la boîte à outil choisir l'objet "Zone de texte", le dessiner sur la boîte de dialogue et lui
donner un nom par exemple Texte1 et lui affecter une cellule ControlSource ; puis choisir
l'objet "Toupie", le dessiner sur la boîte de dialogue et lui donner un nom par exemple
Compteur1. Remplir les propriétés Max, Min et value de cet objet (Attention ces valeurs sont
entières).
G. Mauffrey
Introduction à la programmation VBA
page 5/51
Pour lier ces deux objets, il faut alors créer des méthodes associées aux événements
intéressants, ici le fait de cliquer sur la toupie ou d'entrer une valeur dans la zone de texte.
Pour cela sélectionner un objet et cliquer sur le bouton droit de la souris pour choisir "code".
•
Pour la toupie, par défaut il vous est demandé le code pour tout changement de valeur
(événement Change), il faut alors mettre à jour la valeur de la zone Texte1 par le code
suivant :
Choix.Texte1.Value=Choix.Compteur1.Value/100
•
Pour la zone de texte, on opère de la même façon, soit avec l'événement Change, soit ce
qui est plus simple si on veut contrôler la valeur entrée avec l'événement Exit :
Choix.Compteur1.Value=Choix.Texte1.Value*100
3) Ajout du bouton OK
Dessiner le bouton changer son Caption, puis lui affecter comme code en cas de click, la fin
de dialogue en cachant simplement la boîte :
Choix.Hide
4) Initialisation des objets
Pour que les listes déroulantes et les zones de texte ne soient pas vides lors du premier
chargement de la boîte de dialogue, il est possible d'utiliser l'événement Initialize de la boîte,
avec le code suivant :
Choix.Maliste1.ListIndex=0 (affiche le premier élément)
Choix.Texte1.Value=Choix.Compteur1.Value/100
5) Exécution de la boîte de dialogue
Insérer un module contenant une seule macro d'une ligne :
Choix.Show
Il suffira alors d'exécuter cette macro pour ouvrir le dialogue et de mettre dans la deuille de
calcul les éléments choisis par l’utilisateur :
Range("tissu")=Choix.Maliste1.value
Amélioration de la boîte de dialogue
Il s'agit ici de faire apparaître l'imprimé du tissu, dans une image quand le client choisit un
autre tissu et de visualiser les dimensions relatives de la fenêtre.
G. Mauffrey
Introduction à la programmation VBA
page 6/51
On obtiendra alors le dialogue suivant :
Pour cela, il nous faut d'abord dans les données Excel associer à chaque tissu un fichier
image, donc ajouter une colonne à la table de données des tissus cette dernière colonne
contenant le chemin d'accès complet à ce fichier (Exemple c:\mesdessins\imprime1.wmf).
Dans un premier temps, il est possible de considérer une image unique pour tous les tissus.
Sur la boîte de dialogue, il faudra alors préparer une zone image pour recevoir cette image, et
ajouter deux barres de défilements pour ajuster sa taille qui correspondra à celle de la fenêtre,
pour afficher les dimensions de la fenêtre on utilisera aussi deux zones de libellés.
La taille maximum de l'image correspond à la taille maximum de la fenêtre (par exemple 150
pixels sur 90 pixels pour une fenêtre de 5m sur 3m); on aura alors un facteur de conversion de
0,3 entre les pixels sur l'image et les mètres sur la fenêtre (noté ‘coef’ dans la suite). La zone
image (nous lui avons donné le nom de im_fenetre) est définie sur la boîte de dialogue par
son sommet supérieur gauche (propriétés ‘top’ et ‘left’ de l'objet) et sa hauteur et largeur
(propriétés ‘height’ et ‘width’ de l'objet). Ces quatre propriétés devront être modifiées quand
l'utilisateur utilisera les barres de défilement; de façon plus précise les deux propriétés top et
height avec la barre verticale, left et width avec la barre horizontale. Les valeurs
correspondant au coin inférieur gauche de l'image à la taille maximale sont conservées au
moment de l'initialisation de la boîte de dialogue :
Lebas = Im_fenetre.Top+im_fenetre.Height
Lagauche=Im_fenetre.Left
Ces valeurs serviront à calculer la place de l'image à chaque définition de la taille de la
fenêtre.
Les barres de défilement sont à placer sur la boîte de dialogue aux côtés de la zone image
dans son format le plus grand. Ne pas oublier de définir le maximum et le minimum des
valeurs admissibles (ces valeurs doivent être entières et correspondent aux dimensions
maximales possibles en cm pour la fenêtre), ces deux barres seront nommées respectivement
sc_hauteur et sc_largeur. En désignant par lab_hauteur et lab_largeur les étiquettes associées
à l'affichage des valeurs, le code associé au changement de valeur de la barre de défilement
est alors le suivant.
G. Mauffrey
Introduction à la programmation VBA
page 7/51
Private Sub Sc_hauteur_Change()
Im_fenetre.Top = lebas - (Sc_hauteur.Max - Sc_hauteur.Value) * 0.3
Im_fenetre.Height = (Sc_hauteur.Max - Sc_hauteur.Value) * 0.3
Lab_hauteur.Caption = CStr((Sc_hauteur.Max - Sc_hauteur.Value) / 100) & " m"
End Sub
Les deux premières instructions concernent l'image (sa position et sa taille), la dernière est
uniquement un affichage dans l'étiquette de la valeur correspondant en mètres pour la fenêtre.
L'écriture pour l'autre barre de défilement est laissée au lecteur.
Il nous reste à changer d'image quand l'utilisateur change de tissu, donc à associer ce
changement d'image au changement de valeur de la liste modifiable du tissu (combotissu). En
nommant nomfic la variable contenant le nom du fichier image, le code est le suivant :
Private Sub Combotissu_Change()
Im_fenetre.Picture = LoadPicture(nomfic)
End Sub
G. Mauffrey
Introduction à la programmation VBA
page 8/51
Éléments de programmation avec VBA
La programmation en Visual Basic pour Application (VBA) permet d’ajouter aux logiciels de
Microsoft Office des fonctionnalités nouvelles, tout en utilisant les interfaces déjà définies par
ces applications. Les programmes en VBA, ne sont pas des entités indépendantes et ne
peuvent fonctionner que sous l’application parent (Excel, Word etc..).
D’autre part ces applications peuvent utiliser des objets propres à l’application parent par
l’intermédiaire d’objets prédéfinis accessibles au programmeur ; par exemple une ou plusieurs
cellules d’une feuille de calcul, un graphique ou des dialogues prédéfinis tels que le dialogue
d’ouverture de fichiers ou de sauvegarde.
L’incorporation de ces nouvelles fonctionnalités se fait par l’intermédiaire de « Macros » qui
sont des procédures sans argument qui peuvent être appelées depuis l’application parent (ici
Excel).
3
Organisation d'un projet sous Excel
L'ensemble des macros, procédures, fonctions, boites de dialogues et éventuellement objets
constituant une application en VBA est appelée un projet. Ces différents constituants doivent
être implémentés dans des zones précises :
Projet VBA
Modules
Modules de Classe
UserForms
Déclarations
Procedures
Fonctions
Propriétés
Méthodes
Déclarations
Gestion des événements
Un module est un ensemble de procédures et de fonctions qui utilisent en commun des
variables et des constantes qui leur sont propres et qui, par défaut, ne sont pas accessibles aux
autres modules ou boites de dialogues.
Un module de classe permet à l'utilisateur de définir ses propres objets, propriétés, méthodes,
de façon conceptuelle. Nous reviendrons dans un autre chapitre sur ces modules.
Un UserForm est une boite de dialogue, contenant à la fois la description physique des
contrôles qui la composent et les procédures événementielles nécessaires à leur gestion.
Dans ce chapitre nous nous limiterons aux modules.
4
Notions générales de programmation
Un programme est un ensemble d'instructions qui permettent de résoudre une classe de
problèmes ; ces instructions sont regroupées en entités qui constituent des procédures, des
fonctions ou des objets. Les instructions sont exécutées en séquence dans l'ordre où elles
apparaissent dans le programme. Ces instructions sont constituées de « mots –clés » propres
au langage et de variables qui permettent de stocker des valeurs durant l'exécution du
programme.
G. Mauffrey
Introduction à la programmation VBA
page 9/51
4.1 La notion de variables et de type de variable
Une variable est une zone de la mémoire centrale qui permet de stocker des valeurs durant
l'exécution du programme, cette valeur peut bien sûr évoluer au cours de cette exécution. En
général la nature du contenu de la variable reste la même durant tout le programme (par
exemple entier, réel ou chaîne de caractères) : on dit que la variable est typée, le type de la
variable détermine la taille utilisée en mémoire. Il est d'usage en "bonne programmation" de
déclarer les variables avant leur utilisation, certains langages tels que Pascal, C ou Java
rendent obligatoire cette déclaration, en revanche le Basic autorise l'utilisation de variables
sans déclaration ; il est toutefois recommandé de faire cette déclaration.
Enfin le langage VBA, contrairement à Java par exemple, n'est pas sensible à la « casse » (no
« case sensitive »), c'est à dire qu'il ne différencie pas les majuscules des minuscules.
4.1.1
Les différents types de variable.
Tous les langages possèdent des types prédéfinis que l'on peut utiliser dans les programmes,
en VBA les principaux types sont les suivants :
1. Types "classiques"
Entier : entre -32 768 et 32 767, nommé INTEGER.
Entier long : entre -2 147 483 648 et 2 147 483 647, nommé LONG.
Réel simple : entre -3,402823E38 et -1,401298E-45 pour les nombres négatifs et entre
1,401298E-45 et 3,402823E38 pour les positifs, nommé SINGLE
Réel double : entre -1,79769313486232E308 et -4,94065645841247E-324 pour les
nombres négatifs et entre 4,94065645841247E-324 et
1,79769313486232E308 pour les positifs, nommé DOUBLE.
Booléen : ne peuvent avoir pour valeur que True ou False, nommé BOOLEAN.
Chaîne de caractères : contient du texte (2^31 caractères au max), nommé STRING.
Une chaîne de caractère est affectée à une variable avec des guillemets :
Machaine="Voilà trois mots"
Pour assembler deux ou plusieurs chaînes de caractères on utilise
l'opérateur de « concaténation » , & (esperluette ou « et commercial »).
2. Type objet
Le type objet est un type générique qui permet à l'utilisateur de définir ses propres
objets dans la philosophie de la programmation objet, nous reviendrons dans un autre
chapitre sur cette notion.
Toutefois, en VBA, les objets de l'application parent sont prédéfinis et peuvent être
utilisés dans les programmes, nous ne développerons pas ici tous les objets d'Excel,
mais en fonction des exercices nous donnerons quelques indications sur les objets
utilisés.
On pourra consulter l'aide de VBA ou mieux l'explorateur d'objet de VBA, pour avoir
une idée sur la diversité des objets.
3. Le type Variant
Le type Variant est le type par défaut de VBA, c'est à dire attribué à toute variable non
déclaré explicitement. De façon générale la première affectation de valeur à une
variable de ce type lui donne un type "classique" qu'elle conservera par la suite, il est
donc assez dangereux d'utiliser ce type (donc de ne pas déclarer une variable dans un
programme).
G. Mauffrey
Introduction à la programmation VBA
page 10/51
4.1.2
Les caractéristiques d'une variable
Une variable a trois caractéristiques importantes :
Son nom : c'est un identificateur qui permet de faire référence à la variable, son
premier caractère doit être une lettre, il est composé d'au plus 255
caractères, différents de ., !, @, &, $, #. Il est recommandé de ne pas
utiliser de noms déjà définis soit comme mot clé, soit comme fonction,
procédure ou objet dans VBA.
La visibilité : c'est l'ensemble des modules, procédures ou fonctions qui peuvent
accéder à cette variable. Par défaut la visibilité d'une variable est
locale, c'est à dire limitée au module, à la procédure ou la fonction où la
variable est définie. Nous verrons plus loin comment étendre cette
visibilité. Si à un endroit du programme un nom peut faire référence à
deux variables visibles, c'est la variable locale (définie dans la procédure)
qui a priorité.
La durée de vie : c'est le temps d'exécution du programme pendant lequel la variable
est accessible (peut prendre une valeur). Par défaut la durée de vie d'une
variable est le temps d'exécution du module, de la procédure ou de la
fonction dans lequel la variable est utilisée.
4.1.3
La déclaration de variable
Pour déclarer une variable, on emploie généralement une instruction Dim. Une instruction de
déclaration peut être placée dans une procédure pour créer une variable de niveau procédure.
Elle peut être également placée au début d'un module, dans la section Déclarations, pour créer
une variable de niveau module.
L'exemple suivant crée la variable machaine et spécifie le type de données String :
Dim machaine As String
Par défaut les déclarations sont locales au niveau où elles sont faites, c'est à dire que la
visibilité de la variable est limitée au module ou à la procédure de déclaration. De même leur
durée de vie est limitée à l'exécution de la procédure ou du module, la variable étant
réinitialisé à chaque exécution. Ces valeurs par défaut peuvent être modifiées par le
programmeur.
Une variable est rendue visible de tous les modules et formulaires si à la place du mot clé Dim
sa déclaration est précédée du mot clé Public dans la partie Déclaration d'un module, dans ce
cas sa durée de vie est celle de l'application parent (Excel ici). Exemple :
Public nbclients as Integer
Une variable peut être déclarée comme Static dans ce cas, elle n'est pas réinitialisée à chaque
exécution de la procédure ou du module. Par exemple, la suite d'instructions :
Static moncompteur as integer
moncompteur=moncompteur+1
……
Donnera la valeur 1 à moncompteur lors de la première exécution de la procédure, puis la
valeur 2 à l'exécution suivante etc. , c'est cette déclaration qui permet, par exemple, de
nommer par défaut les feuilles d'un classeur Excel.
G. Mauffrey
Introduction à la programmation VBA
page 11/51
Remarque : il est possible de rendre obligatoire la déclaration des variables dans un module
en utilisant l'option explicite par l'instruction :
Option Explicit
4.2 Les instructions
En Basic chaque instruction correspond à une ligne de programme, il est cependant possible
en Visual Basic de mettre sur une même ligne plusieurs instructions séparées par ‘ : ’
On distingue deux types d'instructions (en dehors des appels de procédures que nous verrons
plus loin) : les instructions d'affectation et les instructions de contrôle.
4.2.1
L'instruction d'affectation
L'instruction d'affectation permet de donner une valeur à une variable, elle peut prendre deux
formes suivant le type de la variable.
Pour une variable de type classique, la syntaxe de l'instruction est la suivante :
nom_var=expression
La variable de nom ‘nom_var’ prend la valeur définie par expression, l'ancienne valeur est
effacée de la mémoire et ne peut plus être récupérée. Exemples
machaine ="C'est une chaîne"
X= Y+23*Z
X = X+1
Attention ne pas confondre cette affectation avec l'égalité mathématique, cette relation
d'affectation n'est pas symétrique, l'élément de gauche est modifié et doit donc être une
variable, les éléments apparaissant à droite du signe = restent inchangés.
Pour une variable de type objet, l'instruction d'affectation commence par le mot clé Set :
Dim mazone as Range
Set mazone = Range("toto")
4.2.2
Les instructions de contrôle
Les instructions de contrôles sont liées aux structures de contrôle structure alternative ou
structure répétitive. Une structure alternative est un ensemble d'instructions dont seulement
une partie est exécutée suivant certaines conditions, une structure répétitive est un ensemble
d'instructions qui sont exécutées un nombre fini de fois.
4.2.2.1 Structures alternatives
Une condition est une relation logique entre deux expressions constituées à partir de variable
et/ou de constantes. Les opérateurs logiques sont
‘=’ l'égalité (à ne pas confondre avec l'affectation)
‘>’,‘<’, (resp. ‘>=’,‘<=’) inégalités strictes (resp. larges)
Les connecteurs logiques qui permettent de modifier ou d'associer des conditions sont :
AND, OR, XOR, NOT : conjonction, disjonction, disjonction stricte, négation.
Quand on utilise ces connecteurs, il faut mettre entre parenthèses les différentes conditions.
G. Mauffrey
Introduction à la programmation VBA
page 12/51
Remarque : il existe d'autres opérateurs de comparaison que l'on peut consulter dans l'aide en
ligne.
La structure alternative de base est :
Si (condition) alors instruction1 sinon instructions2 , la partie sinon étant facultative.
La syntaxe correspondante est :
If condition Then
Instructions à exécuter si la condition est vérifiée
Else
Instructions à exécuter si la condition n'est pas vérifiée
End If
Evidemment la section Else de la structure peut contenir une autre structure alternative. Dans
certains cas il est plus court d'utiliser une autre structure qui est la structure de sélection. Cette
structure permet d'exécuter certaines instructions suivant les différentes valeurs d'une variable
donnée. La syntaxe des instructions correspondantes est la suivante :
Select Case nom_var
Case val1
Instructions à exécuter si nom_var=val1
Case val2, val3
Instructions à exécuter si nom_var=val2 ou val3
Case val4 To val5
Instructions à exécuter si val4<=nom_var<=val5
Case Is > val6
Instructions à exécuter si nom_var>val6
Case Else
Instructions à exécuter dans tous les autres cas
End Select
Remarque : un seul des "case" est exécuté, il faut donc que les cas ne se recoupent pas.
4.2.2.2 Structure répétitive
Une structure répétitive permet l'exécution d'un ensemble d'instructions un nombre fini de
fois, nous ne détaillerons pas ici toutes les structures répétitives mais simplement les deux
plus importantes.
La structure For .. Next
Si le nombre de répétition est connu à priori on utilise la structure For .. Next, dont la syntaxe
est :
For compteur = a to b step c
Instructions à exécuter
Next compteur
a représente la valeur de départ b la valeur maximum et c l'incrément, positif ou négatif. Par
défaut c est supposé égal à 1 et la partie step peut être omise dans ce cas.
La structure While .. Wend
Quand le nombre de répétition n'est pas connue, mais qu'il est limité par une condition, on
utilise la structure :
G. Mauffrey
Introduction à la programmation VBA
page 13/51
Initialisation de la condition
While condition
Instructions à exécuter
modification de la condition
Wend
Les instructions sont répétées tant que la condition est vraie. Attention, il ne faut pas oublier
dans ce cas d'initialiser la condition avant d'entrer dans la "boucle" et de modifier cette
condition avant l'instruction Wend, sinon soit on n'entre jamais dans la boucle, soit on n'en
sort jamais ("boucle infinie").
La structure Do ……. Loop
La structure itérative la plus générale est la structure :
Do [{While | Until} condition]
Instructions à exécuter
Modification de la condition
Loop
Ou
Do
Instructions à exécuter
Modification de la condition
Loop [{While | Until} condition]
Dans la seconde formulation le programme exécute une fois au moins les instructions de la
structure itérative.
Remarque : cette structure serait suffisante, la structure For .. Next pouvant être remplacée par
la suite d'instructions :
compteur = a
Do while compteur<=b
Instructions à exécuter
compteur=compteur+c
Loop
4.3 Procédures et Fonctions
Plutôt que d'écrire un programme long et difficile à déboguer, il est d'usage en bonne
programmation de décomposer les tâches à exécuter en tâches plus petites auxquelles sont
associées soit des procédures soit des fonctions. Ceci permet d'ailleurs d'utiliser à partir de
différentes procédures ces éléments. Le programme principal, ou la procédure principale en
VBA, étant alors presque uniquement constitué de déclaration et d'appel aux procédures et
fonctions.
4.3.1
Procédures
Une procédure est donc un ensemble d'instructions permettant d'effectuer une tâche précise,
en utilisant certaines variables du programme appelant pour modifier les valeurs d'autres
variables du programme appelant ou pour effectuer des affichages ou pour saisir des données.
Une procédure peut effectuer des modifications sur certaines variables tout en n’utilisant que
les valeurs (non modifiées) d'autres variables, on pourrait schématiser une procédure de la
façon suivante :
G. Mauffrey
Introduction à la programmation VBA
page 14/51
Procédure Ma proc
Entrées
Sorties
Les variables d'entrée et de sortie doivent correspondre à des variables déclarées dans le
programme appelant.
Les variables qui sont uniquement utilisées comme variables d'entrée ne doivent
théoriquement pas être modifiées durablement par la procédure, et seules leurs valeurs sont
passées à la procédure, on dit qu'on a un passage par valeur.
En revanche les variables de sortie doivent être modifiées définitivement par la procédure et
c'est donc l'adresse mémoire qui doit être passée à la procédure, on dit qu'on a un passage par
Référence.
Déclaration d'une procédure
En VBA la déclaration d'une procédure se fait par le mot clé Sub, la fin de la procédure est
marquée par le mot clé End Sub. La déclaration est l'instruction :
Sub nom_proc (Byval entr1 as type1, Byval entr2 as type2,..,Byref sor1 as types1,..)
Par défaut le passage est par référence, le mot clé Byref peut donc être omis, le type est par
défaut variant mais il est recommandé dans la mesure du possible de le spécifier.
Les noms de variables entre parenthéses correspondent aux paramètres de la procédure et sont
locaux à cette procédure, il ne doivent pas être redéclarés dans le corps de la procédure et ne
sont pas nécessairement les mêmes que ceux des variables correspondant dans le programme
appelant ; ce qui permet d'appeler cette procédure de différents programmes.
Appel d'une procédure
Le programme ou procédure qui utilise la procédure doit y faire référence parmi ses
instructions, cette instruction particulière est appelée instruction d'appel de procédure. Cette
instruction a la forme suivante :
nom_proc var1, var2, ..
Les variables var1, var2, .. doivent être déclarées dans la procédure appelante et de même type
que les paramètres de la procédure et être mises dans le même ordre que lors de la déclaration
de procédure.
Remarque : en VBA, il est recommandé de déclarer les procédures avant de les appeler dans
un programme, car l'éditeur VBA vous aide lors de l’écriture de l'instruction d'appel en
énumérant les variables de la déclaration ainsi que leur type.
Procédure appelable de l'application parent
Seules les procédures sans arguments sont appelables depuis l'application parent, elles
correspondent en fait à un programme autonome.
4.3.2
Fonctions
Dans le cas particulier où la variable de sortie est unique, il est possible de définir la
procédure sous forme de fonction, dans ce cas le nom de la fonction ‘nom_fonc’ joue le rôle
de variable de sortie.
G. Mauffrey
Introduction à la programmation VBA
page 15/51
Déclaration d'une fonction
La déclaration d'une fonction se fait par le mot clé Function, la fin des instructions de
définition étant marquée par le mot clé End Function.
La structure d'une fonction est alors la suivante :
Function nom_fonc(Byref val1 as type1, Byref val2 as type2,…) as typefonc
Instructions…
nom_fonc = valeur
End Function
Ne pas oublier la dernière instruction (dans l'exemple) qui donne la valeur de la fonction.
Utilisation d'une fonction dans une procédure
Pour utiliser une fonction dans une procédure, il suffit d'affecter sa valeur à une variable(de
même type) déclarée dans cette procédure :
mavar =nom_fonc(var1,var2,..)
où var1, var2 sont des variables ou des valeurs de même type que val1, val2 dans la
déclaration.
Utilisation d'une fonction dans Excel
Les fonctions définies en VBA sont accessibles, sauf spécification du programmeur (voir plus
loin), dans une feuille d'un classeur. Il suffit dans une cellule de taper :
=nom_fonc(v1,v2,..)
où v1, v2 sont des valeurs ou des adresses de cellules.
Portée des procédures et fonctions
Par défaut les procédures et fonctions sont Public, donc visible de tout module et d'Excel, le
programmeur peut changer cette option en précisant le caractère local de la procédure ou
fonction par le mot clé Private. Dans ce cas les procédures et fonctions ne peuvent être
appelées que d'une procédure ou fonction du module et ne peuvent donc, en particulier, pas
être appelées de l'application parent (Excel en l'occurrence).
5
A propos des variables objets définis par Excel
Une variable objet est une variable complexe, composée de données ( sous variables qui
peuvent elles même être des variables objets) appelées propriétés et de procédures ou
fonctions appelées méthodes. Nous verrons dans un autre chapitre comment créer ces
variables, ici nous ne intéresserons qu'aux variables objets déjà créées dans le programme
Excel et accessibles à l'utilisateur de VBA.
Pour atteindre les propriétés ou méthodes d'une variable objet, il faut indiquer le nom de la
variable suivie d'un point puis le nom de la propriété ou de la méthode.
Il est évidemment hors de question d'être exhaustif, aussi nous n'indiquerons ici que quelques
variables de base nécessaires pour les entrées/sorties sur les classeurs et feuilles de calcul.
L'ensemble des objets peut être exploré grâce à l'explorateur d'objet de l'éditeur VBA (menu
Affichage…Explorateur d'objet ou icône :
).
L'objet de base pour atteindre les objets définis par Excel est une variable nommée
Application qui représente Excel. Il est généralement inutile de rappeler cette variable quand
on utilise ses propriétés.
G. Mauffrey
Introduction à la programmation VBA
page 16/51
5.1
Les classeurs
5.1.1
La collection des classeurs ouverts
L'ensemble des classeurs ouverts sous Excel sont des objets de type WorkBook regroupés
dans une collection (tableau dynamique) qui est une propriété de l'objet application et qui a
pour nom Workbooks. Ces classeurs sont indexés soit par un nombre (1, 2,…) ( mais ce
nombre dépend de l'ordre d'ouverture des classeurs) soit par la chaîne de caractères de leur
nom. Par exemple pour atteindre le classeur de nom "Cestlemien", on peut utiliser les
instructions suivantes :
Dim Monclas as WorkBook
Set Monclas =Application.WorkBooks("Cestlemien")
On peut en fait se dispenser de préciser Application :
Set Monclas =WorkBooks("Cestlemien")
Le classeur actif est le classeur par défaut, il est repéré par la variable ActiveWorkbook.
Pour créer un nouveau classeur (équivalent du menu Fichier Nouveau), on utilisera la
méthode (fonction) Add :
Set Monclass = WorkBooks.Add
Ce classeur deviendra le classeur actif
Pour explorer l'ensemble des classeurs ouverts, on utilisera la boucle For each .. in..- Next :
Dim Unclas as WorkBook
For Each Unclas In Workbooks
MsgBox Unclas.Name
Next
affichera successivement tous les noms des classeurs ouverts.
5.1.2
Quelques propriétés et méthodes de l'objet Workbook
Pour fermer un classeur on utilise la méthode Close avec éventuellement deux arguments, le
premier argument booléen indiquant s'il faut conserver les modifications, le deuxième
donnant le nom du fichier sous lequel doit être sauvegardé le classeur.
Monclass.close True,"C:\Mesdocs\Machin.xls"
Si les arguments sont omis, la demande de sauvegarde des modifications est affichée, et
éventuellement, si le nom est demandé si le classeur n'avait pas déjà été sauvegardé.
Pour rendre un classeur actif, on utilise la méthode Activate
Monclass.Activate
Le classeur devient alors le classeur actif, généralement on aura pris soin de conserver au
préalable dans une variable de type Workbook, l'ancien classeur actif :
Set AncClasActif=ActiveWorkBook
Pour connaître le répertoire du fichier associé à un classeur, on utilisera la propriété Path,
pour avoir son nom complet (répertoire+nom de fichier) la propriété FullName, par exemple :
MsgBox ActiveWorkbook.FullName
G. Mauffrey
Introduction à la programmation VBA
page 17/51
Un classeur est composé de feuilles de calcul, chaque feuille de calcul est un objet de type
WorkSheet, regroupées dans une collection associée à la propriété WorkSheets d'un objet de
type WorkBook. Par exemple :
Workbooks("Cestlemien").Worksheets
Désigne l'ensemble des feuilles de calcul du classeur ouvert et nommé "Cestlemien". On peut
explorer les noms des feuilles de calcul comme celui des classeurs à l'aide de la structure,
For each .. in..- Next .
L'ensemble des feuilles (Calcul et Graphique) d'un classeur est conservé dans la collection
Sheets.
5.2
Les objets Feuilles
5.2.1
La collection des feuilles d'un classeur
Il n'existe qu'un seul type d'objet Feuille, l'objet feuille de calcul de type WorkSheet, objets
regroupés dans la collection Worksheets vue ci-dessus, les feuilles graphiques n'ont pas de
type particulier, elles apparaissent dans la collection Sheets, au même titre que les autres
feuilles. Nous ne parlerons ici que des feuilles de calcul, nous reviendrons sur les feuilles
graphiques dans un autre document.
Comme les classeurs, les feuilles de calcul d'un classeurs sont indexées par un numéro et par
leur nom, par exemple la feuille de nom "majoliefeuille" du classeur "Cestlemien" peut-être
associée à une variable de la façon suivante :
Dim LaFeuille as Worksheet
Set LaFeuille =WorkBooks("Cestlemien").Worksheets("majoliefeuille")
Si la feuille appartient au classeur actif, il est inutile de préciser ce classeur.
Pour ajouter une nouvelle feuille de calcul à un classeur, on utilisera la méthode Add de la
collection Worksheets, les instructions suivantes ajoutent une feuille au classeur actif et lui
donnent le nom "Ma nouvelle feuille" :
Dim Nouvfeuil As Worksheet
Set Nouvfeuil = Worksheets.Add
Nouvfeuil.Name = "Ma nouvelle feuille"
La feuille active du classeur est associée à la variable prédéfinie ActiveSheet.
Pour énumérer les noms des feuilles de calcul du classeur actif on pourra utiliser les
instructions suivantes :
Dim elt As Worksheet
For Each elt In Worksheets
MsgBox elt.Name
Next
Dans ce cas le nom des feuilles graphiques n'apparaîtra pas, si l'on veut énumérer les noms de
toutes les feuilles du classeur actif il faudra utiliser les instruction suivantes :
For Each elt In Sheets
MsgBox elt.Name
Next
Attention : on ne peut déclarer la variable ‘elt’ comme ayant un type particulier (Sheet par
exemple) car ce type n'existe pas, éventuellement on peut la déclarer comme un objet.
G. Mauffrey
Introduction à la programmation VBA
page 18/51
5.2.2
Quelques propriétés et méthodes de l'objet WorkSheet
Nous avons vu précédemment la propriété Name qui permet de retrouver ou de changer le
nom d'une feuille, alors que pour un classeur il n'est possible que de retrouver (lire) le nom du
classeur et il n'est pas permis de changer ce nom
Pour activer une feuille de calcul on utilisera la méthode Activate, comme dans le cas d'un
classeur, pour recalculer une feuille de calcul particulière on utilisera la méthode Calculate,
cette opération de recalcul d'une seule feuille de calcul n'est possible qu'avec l'utilsiation de
macros puisque la touche F9 recalcule toutes les feuilles de tous les classeurs ouverts et
correspond en fait à l'instruction : Application.Calculate.
On peut protéger et déprotéger une feuille de calcul à l'aide des méthodes Protect et UnProtect
suivies du mot de passe :
Dim LaFeuille as Worksheet
…..
LaFeuille.Unprotect "Monmot"
…..
LaFeuille.Protect "Monmot"
Enfin pour connaître la plage utilisée sur une feuille on pourra utiliser la propriété
UsedRange, qui renvoie un objet Range (cf plus bas) correspondant au rectangle circonscrit à
l'ensemble des cellules utilisées de la feuille.
5.3 L'objet Range
L'ensemble des cellules d'une feuille est réuni dans une collection Cells. Cette collection est
doublement indexée, par les lignes et les colonnes. Pour désigner la cellule se trouvant à
l'intersection de la ième ligne et de la jème colonne de la feuille nommée "Mabellefeuille" du
classeur nommé "Monbeauclasseur" on utilise la formulation :
Workbooks("Monbeauclasseur").Worksheets("Mabellefeuille").Cells(i,j)
Si l'on veut faire référence à la feuille active (donc du classeur actif) il suffira d’écrire
Cells(i,j).
Il n'existe pas d'objet Cellule, mais un objet Range, qui correspond à une zone rectangulaire
composée d'une ou plusieurs cellules.
5.3.1
Affectation d'une variable objet Range.
Il existe plusieurs méthodes pour affecter une valeur à une variable de type Range, nous
donnerons ici les trois principales (pour simplifier l'écriture nous les donnerons dans le cas de
la feuille active).
A partir des cellules coin supérieur gauche, coin inférieur droit, à partir de la collection Cells :
Dim Mazone as Range
Set Mazone=Range(Cells(1,1),Cells(4,5))
Ou à partir des adresses de type Excel mises entre guillemets :
Set Mazone=Range("A1:E4")
Enfin quand on a défini un nom dans un classeur Excel, il est possible de définir une variable
à partir de ce nom mis entre guillemets :
Set Mazone=Range("lenom")
G. Mauffrey
Introduction à la programmation VBA
page 19/51
Pour explorer toutes les cellules de la variable Mazone, on utilisera la structure For Each :
Dim elt as Range
For Each elt in Mazone
……
Next
Enfin, comme pour les feuilles et les classeurs, il existe une variable prédéfinie correspondant
à la zone sélectionnée sur la feuille active la variable nommée Selection, la cellule active étant
associée à la variable ActiveCell.
5.3.2
Quelques propriétés et méthodes de l'objet Range
Nous nous limiterons ici à quelques propriétés simples (Mazone est une variable de type
Range déclarée par Dim Mazone as Range) :
•
Numéro de la ligne supérieure : Mazone.row
•
Numéro de la colonne de gauche : Mazone.column
•
Nombre de lignes de la zone : Mazone.rows.count
•
Nombre de colonnes de la zone : Mazone.columns.count
•
Pour la cellule se trouvant en ième ligne et jème colonne de la zone: Mazone.Cells(i,j) ; il
n'y a pas de contrôle de débordement, en fait ceci localise la cellule qui se trouve à la ième
ligne et jème colonne à partir du coin supérieur gauche de la zone.
•
Valeur de la cellule se trouvant à la ligne i, colonne j : Mazone.Cells(i,j).Value, la
propriété Value étant la propriété par défaut, il est inutile de la préciser.
•
La propriété HasFormula retourne vrai si la cellule contient une formule, faux sinon
•
La propriété Formula retourne la formule de la cellule (en anglais) ou permet de mettre
une formule dans une cellule
•
Pour effacer le contenu d'une zone : Mazone.Clear
•
Pour obtenir l'adresse d'une zone sous forme d'une chaîne de caratères : Mazone.Address
•
Pour décaler une plage, il existe une méthode Offset(décalage lignes, décalage colonnes),
les décalages pouvant être positifs, négatifs ou nul. Cette méthode correspond à une
fonction et retourne un objet Range. Exemple
Dim Mazone as Range, Nouvzone as Range
Set Mazone = Range ("C4:D8")
Set Nouvzone=Mazone.offset(-2,3)
Donnera pour Nouzone, la plage F2:G6
•
Pour sélectionner la plage associée à la variable Mazone, on utilise la méthode Select :
Mazone.Select
•
Pour obtenir la zone rectangulaire la plus petite contenant les cellules non vides connexes
à une cellule donnée (par exemple la cellule active) on utilise la propriété CurrentRegion.
•
Pour lire ou entrer une formule dans une cellule, on utilisera soit la propriété Formula
pour la formule en Anglais, soit la propriété FormulaLocal pour la formule dans la langue
dans laquelle est installé Windows.
G. Mauffrey
Introduction à la programmation VBA
page 20/51
Beaucoup d'autres propriétés peuvent être utiles, par exemple sur les formats, vous pouvez
alors utiliser les commandes d'Excel correspondant en les enregistrant, puis les adapter à votre
problème. Ne surtout pas oublier d'arrêter l'enregistrement!!
G. Mauffrey
Introduction à la programmation VBA
page 21/51
6
Exercices
Dans les trois premiers exercices, on supposera donné le nombre de lignes et de colonnes.
6.1 Exercice 1
Inverser les éléments d’une colonne
Exemple :
AAAA
EEEE
BBBB
DDDD
CCCC
donne
CCCC
DDDD
BBBB
EEEE
AAAA
6.2 Exercice 2
Pour un tableau inverser les éléments.
Exemple :
AAA
AAA1
AAA2
FFF2
FFF1
FFF
BBB
BBB1
BBB2
EEE2
EEE1
EEE
CCC
CCC1
CCC2
DDD2
DDD1
DDD
DDD
DDD1
DDD2
CCC2
CCC1
CCC
EEE
EEE1
EEE2
BBB2
BBB1
BBB
FFF
FFF1
FFF2
AAA2
AAA1
AAA
donne
6.3 Exercice 3
Pour un tableau, inverser les colonne et si la colonne est paire inverser ses éléments.
Exemple :
AAA
AAA1
AAA2
AAA3
FFF3
AAA2
FFF1
AAA
BBB
BBB1
BBB2
BBB3
EEE3
BBB2
EEE1
BBB
CCC
CCC1
CCC2
CCC3
DDD3
CCC2
DDD1
CCC
DDD
DDD1
DDD2
DDD3
CCC3
DDD2
CCC1
DDD
EEE
EEE1
EEE2
EEE3
BBB3
EEE2
BBB1
EEE
FFF
FFF1
FFF2
FFF3
AAA3
FFF2
AAA1
FFF
G. Mauffrey
donne
Introduction à la programmation VBA
page 22/51
6.4 Exercice 4
On suppose ici que seul le nombre de lignes est donné, inverser alors les lignes et les éléments
de chaque ligne.
Exemple :
AAA
AAA1
AAA2
BBB
BBB1
CCC
CCC1 CCC2
DDD
DDD1
AAA3
FFF3
FFF1
FFF1
FFF
EEE
donne
DDD1 DDD
CCC2 CCC1 CCC
EEE
FFF
FFF2
FFF2
FFF3
BBB1
BBB
AAA3
AAA2
AAA1
AAA
6.5 Exercice 5
Le programme choisi un nombre au hasard entre 0 et 100 (fonction RND)
L’utilisateur doit trouver ce nombre en faisant des propositions (on pourra utiliser la fonction
InputBox)
1) A chaque proposition de l’utilisateur le programme répond :
• Trop grand
• Trop petit
Le programme s’arrête si le nombre est trouvé
2) A la fin du programme ajouter le nombre d’essais nécessaire au joueur pour gagner.
3) Dans votre programme vérifier la cohérence du joueur en fonction des informations
qu’il reçoit.
6.6 Fusion de deux listes
Dans une feuille de calcul, on dispose de deux listes de noms ordonnées par ordre
alphabétique.
Ecrire un programme qui fait la fusion ordonnée des deux listes en l'affichant dans une autre
zone de la feuille.
6.7 Contrôle des résultats d'un vendeur
Il s'agit de mettre en évidence les produits dont les objectifs de vente n'ont pas été atteints.
Dans une zone de la feuille de calcul vous avez les éléments suivants :
Produit
Bicyclette
Ballons
Poupée
Voiture
Puzzle
Objectif
100
2000
500
1500
180
Réalisé
50
2500
480
1420
250
Votre programme doit colorer les lignes où les objectifs ne sont pas atteints :
G. Mauffrey
Introduction à la programmation VBA
page 23/51
Produit
Bicyclette
Ballons
Poupée
Voiture
Puzzle
Objectif
100
2000
500
1500
180
Réalisé
50
2500
480
1420
250
a) Vous supposerez tout d'abord donnés, la zone entière des produits et valeurs des objectifs
et réalisés.
b) Utiliser une boite de dialogue pour saisir les éléments du programme :
Ecrire les procédures suivantes :
•
sélection des lignes d'une zone dont le coin supérieur gauche, le nombre de lignes,
les numéros des colonnes à tester est donné
•
mise en couleur d'une ligne sélectionnée
Ecrire les fonctions retournant le nombre de lignes et de colonnes adjacentes remplies à partir
du coin supérieur gauche d'une zone
Ecrire le programme utilisant ces procédures et permettant de résoudre le problème posé.
6.8 Coloration de cellules en fonction du contenu
Sur une plage de données choisie par l'utilisateur colorier les cellules suivant leur contenu :
•
Couleur 1 pour les formules
•
Couleur 2 pour les textes
•
Couleur 3 pour les valeurs numériques (Utiliser la fonction IsNumeric)
•
Couleur 4 pour les cellules vides
Les couleurs pourront être choisies par l'utilisateur
G. Mauffrey
Introduction à la programmation VBA
page 24/51
7
Annexes – Quelques compléments sur VBA Excel
7.1 L'objet RefEdit d'une boite de dialogue
L'objet RefEdit d'une boite de dialogue permet à l'utilisateur de saisir en pointant les adresses
définissant une zone Excel.
Sa valeur retourne la chaîne de caractères correspondant à la zone pointée : par exemple
"$B$2". Il faut donc ensuite transformer cette chaîne en une adresse Excel par l'objet Range :
Set mazone = Range(marefedit.value)
7.2 Quelques compléments sur l'objet Range
L'objet Range définit une cellule ou un ensemble rectangulaire de cellules d'une feuille de
calcul. On peut grâce aux propriétés de cet objet obtenir des renseignements sur cette zone ou
adresser des cellules à partir du coin supérieur gauche de cette zone ou modifier l'apparence
de cette zone ou d'une partie de la zone.
La couleur de fond d'une cellule est attribuée en fonction de la palette associée au Classeur
actif, elle est donnée par un nombre entier qui est appelé l'index de la couleur dans la palette,
ce nombre est compris entre 0 et 52. Une valeur spéciale notée xlColorIndexnone correspond
à aucun remplissage, pour affecter une couleur à l'intérieur d'une cellule on utilisera
l'instruction :
Mazone.Cells(i,j).Interior.ColorIndex =index de la couleur
Pour savoir si une cellule est vide, il faut utiliser la constante Empty :
If (Range("toto").Cells(i,j)=Empty) Then
…
7.3 Les couleurs
Pour utiliser les couleurs dans Excel ou dans les boites de dialogue, le plus simple est de
définir leur composition RGB (Rouge, Vert, Bleu), chacune des valeurs étant comprise entre 0
et 255. Par exemple :
Mondialogue.BackColor=RGB(0,0,255)
définit un fond de boite de dialogue Bleu. RGB(0,0,0) correspond au noir, RGB(255,255,255)
au blanc.
On peut récupérer les couleurs de la palette avec la fonction Colors, qui est une méthode de
l'objet Classeur (Workbook). Par exemple si on veut que le fond d'une zone étiquette(label)
soit de la couleur 11 de la palette du classeur, on utilisera l'instruction suivante :
Mon_etiquette.backcolor=ActiveWorkbook.Colors(11)
G. Mauffrey
Introduction à la programmation VBA
page 25/51
Fichiers et boites de dialogues
8
Utiliser un fichier de l'application parent (Fichier xls)
Il est souvent nécessaire dans une application VBA d'ouvrir un fichier du type de l'application
Parent, en demandant à l'utilisateur de sélectionner ce fichier. Il est alors possible d'utiliser le
dialogue standard de l'application. Le programmeur a accès à ces dialogues par la propriété
‘Dialogs’ de l'application qui est la collection de dialogues standard, chaque dialogue standard
étant repéré par un index (un entier) associé à une mnémonique commençant par ‘xlDialog’
pour Excel, ‘wdDialog’ pour Word, etc… Par exemple l'instruction :
Ouvert=Application.Dialogs(xlDialogOpen).Show
provoque l'apparition de la boite de dialogue d'ouverture sous Excel :
La variable Ouvert est une variable booléenne qui prend la valeur True si l'utilisateur a ouvert
un fichier, False si l'utilisateur a cliqué sur le bouton Annuler.
Le fichier ouvert est alors actif dans l'application. Pour adresser un autre classeur dans
l'application on utilisera l'objet WorkBooks(nomduclasseur). Par exemple pour rendre actif le
classeur dont le nom est Toto.xls on utilisera l'instruction :
Workbooks("Toto.xls").Activate
Il est aussi possible d'ouvrir directement, sans dialogue, un classeur dont on connaît le nom
par l'instruction Workbooks.Open filename:=nom du fichier. Par exemple :
Workbooks.Open filename:="c:\gm\vbasic\control1.xls"
Pour fermer un fichier, on peut utiliser l'instruction Wokbooks(nomduclasseur).Close qui peut
avoir comme paramètre (après ‘Close’) le fait de sauvegarder ou pas les modifications. Si ce
paramètre est omis, la boite de dialogue de sauvegarde des modifications sera affichée.
G. Mauffrey
Introduction à la programmation VBA
page 26/51
Par exemple :
Workbooks ("control1.xls").Close False
ferme le classeur précédemment ouvert sans sauvegarde, tandis que l'instruction
Workbooks ("control1.xls").Close
provoque en cas de modification l'affichage de la boîte de dialogue :
Remarque il est possible d'utiliser des variables pour stocker les objets classeurs :
Dim PremierCl as Workbook, DeuxiemeCl as Workbook
'On conserve le classeur actif avant d'ouvrir un nouveau classeur
Set PremierCl=ActiveWorkbook
If Application.Dialogs(xlDialogOpen).Show Then
Set DeuxiemeCl=ActiveWorkbook
…..
DeuxiemeCl.Close False
End If
…..
PremierCl.Close False
9
Contrôles multipage
Un contrôle multipage est un contrôle qui contient plusieurs pages (ici, 2 pages, ‘Zones’ et
‘Couleur’) atteignables par un onglet dans lesquelles sont implantés des contrôles de saisie,
l'utilisateur passant d'une page à l'autre en cliquant sur l'onglet. Les pages sont numérotées à
partir de 0.
G. Mauffrey
Introduction à la programmation VBA
page 27/51
Si le nom du contrôle multipage est ‘Detzon’, les pages se nomment ‘Detzon.Pages(0)’,
‘Detzon.Pages(1)’, etc.… Le programmeur n'a pas à gérer le click sur l'onglet ceci est fait
automatiquement par Windows, en revanche s'il veut par programme modifier la page visible,
le programmeur utilisera la propriété Value de la page. Par exemple pour rendre visible la
page ‘Couleur’ de l'exemple ci-dessus, on utilisera l'instruction :
Detzon.Pages(1).Value = True
10 Ajouts de contrôles dans une boîte de dialogues par programme
Il peut être utile, comme nous le verrons dans l'exemple suivant, d'ajouter des contrôles dans
une boîte ou un contrôle d'une boite de dialogue (par exemple une page ou un groupe). Ceci
peut se faire à l'initialisation ou lors d'un événement provoqué par l'utilisateur.
Pour ce faire, on utilise la méthode Controls.Add(type de contrôle) de l'objet auquel on veut
ajouter le contrôle, type de contrôle est une chaîne de caractères définissant la nature du
contrôle à ajouter. Les types de contrôles définis en VBA sont les suivants :
Type du contrôle
Chaîne de caractères
CheckBox
Forms.CheckBox.1
ComboBox
Forms.ComboBox.1
CommandButton
Forms.CommandButton.1
Frame
Forms.Frame.1
Image
Forms.Image.1
Label
Forms.Label.1
ListBox
Forms.ListBox.1
MultiPage
Forms.MultiPage.1
OptionButton
Forms.OptionButton.1
ScrollBar
Forms.ScrollBar.1
SpinButton
Forms.SpinButton.1
TabStrip
Forms.TabStrip.1
TextBox
Forms.TextBox.1
ToggleButton
Forms.ToggleButton.1
(on pourra consulter l'aide en ligne de Controls.Add de MsForms pour plus de détails)
Par exemple pour ajouter une étiquette ‘Monlabel’ (de libellé ‘Votre Choix’) à une boîte de
dialogue ‘Maboite’, on utilisera les instructions suivantes :
Set Monlabel = Maboite.Controls.Add("Forms.Label.1")
Monlabel.Caption = "Votre Choix"
11 Un exemple
Nous allons montrer ici comment construire le choix des couleurs dans un contrôle multipage
nommé ‘Detzon’.
G. Mauffrey
Introduction à la programmation VBA
page 28/51
Le problème : contrairement à Visual Basic, VBA ne connaît pas les collections de contrôle
dans une boîte de dialogue, il n'est donc pas possible de définir les 56 couleurs comme une
collection d'images et de récupérer par un événement Click, le numéro de la couleur choisie.
Une solution : pour simuler ce comportement, nous allons créer des images de couleurs
voulues à l'intérieur d'une autre image (nommée ‘Toutes’), les rendre inactive de façon à ce
que l'application ne leur attribue pas les clicks de souris mais passe cet événement à l'image
les contenant c'est à dire à ‘Toutes’.
Remarque : il est plus simple de créer les contrôles images de couleur à l'initialisation car la
procédure est moins fastidieuse et le choix des couleurs plus simple. Nous supposerons que
l'image ‘Toutes’, en revanche, a été créée graphiquement et que sa taille est suffisante pour
contenir toutes les images de couleur.
Les images couleur sont présentées dans un tableau à 8 lignes et 7 colonnes (il y a 56 couleurs
dans la palette), les couleurs étant rangées par ligne.
La constante Marge désigne la marge droite, gauche, haut et bas par rapport à l'image
container (Toutes) et aussi l'écart entre chaque image couleur (ligne et colonne) ; la constante
Cote désigne le coté du carré correspondant à l'image couleur.
Les lignes sont numérotées de 0 à 6 et les colonnes de 0 à 7, la ligne 0 contient donc les
couleurs de 1 à 8, la ligne 1 les couleurs de 9 à 16 etc. L'image couleur qui se trouve à
l'intersection de la ligne de numéro Ligne et de colonne de numéro Col correspond à la
couleur de la palette d'index : 8*Ligne+Col+1. Le sommet supérieur gauche de chaque image
est calculé en fonction de la position, et des constantes Marge et Cote.
Voici le code correspondant à l'initialisation, les contrôles sont crées dans la page numéro 1
du contrôle multipage Detzon :
Const Marge as Integer = 4
Const Cote as Integer = 14
Private Sub UserForm_Initialize()
Dim Zcouleur As Image
Dim Col As Integer, Ligne As Integer
With Detzon.Pages(1)
For Col = 0 To 7
For Ligne = 0 To 6
Set Zcouleur = .Controls.Add("Forms.Image.1")
Zcouleur.Left = Toutes.Left + Marge + Col * (Cote + Marge/2)
Zcouleur.Top = Toutes.Top + Marge + Ligne * (Cote + Marge/2)
Zcouleur.Width = Cote
Zcouleur.Height = Cote
Zcouleur.BackColor = ActiveWorkbook.Colors(Ligne * 8 + Col + 1)
'Pour que le click de la souris arrive au cadre Toutes
Zcouleur.Enabled = False
Next Ligne
Next Col
G. Mauffrey
Introduction à la programmation VBA
page 29/51
End With
Detzon.Value = 0
' Active la première page du contrôle Multipage Detzon
…….
End Sub
Il nous faut maintenant intercepter le choix de couleur de l'utilisateur. Pour cela il faut
connaître, les coordonnées du point où l'utilisateur a cliqué dans l'image ‘Toutes’, puisque les
contrôles images de couleur sont inactifs. On utilisera pour ce faire l'événement Mouse_Down
qui retourne ces coordonnées (X en abscisse relative à l'objet Toutes, Y en ordonnée), ainsi
que le bouton (fmButtonLeft=1 pour le bouton gauche, fmButtonRight=2 pour le bouton
droit, fmButtonMiddle=4 pour le bouton central) et la modification par une touche Majuscule,
Control ou Alt.
Après avoir vérifié que c'est bien le bouton gauche de la souris qui a été appuyé, la ligne et la
colonne de l'image sont déterminées en fonction de X et Y, l'index de la couleur peut alors
être calculé comme précédemment.
Voici le code correspondant, la touche de modification est ignorée :
Private Sub Toutes_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As
Single, ByVal Y As Single)
Dim Ligne As Integer, Col As Integer
If Button = 1 Then
Ligne = Int((Y - Marge) / (Cote +Marge/2))
Col = Int((X - Marge) / (Cote +Marge/2))
Numcoul = 8 * Ligne + Col + 1
Exemple.BackColor = ActiveWorkbook.Colors(Numcoul)
'Affichage de la couleur choisi dans la zone texte Exemple
End If
End Sub
12 Exercices
Suivi de résultats
Chaque semaine, vous recevez les résultats de tournois avec les points accordés à des joueurs
sur un fichier Excel, les noms sont dans une zone de deux colonnes commençant en A1 (on
pourra par la suite faire choisir la zone dans un contrôle RefEdit), les points dans une zone
nommée Points.
G. Mauffrey
Introduction à la programmation VBA
page 30/51
Exemple de fichier que vous pouvez recevoir :
Durand
18
Jacques
15
Raymond
13
Albert
8
Bizarre
3
Il s'agit d'écrire un programme qui ne conserve que les trois meilleurs résultats des joueurs.
Attention les noms ne sont pas les mêmes chaque semaine, il faut donc ajouter des noms dans
votre fichier résumé au fur et à mesure des fichiers résultats.
On pourra supposer soit que les fichiers sont nommés Résultatn.xls pour la semaine n, soit
que l'utilisateur choisit le fichier résultat à traiter et la feuille de résultat dans ce classeur, on
pourrait alors avoir une boîte de dialogue telle que :
Indications pour le programme :
a) Ecrire et vérifier une fonction ‘Trouvenom’ qui retourne un nombre entier représentant la
ligne où se trouve un nom donné dans une zone donnée d'une feuille de calcul, si le nom
n'existe pas la fonction retourne le numéro de la première cellule vide.
b) Ecrire et vérifier une procédure écrivant la nouvelle note.
Indications pour la boîte de dialogue :
c) Pour remplir la liste modifiable des feuilles, il faut utiliser la méthode Additem. du
contrôle.
d) Pour la zone donnant un aperçu de la feuille, on pourra utiliser des contrôles Intitulé
(Label). En les créant dynamiquement lors de l'initialisation du dialogue, il est possible de les
stocker dans un tableau, ce qui peut faciliter leur gestion.
Contrôle des objectifs (suite)
Reprendre l'exercice sur le contrôle des objectifs, en utilisant un contrôle multipage pour le
choix des zones et le choix des couleurs.
Au lieu de se limiter à un exemple de la couleur, on fera apparaître dans le tableau des images
couleur, la couleur choisie comme un bouton appuyé, les autres couleurs comme des boutons
relevés (utiliser la propriété specialEffect de l'image). Pour cela, on sera conduit à stocker les
images couleur dans un tableau.
G. Mauffrey
Introduction à la programmation VBA
page 31/51
13 Annexe : Modification de la barre de menus
Il est souvent utile pour des applications "clés en main" de modifier la barre de menu Excel,
de façon à ce que l'utilisateur final puisse choisir dans un menu les opérations à effectuer. De
plus le nouveau menu doit être installé au chargement du fichier et désinstallé quand
l'utilisateur ferme le fichier. Nous allons indiquer ici comment écrire des procédures
d'installation et de suppression d'éléments de menu, d'activation de menu, et comment lancer
les procédures adéquates à l'ouverture et à la fermeture du fichier.
13.1 Ajout de menus à la barre de menus d'Excel
La barre de menu est un objet CommandBar qui fait partie de la collection CommandBars, il
peut être utile de stocker la barre de menu dans une variable (globale) :
Dim labarre as CommandBar
Set labarre = CommandBars.ActiveMenuBar
Cette barre de menu, comporte des contrôles (les menus déroulant) qui sont des objets de type
CommandBarPopup, il faut donc ajouter un contrôle de ce type à la barre de menu Excel et
indiquer le titre de ce menu déroulant dans la propriété Caption de ce contrôle (si l'on veut
pouvoir accéder à ce menu par un raccourci, il faut faire précéder la lettre de raccourci par le
caractère &). Là aussi il est bon de conserver dans une variable globale ce contrôle de façon à
pouvoir le supprimer éventuellement. On insère ce menu avant le ? qui est le dernier menu
déroulant :
Public monmenu as CommandBarControl
Set monmenu = labarre.Controls.Add ( Type := msoControlPopup,
Before:=labarre.Controls.Count)
With monmenu
.Caption = "A&moi"
End With
Si l'on veut que le menu soit oté quand l'utilisateur ferme l'application, on ajoutera lors de la
création du contrôle, le paramètre temporary avec la valeur vraie. L'instruction sera alors:
Set monmenu = labarre.Controls.Add(….., Temporary:=true)
On ajoutera ensuite ensuite les élément du menu qui seront soit de type CommandBarButton
pour des commandes soit CommandBarPopup pour des sous menus. Ces contrôles sont
évidemment ajoutés au menu personnalisé. Là aussi on donnera le texte avec la propriété
caption, pour associer une procédure à la commande on utilise la propriété OnAction, pour
rendre la commande active ou inactive on utilise la propriété Enabled, si l'on veut une ligne de
séparation avant la commande on mettra à vrai la propriété BeginGroup qui par défaut est à
faux. Les contrôles ainsi créés sont ajoutés à la collection Controls du menu et sont repérés
par leur index 1,2,..n qui correspond à l'ordre de création. Par exemple :
G. Mauffrey
Introduction à la programmation VBA
page 32/51
Dim ctrl as CommandBarButton, sousmenu as CommandBarPopup
With monmenu.Controls
Set ctrl = .Add (Type:=msoControlButton)
With ctrl
.Caption = "Commande1"
.Onaction= "Proc1"
End With
Remarque : ce sera monmenu.Controls(1)
Set sousmenu = .Add(Type :=msoControlPopup)
With sousmenu
.caption = "sousmenu1"
.BeginGroup= True
Set Ctrl = .Controls.Add( Type := msoControlButton) etc…
Remarque : sousmenu estmonmenu.Controls(2), tandis que Ctrl nouvellement
défini est monmenu.sousmenu.controls(1)
Toutes les instructions de création du menu seront regroupées dans une procédure, ici
nommée Crée_menu.
13.2 Suppression du menu personnalisé
Comme le menu personnalisé a été conservé dans une variable globale, il suffit d'écrire une
procédure (Ote_menu, par exemple) ne contenant qu'une instruction :
Monmenu.Delete
13.3 Activation ou désactivation de commandes
Il suffit de changer la valeur de la propriété Enabled du contrôle correspondant :
Monmenu.Controls(i).Enabled = Not Monmenu.Controls(i).Enabled
13.4 Installation du menu à l'ouverture du fichier
Il peut être bon que le menu ne soit affiché que lorsque le classeur actif est le classeur de
l'application, nous allons utiliser l'évenement Activate de l'objet WorkBook d'Excel, pour
cela en VBA cliquer dans l'explorateur de projets, sur l'élément ThisWorkbook, puis dans la
fenêtre de code, choisir l'élément WorkBook dans la liste déroulante de gauche (qui affiche
par défaut Général), automatiquement il y a création d'une procédure WorkBook_Open, il
nous faut alors choisir l'événement Activate et dans la procédure WorkBook_Activate il suffit
d'écrire l'instruction d'appel de la procédure de création de menu :
Crée_menu
Pour effacer le menu quand le classeur n'est plus actif, on utilisera l'événement Deactivate, et
nous n'entrerons qu'une seule instruction :
Monmenu.delete
Remarque : si l'on veut que le menu soit actif durant toute la session Excel après le
chargement du classeur contenant la macro et quel que soit le classeur actif, il faut alors
utiliser l'événement d'ouverture du classeur et bien évidemment ne plus utiliser l'événement
Deactivate.
G. Mauffrey
Introduction à la programmation VBA
page 33/51
Récursivité
14 Généralités
On appelle récursive toute procédure ou fonction qui de façon directe ou indirecte fait appel à
elle-même.
Exemple : la fonction puissance nième (pour n>=0) d'un nombre A peut être définie par :
A0=1 et An=A*An-1
Ce qui se traduit en VB par la fonction suivante :
Function Puissance(ByVal A as Double, Byval n as Integer) as Double
If n=0 Then
Puissance = 1
(1)
Else
Puissance = A * Puissance( A , n-1)
(2)
End if
14.1 End Function
Quelques remarques sur cette écriture
1. La procédure est arrêtée par le test conditionnel à 0 (1), Dans toute procédure ou
fonction récursive, il doit y avoir une condition d'arrêt, qui empêche toute boucle
"infinie"
2. Dans l'instruction (2) bien faire la différence entre le nom Puissance à gauche du
signe d'affectation qui donne une valeur à la fonction et l'appel de la fonction
puissance qui se trouve à droite et qui donc "relance" la fonction
3. La variable n doit être passée en valeur sous peine de voir sa valeur "écrasée" par
les appels successifs de la fonction. En revanche le passage de A est indifférent
dans la mesure où cette variable est inchangée dans la fonction
4. Dans le cas où le passage en valeur serait impossible (Tableau, type utilisateur par
exemple), il est nécessaire de créer des variables locales dans la fonction ou la
procédure. Leur portée étant limitée à la copie en cours de la fonction.
15 Exécution d'une procédure ou fonction récursive :
Nous allons suivre ici l'exécution de l'instruction de la procédure appelante
X = puissance( 5, 3)
1.
Une première "copie" de la fonction est créée en mémoire avec des variables locales
A1 =5 et n1=3
L'exécution est suspendue à l'instruction (2) car puissance( 5,2) est inconnue
2.
Une deuxième copie de la fonction est alors créée avec les variables locales
A2=5 et n2=2
L'exécution est suspendue à l'instruction (2)
G. Mauffrey
Introduction à la programmation VBA
page 34/51
3.
Une troisième copie de la fonction est créée avec les variables locales
A3=5 et n3=1
L'exécution est suspendue à l'instruction (2)
4.
3b.
Cette fois ci, avec A4=5 et n5=0, la copie s'exécute est retourne
puissance(5,0)=1
La troisième copie peut se terminer et retourne alors
Puissance(5,1)=5
2b.
La deuxième copie peut se terminer et retourne alors
Puissance(5,2) = 25
1b.
La première copie se termine et retourne au programme appelant
Puissance(5,3)=125
La récursivité permet de programmer de façon plus simple et souvent plus « lisible », mais en
revanche cette méthode utilise plus de mémoire que les méthodes classiques et le temps
d’exécution d’un programme peut rapidement dégénérer (cf. exercice 2)
G. Mauffrey
Introduction à la programmation VBA
page 35/51
16 Exercices
Exercice n°1
Ecrire une fonction récursive permettant de calculer n !
Exercice n°2
On rappelle que les nombres de Fibonnacci sont définis par
F(1)=F(2)=2
F(n)=F(n-1)+F(n-2)
a) Ecrire une fonction récursive permettant de calculer le nième nombre de Fibonnacci
b) Ecrire une fonction non récursive permettant de calculer ce nombre
c) Comparer les temps d’exécution pour n=30, expliquer cette différence.
Exercice n°3
Reprendre l'exercice de fusion de deux listes et l'écrire sous forme récursive
Exercice n°4
On vous donne la liste suivante :
Père
Jules
Jules
Marius
César
Bernard
Edouard
Gustave
Fils
Marius
César
Bernard
Edouard
Noël
Hubert
Jules
Il s’agit d’écrire un programme permettant de déterminer les ancêtres d’une personne choisie
dans la liste des fils.
On pourra améliorer ce programme, en sortant l’arbre généalogique de la personne choisie
pour obtenir par exemple :
Gustave
G. Mauffrey
Jules
Marius
Bernard
Noël
César
Edouard
Hubert
Introduction à la programmation VBA
page 36/51
Exercice n°4 : Quelques Fractales
a) La courbe de van Koch
En partant d’un segment de longueur L0 (F0), on définit un générateur qui transforme ce
segment en quatre segments de longueur L1=L0/3 (F1). Puis ce générateur est appliqué à
chacun des 4 segments de F1 (F2) etc..
F0
F1
F2
On obtient ainsi, à la limite, une courbe continue, de longueur infinie (puisque la longueur est
multipliée par 4/3 à chaque étape) et non différentiable. Seules les extrémités des segments de
chaque étape sont conservées dans la courbe finale.
On appelle résolution la longueur minimale qu’un observateur peut distinguer, ceci revient à
arrêter le processus de construction à l’étape où la longueur d’un segment est inférieure ou
égale à cette résolution. Construire un programme permettant de construire la courbe de van
Koch à une résolution donnée :
Indications : On définira de façon récursive la transformation d’un segment en quatre
segments, en définissant les extrémités des nouveaux segments. Pour ceux qui auraient oublié
leur trigonométrie, voici les formules définissant ces coordonnées (dans le repère d’une
feuille graphique) x0deb,y0deb définissent les coordonnées de l’extrémité initiale du segment,
x0fin, y0fin celles de l’extrémité finale. Avec des notations évidentes :
x1deb = x0deb
x1fin = (2 * x0deb + x0fin) / 3
y1deb = y0deb
y1fin = (2 * y0deb + y0fin) / 3
x2deb = x1fin
x2fin = x2deb + (x0fin – x0deb) / 6 + (y0fin – y0deb) * Sqr(3) / 6
y2deb = y1fin
y2fin = y2deb - (x0fin – x0deb) * Sqr(3) / 6 + (y0fin – y0deb) / 6
x3deb = x2fin
x3fin = x3deb + (x0fin – x0deb) / 6 - (y0fin – y0deb) * Sqr(3) / 6
y3deb = y2fin
G. Mauffrey
Introduction à la programmation VBA
page 37/51
y3fin = y3deb + (x0fin – x0deb) * Sqr(3) / 6 + (y0fin – y0deb) / 6
x4deb = (x0deb + 2 * x0fin) / 3
x4fin = x0fin
y4deb = (y0deb + 2 * y0fin) / 3
y4fin = y0fin
On partagera le segment suivant le générateur jusqu'à ce que la résolution soit atteinte, alors
on tracera le segment correspondant.
Voir en annexe les indications pour ouvrir une feuille graphique et tracer des segments sous
Excel
Si on part d'un carré, au lieu d'un segment on obtient alors le flocon :
b) Le triangle de Sierpinski
A partir d’un triangle équilatéral (F0), on partage ce triangle en quatre triangles équilatéraux
dont on ne conserve que les trois "extérieurs" (F1) l'opération étant alors répétée sur ces trois
triangles conservés(F2) ; l'opération se répète indéfiniment. Ici ce sont les côtés qui sont
F0
F1
1.1.1
conservés dans la fractale finale.
Ecrire un programme, permettant de construire cette fractale à une résolution donnée :
Remarque : on pourra utiliser les types suivants définis par l'utilisateur :
G. Mauffrey
Introduction à la programmation VBA
page 38/51
Type MonPoint
Abscisse as Integer
Ordonnée as Integer
End Type
Type Triangle
Sommets(1 To 3) as MonPoint
End Type
Indications : On construira les triangles intérieurs à un triangle donné, jusqu'à ce que la
résolution voulue soit atteinte auquel cas on tracera le triangle correspondant.
G. Mauffrey
Introduction à la programmation VBA
page 39/51
17 Annexe 1 - Utilisation des dessins sous Excel1.
Les dessins sont sous Excel des objets de la collection "Shapes" qui est une propriété d'une
feuille de calcul ou graphique. Ils sont donc obtenus en ajoutant des objets sur une feuille bien
définie.
a) Ajout d'une feuille graphique à un classeur.
Les instructions suivantes ajoute une feuille graphique au classeur, l'associe à la variable
mondessin, puis détermine la taille de la zone de graphique et enfin donne un nom à la feuille
ainsi créée
ActiveWorkbook.Sheets.Add Type:=xlChart
Set mondessin = ActiveChart
With mondessin.ChartArea
hauteur = .Height
largeur = .Width
End With
mondessin.Name = "triangle"
L'origine des coordonnées de la feuille se trouve dans le coin supérieur gauche de la feuille.
b) Ajout d'un segment sur une feuille.
Sur la feuille graphique précédemment créer, on peut ajouter un segment de droite joignant le
point de coordonnées x1,y1 au point de coordonnées x2,y2 :
Set line = mondessin.Shapes.AddLine(x1, y1, x2, y2)
c) Ajout d'un triangle
On pourrait bien évidemment construire un triangle à l'aide de trois segments comme indiqué
au-dessus, cependant dans ce cas la figure ne serait pas considérer comme "fermée" et le
remplissage serait délicat à faire. Nous allons donc utiliser des primitives de polygone fermé,
qui contienne les fonctions de remplissage, ce sont les "formes libres". Voici la suite
d'instructions pour créer un polygone de sommet (x0,y0), (x1,y1), …, (xn,yn).
With mondessin.Shapes.BuildFreeform(msoEditingAuto, x0, y0)
'Initialise le polygone par son premier sommet
.AddNodes msoSegmentLine, msoEditingAuto, x1, y1
.AddNodes msoSegmentLine, msoEditingAuto, x2, y2
'Ajout des différents sommets
.AddNodes msoSegmentLine, msoEditingAuto, xn, yn
'Ne pas oublier de fermer
.AddNodes msoSegmentLine, msoEditingAuto, x0, y0
'Sauvegarder dans une variable le polygone fermé
Set montruc = .ConvertToShape
'Remplir d'une couleur
montruc.Fill.ForeColor.RGB = RGB(100, 100, 100)
End With
1
Pour d'autres types de dessin, vous pouvez utiliser l'enregistrement automatique de macro et regarder le code
obtenu.
G. Mauffrey
Introduction à la programmation VBA
page 40/51
18 Annexe 2 – Quelques éléments sur la courbe de Koch en tant que fractale
La lecture de cette annexe n'est pas indispensable pour la réalisation des programmes.
La courbe de Koch est un exemple simple de fractale auto-similaire, à chaque résolution on
retrouve le même motif (générateur), si la dimension topologique de cette courbe est la même
que celle d'une droite, c'est à dire 1, on "devine" qu'elle occupe plus de place dans le plan
qu'une courbe classique (différentiable) car elle se replie beaucoup sur elle-même ; c'est pour
cela que sa longueur est infinie, alors qu'elle définit un ensemble fermé et borné (un compact
de R2). Toutefois elle ne remplit pas entièrement une surface telle qu'un carré : sa surface est
nulle, d'où l'idée de définir une dimension pour laquelle sa longueur sera finie ; cette
dimension sera strictement comprise entre 1 et 2.
Soit une courbe de longueur finie L, elle peut être approximée par L* (1/ε) segments de
longueur ε, de même une surface finie S peut être approximée par S*(1/ε)2 carrés de côté.
Ici pour approximer la courbe de van Koch avec des segments de longueur (1/3)n, il en faut
L0*(4)n, on peut alors définir comme dimension de cette courbe le nombre DF tel que :
4n=(3n)DF
c'est à dire :
DF = log(4)/log(3)
La "longueur" de la courbe de van Koch dans cet espace fractal est alors L0!
La construction faite pour la courbe de van Koch peut être généralisée, à partir d'un
générateur qui partage un segment donné en p segments égaux de longueur égale à 1/q fois le
segment initial, la dimension de la fractale obtenue étant alors : log(p)/log(q).
Exemple : si l'on considère le générateur suivant :
On obtient une fractale de dimension 4/3, car ici p=4 et q=2*racine(2)
G. Mauffrey
Introduction à la programmation VBA
page 41/51
19 Annexe 3 – A propos du triangle de Sierpinski
Le triangle de Sierpinski propose, en quelque sorte, une approche duale de van Koch de la
construction de fractale puisque ici, partant d'une surface, on obtient un ensemble de
dimension inférieure. L'origine de cette construction peut se trouver dans l'ensemble de
Cantor (exemple classique d'ensemble ne contenant aucun intervalle et compact, avec
beaucoup d'autres propriétés intéressantes) défini à partir du schéma générateur :
F0
F1
Ce qui conduit à la "poussière" de Cantor de dimension log2/log3 :
Le triangle de Sierpinski a comme dimension fractale log3/log2.
On peut passer en dimension 3 avec un cube et le schéma générateur suivant :
On obtient alors l'"éponge" de Sierpinski de dimension log22/log3
Pour en savoir plus sur les fractales, voici une bibliographie sommaire :
-
Mandelbrot , B., Les objets fractals (avec une introduction au mouvement brownien
fractionnaire utilisé en finance par exemple) – NSB Flammarion, Paris, 1989
-
Le Méhauté, A., Les géométries Fractales (est abordée ici la différenciation fractionnaire)
– Hermès, Paris, 1990
-
Nottale, L., Fractal Space-Time and Microphysics (avec application à la physique et
quelques liens avec le chaos) – World Scientific 1993
G. Mauffrey
Introduction à la programmation VBA
page 42/51
Introduction à la programmation Objet
20 Généralités
Traditionnellement la programmation sépare le code (instructions) des données. Par exemple
en Pascal, les données sont spécifiées dans des structures, et le code est regroupé en unités
(les procédures et les fonctions). Les fonctions (ou procédures) et les structures ne sont pas
formellement reliées dans les langages traditionnels, une fonction peut être utilisée sur
différentes structures et une structure peur utiliser des fonctions différentes qui ne lui sont pas
propres.
Dans la programmation objet le code et les données sont rassemblés dans une entité appelée
"Objet". Cet objet peut être considéré comme une boîte noire qui reçoit et envoie des
messages à un autre objet ou à un programme ‘traditionnel’.
Un objet est composé de données définissant ses caractéristiques (propriétés) et d'une
interface permettant de traiter les messages reçus ou d'envoyer des messages, cette interface
2
Message
Propriétés
est composée de procédures, fonctions et réponses à des évènements, appelées méthodes.
Seules les méthodes sont accessibles de l'extérieur de l'objet (Principe d'encapsulation des
données).
Les objets de même nature font partie d'une même classe, qui est la description abstraite des
propriétés et méthodes des objets, l'équivalent en fait du type pour une variable. Cette classe
est en fait un sous programme qui se suffit à lui-même, un utilisateur externe n'a pas besoin de
connaître le contenu exact de ce programme mais seulement l'interface, ce qui permet la
réutilisation des objets, sous forme compilée, dans différents programmes.
La déclaration de cette classe comportera donc des variables correspondant aux propriétés et
des procédures ou fonctions correspondant aux méthodes. Les variables correspondant aux
propriétés ne doivent pas être directement accessibles à l'utilisateur, mais sont accessibles par
de méthodes particulières.
20.1 Un exemple : l'objet nombre complexe.
Les propriétés de cet objet peuvent être :
Partie réelle
Partie imaginaire
Module
Argument
Les méthodes :
G. Mauffrey
Ecriture d'un nombre sous forme algébrique (x+iy)
Ecriture d'un nombre sous forme géométrique (r,θ)
Introduction à la programmation VBA
page 43/51
Addition de deux nombres complexes
Multiplication de deux nombres complexes
Etc..
20.2 Utilisation d'objets dans un programme
Pour utiliser un objet dans un programme, il faut lui associer une variable qui a comme type
le nom de la classe d'objets. Il faut ensuite réserver la place mémoire nécessaire au stockage
des propriétés de cet objet, ceci se fait dans de nombreux langages et en VBA en particulier
par la fonction New ( voir ci-dessous).
Les propriétés et méthodes de l'objet sont appelées en indiquant
nom_variable_objet.méthode
ou
nom_variable_objet.propriété
21 Définition d'une classe d'objets sous VBA
Pour satisfaire les contraintes énoncées précédemment, la classe d'un objet doit être définie
dans un module qui lui est propre, c'est ce que VBA appelle un module de classe. Pour créer
un module de classe, utiliser le menu Insertion-Module de Classe, puis dans les propriétés du
module de classe donner un nom à la classe ainsi créée.
Les variables de stockage des propriétés seront déclarées comme Private, en revanche les
méthodes accessibles à l'utilisateur seront déclarées comme Public.
Remarque : dans un module de classe, il peut exister des procédures ou fonctions qui ne sont
utilisées que par ce module et sont donc cachées à l'utilisateur, dans ce cas il faut bien sur les
déclarer comme Private.
21.1 Déclaration des propriétés
La déclaration des propriétés d'un objet se fait en deux temps :
Déclaration d'un espace de stockage privé associé
Déclaration de procédure de communication pour l'affectation de valeur aux
propriétés ou la lecture de la valeur de la propriété par un utilisateur externe :
Procédure Property Let pour l'affectation d'une valeur à un type non-objet
Procédure Property Set pour l'affectation d'une valeur à une propriété objet
Fonction Property Get pour la lecture de la valeur d'une propriété
Remarque importante : C'est le nom associé aux procédures ou fonctions ‘property’ qui
définissent le nom de la propriété, c'est à dire le nom connu des utilisateurs ; le nom des
variables de stockage privées est évidemment ignoré de l'utilisateur et peuvent être
quelconques. Il est recommandé de ne pas utiliser les noms des zones de stockage dans les
méthodes (mis à part les procédure Property), mais le nom des propriétés.
Par exemple pour la classe des nombres complexes, pour la propriété partie réelle on fera les
déclarations suivantes :
Private M_reel as double
zone de stockage privée
Public Property Let Reel (ByVal x as double)
M_reel = x
‘(code complémentaire éventuel)
End Property
G. Mauffrey
Fin de la procédure d'affectation
Introduction à la programmation VBA
page 44/51
Remarque : cette procédure est appelée d'un programme par l'instruction :
(Dim Moncomplexe as complexe)
Moncomplexe.Reel = unevaleur
Où ‘moncomplexe’ est une variable objet de la classe des nombres complexes, la valeur une
valeur est alors stockée dans la variable locale à la classe ‘M_reel’.
Public Property Get Reel() as double
Reel =M_reel
End Property
Fin de la fonction de lecture
Remarque : cette fonction est appelée d'un programme par l'instruction
Autreval = Moncomplexe.Reel
La valeur de la variable locale (à la classe) M_reel est alors stockée dans la variable du
programme appelant Autreval.
Certaines propriétés peuvent n'être qu'en lecture, c'est à dire qu'un utilisateur n'aura pas le
droit d'en changer directement la valeur, dans ce cas, il suffit de ne pas écrire dans la classe de
procédure Property Let ou Property Set (ou mieux encore de l'écrire avec le mot clé Private),
voir dans l'exemple le cas du module et de l'argument.
21.2 La procédure d'initialisation
Pour chaque classe d'objet, il est nécessaire de créer une procédure d'initialisation qui est
appelée par l'instruction New. Cette procédure initialise les variables de stockage de l'objet à
des valeurs par défaut, et par ce fait réserve l'espace mémoire de l'objet. Cette procédure est
privée, sans paramètre et a pour nom Class_Initialize
Par exemple pour les nombres complexes, on pourrait avoir la procédure suivante :
Private Sub Class_Initialize()
reel = 0
imaginaire = 0
module=0
argument=0
End Sub
Cette procédure sera appelée dans le programme principal par l'instruction :
Set moncomplexe = New complexe
Comme dans cette procédure les noms de propriétés ne sont pas précédées d'un "." Cela
signifie que ces noms se rapportent à l'objet courant, c'est à dire l'objet qui a appelé la
méthode.
Remarque : dans certains cas, par exemple s'il existe un dessin associé à l'objet, il est
nécessaire de faire certaines opérations quand l'objet est "détruit" par l'instruction :
Set nom_objet = Nothing
Il faut alors écrire une méthode privée appelée Class_terminate.
G. Mauffrey
Introduction à la programmation VBA
page 45/51
21.3 Ecriture de méthodes
L'écriture de méthodes est identique à l'écriture de procédure ou de fonction dans un
programme "classique", simplement le nom donné à la procédure ou fonction est le nom de la
méthode connue de l'utilisateur. Bien évidemment ces procédures doivent être déclarées
comme Public.
Exemples :
a- Méthode mise à zéro d'un nombre complexe, cette méthode sera appelée par l'instruction :
Moncomplexe.mis_a_0
Public Sub mis_a_0 ()
Reel = 0
Imaginaire=0
End Sub
Remarque : comme Reel n'est pas précédée d'un . elle fait référence à l'objet appelant.
b- Ecriture algébrique d'un nombre complexe, cette méthode retourne un "String" contenant
l'écriture x+iy, elle est appelée par l'instruction :
Chaine = Moncomplexe.ecrit_algeb
Public Function ecrit_algeb () as String
Ecrit_algeb=Cstr(Reel) & " + i " & Cstr(Imaginaire)
End Function
c- Terminons avec une méthode un peu plus délicate, la multiplication de deux nombres
complexes, le résultat étant stocké dans un troisième. L'appel sera fait par l'instruction :
comp3 = comp1.mult(comp2)
où comp1, comp2 et comp3 sont des variables objet ‘complexe’.
Dans cette méthode nous devons créer un nouvel objet qui recevra le résultat, ce qui est fait
par l'instruction New, le reste du code est assez simple :
Public Function Mult( autrec as complexe) as complexe
Set Mult = New complexe
'crée l'objet
With autrec
Mult.Reel = .Reel*Reel -.Imaginaire*Imaginaire
Mult.Imaginaire=.Reel*Imaginaire+.Imaginaire*Reel
End With
End Function
21.4 Enregistrement d'une classe
Comme une classe est autosuffisante, il est bon de l'enregistrer en tant que module de classe
indépendant réutilisable dans tous les programmes visual basic ; ceci se fait en exportant le
module qui prend alors un nom d'extension ‘cls’.
21.5 Utilisation d'objets dans un programme
Pour utiliser des objets dans un programme, il faut déclarer des variables du type de l'objet,
par la déclaration Dim :
G. Mauffrey
Introduction à la programmation VBA
page 46/51
Dim machin as nom_de_classe
Réserver l'espace de stockage par l'instruction new :
Set machin = new nom_de_classe
Ensuite l'appel des méthodes se fait en utilisant le nom de la variable objet. le nom de la
méthode, avec les conventions habituelles suivant que la méthode correspond à une fonction
ou une procédure. Quand l'utilisateur, au moment de l’écriture de son programme, tape le
point, il apparaît une fenêtre contextuelle, avec toutes les propriétés et méthodes de la classe
d'objet.
22 Un exemple de module de classe : la classe des complexes
Voici le début de la définition de la classe des complexes, les conventions suivantes ont été
choisies :
L’utilisateur peut lire et écrire les parties réelles et imaginaires d’un nombre
complexe, en cas d’écriture le module et l’argument sont recalculés (procédure
privée calmodarg)
L’utilisateur ne peut que lire le module et l’argument de façon indépendante, il
faudra créer une méthode de saisie du couple (cf. exercice1)
Seules les méthodes de multiplication et d’écriture ont été implémentées
Le fichier correspondant est accessible sur le site Web.
Const pi As Double = 3.14159265358979
Dim m_reel As Double
Dim m_imaginaire As Double
Dim m_module As Double
Dim m_argument As Double
Public Property Let reel(ByVal p_reel As Double)
m_reel = p_reel
calmodarg
End Property
Public Property Get reel() As Double
reel = m_reel
End Property
Public Property Let imaginaire(ByVal p_imaginaire As Double)
m_imaginaire = p_imaginaire
calmodarg
End Property
Public Property Get imaginaire() As Double
imaginaire = m_imaginaire
End Property
G. Mauffrey
Introduction à la programmation VBA
page 47/51
Public Property Get module() As Double
module = m_module
End Property
Private Property Let module(ByVal modu As Double)
m_module = Abs(modu)
End Property
Public Property Get argument() As Double
argument = m_argument
End Property
Private Property Let argument(ByVal angle As Double)
m_argument = angle
End Property
Private Sub Class_Initialize()
reel = 0
imaginaire = 0
calmodarg
End Sub
Private Sub calmodarg()
module = reel ^ 2 + imaginaire ^ 2
module = Sqr(module)
If module = 0 Then
argument = 0
Else
If reel = 0 Then
argument = Sgn(imaginaire) * pi / 2
Else
argument = Atn(imaginaire / reel)
argument = (1 - Sgn(reel)) * pi / 2 + argument
End If
End If
End Sub
Public Function mult_compl(autrec As complexe) As complexe
Set mult_compl = New complexe
With autrec
mult_compl.reel = reel * .reel - imaginaire * .imaginaire
mult_compl.imaginaire = reel * .imaginaire + imaginaire * .reel
G. Mauffrey
Introduction à la programmation VBA
page 48/51
End With
End Function
Public Function ecriture_cart() As String
ecriture_cart = CStr(reel) & " + " & CStr(imaginaire) & "i"
End Function
Public Function ecriture_geom() As String
ecriture_geom = module & " exp(" & argument & "i)"
End Function
Private Sub calmodarg()
module = reel ^ 2 + imaginaire ^ 2
module = Sqr(module)
If module = 0 Then
argument = 0
Else
If reel = 0 Then
argument = Sgn(imaginaire) * pi / 2
Else
argument = Atn(imaginaire / reel)
argument = (1 - Sgn(reel)) * pi / 2 + argument
End If
End If
End Sub
Public Function mult (autrec As complexe) As complexe
Set mult = New complexe
With autrec
mult.reel = reel * .reel - imaginaire * .imaginaire
mult.imaginaire = reel * .imaginaire + imaginaire * .reel
End With
End Function
Public Function ecriture_cart() As String
ecriture_cart = CStr(reel) & " + i" & CStr(imaginaire)
End Function
Public Function ecriture_geom() As String
ecriture_geom = module & " exp(i" & argument & ")"
End Function
G. Mauffrey
Introduction à la programmation VBA
page 49/51
23 Exercices
23.1 Compléter la classe des nombres complexes
Ecrire les méthodes permettant de :
Additionner deux nombres complexes
Multiplier un nombre complexe par un nombre réel, le résultat étant stocké dans le
nombre complexe initial (correspondrait à l’instruction "classique" z=λ*z)
Saisir le module et l'argument d'un nombre complexe, la méthode doit alors
calculer les parties réelle et imaginaire du nombre.
Bien évidemment il vous faudra aussi écrire un programme permettant de tester ces nouvelles
méthodes.
23.2 Relation entre deux tables
On considère une liste d'entreprises (Table ‘Père’) avec leur localisation, chaque entreprise
étant caractérisée par un code, et d'autre part une liste de contacts dans ces entreprises (Table
‘Fils’), contenant le nom de la personne, le code de la société à la quelle elle appartient, son
service.
Code Société Nom
12 LilleHaut
14 MegaSoft
15 Packard
Adresse
Roubaix
Lyon
Bordeaux
Nom
Dupond
Durand
Jules
Germain
Fortin
Gremont
Boudard
Fonction
Code Société
Marketing
12
Finance
15
Compta
14
DRH
12
Informatique
15
Planification
11
Production
12
Construire un objet relation entre ses tables, cet objet doit mettre en relation le code société
des deux tables et permettre :
De vérifier qu'aucun code de la table fils n'est erroné
D'afficher tous les contacts pour une entreprise donnée
De supprimer une société et tous les contacts associés
Indications :
La relation sera définie comme une classe, dont les propriétés contiendront entre autres
l'adresse des tables, l'adresse du code en relation
L'affichage de tous les contacts pourra se faire par exemple en coloriant la zone correspondant
à la société et les zones correspondant aux contacts, on pourra par exemple supposer que la
société choisie correspond à la cellule active de la feuille. Exemple :
G. Mauffrey
Introduction à la programmation VBA
page 50/51
Code Société Nom
12 LilleHaut
14 MegaSoft
15 Packard
Adresse
Roubaix
Lyon
Bordeaux
Nom
Dupond
Durand
Jules
Germain
Fortin
Gremont
Boudard
Fonction
Code Société
Marketing
12
Finance
15
Compta
14
DRH
12
Informatique
15
Planification
11
Production
12
La cellule sélectionnée est associée en VBA à la variable objet de type Range : Selection.
Le remplissage d'une cellule peut se faire avec l'instruction :
Cells(i, j).Interior.Colorindex = n
Où n est un entier compris entre 1 et 56 représentant la couleur de numéro n dans la palette,
pour indiquer aucun remplissage on utilise la valeur xlColorIndexnone.
Remarque : il faudra bien sûr prévoir une méthode remettant à blanc la sélection.
Une autre façon de procéder pourrait consister à afficher les contacts d'une société quand
l'utilisateur clique sur une cellule contenant le code d'une société, dans ce cas il faut utiliser la
procédure Worksheet_SelectionChange(ByVal Target As Excel.Range) de la feuille de
calcul contenant les tables, le code à écrire dans cette procédure consisterait à vérifier que la
cellule sélectionnée (Target) est bien une cellule contenant un code, puis à sélectionner les
contacts correspondant :
On Error goTo Fin
'pour le cas où l'objet ‘ma relation’ n'est pas initialisé
If marelation.contient(Target) then
Marelation.Traitement
End if
Fin:
23.3 La classe triangle
Construire une classe triangle, dont les propriétés sont les sommets, la couleur de remplissage,
etc.., dont les méthodes sont entre autres : le dessin du triangle et certaines transformations
géométriques (translation , homothétie par exemple)
G. Mauffrey
Introduction à la programmation VBA
page 51/51

Documents pareils