FAQ Excel
FAQ ExcelConsultez toutes les FAQ
Nombre d'auteurs : 46, nombre de questions : 845, dernière mise à jour : 30 mars 2022
- Comment programmer efficacement en VBA Excel ?
- Comment utiliser l'éditeur de macros ?
- Où peut-on trouver un recensement et des explications sur les syntaxes de base du langage VBA ?
- Comment créer un certificat local pour les macros VBA ?
- Comment utiliser les variables en VBA ?
- Comment manipuler l'éditeur de macros par macro ?
- Comment manipuler les chaînes de caractères en VBA Excel ?
- Comment stopper une macro qui ne veut plus s'arrêter ?
- Comment protéger les macros par mot de passe ?
- Comment vérifier si un projet VBA est protégé ?
- Comment remplacer un mot dans toutes les procédures d'un classeur ?
- Comment supprimer une macro par le code ?
- Comment supprimer tous les modules vides dans le classeur actif ?
- Ou trouver la traduction des mots clés Visual Basic ?
- Quelle est la différence entre ByRef et ByVal ?
- Comment effectuer une temporisation dans une macro ?
- Peut-on appeler une macro d'un autre classeur ?
- Où se trouve l'onglet de gestion des macros, dans Excel 2007 ?
- Comment gérer les macros complémentaires dans Excel 2007 ?
- Comment affecter un caractère guillemet à une variable ?
- Comment tester la présence d'un argument optionnel dans une fonction ?
- Comment importer un module type cls dans un module ThisWorkbook ?
- Comment utiliser les variables tableaux ?
- Quels sont les différents types de boucles utilisables en VBA ?
- Comment lancer une procédure qui contient des arguments lorsque l'on utilise la méthode OnTime ?
- Comment définir une donnée par défaut pour un argument de procédure type Optional ?
- Comment vérifier par le code si l'option 'Faire confiance au projet visual basic' est cochée ?
- Comment vérifier si un classeur contient des macros ?
- Comment suivre l'évolution des variables lorsque je teste mes macros ?
- Comment fonctionnent les APIs ?
- Que signifie le symbole \ (antislash) dans un code VBA ?
- Existe t'il une liste pour connaitre la propriété par défaut des objets ?
- Que signifie le message d'erreur 'L'accès par programme au projet VB n'est pas fiable' ?
- Comment identifier l'utilisation du bouton "Réinitialiser" (Stop) dans l'éditeur de macros ?
- Comment mettre à jour automatiquement un complément distribué en réseau local ?
- Pourquoi ma variable ne change pas dans la procédure appelante lorsque j'utilise l'instruction ByRef ?
- Comment installer et piloter un fichier xll ?
- Pourquoi parfois lors de l'ouverture des classeurs, l'alerte de sécurité des macros n'est pas toujours la même, sous Excel 2007 ?
- A quel moment une variable Publique est-elle vidée ?
- Comment lister le nom de toutes les procédures contenues dans un classeur ?
- Pourquoi les fonctions VBA renvoient des messages d'erreur sur certains postes ?
- A quoi sert la transaction 'Compiler VBAProject' ?
- Comment exécuter une macro d'un fichier Excel déjà ouvert dans une autre instance ?
- Ou se trouve l'accès aux références relatives de l'enregistreur de macros sous Excel 2007 ?
- Comment calculer le cosinus, le sinus ou la tangente d'un angle, par VBA ?
- Comment ajouter et gérer des boutons personnels dans la barre de menus de l'éditeur de macros ?
- 27.1. Les UserForm et les contrôles (52)
- 27.2. Les fonctions aléatoires (7)
- 27.3. piloter d'autres applications depuis Excel (56)
- 27.4. Les répertoires et les fichiers (21)
- 27.5. Les modules de classe (3)
- 27.6. Le PC et le système d'exploitation (12)
Consultez le cours de J-M RABILLOUD : Support de cours complet pour le VBA d'Excel.
Consultez le tutoriel pour faire vos premiers pas dans l'éditeur de macros Excel.
Consultez le tutoriel de Maxence Hubiche.
Lorsque le niveau de sécurité intrinsèque des documents Office est réglé sur moyen ou élevé, il est alors impossible d'activer automatiquement les macros d'un document.
La première solution consiste à régler le niveau de sécurité sur faible (Menu Outils >> Macros >> Sécurité...), mais ce n'est pas très recommandé.
L'autre solution consiste à auto-certifier les macros d'un document.
Un certificat local, valable uniquement sur la machine sur laquelle il est installé, va vous permettre d'éviter le
désagrément d'avoir à confirmer l'activation des macros à l'ouverture d'un document, ou pire, la désactivation
systématique des macros.
Comment procéder :
* Rechercher dans le répertoire d'installation de Microsoft Office (généralement C:\Program Files\Microsoft Office\OfficeXX) le programme SelCert.exe
* Exécuter SelfCert.exe
* Renseigner le nom du certificat dans la zone de texte et valider
* Fermer SelfCert.exe
* Ouvrir le document Office dont les macros doivent être certifiées
* Dans l'éditeur VBA (Alt-F11), menu Outils >> Signature électronique ...
* Cliquer sur "Choisir..." et sélectionner le certificat précédemment créé
* Enregistrer le document
A la prochaine ouverture du document, une alerte de sécurité va apparaître, cocher alors la case "Toujours faire confiance au macros provenant de... ".
Pour supprimer un certificat existant :
* Panneau de configuration >> Options Internet
* Onglet Contenu, cliquer sur Certificats...
* Sélectionner le certificat et cliquer sur Supprimer
Consultez le tutoriel pour utiliser les variables en VBA Excel.
Consultez le tutoriel pour manipuler l'éditeur de macros par macro.
Consultez le tutoriel pour manipuler les chaînes de caractères en VBA Excel.
Lorsqu'une macro tourne en boucle et ne veut plus s'arrêter, utilisez les touches clavier :
Ctrl + Pause
Vous pouvez aussi essayer la touche ECHAP.
Ouvrez l'éditeur de macros (Alt+F11).
Activez votre projet.
Menu Outils.
Sélectionnez "Propriétés de VBA Project".
Sélectionnez l'onglet "Protection".
Cochez la case "Verrouiller le projet pour affichage".
Indiquez et confirmez un mot de passe.
Cliquez sur le bouton OK pour valider.
Le code VBA sera protégé par mot de passe lors de la prochaine ouverture du classeur.
Sub
Test
(
)
MsgBox
IsProtectedProjetVBE
(
Workbooks
(
"NomClasseur.xls"
))
End
Sub
Function
IsProtectedProjetVBE
(
Wb As
Workbook) As
Boolean
Dim
i As
Integer
On
Error
Resume
Next
i =
Wb.VBProject.VBComponents.Count
On
Error
GoTo
0
IsProtectedProjetVBE =
IIf
(
i =
0
, True
, False
)
End
Function
Cet exemple remplace la chaîne "Feuil1" par "Feuil3" dans le classeur ouvert nommé "NomClasseur.xls".
Sub
RemplacementMotDansProcedure
(
)
'Nécéssite d'activer la référence
'"Visual basic For Application Extensibility 5.3"
'
Dim
Ancien As
String
, Nouveau As
String
, Cible As
String
Dim
VBComp As
VBComponent
Dim
i As
Integer
Dim
Wb As
Workbook
Set
Wb =
Workbooks
(
"NomClasseur.xls"
)
Ancien =
"Feuil1"
Nouveau =
"Feuil3"
For
Each
VBComp In
Wb.VBProject.VBComponents
For
i =
1
To
VBComp.CodeModule.CountOfLines
Cible =
VBComp.CodeModule.Lines
(
i, 1
)
Cible =
Replace
(
Cible, Ancien, Nouveau)
VBComp.CodeModule.ReplaceLine
i, Cible
Next
i
Next
VBComp
End
Sub
Vous devez connaître le nom de la macro et le nom du module dans lequelle elle se trouve.
Vous devez ajouter la référence "Microsoft visual Basic For Application Extensenbility x.x" à votre projet :
'Supprimer la macro nommée "MaMacro" dans le "module3"
Sub
supprimerUneMacroPrecise
(
)
Dim
Debut As
Integer
, Lignes As
Integer
With
ThisWorkbook.VBProject.VBComponents
(
"Module3"
).CodeModule
Debut =
.ProcStartLine
(
"MaMacro"
, 0
)
Lignes =
.ProcCountLines
(
"MaMacro"
, 0
)
.DeleteLines
Debut, Lignes
End
With
End
Sub
Sub
supprimerTousModulesVides
(
)
Dim
vbComp As
VBComponent
Dim
i As
Integer
, j As
Integer
For
Each
vbComp In
ActiveWorkbook.VBProject.VBComponents
If
vbComp.Type
=
1
Then
i =
vbComp.CodeModule.CountOfDeclarationLines
+
1
j =
vbComp.CodeModule.CountOfLines
If
j <
i Then
ActiveWorkbook.VBProject.VBComponents.Remove
vbComp
End
If
Next
End
Sub
Recherchez le fichier Excel nommé VBALIST.xls sur votre PC.
Il est généralement stocké à l'emplacement :
C:\Program Files\Microsoft Office\Office10\1036
Ce classeur contient la liste des mots clés Visual Basic et leur traduction Français/Anglais.
ByRef permet de passer à une procédure l'adresse d'un argument plutôt que sa valeur. La procédure peut ainsi
accéder à la variable proprement dite. La valeur réelle de cette dernière peut, de ce fait, être modifiée par la procédure
à laquelle elle a été passée. Par défaut, les arguments sont passés par référence.
Si la procédure appelée change la valeur de ces variables, elle changeront au retour dans la procédure appelante.
ByVal permet de passer à une procédure la valeur d'un argument plutôt que son adresse. La procédure peut de ce fait
accéder à une copie de la variable. La valeur réelle de cette dernière n'est donc pas modifiée par la procédure
à laquelle elle est passée.
Si la procédure appelée change la valeur des variables, elles ne changeront pas dans la procédure appelante.
L'utilisation de ByVal implique un temps de calcul plus long et nécessite un espace mémoire plus important.
Un exemple de mise en application pour montrer les valeurs prises successivement par la variable Donnee, en fonction du passage par des sous procédures ByRef, ByVal, puis non spécifiée.
Sub
Test
(
)
Dim
Donnee As
Integer
Donnee =
50
MaProcedure_1 Donnee
MsgBox
Donnee
MaProcedure_2 Donnee
MsgBox
Donnee
MaProcedure_3 Donnee
MsgBox
Donnee
End
Sub
'Passe la référence en argument.
Sub
MaProcedure_1
(
ByRef
x As
Integer
)
x =
x *
2
End
Sub
'Passe la valeur en argument.
Sub
MaProcedure_2
(
ByVal
y As
Integer
)
y =
y *
2
End
Sub
'ByRef est la valeur par défaut si non spécifiée.
Sub
MaProcedure_3
(
z As
Integer
)
z =
z *
2
End
Sub
Voici 3 exemples qui appliquent une temporisation d'une seconde dans la procédure :
Option
Explicit
Declare
Sub
Sleep Lib
"kernel32"
(
ByVal
dwMilliseconds As
Long
)
Sub
LaMacro_V01
(
)
'tempo 1 seconde
Sleep 1000
'pause en millisecondes
'la suite de la macro
MsgBox
"test"
End
Sub
Sub
LaMacro_V02
(
)
Dim
t As
Date
'Tempo 1 seconde
t =
Timer +
1
: Do
Until
Timer >
t: DoEvents: Loop
MsgBox
"test"
End
Sub
Sub
LaMacro_V03
(
)
'tempo 1 seconde
Application.Wait
(
Now
+
TimeValue
(
"0:00:01"
))
MsgBox
"test"
End
Sub
Il faut utiliser Run. Cette méthode permet aussi de passer des paramètres.
Supposons que mon classeur "calcul.xls" contienne une fonction Log10 telle que :
Public
Function
Log10
(
ByVal
X As
Single
) As
Single
Log10 =
Log
(
X) /
Log
(
10
#)
End
Function
Il est possible de l'utiliser depuis un autre classeur en faisant
Result =
Application.Run
(
"calcul.xls!Log10"
, 1
.2
)
Ouvrez l'onglet Développeur pour atteindre le menu de gestion des macros.
L'onglet Développeur est constitué de 3 groupes :
Le groupe Code :
* Accéder à l'éditeur de macros (Alt+F11).
* Afficher la classique boîte de dialogue qui liste les macros exécutables (Alt+F8).
* Utiliser l'enregistreur de macros.
* Gérer la sécurité des macros.
Le groupe Contrôles :
* Insérer des contrôles Formulaires ou ActiveX.
* Activer ou désactiver le mode création.
* Afficher la fenêtre Propriétés.
* Visualiser le code de la feuille active.
Le groupe XML :
* Importer et exporter des fichiers xml.
* Actualiser les données.
* Mapper dans le classeur.
Si l'onglet Développeur n'apparaît pas dans le ruban :
Cliquez sur le bouton Office,
puis sur le bouton Options Excel.
Cliquez sur le menu Standard.
Cochez l'option Afficher l'onglet Développeur dans le ruban.
Cliquez sur le bouton OK pour valider.
L'onglet Développeur peut être affiché ou masqué par macro :
Sub
AfficherMasquer_OngletDeveloppeur
(
)
With
Application
If
.ShowDevTools
=
False
Then
.ShowDevTools
=
True
Else
.ShowDevTools
=
False
End
If
End
With
End
Sub
Cliquez sur le bouton Office.
Cliquez sur le bouton Options Excel.
Sélectionnez le menu Compléments.
Choisissez Compléments Excel dans le menu déroulant Gérer (en bas de la fenêtre).
Cliquez sur le bouton Atteindre.
Une première solution consiste à doubler les guillemets :
Dim
MaVariable As
String
MaVariable =
""""
MsgBox
MaVariable
Une autre possibilité consiste à utiliser la fonction Chr et le nombre (34) représentant ce caractère.
Dim
MaVariable As
String
MaVariable =
Chr
(
34
)
MsgBox
MaVariable
Le mot-clé Optional permet de spécifier des arguments facultatifs dans une fonction. Ces arguments doivent être placés en dernière position dans la liste des paramètres.
Attribuez le type Variant aux paramètres optionnels. Ainsi la fonction IsMissing permettra d'identifier les données omises, en renvoyant True si l'argument n'est pas indiqué.
Sub
test
(
)
NomFonction Arg1:=
0
, Arg2:=
56765765
NomFonction Arg1:=
453
NomFonction Arg2:=
56765765
NomFonction
End
Sub
Function
NomFonction
(
Optional
Arg1 As
Variant
, Optional
Arg2 As
Variant
) As
Variant
MsgBox
"Arguments manquants:"
&
vbCrLf
&
_
IsMissing
(
Arg1) &
" / "
&
IsMissing
(
Arg2)
End
Function
Il est possible de sauvegarder la procédure d'un module objet ThisWorkbook en l'enregistrant sur le disque dur (extension de fichier .cls). Vous pouvez ensuite réimporter ce fichier dans un autre classeur, pour par exemple effectuer la mise à jour d'une procédure. Lors de l'import, le fichier va être créé comme un module de classe et non en lieu et place du module ThisWorkbook.
La procédure suivante permet d'automatiser le chargement du fichier .cls et le remplacement des macros dans le module objet ThisWorkbook.
'Nécessite d'activer la référence "Microsoft Visual Basic for Applications Extensibility 5.3"
Dim
Wb As
Workbook
Dim
oModule As
CodeModule
Dim
VbComp As
VBComponent
Dim
x As
Integer
Dim
Cible As
String
Cible =
"NomModule"
'Définit le classeur de destination (qui doit être préalablement ouvert).
Set
Wb =
Workbooks
(
"NomClasseur.xls"
)
'Charge le module dans le classeur
Set
VbComp =
Wb.VBProject.VBComponents.Import
(
"C:\ThisWorkbook.cls"
)
'Le renomme (pour le supprimer plus facilement ultérieurement
VbComp.Name
=
Cible
Set
oModule =
VbComp.CodeModule
'Transfère les données chargées dans ThisWorkbook.
'Attention les données existantes dans "ThisWorkbook" sont écrasées.
With
Wb.VBProject.VBComponents
(
"ThisWorkbook"
).CodeModule
x =
.CountOfLines
.DeleteLines
1
, x
.InsertLines
1
, oModule.Lines
(
1
, oModule.CountOfLines
)
End
With
'Suppression du module précédemment chargé
With
Wb.VBProject.VBComponents
.Remove
.Item
(
Cible)
End
With
Vous pouvez utiliser cette syntaxe :
Sub
Test
(
)
Application.OnTime
Now
+
TimeValue
(
"00:00:03"
), "'NomMacro ""mimi"", 50'"
End
Sub
Sub
NomMacro
(
Arg1 As
String
, Arg2 As
Integer
)
MsgBox
Arg1 &
vbCrLf
&
Arg2
End
Sub
C'est possible en utilisant la syntaxe :
Optional [NomVariable] As [TypeVariable] = [Donnée par défaut]
Sub
Test
(
)
'Renvoie tous les arguments spécifiés
MsgBox
MaProcedure
(
5
, "fifi"
)
'Renvoie 5 et "mimi" car l'argument Optional (strPrenom) n'est pas précisé
MsgBox
MaProcedure
(
5
)
End
Sub
Function
MaProcedure
(
lngValeur As
Long
, Optional
strPrenom As
String
=
"mimi"
)
MaProcedure =
lngValeur &
vbCrLf
&
strPrenom
End
Function
Private
Sub
Workbook_Open
(
)
Dim
vbpName As
String
On
Error
Resume
Next
vbpName =
ThisWorkbook.VBProject.Name
If
vbpName =
vbNullString
Then
MsgBox
"Veuillez cocher ..."
End
Sub
Cette fonction renvoie Vrai ou Faux.
Le classeur à tester doit être ouvert :
'Nécessite d'activer la référence :
'Microsoft Visual Basic for Applications Extensibility 5.3
Function
ContientMacro
(
Wb As
Workbook) As
Boolean
Dim
VbComp As
VBComponent
For
Each
VbComp In
Wb.VBProject.VBComponents
With
VbComp.CodeModule
ContientMacro =
.CountOfDeclarationLines
+
1
<
.CountOfLines
End
With
If
ContientMacro Then
Exit
For
Next
VbComp
End
Function
Dans Excel 2007, vous pouvez utiliser directement la propriété HasVBProject de l'objet Workbook. La propriété renvoie VRAI si le classeur testé contient du code, et FAUX dans le cas contraire.
'le fichier "NomClasseur.xls" doit être préalablement ouvert.
MsgBox
Workbooks
(
"NomClasseur.xls"
).HasVBProject
Vous pouvez afficher la fenêtre "Variables locales" afin de suivre les différentes valeurs prises par les variables
de la procédure en cours d'exécution.
Dans l'éditeur de macros :
Menu Affichage
Sélectionnez "Fenêtre variables locales".
Ensuite exécutez votre code en mode pas à pas (F8).
La valeur des variables s'affiche dans la fenêtre.
La fenêtre est vidée lorsque la procédure est terminée.
Nota :
Vous pouvez accéder à la pile des appels depuis cette fenêtre, en cliquant sur le bouton de droite (...).
La pile énumère les procédures dont l'exécution est en cours.
Une autre solution consiste à utiliser la méthode Debug.Print pour envoyer le contenu des variables dans la fenêtre d'exécution (Ctl+G).
Sub
NomMacro
(
)
Dim
x As
Integer
x =
7
x =
x *
3
Debug.Print
"premier calcul: "
&
x
x =
x +
4
Debug.Print
"deuxième calcul: "
&
x
End
Sub
On entend par API (Application Programming Interface), l'ensemble des fonctions systèmes de l'OS qui peuvent être
appelées à partir du code Visual Basic.
Elles se trouvent dans des fichiers DLL du répertoire système. Par extension, on peut de la même façon utiliser
des fonctions se trouvant dans des DLL non-système.
Consultez le tutoriel de Jean-Marc Rabilloud. L'article vous permettra de comprendre comment utiliser les APIs, les avantages et les risques potentiels.
Le symbole \ (antislash), qu'il ne faut pas confondre avec / (slash), renvoie la partie entière d'une division. Par exemple :
MsgBox
10
/
3
MsgBox
10
\
3
Pour connaitre les valeurs par défaut, il faut consulter l'explorateur d'objets dans l'éditeur VBE (raccourci clavier F2). Ce sont celles dont l'icône possède un point bleu.
Attention : tous les objets n'ont pas forcément de propriété par défaut.
L'application Excel dispose de plusieurs niveaux de sécurité. La protection contre les manipulations de l'éditeur VBE par macro en fait partie. Le message d'erreur 'L'accès par programme au projet VB n'est pas fiable' survient si vous n'avez pas préalablement autorisé ce type d'opération.
Pour rendre utilisables ces procédures, dans les versions antérieures à Excel 2007 :
Menu Outils
Macro
Sécurité
Onglet "Sources fiables"
Cochez les deux options
Cliquez sur le bouton OK pour valider.
Dans Excel 2007 :
Sélectionnez l'onglet Développeur.
Cliquez sur le bouton "Sécurité des macros" dans le groupe "Code".
Paramètres des macros.
Cochez l'option "Accès approuvé au modèle d'objet du projet VBA".
Cliquez sur le bouton OK pour valider.
La référence "Microsoft Visual Basic for Application Extensibility" doit être cochée.
Dans un module standard :
Option
Explicit
Public
instObj As
user
Sub
Instanciation
(
)
Set
instObj =
New
user
End
Sub
Dans un module de classe nommé user :
Option
Explicit
Private
EventHandlers As
Collection
Private
Sub
Class_Initialize
(
)
Dim
VBEControls As
CommandBarControls
Dim
VBEControl As
VbeControlEvent
Dim
j As
Long
MsgBox
(
"Un user vient d'être instancié"
)
Set
EventHandlers =
New
Collection
Set
VBEControls =
Application.VBE.CommandBars.FindControls
(
, 228
)
For
j =
1
To
VBEControls.Count
Set
VBEControl =
New
VbeControlEvent
Set
VBEControl.Control
=
Application.VBE.Events.CommandBarEvents
(
VBEControls
(
j))
EventHandlers.Add
VBEControl
Next
End
Sub
Dans un autre module de classe nommé VbeControlEvent :
Option
Explicit
Public
WithEvents Control As
CommandBarEvents
Private
Sub
Control_Click
(
ByVal
CommandBarControl As
Object, _
handled As
Boolean
, CancelDefault As
Boolean
)
MsgBox
"Click sur stop"
End
Sub
Voici une méthode pour permettre la mise à jour automatique d'un Add-In distribué sur un réseau local d'entreprise.
On peut imaginer le même fonctionnement avec un Add-In sur le net.
Fonctionnement :
- Vous mettez votre add-in à distribuer à un emplacement fixe.
- Vous devez gérer un fichier *.ini qui vérifie toutes les semaines la version.
- Si la version sur le réseau est plus récente, le programme propose la mise à jour.
- La mise à jour consiste à archiver l'actuel add-in avant de copier la nouvelle version.
Les fonctions de lecture/écriture de fichier INI :
Private
Declare
Function
GetPrivateProfileString Lib
"kernel32"
Alias _
"GetPrivateProfileStringA"
(
ByVal
lpApplicationName As
String
, ByVal
lpKeyName As
Any, _
ByVal
lpDefault As
String
, ByVal
lpReturnedString As
String
, ByVal
nSize As
Long
, _
ByVal
lpFileName As
String
) As
Long
Private
Declare
Function
WritePrivateProfileString Lib
"kernel32"
Alias _
"WritePrivateProfileStringA"
(
ByVal
lpApplicationName As
String
, ByVal
lpKeyName As
Any, _
ByVal
lpString As
Any, ByVal
lpFileName As
String
) As
Long
Function
EcrireINI
(
Entete As
String
, Variable As
String
, Valeur As
String
) As
String
Dim
Fichier As
String
Fichier =
"C:\temp\MyAddin.ini"
WriteINI =
WritePrivateProfileString
(
Entete, Variable, Valeur, Fichier)
End
Function
Function
LireINI
(
Entete As
String
, Variable As
String
) As
String
Dim
Retour As
String
Dim
Fichier As
String
Fichier =
"C:\temp\MyAddin.ini"
Retour =
String
(
255
, Chr
(
0
))
LireINI =
Left
$(
Retour, GetPrivateProfileString
(
Entete, ByVal
Variable, ""
, Retour, Len
(
Retour), Fichier))
End
Function
Sur l'évènement Workbook_Open de la macro-complémentaire :
Private
Sub
Workbook_Open
(
)
' check UPDATE
If
LireINI
(
"Main"
, "lastCheckUpdate"
) &
""
=
""
Then
CheckVersion
EcrireINI "Main"
, "lastCheckUpdate"
, Format
(
Now
, "dd/mm/yyyy hh:nn:ss"
)
Else
If
CDate
(
LireINI
(
"Main"
, "lastCheckUpdate"
)) +
7
<
Now
Then
CheckVersion
EcrireINI "Main"
, "lastCheckUpdate"
, Format
(
Now
, "dd/mm/yyyy hh:nn:ss"
)
End
If
End
If
End
Sub
Puis un module de code :
Sub
CheckVersion
(
)
Dim
fso As
FileSystemObject
Dim
ad As
AddIn
Set
fso =
New
FileSystemObject
For
Each
ad In
application.AddIns
If
ad.FullName
Like "*MyAddin.xla"
Then
If
fso.GetFile
(
ad.FullName
).DateLastModified
<
_
fso.GetFile
(
"\\LecteurReseau\...\Divers\MyAddin.xla"
).DateLastModified
Then
rep =
MsgBox
(
"Votre version de l'Add-in n'est plus à jour."
&
vbCrLf
&
_
"Voulez-vous mettre à jour votre Add-in ?"
, vbInformation
+
vbYesNo
, "MyAddin"
)
If
rep =
vbYes
Then
' il faut mettre à jour
On
Error
Resume
Next
Kill Left
(
ad.FullName
, Len
(
ad.FullName
) -
4
) &
"(old).xla"
ThisWorkbook.SaveAs
Left
(
ad.FullName
, Len
(
ad.FullName
) -
4
) &
"(old).xla"
FileCopy _
"\\LecteurReseau\...\Divers\MyAddin.xla"
, _
ad.FullName
MsgBox
"La mise à jour de votre Add-in a été effectuée."
&
vbCrLf
&
_
"Redémarrez Excel pour qu'elle soit effective"
, vbInformation
+
vbOKOnly
, _
"MyAddin"
Else
MsgBox
"La prochaine vérification aura lieu dans une semaine !"
, _
vbCritical
+
vbOKOnly
, _
"MyAddin"
End
If
End
If
End
If
Next
ad
Set
fso =
Nothing
Set
ad =
Nothing
End
Sub
Vous pouvez également publier sur le réseau un add-in afin de déclencher une mise à jour chez
les utilisateurs.
Toujours dans la même logique le fichier MyAddin.ini se complète avec la ligne :
[ADMIN]
EnablePublishing
=
True
Que seul celui qui est autorisé à mettre à jour l'addin aura.
Vous n'aurez qu'à contrôler que EnablePublishing est à True pour autoriser l'appel à la sub PublishAddin.
et voici l'implémentation du code :
Public
Const
FullPathAddin As
String
=
_
"\\serveur\MyAddin.xla"
Public
Const
FullPathGetVer As
String
=
_
"\\serveur\AddinVersion.txt"
Sub
PublishAddin
(
)
Dim
fso As
FileSystemObject
Dim
fic As
TextStream
Dim
ad As
AddIn
Set
fso =
New
FileSystemObject
For
Each
ad In
application.AddIns
If
ad.FullName
Like "*MyAddin*.xla"
Then
' copie le fichier
On
Error
Resume
Next
Kill Left
(
ad.FullName
, Len
(
ad.FullName
) -
4
) &
"(publish).xla"
ThisWorkbook.SaveAs
Left
(
ad.FullName
, Len
(
ad.FullName
) -
4
) &
"(publish).xla"
FileCopy ad.FullName
, FullPathAddin
' crée le fichier de version
Set
fic =
fso.CreateTextFile
(
FullPathGetVer, True
)
fic.Write
InputBox
(
"Entrez la date de mise à jour de l'Add-in"
, "MyAddin Admin"
, _
Format
(
fso.GetFile
(
ad.FullName
).DateLastModified
, "dd/mm/yy hh:nn"
))
' revient sur le fichier original
Kill ad.FullName
ThisWorkbook.SaveAs
ad.FullName
MsgBox
"Le fichier a bien été publié !"
, vbInformation
+
vbOKOnly
, _
"MyAddin Admin"
End
If
Next
ad
Set
fso =
Nothing
Set
fic =
Nothing
Set
ad =
Nothing
End
Sub
Généralement, ByRef permet de passer à une procédure l'adresse d'un argument plutôt que sa valeur. La procédure peut ainsi accéder
à la variable proprement dite. La valeur réelle de cette dernière peut, de ce fait, être modifiée par la procédure à laquelle
elle a été passée. Par défaut, les arguments sont passés par référence.
Si la procédure appelée change la valeur de ces variables, elles changeront au retour dans la procédure appelante.
Cas particulier ByRef, si la variable est encadrée par des parenthèses :
Dans ce cas, si la procédure appelée change la valeur de la variable, elle ne changera pas dans la procédure appelante.
Sub
Test
(
)
Dim
i As
Integer
i =
1
Essai (
i)
MsgBox
i
Essai i
MsgBox
i
End
Sub
Sub
Essai
(
ByRef
j As
Integer
)
j =
j +
1
End
Sub
Dim
oAddIn As
AddIn
Set
oAddIn =
Application.AddIns.Add
(
Filename:=
"C:\Program Files\IBM\Client Access\Shared\cwbtfxla.xll"
)
oAddIn.Installed
=
True
Application.RegisterXLL
"cwbtfxla.xll"
'Lance la procédure "fShowTTODialog" contenue dans le fichier xll
Application.Run
(
"fShowTTODialog"
)
Effectivement, dans certains cas, vous pouvez voir apparaitre un bouton "Options" entre le ruban et la barre de formules. La boîte de
dialogue d'alerte macros "Options de sécurité Microsoft Office" s'affiche ensuite, lorsque vous cliquez sur le bouton.
Parfois, la boîte de dialogue "Avis de sécurité Microsoft Office Excel" est affichée directement.
En fait, le bouton "Options" apparait uniquement lorsque l'éditeur de macros n'est pas ouvert. Sinon, la fenêtre d'alerte macros s'affiche dès l'ouverture du classeur.
Les variables publiques d'un module standard sont vidées :
Lorsque vous terminez une procédure en appliquant l'instruction "End".
Lorsque que vous utilisez le menu Exécution/Réinitialiser depuis l'éditeur de macros.
Lorsque la fenêtre de gestion des erreurs est affichée et que vous cliquez sur le bouton "Fin".
La macro nécessite d'activer la référence "Microsoft Visual basic For Application Extensibility 5.3"
Vous devez également paramétrer le niveau de sécurité :
menu Outils
Macro
Sécurité
Onglet "Sources fiables"
Assurez vous que les deux options sont cochées.
Cliquez sur le bouton OK pour valider.
Sous Excel 2007 :
Onglet "Développeur" dans le ruban.
Cliquez sur le bouton "Sécurité des macros" dans le groupe "Code".
Assurez vous que l'option "Accès approuvé au modèle d'objet du projet VBA" est cochée.
'Nécessite d'activer la référence
'Microsoft "Visual basic For Application Extensibility 5.3"
Dim
Ajout As
Integer
Dim
VBCmp As
VBComponent
Dim
cdMod As
CodeModule
Dim
Wb As
Workbook
Dim
Debut As
Long
'Indiquez le nom du classeur ouvert
'Set Wb = ThisWorkbook
Set
Wb =
Workbooks
(
"Classeur1.xls"
)
Ajout =
1
'Boucle sur tous les composants du projet :
'Modules standards
'Modules de feuilles et de classeur
'Modules de classe
'UserForms
For
Each
VBCmp In
Wb.VBProject.VBComponents
Set
cdMod =
VBCmp.CodeModule
With
cdMod
Debut =
.CountOfDeclarationLines
+
1
Do
Until
Debut >=
.CountOfLines
'Nom de la procédure
Debug.Print
.ProcOfLine
(
Debut, vbext_pk_Proc)
Debut =
Debut +
_
.ProcCountLines
(
.ProcOfLine
(
Debut, _
vbext_pk_Proc), vbext_pk_Proc)
Ajout =
Ajout +
1
Loop
End
With
Next
VBCmp
Pour récupérer le nom et le type de procédure (private, public, sub, function), utilisez :
Debug.Print
.Lines
(
.ProcBodyLine
(
.ProcOfLine
(
Debut, vbext_pk_Proc), vbext_pk_Proc), 1
)
Et pour afficher également le détail de chaque macro :
Sub
listeMacros
(
)
'Nécessite d'activer la référence
'"Visual basic For Application Extensibility 5.3"
Dim
i As
Integer
, Ajout As
Integer
, x As
Integer
Dim
Msg As
String
Dim
VBCmp As
VBComponent
Dim
Wb As
Workbook
'Indiquez le nom du classeur (ouvert)
'Set Wb = ThisWorkbook
Set
Wb =
Workbooks
(
"Classeur1.xls"
)
Ajout =
1
For
Each
VBCmp In
Wb.VBProject.VBComponents
Msg =
VBCmp.Name
With
Cells
(
Ajout, 1
)
.Interior.ColorIndex
=
6
.Value
=
Msg
End
With
x =
Wb.VBProject.VBComponents
(
Msg).CodeModule.CountOfLines
For
i =
1
To
x
Cells
(
Ajout +
i, 1
) =
_
Wb.VBProject.VBComponents
(
Msg).CodeModule.Lines
(
i, 1
)
Next
Ajout =
Ajout +
x +
2
Next
VBCmp
End
Sub
Il s'agit d'un problème de compatibilité qui n'est pas clairement expliqué à ce jour.
Pour résoudre le souci, vérifiez s'il n'y a pas de références manquantes sur le PC.
Si oui, décochez ces références, validez en cliquant sur le bouton OK et retestez vos procédures.
Deuxième solution, faites précéder le nom de la fonction par le nom de la bibliothèque : VBA.
Par exemple, au lieu d'écrire :
x =
Left
(
strVariable, 1
)
indiquez
x =
VBA.Left
(
strVariable, 1
)
La compilation est accessible depuis l'éditeur de macros, dans le menu Débogage.
Cette fonction permet de vérifier si votre projet contient des oublis ou des erreurs de syntaxe
avant d'exécuter les procédures.
Les erreurs identifiées peuvent être des variables non ou mal déclarées, des instructions
manquantes (For, Next, End If, With, End With ...).
C'est possible à condition de connaitre au moins le chemin et le nom du classeur ouvert dans l'autre session :
Sub
ClasseurAutreInstance
(
)
Dim
Wb As
Workbook
Dim
Chemin As
String
Chemin =
"C:\dossier\nomClasseur.xls"
Set
Wb =
GetObject
(
Chemin)
If
Not
Wb Is
Nothing
Then
_
Wb.Parent.Run
"'nomClasseur.xls'!Module1.nomMacro"
End
Sub
Sélectionnez onglet 'Affichage' dans le ruban.
Cliquez sur le bouton 'Macros' dans le groupe du même nom.
La référence relative est la troisième option de la liste.
La référence relative est activée tant que l'option du ruban est surlignée.
La bibliothèque VBA possède des fonctions COS, SIN et TAN, mais la valeur de l'angle doit être exprimée en radians.
Si vous disposez des valeurs d'angles en degrés, multipliez-les par 180/pi afin d'obtenir l'équivalence en radian.
Sub
Test
(
)
Dim
x As
Double
'Exemple pour un angle de 30 degrés.
'Transformation en radians :
x =
30
*
Application.WorksheetFunction.Pi
/
180
'Résultats :
MsgBox
Cos
(
x) 'cosinus
MsgBox
1
/
Cos
(
x) 'secante
MsgBox
Sin
(
x) 'sinus
MsgBox
1
/
Sin
(
x) 'cosecante
MsgBox
Tan
(
x) 'tangente
MsgBox
1
/
Tan
(
x) 'cotangente
End
Sub
Le code VBA suivant permet d'ajouter 3 boutons dans l'éditeur VBE lorsque le classeur est ouvert, et montre comment identifier
lequel est utilisé.
La procédure nécessite d'activer la référence 'Microsoft Visual Basic for Applications Extensibility 5.3'.
Dans un module standard :
Option
Explicit
Public
Collect As
New
Collection
Dans le module ThisWorkbook du classeur :
Option
Explicit
Private
Sub
Workbook_Open
(
)
Dim
cbEvent As
Classe1
Dim
cBar As
CommandBar
Dim
cbButton As
CommandBarButton
Dim
i As
Integer
'Suppression de la barre si elle existait déjà.
On
Error
Resume
Next
Application.VBE.CommandBars
(
"Ma barre perso VBE"
).Delete
On
Error
GoTo
0
'Ajoute la nouvelle barre dans l'éditeur de macros
Set
cBar =
Application.VBE.CommandBars.Add
(
"Ma barre perso VBE"
, , True
, True
)
cBar.Visible
=
True
For
i =
1
To
3
Set
cbButton =
cBar.Controls.Add
(
msoControlButton)
With
cbButton
.Caption
=
"Le bouton perso "
&
i
.FaceId
=
350
+
i
.Tag
=
"Btn0"
&
i
.OnAction
=
"LaMacro"
&
i
End
With
Set
cbEvent =
New
Classe1
Set
cbEvent.objEvents
=
Application.VBE.Events.CommandBarEvents
(
cbButton)
'Ajoute un élément dans la collection
Collect.Add
cbEvent
Next
i
End
Sub
Private
Sub
Workbook_BeforeClose
(
Cancel As
Boolean
)
On
Error
Resume
Next
Application.VBE.CommandBars
(
"Ma barre perso VBE"
).Delete
End
Sub
Dans un module de classe nommée Classe1 :
Option
Explicit
'Nécessite d'activer la référence :
'Microsoft Visual Basic for Applications Extensibility 5.3
'
Public
WithEvents objEvents As
CommandBarEvents
Private
Sub
objEvents_Click
(
ByVal
cbControl As
Object, _
Handled As
Boolean
, CancelDefault As
Boolean
)
'Application.Run cbControl.OnAction
MsgBox
cbControl.Tag
Handled =
True
CancelDefault =
True
End
Sub