web-dev-qa-db-ja.com

VBA:文字列がNullかどうかをテストする方法

私はVBAでかなり新しいですし、まだ完全に構文に慣れていないので、私の質問が愚かに聞こえたらすみません。

Word 2010でRequisitePro40とVBA 7.0を使用しています。モジュールの1つに、次のループとIf条件があります。

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

ループの各反復では、a = 1a = 2実行されます!!

This に基づいて、等価演算子と不等価演算子は「=」と「<>」です。したがって、a = 1またはa = 2のいずれかが実行されることを期待します文字列の場合。構文に問題がありますか?それともReqPro関連の問題ですか?

「Is」および「IsNot」演算子も使用しようとしましたが、コンパイラエラーが発生します:タイプの不一致

誰かがこれを手伝ってくれる?

更新:実際の目標は、

rqRequirement.AttrValue( "MyAttreName"、eAttrValueLookup_Label).text

nullかどうか。 2番目のステートメントを追加したのは、ステートメントが期待どおりに機能しないという問題を示すためです。

「Null」を「vbNullString」に置き換えても変更は行われませんでした。

@Slaiが示唆するように、IsNull関数も試しました。結果はほとんど同じです:

    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

a = 3a = 4の両方のステートメントが真で実行されます。

5
dieKoderin

VBAは、文字列が「Null」かどうかのテストをサポートしていません。 VBAは、.NET言語やJavaScriptなどとは異なります。基本的な変数型にはすべてデフォルト値があり、文字列の長さはゼロ("")変数が宣言された瞬間から-インスタンス化されていない状態はありません。 vbNullStringをテストすることもできます。

あなたがテストする場合

Dim s as String
Debug.Print s = Null, s <> Null, s = "", s = "a", IsNull(s), s = vbNullString

戻りは

Null  Null  True  False  False  True

したがって、文字列変数に何かが割り当てられているかどうかをテストしようとしている場合、できることは次のとおりです。

Debug.Print Len(s), s = "", Len(s) = 0, s = vbNullString

どっちが戻る

0  True  True True

これらの可能性の中で最も遅いのはs = ""、覚えるのが最も簡単なようですが。

5
Cindy Meister

他の人が指摘したように、具体的にはNullではなく、文字列のnullバージョンであるvbNullStringに対してテストする必要があります。これに加えて、オブジェクト自体がnullにならないようにする必要もあります。例えば:

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

今、私は以前にこの特定のオブジェクトタイプを扱ったことはありませんが、AttrValue("MyAttreName", eAttrValueLookup_Label)が何らかのオブジェクトを返すことはかなり確実です。この場合、以下のパターンが推奨されます。

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

このように、実際にtextを設定した場合に限り、AttributeAttributeプロパティを呼び出すだけです。これにより、将来の424エラーが回避されます。

最後に、両方のifが実行される原因となっているコードで何が起こっているのかを把握するには、次のようにします。

_Debug.Print "Attribute Text: ", Attribute.Text_

これにより、コードの内容を確認できます。ブレークポイントの使用も検討できます。

2
Brandon Barney

1)vbNullStringを使用して空の文字列をテストできると思います。それ以外の場合、実際の文字列値の場合は「Null」を使用します。

2)が宣言されていることを確認します

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

相互排他性を確保するために、質問は一度だけ行ってください。

a = IIf(rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString , 2, 1)

特に同時に実行したい他のアクションがある場合は、If-Then-Else構文を使用することもできます。

上記のコード例は、~.text呼び出しが正しいことを前提としています。

0
AJD

「VBA:文字列がNullかどうかをテストする方法」への回答を探してここに着陸しました

この回答はこの特定のユーザーの状況には適用されない場合がありますが、件名の質問には適用されます。

Dim s As String, s2 As String
s = ""
s2 = vbNullString
Debug.Print StrPtr(s) = 0, StrPtr(s2) = 0

戻る

False   True

vbNullStringはCOMオブジェクトを操作するためのCスタイルのNULLポインターであるため、ドキュメント化されていないStrPtr関数から返されるときのメモリアドレスは常に0になるためです。

0
Gregor y