1 votes

Excel VBA - Portée de la variable Const pour être accessible uniquement par le projet actuel

J'ai un complément Excel pour le stockage des UDF ainsi qu'un classeur personnel pour le stockage des sous-routines.

À l'intérieur du complément, j'ai un module pour les constantes, où j'ai une entrée pour la constante des gaz parfaits :

Global Const r = 8.314 'Même résultat en utilisant Global ou Public

Cette constante "globale" peut être accédée depuis tous les modules dans le complément Excel et le classeur personnel.

Mon problème est que je voudrais pouvoir limiter la portée de cette variable uniquement aux modules du complément et à aucun autre projet ouvert. Sinon, je dois suivre dans tous les projets ouverts quelles variables je déclare comme Globales. À terme, je finirai comme la NASA, en me perdant dans mes unités...

Merci à tous pour votre aide.

1voto

Yasir Points 30

Une solution consisterait à ajouter une déclaration Option Private à la section de déclaration du module. Cela limitera la portée uniquement au projet dans lequel le module se trouve, pas à tout projet ouvert. Lien inclus ci-dessous à partir de Microsoft Docs sur la manière de le faire spécifiquement.

Pour plus d'informations sur la portée et la visibilité, consultez le lien ci-dessous à partir de Microsoft Docs :

https://docs.microsoft.com/fr-fr/office/vba/language/concepts/getting-started/understanding-scope-and-visibility

https://docs.microsoft.com/fr-fr/office/vba/language/reference/user-interface-help/option-private-statement

edit 04/22/2019: Removed the piece around Public to Global variable identifier as this didn't fix the problem.

1voto

seren Points 273

Global est un mot-clé obsolète; la seule différence entre Global et Public est que vous ne pouvez pas utiliser Global dans un module de classe. Préférez Public pour la cohérence.

Utilisez le modificateur d'accès peu connu Friend pour rendre un membre accessible partout à l'intérieur du projet dans lequel il est déclaré, mais seulement à l'intérieur de ce projet.

L'inconvénient est qu'il n'est utilisable que dans un module de classe, et seulement pour les procédures - vous ne pouvez pas créer un Friend Const.

Une solution de contournement pourrait consister à tirer parti de l'attribut de classe caché VB_PredeclaredId et le définir sur True - créez un nouveau fichier texte dans le Bloc-notes, avec ce contenu:

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "StaticClass1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Enregistrez le fichier avec une extension .cls, puis importez-le dans votre projet.

Ensuite, vous pouvez le renommer en quelque chose de plus significatif, et exposer un membre Friend Property Get:

Friend Property Get R() As Single
    R = 8.314
End Property

Et maintenant, vous pouvez utiliser cette valeur, mais seulement à l'intérieur du projet qui contient cette classe. Grâce à l'attribut PredeclaredId, vous n'avez pas besoin de créer une instance New:

Debug.Print StaticClass1.R ' 8.314

Malheureusement (?) l'attribut VB_GlobalNamespace n'a aucun effet dans les classes utilisateur VBA, donc l'objet qualifiant (l'instance de classe pré-déclarée a le même nom que le module de classe lui-même - c'est exactement ainsi que UserForm1.Show peut fonctionner) est requis.

Attention : il peut être tentant de stocker l'état d'instance (par exemple des variables de niveau de module privé) sur une instance par défaut (surtout dans les formulaires), mais cela devrait être évité autant que possible. Si vous avez besoin de stocker l'état, envisagez de travailler avec une instance New de la classe à la place. Les instances par défaut avec état sont plus sujettes aux erreurs, notamment parce que la durée de vie de l'objet est gérée par le runtime VBA, et non par le code utilisateur. Si l'instance par défaut est recyclée/recréée, tout état précédemment détenu est réinitialisé à ce que sont les valeurs par défaut au moment de la conception.

Notez que les modules de classe sont privés par défaut, ce qui les rend déjà invisibles pour les autres projets de référence. Vous pouvez changer la propriété Instancing de la classe pour la rendre PublicNotCreatable, ce qui changera la valeur de son attribut VB_Exposed en True:

Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True

Les classes publiques peuvent être accédées depuis l'extérieur du projet, mais ne peuvent pas être créées directement avec le mot-clé New (changer la valeur de l'attribut VB_Creatable n'a aucun effet en VBA). Avec une classe publique/exposée, les projets de référence pourront invoquer les membres Public, mais pas les Friend:

Public Property Get UseMeAnywhere() As Long
    UseMeAnywhere = 42

Friend Property Get YouOnlySeeMeInThisProject() As Long
    YouOnlySeeMeInThisProject = 42

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X