Самая странная проблема VBA, которую я когда-либо видел (Vbasigned возможная ошибка при Булевом условии)
в MS Word я добавил код, чтобы узнать, отсутствует ли в документе его цифровая подпись, или, по крайней мере, я думал, что сделал. Я решил поделиться, прежде чем тестировать это на других системах.
Sub test()
If Not ThisDocument.VBASigned Then
Debug.Print "I am NOT signed"
End If
End Sub
проблема: приведенный выше код дает тот же результат независимо от того, имеет ли документ цифровую подпись. Если я изменю код, удалив Not
Я все еще получаю неожиданные результаты.
Я пытался принуждать вещи, делая вещи например:
If Not CBool(ThisDocument.VBASigned) Then
но что более удивительно, следующий код также терпит неудачу:
Sub test()
Dim isSigned As Boolean
isSigned = ThisDocument.VBASigned
If Not isSigned Then
Debug.Print "I am NOT signed"
End If
End Sub
хотя ThisDocument.VBASigned
и isSigned
как TRUE
...
но если изменить isSigned = ThisDocument.VBASigned
to isSigned = True
тогда все работает так, как ожидалось.
может ли кто-нибудь подтвердить это? Есть мысли?
правки ниже отвечают на некоторые вопросы:
-
да, с помощью
Option Explicit
да тоже пробовал Отлаживать.
Этот код: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
производит этот выход:
правда
Я не подписал -
тестирование:
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
производит этот (ожидаемый) выход:
правда
Edit: интересная статья Раймонда Чена, которая может дать некоторые дополнительные идеи о том, как это произошло: https://blogs.msdn.microsoft.com/oldnewthing/20041222-00/?p=36923
короче говоря, по мере развития операционной системы Windows она включала различные типы логических значений: int > byte > variant
2 ответов
после игры с цифровой подписью версии документа, который SlowLearner предоставил мне, я определил, что Vbasigned Word возвращает 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
должно быть), он не беспокоится о каких-либо преобразованиях. Но, когда параметр CBool
- это не 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
тестирование этого против Excel показывает, что это ошибка в Word.
предполагая, что у нас есть новые документы с включенным VBA и подписанным VBA:
использование в 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
результаты
True
Я подписан
но используя то же самое в 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
результаты
True
Я не подписал
это ясно показывает, что есть ошибка в слово.
Это было проверено с
- Windows 10 для 64-разрядных
- Office Профессиональный Плюс 2016
- Версия 1703 Построить 7967.2139
- немецкий
- 64 Бит Office