3

Проблема:

Я наконец обновился до Windows 10 и несколько макросов в Excel 2010, которые я часто использую, больше не работают. Когда я их запускаю, они мгновенно выходят из строя, и все, что я получаю, это « ошибка автоматизации ». Они не ссылаются ни на какие внешние программы / файлы; просто много копирования / вставки и сортировки в паре листов. Макросы, кажется, работают на компьютерах других людей (в Windows 10) так же, как раньше.

Материал, который я сделал:

  • обязательная перезагрузка
  • Ремонт Excel
  • переустановить Excel
  • скрипка с разрешениями макросов
  • использовать копии рабочей книги, которые работают на других компьютерах
  • Странные вещи: если я создаю новый макрос, включаю книгу и копирую-вставляю в мои старые макросы + содержимое книги и пытаюсь запустить макросы, они работают. Как только я выхожу и снова открываюсь, макросы перестают работать. Это справедливо для действительно простых тестовых макросов, которые я пытался сделать. Макрос, который копирует письмо из одной ячейки в другую, дает сбой после закрытия книги, в которой она была сохранена, и открытия ее заново.

Мне кажется, что я забыл несколько вещей, которые я проверял, но это должно охватывать большую часть этого.

1 ответ1

0

Поскольку вы больше не отвечаете на комментарии, я могу только предположить, что с обновлением вашей ОС вы также обновились с 32-разрядной до 64-разрядной версии.

Если вы объявляете вызовы API, вам нужно сделать их PtrSafe .

Например, рассмотрим следующий вызов DLL:

Declare Function RegOpenKeyA Lib "advapi32.dll" ( _
    ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long

Любой указатель адреса памяти и дескрипторы окна должны быть определены как LongPtr , потому что 64-битная ОС управляет своей памятью. Тип возврата для вышеупомянутой функции можно оставить как Long , потому что он не обращается к памяти или дескриптору.

Как только вы сделаете преобразование указателя памяти и дескриптора окна, вам нужно будет сказать Excel, что это "безопасно" использовать, объявив вашу функцию как PtrSafe (подумайте о "безопасном указателе" для указателей памяти):

Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" ( _
    ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long

Обратите внимание на три изменения, внесенные в нашу декларацию:

Declare Function изменено на Declare PtrSafe Function

(Это говорит Excel, что все указатели были изменены, и функция безопасна для использования)

ByVal Key As Long изменен ByVal Key As LongPtr

и наконец

ByVal NewKey As Long изменено на ByVal NewKey As LongPtr

Так что теперь вопрос остается. Что если бы я хотел распространить это на разные архитектуры операционных систем?

Вам повезло, так как VBA позволяет использовать специальный If...Then заявление для ваших объявлений модуля. Таким образом, для вышеприведенного кода вы можете распространять его на 32- и 64-разрядные ОС с помощью следующего оператора:

#If VBA7 Then '64-bit Office
    Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" ( _
        ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long
#Else
    Declare Function RegOpenKeyA Lib "advapi32.dll" ( _
        ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long
#End If

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .