Объявление функций, созданных для 32-разрядных платформ, в 64-разрядных версиях VBA Excel с помощью оператора Declare и ключевого слова PtrSafe.
Ключевое слово PtrSafe
Если в 64-разрядной среде разработки VBA Excel объявить следующую функцию с помощью оператора Declare:
1 |
Private Declare Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As String, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long |
то она будет выделена красным цветом, а при запуске любой процедуры в этом модуле, будет сгенерирована ошибка компиляции:
Чтобы данная функция была объявлена корректно в 64-разрядной версии VBA Excel, необходимо после оператора Declare вставить ключевое слово PtrSafe:
1 |
Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As String, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long |
Среда разработки VBA 7
Операторы Declare с ключевым словом PtrSafe представляют собой рекомендованный синтаксис для среды разработки VBA 7. Функции, объявленные таким образом, корректно работают как на 32-битных, так и на 64-битных платформах.
Тип переменных, объявленных как Long, рекомендуется заменить на LongPtr, который в 32-разрядных системах интерпретируется как Long, а в 64-разрядных — как LongLong:
1 |
Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As LongPtr, ByVal dwFlags As LongPtr, ByVal lpMultiByteStr As String, ByVal cchMultiByte As LongPtr, ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As LongPtr) As LongPtr |
Обратная совместимость
Чтобы обеспечить обратную совместимость процедур (Function, Sub) в VBA7 и более ранних версиях офисных программ, используйте следующую структуру:
1 2 3 4 5 |
#If VBA7 Then Declare PtrSafe Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As LongPtr, ByVal dwFlags As LongPtr, ByVal lpMultiByteStr As String, ByVal cchMultiByte As LongPtr, ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As LongPtr) As LongPtr #Else Declare Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As String, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long #EndIf |
Функция из примера используется для преобразования кодировки UTF-8 в Windows-1251.
Примечание
Пакеты Office 2010, 2013 и 2016 по умолчанию устанавливаются в 32-разрядной версии, для установки 64-разрядной версии ее необходимо выбрать явно. Начиная с Office 2019 и Microsoft 365, по умолчанию устанавливается 64-разрядная версия.