web-dev-qa-db-fra.com

VBA: comment tester si une chaîne est Null

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.

5
dieKoderin

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.

5
Cindy Meister

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.

2
Brandon Barney

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
1
QHarr

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.

0
AJD

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

0
Gregor y