Самая странная проблема 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