а что Вас не устроило из того что Вы прочитали до этого вопроса о раннем и позднем связывании в инете? раннее связывание - это точное определение типа обьекта. это оптимизирует скорость работы компилятора и позволяет более рационально выделять память Microsoft рекомендует использовать ранее связывание везде, где это возможно раннее связывание позволяет компилятору понять Вы используете корректные свойства и методы обьекта еще на стадии проверки синтаксиса кода, а не в ходе его выполнения. отдаленный аналог: Option Explicit он заставляет программиста с самого начала представлять какие переменные и какого типа ему понадобятся.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
ранее связывание - компилятор/транслятор знает об объекте ДО компиляции/трансляции, т.е. вы можете посмотреть свойства и методы даже в процессе написания кода. Поэтому это связывание на 50% быстрее позднего (оценочно). При позднем связывании компилятор/транслятор ничего не знает о вашем объекте, и работает с ним в процессе выполнения кода (поэтому в отладчике не видно свойств и методов). Но для раннего связывания, что бы компилятор видел ваш объект, нужно его подключить в референсах проекта. Есть объекты, которые работают через раннее или позднее связывание, есть с двойным СОМ интерфейсом - dual.
vikttur написал: а что такое компиляция и для чего транслятор
Цитата
ttt480 написал: в чем преимущества позднего связывания ?
Более универсально, разрабатывалось в основном для использования в скриптовых языках (VBA считается таким языком), не нужно подключать библу в References, подключается сразу в коде
Код
Dim I As Object: Set I = CreateObject("ИмяБиблы")
Но есть и минусы, скорость, нет инфо о методах, используется только в ограниченном количестве языков (в основном скриптовые). Можно посмотреть на примере (есть и ранее и позднее связывание). Написал много, но потом удалил - ибо просили по простому, а здесь нужно немного понимать в (интерфейсы IUnknown, IDispatch, Dual(+COM Automation), таблица адресов методов, маршалинг и т.д. ) Матчасть под спойлером
Скрытый текст
При раннем связывании ID известен (достаточно вызвать IDispatch.Invoke(ID,..) для вызова требуемого интерфейного метода), при позднем же требуется сначала получить этот ID, для чего IDispatch предусматривает обязательный к реализации метод GetIDsOfNames. Позднее связывание наиболее универсально (на вызывающей стороне не требуется наличие ни type library в run-time ни ее прототипа в compile-time), но менее эффективно из-за необходимости всякий раз перед вызовом IDispatch.Invoke(ID..) получать нужный ID метода предварительным вызовом IDispatch.GetIDsOfNames(MethodName) При раннем связывании К (клиент) и С (сервер), работающих в едином АП (адрессное пространство), в принципе не требуется даже ID метода (необходимость маршаллинга отпадает), поскольку его адрес доступен непосредственно и может быть вычислен на этапе компиляции и при необходимости эффективно скорректирован загрузчиком на этапе load-time-компоновки. IDispatch основывается на IUnknown - был разработан для использования с языков сценариев (VB считается здесь языком скриптов)
не только. Если пишем код, в котором обращение идет к тому же Outlook, то при раннем связывании мы обязаны поставить галку в Tools -References. При этом связывание будет именно с нашей версией Outlook. У меня это будет Outlook.Application.16. И если я вышлю свой код кому-то, у кого хотя бы 2013 офис или еще меньше - то код еще при запуске выдаст ошибку компиляции, т.к. не найдет библиотеку Outlook16. При позднем же связывании мы указываем только имя класса объекта("Outlook.Application") без указания версии и VBA постарается найти любую сборку. Т.е. будет работать и в 2013 и в 2016. Тут останется только писать код так, чтобы использовать только те свойства и методы, которые есть в обеих версиях.
ttt480, соглашусь больше с bedvit'ом, и Дмитрием. Рассказывать пользователю, какие менюшки нужно открыть и где галочку поставить/снять, чтобы ваш код заработал будет выглядеть, мягко говоря, очень странно… Программа должна просто работать. Позднее связывание намного более универсально для этого. Однако, в случаях, когда разработчик точно уверен, какие библиотеки стоят/подключены на компьютерах пользователей, правильнее и быстрее (по скорости работы макроса) будет раннее связывание.
Лично я практически всегда (для неродных экселю библиотек) стараюсь использовать именно позднее связывание, ввиду описанных выше нюансов. Бывало и такое, что при вылете с ошибкой xl "снимает галочки" некоторых подключенных библиотек. Для позднего связывания это неважно - само подключит, а вот раннее приведёт к вылету с ошибкой.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Дмитрий верно, столкнулся с этим, при переносе с одной версии Excel на другую (с разными операционками) + может быть не зарегестрирован СОМ в реестре и нет ссылки в референсах. Поэтому теперь в коде при раннем связывании обязательно снимаю галку в референсах в конце кода.
Код
ThisWorkbook.VBProject.References.AddFromGuid "{77D79CA3-15A0-4310-B8D8-0BCBE3F72D96}", 1, 0: Continue ' подключаем библу "BedvitCOM" в References - version(1.0)
'Для раннего связывания сначала включаем в References библу, потом в конце кода отключаем. Для позднего связывания этого не нужно (см.ниже).
'Если BedvitCOM не оключать, могут быть ошибки в этом файле при отсутствии зарегестрированной BedvitCOM - выслали кому-то файл, или открыли из другого ПК и т.д., где не установлеена или не открыта надстройка BedvitXLL (которая автоматом распаковывает и регистрирует библиотеку BedvitCOM в реестре) или не зарегистрированна BedvitCOM вручную
ThisWorkbook.VBProject.References.Remove ThisWorkbook.VBProject.References("BedvitCOM") 'оключаем библу в References
Дмитрий Щербаков написал: Тут останется только писать код так, чтобы использовать только те свойства и методы, которые есть в обеих версиях.
Что-то все быстро так написали ответы и выложить не успеваешь, приходится переписывать, и что вообще добавить, наверное, нечего (при моем уровне), кроме того, что некоторые "лентяи" так об этом и не узнали бы в процессе своего творчества. Но даже в рамках данного контекста надо просто помнить о скорости, если обращение к Вашей переменной применяется в коде более 10-ков тыс. раз., то вряд ли Вас за скорость поблагодарят Userы
AAF написал: то вряд ли Вас за скорость поблагодарят Userы
ну это да. Но в противном случае, если код не будет работать вообще из-за ошибки раннего связывания с несуществующей библиотекой - то они тоже вряд ли рассыплются в комплиментах Я считаю, что работающий медленно код лучше, чем вообще не работающий
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Дмитрий Щербаков написал: Я считаю, что работающий медленно код лучше, чем вообще не работающий
Безусловно!!! Но, с предположительной точки зрения ТС, возможно, моя попытка сформировать такой вектор тяги может оказать положительное влияние в определенной ситуации.
видел пару раз такое. Полезный навык и хороший приём - спасибо!
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Ну я думаю, что "лентяйский" код - это не крестовый поход за упрощение, а скорее костыль необходимый для сущности "быстрой" совместимости (ну и, конечно улучшению коммерциализации данного направления и всего что с ним связано)...
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Дмитрий Щербаков написал: работающий медленно код лучше, чем вообще не работающий
Это, конечно, только теория, но нельзя ли сначала попытаться сотворить раннее программно, как писал bedvit, а при фейле — условной компиляцией перейти к позднему?
Можно. Более распространенная практика: отладка сложного макроса (макросов) с ранним связыванием, а затем замена типов переменных для объектов из "прицепленных" библиотек на Object и "отцепка" библиотек.