Всем привет Из VBA обращаюсь к функциям из DLL SeleniumBasic, и всё отлично работает, кроме одного метода. Точнее, всё отлично работает при использовании раннего связывания, но при позднем связывании VBA отказывается видеть содержимое массива Прилагаю скриншот, где видно тип объектов (один - где все работает - с ранним связыванием, второй - с поздним)
При позднем связывании вылетают 2 весьма специфические ошибки: Run-time error 458: Variable uses an Automation Type not supported in Visual Basic Run-time error 10: This array is fixed or temporarily locked
Библиотеку (DLL) сделал китаец, с которым связи нет, и ждать новых версий не приходится Единственная надежда - обойти как-то эту ошибку (это ошибка его библиотеки, а не моего кода), но как именно - не знаю В интернетах пишут, что есть шанс с использованием функции CopyMemory, но я не понимаю, как её применить Может кто подскажет?
PS: мне совсем не вариант использовать раннее связывание
ну, вы же нигде не пишете CreateObject(), а просто присваиваете Set WD = SWD. Поэтому по картинке сложно понять. Может у SWD нужно сделать Set SWD = CreateObject(""), а вы этого не делаете.
Присвоение Set WD = SWD тут роли не играет, - там корректно созданный объект с подключением к браузеру. И у этого объекта работают все десятки методов, кроме одного Эта же проблемная функция возвращает массив объектов пользовательского типа данных, типа такого:
Код
Type Cookie
Domain As String
Value As Single
Expiry As Date
End Type
И вот почему-то объект такого типа доступен только при раннем связывании. И вопрос в том, как при помощи API функции CopyMemory попробовать скопировать содержимое этого массива объектов в другой массив, который VBA сможет обработать.
Т.е. в переменную A данные попадают и при позднем связывании, просто VBA эти данные прочитать не может
Так чтобы эта функция работала, мне надо прописать имя класса И при открытии файла пользователем, выскочит ошибка компиляции
PS: нашел обходное решение, — к счастью, в браузере можно выполнять javascript, и через него легко получить cookies так что можно обойтись без этой проблемной функции Тему можно считать закрытой.
Добрый день, Игорь. Похоже, что Cookies - это отдельный класс/объект, у которого есть метод AllCookies. Позднее связывание может не справиться с раскручиванием такой цепочки Класс1-метод-Класс2-метод без явного доступа к Класс2 до вызова его метода. Можно попробовать сначала достучаться до класса Cookies, а потом уже вызвать его метод AllCookies:
Код
Dim x
Set x = WD.Manage.Cookies
a = x.AllCookies
Если не сработает, то интересно посмотреть в отладчике в Locals, что там попало в 'x'.
С ранним связыванием тоже можно было бы поиграться, 2 варианта: 1. Устанавливать Reference программно при загрузке надстройки, не забывая его отключить в коде BeforeSaving. 2. Перед сохранением релиза надстройки установить Reference на как можно более старую версию библиотеки. Но после этого надстройки не должна сохраняться (поставить ReadOnly), чтобы не сохранялась связь с новой версией библиотеки. Тогда Reference при загрузке надстройки будет автоматически подтягиваться к версии, установленной на компьютере клиента и код будет работать корректно. Если же надстройка сохранена с более поздней версией библиотеки, то у клиента с ранней версией возникнет ошибка MISSING.
Владимир, спасибо Я уже это всё испробовал, - простые варианты не помогали
Причём все остальные методы работают Sub AddCookie(CK As Cookie) - создаёт объект Function GetCookieNamed(Name As String) As Cookie - возвращает объект
Т.е. один объект когда возвращается — всё ОК, но если это МАССИВ объектов, как в функции Function AllCookies() As Cookie(), — то VBA не справляется.
С ранним связыванием не вариант: устанавливать Selenium будут максимум 10-15% от пользователей надстройки (не всем нужен этот функционал) Так что у большинства этой DLL на компе просто не будет
PS: Там и другие функции из этой DLL, возвращающие массив объектов, дают такую же проблему, так что интересно узнать, есть ли решение без раннего связывания
Игорь написал: устанавливать Selenium будут максимум 10-15% от пользователей надстройки
Мы используем в приложениях "главную" надстройку и "специальные" надстройки. Специальные надстройки загружаются динамически главной надстройкой при необходимости выполнения соответствующих функций. Для вызова метода из другой надстройки применяется метод Application.Run, например: