【问题标题】:Testing if a string is null测试字符串是否为空
【发布时间】:2018-08-10 13:20:04
【问题描述】:

我是 VBA 的新手,还没有完全习惯语法,所以如果我的问题听起来很愚蠢,我很抱歉。

我在 Word 2010 中使用 RequisitePro40 和 VBA 7.0。在我的一个模块中,我有以下循环和 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 = 1a = 2 对字符串执行。 我的语法有问题吗?还是与 ReqPro 相关的问题?

我也尝试使用“Is”和“IsNot”运算符,但它们会导致编译器错误:类型不匹配

有人可以帮我吗?

更新:实际目标是看看

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

是否为 Null。我添加了第二个 if 以表明该语句无法按我预期的方式运行。

将“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 两个语句都为真且已执行。

【问题讨论】:

  • 你是如何声明的?作为字符串?
  • 错误在哪一行?
  • @QHarr 没有错误。但显然两个条件 text = Null 和 text Null 对于相同的文本都是正确的。这对我来说似乎不合逻辑,我不明白为什么会发生
  • 1)rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text返回的对象是什么类型的? (您可以查看 ReqPro40 对象模型文档) 2)您的实际目标是什么? (我无法理解您代码中的 If-Then 结构)
  • 使用 VBA,您通常不会测试字符串是否为“Null”。您将测试它是否为“空”,最有效的方法是:Len(stringVariable) &gt; 0 如果strVariable = "" 也是可能的,但执行效率不高。

标签: vba ms-word requirements


【解决方案1】:

VBA 不支持测试字符串是否为“Null”。 VBA 不像 .NET 语言或 JavaScript(例如)。基本变量类型都有一个默认值,从声明变量的那一刻起,String 的长度为零 ("") - 它没有未实例化的状态。您还可以测试 vbNullString。

如果你测试

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

回报是

Null  Null  True  False  False  True

因此,如果您尝试测试是否已将任何内容分配给 String 变量,您唯一可以做的事情是:

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

返回

0  True  True True

请注意,这些可能性中最慢的是s = "",尽管它似乎最容易记住。

【讨论】:

  • s = " " 和 vbNullString 测试不一样吗?
  • 事实上,对vbNullString 的测试是首选。虽然vbNullString = "" 使用内置名称比使用空引号更好。
  • 我是这么想的,这就是我放它的原因:-(
  • 谢谢 - 已将其添加到列表中 :-)
  • vbNullString is not the same 作为""。区别may be important.
【解决方案2】:

正如其他人所指出的,您希望针对字符串的空版本 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

这样,如果我们实际设置了Attribute,我们只会调用Attributetext 属性。这样可以避免 424 错误。

最后,如果您想弄清楚导致两个 if 运行的代码中发生了什么,请执行以下操作:

Debug.Print "Attribute Text: ", Attribute.Text

这将允许您查看您的代码所看到的内容。您也可以考虑使用断点。

【讨论】:

    【解决方案3】:

    1) 我认为您可以使用 vbNullString 来测试空字符串。否则,如果是实际字符串值,则使用“Null”。

    2) 确保 a 声明为 long

    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
    

    【讨论】:

    • if 结构就是这样的!我只想检查字符串是否为空。当然,我不需要全部 3 个。我只是添加它们以显示我的字符串同时为 null 和不为 null 的问题。
    【解决方案4】:

    我来到这里寻找“VBA:如何测试字符串是否为空”的答案

    虽然此答案可能不适用于此特定用户情况,但它确实适用于主题问题。

    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

    【讨论】:

      【解决方案5】:

      为确保互斥性,请仅提出一次问题。

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

      您也可以使用If-Then-Else 构造,特别是如果您想同时执行其他操作。

      以上代码示例假定~.text 调用是正确的。

      【讨论】:

        猜你喜欢
        • 2013-08-05
        • 2012-08-21
        • 1970-01-01
        • 2010-10-28
        • 2011-10-02
        • 2018-06-24
        • 2010-12-17
        • 2012-04-05
        • 2012-04-03
        相关资源
        最近更新 更多