In MS Word I added some code to see if a document is missing its digital signature, or at least I thought I did. I've decided to share before testing this on other systems.
Sub test()
If Not ThisDocument.VBASigned Then
Debug.Print "I am NOT signed"
End If
End Sub
Problem: The code above produces the same result irrespective of whether or not the document has a digital signature. If I modify the code by removing the Not
I still get unexpected results.
I've tried to coerce things by doing things like:
If Not CBool(ThisDocument.VBASigned) Then
But more surprisingly, the following code also fails:
Sub test()
Dim isSigned As Boolean
isSigned = ThisDocument.VBASigned
If Not isSigned Then
Debug.Print "I am NOT signed"
End If
End Sub
Even though ThisDocument.VBASigned
AND isSigned
are both TRUE
...
but if change isSigned = ThisDocument.VBASigned
to isSigned = True
then everything works as expected.
Can anyone confirm this? Any thoughts?
Edits below answer some of the questions:
Yes, using Option Explicit
, Yes also tried Debug.
This code:
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
Produces this output:
True
I am NOT signed
Testing: 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
Produces this (expected) output:
True
Edit: interesting article by Raymond Chen that might provide some further insights as to how this happened: https://blogs.msdn.microsoft.com/oldnewthing/20041222-00/?p=36923
In short, as the Windows operating system evolved it included different types of booleans: int > byte > variant
After playing with a digitally signed version of a document that SlowLearner supplied me, I have determined that Word's VBASigned is returning a 1
when it is signed.
This then leads to problems in the If
statement, because Not 1
is equal to -2
, and Not 0
is equal to -1
- thus leading to Not VBASigned
returning a non-zero (i.e. non-False) value in all cases.
The MSDN documentation states that VBASigned
is a read-only Boolean, and the type of variable returned has been confirmed (by TypeName(ThisDocument.VBASigned)
) to be Boolean
, but it appears it should be treated as a numeric value instead.
An additional interesting fact is that CBool(ThisDocument.VBASigned) * 1
gives an answer of 1
, while a CBool(1) * 1
gives an answer of -1
. So it seems that, when VBA decides that a value is already a Boolean
(such as ThisDocument.VBASigned
is meant to be), it doesn't bother to do any conversions. But, when the parameter to CBool
is not a Boolean
, it converts a non-zero value to be -1
.
Code that would work:
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
Testing this against Excel show that this is a bug in Word.
Assuming we have new documents with VBA enabled and VBA signed:
Using in Excel:
Sub testExcel()
Dim isSigned As Boolean
isSigned = ThisWorkbook.VBASigned
Debug.Print ThisWorkbook.VBASigned
If Not isSigned Then
Debug.Print "I am NOT signed"
Else
Debug.Print "I AM signed"
End If
End Sub
Results in
True
I AM signed
But using the same in Word
Sub testWord()
Dim isSigned As Boolean
isSigned = ThisDocument.VBASigned
Debug.Print ThisDocument.VBASigned
If Not isSigned Then
Debug.Print "I am NOT signed"
Else
Debug.Print "I AM signed"
End If
End Sub
Results in
True
I am NOT signed
This clearly shows that there is a bug in Word.
This was tested with
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With