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
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.
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.
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