2010-07-16 7 views
2

En essayant de passer le nom d'une variable globale à une sous-routine et j'aimerais savoir comment la référencer. Par exemple, je pouvais faire le ci-dessous avec un contrôle:Référencement de la variable globale - MS Access

Private Sub passCtrlName(ctlName as String) 
Me.Controls(ctlName) = "Whatever" 
End Sub 

Edit:

Par exemple

Public imGlobVar As String 
Public Sub passGlobVar(frm as Form, ctlName as String, globVar as String) 
frm.Controls(ctlName) = globVar 
End sub 

Et l'appeler comme Sub imaButton_Click privé() imGlobVar = "quelque chose" Appelez passGlobVar (Me, txtBox1, imGlobVar) Fin sous

2e édition:

Il semble que je pourrais certainement aboyer le mauvais arbre ici, alors je vais vous expliquer ce que j'essaie d'atteindre. J'ai un formulaire qui a des zones de texte pour l'adresse des utilisateurs (risque), avec une case à cocher en haut qui permet à l'utilisateur de sélectionner cette adresse est la même que les détails de contact déjà sur le système, et les zones de texte sont verrouillés.

Remplir les zones de texte est bien et fonctionne. Ce que j'utilise pour les variables globales est d'améliorer la convivialité (quoique légèrement). L'utilisateur peut ajouter de nouveaux détails, et s'ils cochent la case «faire la même chose que le contact», les détails qu'ils ont saisis sont stockés dans les variables globales, une pour chaque contrôle.

Si l'utilisateur a fait une erreur en cochant la case, il n'a pas perdu cette valeur, et en décochant la case, les valeurs saisies sont renvoyées. J'espérais créer une sous-routine dans laquelle je pourrais passer le nom de la variable globale et contrôler et appeler cette routine, plutôt que de l'écrire pour chaque contrôle. J'ai le sentiment que je pourrais utiliser la mauvaise technique pour atteindre mes objectifs. Mais en réponse à ma question initiale, il semble que vous ne pouvez pas passer des variables globales à des sous-routines de la manière que je souhaitais.

+0

Il me semble que vous pourriez envisager d'utiliser une structure de mémoire au niveau du formulaire, comme un jeu d'enregistrements snapshop qui contient les valeurs d'origine des champs en question. C'est un cas où les Globals sont clairement la mauvaise portée. La question de savoir si la structure de données que vous finissez d'utiliser doit être publique ou non doit être déterminée. Si vous en avez besoin dans un sous-formulaire et qu'il va être défini dans le parent, alors si vous l'utilisez depuis le sous-formulaire, il doit être public. Mais c'est très différent de GLOBAL. –

Répondre

1

Si vous vous demandez si vous pouvez référencer dynamiquement des variables globales en utilisant une chaîne contenant la variable nommez la réponse est non. Vous pourriez utiliser un seul tableau global et passer l'index, ce qui vous permettrait de référencer dynamiquement un élément du tableau.

[Modifier]
En réponse à la clarification de la question: Vous pouvez simplement enregistrer la valeur de chaque contrôle à sa Tag propriété lorsque l'utilisateur vérifie la case à cocher.Ensuite, si l'utilisateur décoche la case à cocher, vous pouvez simplement boucler vos contrôles et affecter la valeur du Tag au Value du contrôle.

+0

Oui Ben c'était ce que j'espérais faire, on dirait que je ne peux malheureusement pas, applaudir pour le conseil concernant les tableaux. – noelmcg

+0

@glinch: Et bravo pour l'upvote. Oh attendez ... – BenV

+0

Est-ce que Eval() ne fonctionne pas? –

2

Vous n'avez pas besoin de transmettre des variables globales, vous pouvez simplement vous y référer par leur nom. Notez que les variables globales sont réinitialisées si une erreur non gérée se produit.

Dans http://msdn.microsoft.com/en-us/library/dd897495(office.12).aspx, vous trouverez une section sur l'étendue et la durée de vie des variables et des constantes.

Dans un module:

Option Explicit 
Public glbVarName As String 
Const MyConstant=123 

Sub InitVar 
    glbVarName="Something" 
End Sub 

tout autre module, includeing module de classe d'un formulaire:

Sub SomeSub 
    MsgBox glbVarName 
    SomeVar=2+MyConstant 
End Sub 
+0

Salut Remou, voulez-vous dire que je pourrais le désigner comme "Private Sub passCtrlName (glbVarName as Global)"? Ou quelque chose de similaire? J'ai besoin de pouvoir passer le nom de la variable globale au sous-marin. – noelmcg

+1

Non, j'ai ajouté quelques notes juste pour être sûr que nous parlions de la même chose. Peut-être, si vous dites exactement ce que vous voulez faire et pourquoi, il peut être plus facile pour quelqu'un de vous donner un moyen de le faire. – Fionnuala

+0

Salut Remou, je comprends que je peux me référer à une variable globale par son nom. Ce que j'essaie de faire, c'est de passer la variable globale à une sous-routine (donc le nom ne peut pas être garanti car il pourrait en être un parmi beaucoup d'autres) et de le référencer dans la routine. J'espère que mon édition ci-dessus aide à le rendre plus clair. – noelmcg

1

Vous pouvez stocker les valeurs de vos contrôles dans un objet Dictionary, en utilisant les noms de contrôle comme clés du dictionnaire. Vous pouvez ensuite récupérer la valeur de chaque contrôle en fonction du nom du contrôle.

Option Compare Database 
Option Explicit 

Const cstrMyControls As String = "Text0,Text2,Text4,Text6" 
Dim objDict As Object 

Private Sub chkToggle_Click() 
    If Me.chkToggle = True Then 
     Call SaveValues 
    Else 
     Call RestoreValues 
    End If 
End Sub 

Private Sub SaveValues() 
    Dim varControls As Variant 
    Dim i As Long 

    Set objDict = Nothing 'discard previous saved values ' 
    Set objDict = CreateObject("Scripting.Dictionary") 
    varControls = Split(cstrMyControls, ",") 
    For i = 0 To UBound(varControls) 
     objDict.Add varControls(i), Me.Controls(varControls(i)).Value 
    Next i 
End Sub 

Private Sub RestoreValues() 
    Dim varControls As Variant 
    Dim i As Long 
    If objDict Is Nothing Then 
     'MsgBox "No values to restore." ' 
    Else 
     varControls = objDict.keys() 
     For i = 0 To UBound(varControls) 
      Me.Controls(varControls(i)).Value = objDict(varControls(i)) 
     Next i 
    End If 
End Sub 
+0

Y at-il une raison d'utiliser le dictionnaire d'objets de script au lieu d'une collection personnalisée VBA ou d'un tableau? –

+0

J'ai choisi un dictionnaire sur une collection car les dictionnaires ont une méthode .keys(), ce qui n'est pas vraiment nécessaire ici. Je n'ai pas envisagé d'utiliser un tableau. Aussi j'ai toujours tendance à penser aux dictionnaires d'abord à cause de Python. – HansUp

+0

@HansUp Bravo pour une autre technique que je n'aurais pas connue du tout, merci beaucoup. – noelmcg

-1

J'utiliser le champ supplémentaire dans le tableau - nom annuler - bien sûr booléen - quand je ne suis pas sûr si le contenu des champs seront valables je l'ai mis vrai. Si ce champ sera vrai à la fin - alors je nettoierai (il peut s'agir de tout record ou de certains fileds bien sûr). Très facile.