web-dev-qa-db-fra.com

Variable statique publique dans Excel vba

Est-il possible d'avoir une variable statique déclarée dans une procédure et d'utiliser cette variable dans plusieurs procédures différentes en utilisant Excel VBA?

c'est à dire. 

Public myvar as integer

Sub SetVar()
   static myvar as integer
   myvar=999
end sub

sub Usevar()
    dim newvar as integer
    newvar=myvar*0.5
end sub

J'ai besoin que myvar soit vue par d'autres procédures et ne change pas ou ne soit "perdue". Le code ci-dessus fonctionne si myvar n'est pas déclaré en tant que variable statique, mais que plus de code est utilisé, la variable est "perdue". Si la déclaration statique est utilisée, myvar n'est pas vu par la procédure usevar. Et "myvar public statique en tant qu'entier" n'est pas accepté par VBA.

Merci de votre aide

Zeus

10
Zeus

Essayez ceci en appelant_ PRINCIPAL:

Public myvar As Integer

Sub MAIN()
    Call SetVar
    Call UseVar
End Sub

Sub SetVar()
    myvar = 999
End Sub

Sub UseVar()
    Dim newvar As Variant
    newvar = myvar * 0.5
    MsgBox newvar
End Sub

Si vous déclarez un élément Static , sa valeur sera conservée dans la procédure ou dans la sous-procédure. Si vous déclarez l'élément Public , sa valeur sera préservée et elle sera également visible par d'autres procédures.

6
Gary's Student

Les étudiants de @ Gary ont répondu à cette question il y a plus de quatre ans, mais une nuance subtile mérite d'être mentionnée, car la solution peut dépendre du type de données myvar.

Tout d'abord, comme vous l'avez indiqué dans la question, Public Static myvar as Integer ne fonctionne pas, car Static n'est autorisé qu'à l'intérieur d'une sous-fonction ou d'une fonction.

Comme indiqué dans les commentaires de @Patrick Lepelletier au PO, vous pouvez facilement contourner ce problème en déclarant plutôt une Constant (en supposant que vous n'avez pas besoin de la modifier dynamiquement): Public Const myvar as Integer = 999. (Ou éventuellement Private Const myvar...)

Une autre option consiste à déclarer myvar en tant que fonction à la place d'une variable ou d'une constante, en la transformant effectivement en un pseudo-constante:

Private Function myvar() as Integer
     Static intMyvar as Integer 
     intMyvar = 999
     myvar = intMyvar
End function

Dans cet exemple simple où myvar est un entier, l'approche pseudo-constante est évidemment inutile et ajoute la surcharge d'un appel de fonction. Déclarer simplement une Constant fait le travail. Cependant, l'utilisation d'une constante ne fonctionne que si la valeur est statique et que n'est pas un objet. Cela ne fonctionnera pas si myvar est un objet, par exemple un Range. Dans ce cas, utiliser des pseudo-constantes pourrait être utile:

Private Function myvar() as Range
    Set myvar = Range("A1")
End Function

Un autre avantage est que vous pouvez utiliser du code dans la fonction pour vérifier certaines conditions et affecter différentes valeurs à myvar en conséquence. 

L'approche pseudo-constante peut également être combinée avec des plages de feuille de calcul d'attribution de nom: Si la cellule A1 est une plage nommée, dites MyRange, vous pouvez alors écrire:

Dim strMyString as String
strMyString = "MyRange"
Private Function myvar() as Range
    Set myvar = Range(strMyString)
End Function

Il est maintenant possible de déplacer le contenu de la cellule A1 sans casser le code, car la plage nommée suit si vous coupez et collez la cellule. Je trouve cette approche utile au stade de la conception, lorsque les choses ont tendance à beaucoup bouger dans une feuille de calcul.

Les pseudo-constantes aident également à éviter certains problèmes généralement associés à des variables globales (ou au niveau du module) susceptibles de poser problème dans des projets plus importants.

2
Egalth

La clé est d'utiliser 2 variables. Dans le code ci-dessous, myvar est public mais pas statique. stvar est statique mais pas public. Sa portée est seulement dans Main (). En affectant myvar = stvar et stvar = myvar, il crée effectivement une variable à la fois publique et statique. La valeur est préservée.

Public myvar As String
Sub Main() 'in module 1
Static stvar As String
myvar = stvar
toInput
stvar = myvar
End Sub

Sub toInput() 'in module2
myvar = InputBox("enter something", "Input", myvar)
End Sub
0
On Chang