FAQ Excel

FAQ ExcelConsultez toutes les FAQ
Nombre d'auteurs : 46, nombre de questions : 845, dernière mise à jour : 30 mars 2022
Sommaire→Les macros VBA- 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 FunctionCet 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 SubSub 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 SubVoici 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 SubSub LaMacro_V02()
Dim t As Date
'Tempo 1 seconde
t = Timer + 1: Do Until Timer > t: DoEvents: Loop
MsgBox "test"
End SubSub 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 MaVariableUne autre possibilité consiste à utiliser la fonction Chr et le nombre (34) représentant ce caractère.
Dim MaVariable As String
MaVariable = Chr(34)
MsgBox MaVariableLe 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 FunctionIl 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 WithVous 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 SubC'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 FunctionPrivate 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 FunctionDans 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 \ 3Pour 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 SubDans 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 SubDans 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 FunctionSur 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 SubPuis 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 SubVous 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=TrueQue 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 SubDim 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 VBCmpPour 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 SubIl 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 CollectionDans 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 SubDans 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



