Je suis assez nouveau dans VBA et je ne me suis pas encore complètement familiarisé avec la syntaxe, donc je suis désolé si ma question semble stupide.
Je travaille avec RequisitePro40 et VBA 7.0 dans Word 2010. Dans l'un de mes modules, j'ai les conditions de boucle et If suivantes:
Dim rqRequirements As ReqPro40.Requirements
Dim rqRequirement As ReqPro40.Requirement
Const eAttrValueLookup_Label = 4
Dim a As Integer
...
For Each vReqKey In rqRequirements
Set rqRequirement = rqRequirements(vReqKey)
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text <> Null Then
a = 1
End If
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = Null Then
a = 2
End If
Next
Dans chaque itération de la boucle, a = 1 et a = 2 sont exécutés !!
Basé sur This , les opérateurs d'égalité et d'inégalité sont "=" et "<>". Par conséquent, je m'attends à ce que a = 1 ou a = 2 exécute pour une chaîne. Y a-t-il un problème avec ma syntaxe? Ou s'agit-il d'un problème lié à ReqPro?
J'ai également essayé d'utiliser les opérateurs "Is" et "IsNot" mais ils entraînent une erreur du compilateur: incompatibilité de type
Quelqu'un peut il m'aider avec ça?
Mise à jour: Le but réel est de voir si le
rqRequirement.AttrValue ("MyAttreName", eAttrValueLookup_Label) .text
est nul ou non. J'ai ajouté le deuxième si pour montrer le problème que la déclaration ne fonctionne pas de la manière dont je m'attends à ce qu'elle fonctionne.
Le remplacement de "Null" par "vbNullString" n'a apporté aucune modification.
J'ai également essayé la fonction IsNull comme l'a suggéré @Slai. le résultat est à peu près le même:
If IsNull(rqRequirement.AttrValue(att, eAttrValueLookup_Label).text) Then
a = 3
End If
If Not IsNull(rqRequirement.AttrValue(att, eAttrValueLookup_Label).text) Then
a = 4
End If
Les deux déclarations a = 3 et a = 4 sont vraies et exécutées.
VBA ne prend pas en charge le test si une chaîne est "Null". VBA n'est pas comme un langage .NET ou JavaScript (par exemple). Les types de variables de base ont tous une valeur par défaut, une chaîne est de longueur nulle (""
) à partir du moment où la variable est déclarée - elle n'a pas d'état non corroboré. Vous pouvez également tester vbNullString.
Si vous testez
Dim s as String
Debug.Print s = Null, s <> Null, s = "", s = "a", IsNull(s), s = vbNullString
Le retour est
Null Null True False False True
Donc, si vous essayez de tester si quelque chose a été attribué à une variable String, les seules choses que vous pouvez faire sont:
Debug.Print Len(s), s = "", Len(s) = 0, s = vbNullString
Qui revient
0 True True True
Notez que la plus lente de ces possibilités est s = ""
, même s'il semble le plus simple à retenir.
Comme d'autres l'ont noté, vous souhaitez tester la version nulle d'une chaîne, vbNullString, et non spécifiquement contre Null
. En plus de cela, vous devez également vous assurer que votre objet n'est pas lui-même nul. Par exemple:
Dim rqRequirements As ReqPro40.Requirements
Dim rqRequirement As ReqPro40.Requirement
Const eAttrValueLookup_Label = 4
Dim a As Long ' Avoid Integer since it has a strong habit of causing overflow errors.
...
For Each vReqKey In rqRequirements
Set rqRequirement = rqRequirements(vReqKey)
If Not rqRequirement Is Nothing Then
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text <> vbNullString Then
a = 1
End If
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString Then
a = 2
End If
End If
Next
Maintenant, je n'ai jamais travaillé avec ce type d'objet spécifique auparavant, mais je suis assez certain que AttrValue("MyAttreName", eAttrValueLookup_Label)
retourne une sorte d'objet. Si tel est le cas, le modèle ci-dessous serait préféré:
Dim rqRequirements As ReqPro40.Requirements
Dim rqRequirement As ReqPro40.Requirement
Const eAttrValueLookup_Label = 4
Dim a As Long ' Avoid Integer since it has a strong habit of causing overflow errors.
...
For Each vReqKey In rqRequirements
Set rqRequirement = rqRequirements(vReqKey)
If Not rqRequirement Is Nothing Then
Dim Attribute as Object ' Or whatever type it should be
Set Attribute = rq.Requirement.AttrValue("MyAttreName", eAttrValueLookup)
If Not Attribute is Nothing Then
If Attribute.text <> Null Then
a = 1
End If
If Attribute.text = Null Then
a = 2
End If
End If
End If
Next
De cette manière, nous n'appelons jamais la propriété text
de la Attribute
que si nous avons réellement défini la Attribute
. Cela évite 424 erreurs sur toute la ligne.
Enfin, si vous voulez comprendre ce qui se passe dans le code qui provoque l'exécution des deux if, faites quelque chose comme ceci:
Debug.Print "Attribute Text: ", Attribute.Text
Cela vous permettra de voir ce que voit votre code. Vous pouvez également utiliser des points d'arrêt.
1) Je pense que vous pouvez utiliser vbNullString pour tester la chaîne vide. Sinon, utilisez "Null" si la valeur de chaîne réelle.
2) Assurez-vous que a est déclaré aussi longtemps
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text <> vbNullString Then
a = 1
End If
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString Then
a = 2
Else
a = 3
End If
Pour garantir l'exclusivité mutuelle, ne posez la question qu'une seule fois.
a = IIf(rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString , 2, 1)
Vous pouvez également utiliser un If-Then-Else
construct, en particulier si vous souhaitez effectuer d'autres actions en même temps.
L'exemple de code ci-dessus suppose que le ~.text
l'appel est correct.
J'ai atterri ici à la recherche d'une réponse à "VBA: comment tester si une chaîne est Null"
bien que cette réponse ne s'applique pas à cette situation particulière des utilisateurs, elle s'applique à la question soumise.
Dim s As String, s2 As String
s = ""
s2 = vbNullString
Debug.Print StrPtr(s) = 0, StrPtr(s2) = 0
qui revient
False True
parce que vbNullString
est un pointeur NULL de style C pour travailler avec des objets COM, et donc son adresse mémoire lorsqu'elle est retournée par la fonction StrPtr
non documentée sera toujours 0