我见过的最奇怪的VBA问题(在布尔条件下VBASigned可能的错误)

Slo*_*ner 6 excel vba ms-word excel-vba word-vba

在MS Word中,我添加了一些代码来查看文档是否缺少其数字签名,或者至少我认为我做了.我决定在其他系统上测试之前分享.

Sub test()
    If Not ThisDocument.VBASigned Then
        Debug.Print "I am NOT signed"
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

问题:无论文档是否具有数字签名,上述代码都会产生相同的结果.如果我通过删除我修改代码Not仍然会得到意想不到的结果.

我试图通过以下方式来强迫事情:

If Not CBool(ThisDocument.VBASigned) Then
Run Code Online (Sandbox Code Playgroud)

但更令人惊讶的是,以下代码也失败了:

Sub test()
    Dim isSigned As Boolean
    isSigned = ThisDocument.VBASigned

    If Not isSigned Then
        Debug.Print "I am NOT signed"
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

即使ThisDocument.VBASignedAND isSigned都是TRUE......
我的代码运行的快照 但如果改变isSigned = ThisDocument.VBASigned,isSigned = True那么一切都按预期工作.

谁能证实这一点?有什么想法吗?


以下编辑回答了一些问题:

  1. 是的,使用Option Explicit,Yes也试过Debug.
    这段代码:

    Option Explicit
    
    Sub test()
        Dim isSigned As Boolean
        isSigned = ThisDocument.VBASigned
        Debug.Print ThisDocument.VBASigned
        If Not isSigned Then
            Debug.Print "I am NOT signed"
        End If
    End Sub
    
    Run Code Online (Sandbox Code Playgroud)

    生成此输出:

    是的,
    我没有签名

  2. 测试:True * 0 - 1.

    Sub test()
        Dim isSigned As Boolean
        isSigned = ThisDocument.VBASigned
        Debug.Print ThisDocument.VBASigned
        If Not (isSigned * 0 - 1) Then
            Debug.Print "I am NOT signed"
        End If
    End Sub
    
    Run Code Online (Sandbox Code Playgroud)

    生成此(预期)输出:

    真正


编辑:Raymond Chen的有趣文章,可能会提供一些有关如何发生这种情况的进一步见解:https://blogs.msdn.microsoft.com/oldnewthing/20041222-00/?p = 36923

简而言之,随着Windows操作系统的发展,它包含了不同类型的布尔值:int> byte> variant

Yow*_*E3K 6

在使用SlowLearner提供给我的文档的数字签名版本之后,我确定Word的VBASigned 1在签名时返回.

这导致If语句中出现问题,因为Not 1它等于- -2并且Not 0等于-1- 因此导致Not VBASigned在所有情况下返回非零(即非假)值.


MSDN文档指出VBASigned是一个只读布尔,和变量的类型返回已被证实(通过TypeName(ThisDocument.VBASigned))为Boolean,但它似乎它应该作为数字值,而不是进行处理.


另一个有趣的事实是CBool(ThisDocument.VBASigned) * 1给出一个答案1,而CBool(1) * 1答案是-1.因此,当VBA决定某个值已经是Boolean(例如ThisDocument.VBASigned意图)时,它似乎并不打算进行任何转换.但是,当参数to CBool不是a时Boolean,它会将非零值转换为-1.


可行的代码:

Sub test()
    Dim myVBASigned As Integer
    Dim isSigned As Boolean
    myVBASigned = ThisDocument.VBASigned 'Store as Integer
    isSigned = myVBASigned               'Convert to a "true" Boolean

    If Not isSigned Then                 'Use the "true" Boolean
        Debug.Print "I am NOT signed"
    End If

End Sub
Run Code Online (Sandbox Code Playgroud)

  • 我可以证实这一点.但这仍然是Word中的一个错误. (2认同)