私は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 = 1とa = 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 = 3とa = 4の両方のステートメントが真で実行されます。
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 = ""
、覚えるのが最も簡単なようですが。
他の人が指摘したように、具体的には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
を設定した場合に限り、Attribute
のAttribute
プロパティを呼び出すだけです。これにより、将来の424エラーが回避されます。
最後に、両方のifが実行される原因となっているコードで何が起こっているのかを把握するには、次のようにします。
_Debug.Print "Attribute Text: ", Attribute.Text
_
これにより、コードの内容を確認できます。ブレークポイントの使用も検討できます。
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
相互排他性を確保するために、質問は一度だけ行ってください。
a = IIf(rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString , 2, 1)
特に同時に実行したい他のアクションがある場合は、If-Then-Else
構文を使用することもできます。
上記のコード例は、~.text
呼び出しが正しいことを前提としています。
「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になるためです。