Внешняя компонента 1C, интерфейс IInitDone #380314


#0 by Смайл
Добрый день. Прошу прощения, что немного не по адресу, но за неделю перелопатил практически весь интернет, а ответа так и не нашёл. Microsoft Visual C++ 2005. Пробую сделать внешнюю компоненту к 1С. Согласно официальной инструкции, наследуюсь от IInitDone и перегружаю все его методы и мелоды IUnknown. DLL благополучно регистрируется, и я в состоянии при помощи клиента собственного изготовления создать объект ко-класса: HRESULT hr = ::CoGetClassObject(CLSID_Protection, Методы AddRef и Release вызываются, объект благополучно создаётся. Я даже в состоянии вызвать метод Init передав ему NULL в качестве параметра. Но при попытке создать объект в 1С (любой версии - v77, v81) возникает падение системы после вызова метода Init: Access violation reading location 0x00000000. Опытным путём было обнаружено, что в качестве параметра Init(IDispatch *pConnection) получает нулевой указатель на интерфейс 1С-Предприятия. Причём я не использую этот параметр, но, возможно, его использует 1С после вызова Init-а. Сам Init совершенно безобиден: HRESULT __stdcall CProtection::Init(IDispatch *pConnection) { Если вернуть E_FAIL, 1С не вылетит, но и объект не создаст. С чем может быть связано такое поведение? В каких ветках реестра компонента должна обязательно зарегистрироваться, чтобы 1С считал её полноценно своей? Замечу, что ATL я не использую, хочу все необходимые действия проделать самостоятельно. Что ещё есть в интернете по внешним компонентам, кроме того, что я уже прочёл (материалы с ИТС можно не предлагать - я их знаю наизусть)? Большое спасибо за любые подсказки!
#1 by ТелепатБот
#2 by Смайл
Спасибо, мудрый ТелепатБот, но всё это я уже, к сожалению, знаю. :(
#3 by vde69
вообще можно вообще без регистрации в реестре сделать. по САБЖУ - жди АльФ-а
#4 by Смайл
Спасибо за ответ. АльФ-а жду с нетерпением.
#5 by v77
А если оставить только "return S_OK;" работает?
#6 by Sadovnikov
Если внимательно почитаешь книжку, то увидишь, что в Init нельзя ничего создавать. Там еще интерфейсы недоинициилизированны...
#7 by Sadovnikov
+ "нельзя ничего создавать" = "нельзя создавать объекты 1С и обращаться к самой 1С-ке".
#8 by Смайл
Нет, падает. "Если внимательно почитаешь книжку, то увидишь, что в Init нельзя ничего создавать. Там еще интерфейсы недоинициилизированны..." -- Я ничего и не создаю. Если речь о char buf[255], то он появился только после того, как появилась необходимость отладки. Кстати, о какой именно книжке речь?
#9 by Sadovnikov
Стромозил я. Фраза "Но при попытке создать объект в 1С ...." в заблуждение ввела. Думал, что в Init 1С-ий объект созадешь. "Кстати, о какой именно книжке речь?" - Технология создания внешних компонент.
#10 by Смайл
А, так там не книжка, а статья скорее. Не очень она хороша. Пришлось сперва полностью прочесть для того, чтобы вникнуть. И вот, всё равно не хватает... :(
#11 by Sadovnikov
Так в книжке просто описание интерфейсов. А вот как с ними работать - это уже большое количество толстых книжек по COM :)
#12 by Смайл
Так-то так, но только вот не уверен, что большинство людей, столкнувшихся с необходимостью написать ВК для 1С, хорошо знакомы с COM - это всё-таки целая идеология. Поэтому очень бы хотелось более систематизированный материал именно по написанию с нуля ВК для 1С. Жаль, что такого нет. Часто не хватает понимания принципов поведения самой 1С при работе с ВК. И никакие книги по COM этого понимания не дадут. А ещё удивляет сам подход, изложенный в статье: для написания ВК на таком-то языке возьмите пример с ИТСа и втулите куда-нибудь свой код. Эдакое визуальное конструирование компоненты. А кем переопределены AddRef и QueryInterface и в каком месте создаётся собственно возвращаемый объект можете даже не задумываться.
#13 by Sadovnikov
Пардон. А как вообще можно писать ВК (по сути - COM-объекты), не зная технологии COM??? Имхается мне, что ничего хорошего из этого не выйдет...
#14 by Смайл
"Имхается мне, что ничего хорошего из этого не выйдет..." -- Безусловно, её надо знать. Но надо знать ещё и специфику поведения 1С. А она существует, и заключается не только в перечне наследуемых интерфейсов. Вот, в данной теме, например, как раз и изложена ситуация, когда ошибка происходит не в коде DLL, а ПОСЛЕ вызова метода Init. Опять же, непонятно, почему в этот метод 1С передаёт NULL.
#15 by H A D G E H O G s
Я конечно не сильно разбираюсь в сплюснотом языке, но почему вы передаете в процедуру Init указатель на интерфейс, а не интерфейс. В Дельфи надо просто интерфейс (который сам является указателем).. HRESULT __stdcall CProtection::Init(IDispatch *pConnection)
#16 by H A D G E H O G s
HRESULT __stdcall CProtection::Init(IDispatch pConnection) - так нельзя?
#17 by DmitrO
Да непричем тут 1С. Скорее всего т.к. делаешь без АТЛ чета накосячил в объявлении класса или реализации IUnknown или IInitDone.
#18 by Смайл
Цитата из статьи "Технология создания внешних компонент" (ИТС): "Init Синтаксис: HRESULT Init(IDispatch *pBackConnection) Параметры: <pBackConnection> Тип: IDispatch. Указатель на интерфейс 1С:Предприятия." Всё по инструкции. Да и ИТС-ные примеры указывают на то же самое.
#19 by Смайл
Объявление класса: class CProtection : public IInitDone { private:    virtual HRESULT __stdcall Done(void);    virtual HRESULT __stdcall GetInfo(SAFEARRAY **pInfo);    virtual HRESULT __stdcall QueryInterface(const IID &riid, void __RPC_FAR *__RPC_FAR *ppvObject);    virtual ULONG __stdcall AddRef(void);    virtual ULONG __stdcall Release(void); } Ничего военного. Реализации каких методов привести? Как я уже говорил, процедура DllGetClassObject отрабатывает безупречно, равно как и конструктор и метод QueryInterface. Объект создаётся. this нулю не равен. Падение происходит только ПОСЛЕ того, как метод Init отработает. Если в Init вернуть E_FAIL, то падения не происходит вовсе.
#20 by Смайл
Ещё раз подчёркиваю, что мой собственный C++-клиент объект создаёт и способен с ним работать.
#21 by orefkov
Вообще-то Init вызывать самому нельзя. Его должна вызывать 1С сначала при загрузке ВК, затем каждый раз при СоздатьОбъект("Addin.ТвойАддин") Скорее всего у тебя накосячено в AddRef/Release, или ты где-то сам с ссылками косячишь, ошибка стопудово с этим связана. Поставь останов в деструкторе твоего объекта, увидишь, когда и где он убивается.
#22 by orefkov
Ну и желательно увидеть код DllGetClassObject, QueryInterface, и твою реализацию IClassFactory.
#23 by Смайл
"Вообще-то Init вызывать самому нельзя. Его должна вызывать 1С сначала при загрузке ВК, затем каждый раз при СоздатьОбъект("Addin.ТвойАддин")" -- Init собственноручно я вызывал только из C++-клиента, для проверки. Из 1С-а я его вызвать, конечно, не могу, так как объект не создаётся. -- Маловероятно, так как объект я создаю статически: HRESULT __stdcall CProtection::QueryInterface(const IID &riid, void __RPC_FAR *__RPC_FAR *ppvObject) { STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { "Поставь останов в деструкторе твоего объекта, увидишь, когда и где он "убивается. -- Он НЕ убивается. Он не создаётся вообще. После непойманного исключения 1С падает и необходимость удалять объект ко-класса исчезает. В случае если возвращать E_FAIL, деструктор вызывается при закрытии 1С, что вполне логично, т.к. объект создан статически. Пробовал создать объект и на куче. Картина та же. При этом C++-клиент благополучно работал с ним, и создавал, и удалял при помощи Release. -- Первые две привёл выше, а фабрику классов не реализовывал, так как создавал простой пример. Меня интересовало для начала вообще создать объект и вернуть его в 1С. Реализация IClassFactory необходима?
#24 by Смайл
На всякий случай привожу AddRef и Release: ULONG __stdcall CProtection::AddRef(void) { ULONG __stdcall CProtection::Release(void) { Здесь dwSrvRefCnt - глобальная DWORD-переменная. Необходима для корректной работы DllCanUnloadNow. m_dwRefCnt - счётчик ссылок объекта, свойство CProtection (см. протокол класса выше).
#25 by orefkov
Понятненько. В DllGetClassObject ты почему-то возвращаешь ссылку на свой объект. А надо возвращать ссылку на твою реализацию IClassFactory, которая уже в своей реализации CreateInstance будет возвращать ссылку на твой объект.
#26 by luns
Вот тут спроси: Душелов точно знает..
#27 by Смайл
Спасибо за совет. Это обязательное условие? Сейчас буду исследовать.
#28 by Смайл
luns, спасибо за ссылку. Поисследую вариант работы с фабрикой классов, расскажу о результате. Если не поможет, то спрошу и там. Кстати, сейчас ещё раз просмотрел материалы с ИТСа. Ни слова о IClassFactory. Равно и ИТС-ный пример не реализует этот интерфейс. Удивительно.
#29 by Смайл
orefkov, всё-таки хочу немного вникнуть. Мой класс должен В ОБЯЗАТЕЛЬНОМ ПОРЯДКЕ наследовать IClassFactory и реализовывать CreateInstance и LockServer? Я правильно понимаю? Каким приблизительно образом будет выглядеть DllGetClassObject?
#30 by DmitrO
правильно, там АТЛ фабрику реализует :)
#31 by Смайл
Да, было у меня такое подозрение. :) Но почему статья на ИТС молчит о таких вещах?
#32 by orefkov
Твой объект не обязательно должен наследоваться от IClassFactory, это может быть другой объект, реализующий интерфейс IClassFactory и в CreateInstance создающий твой объект. Но для простоты реализации (тем более у тебя статический объект) можешь реализовать IClassFactory в своем же объекте, и возвращать ссылку на себя-же. Только при возрате ссылок не забывай кастить к нужным типам: В DllGetClassObject
#33 by orefkov
На ИТС об этом ни слова потому, что так работает технология COM - любой COM объект создается через IClassFactory.
#34 by Смайл
orefkov, большущее спасибо. Кстати, насколько я понял материалы , фабрика классов - это один из подходов в COM-технологии, но не всегда обязательный для создания COM-объекта.
#35 by orefkov
Если вкратце - COM объекты в экзешниках регятся в системе через CoRegisterClassObject, COM объекты в дллках создаются через DllGetClassObject и IClassFactory(IClassFactory2).
#36 by DmitrO
Кстати, если уж без АТЛ, тогда надо и без CRTL (си рантайм лайбрари) писать иначе ее все равно редистрибутить придется, а это ужо так и пуп можно вывернуть, а?
#37 by Смайл
Зачем же дистрибутить CRT?
#38 by Смайл
М-дя. Реализовал IClassFactory. В теле QueryInterface сделал такие проверки: HRESULT __stdcall CProtection::QueryInterface(const IID &riid, void __RPC_FAR *__RPC_FAR *ppvObject) { Проверка показала, что 1С делает запросы следующих интерфейсов: 1. IClassFactory 2. IUnknown Что дальше - пока неизвестно, потому что получив в ответ на последние два запроса E_NOINTERFACE, она прекращает попытки создать объект. Эти интерфейсы тоже должны быть реализованы в обязательном порядке? Что ещё? Где можно прочесть перечень всего, что ОБЯЗАТЕЛЬНО реализовать для работоспособности ВК? Всем большое спасибо за оказанную помощь.
#39 by orefkov
Реализацию CreateInstance покажи
#40 by orefkov
IRunnableObject, IDispatch - реализация не нужна. Для ВК минимум - только IInitDone. Для использования в языке 1С - еще ILanguageExtender. Покажи DllGetClassObject.
#41 by Смайл
Реализация DllGetClassObject: STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { }
#42 by Смайл
Реализация CreateInstance: HRESULT __stdcall CProtection::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) {
#43 by Смайл
Всё работает через QueryInterface. Реализация QueryInterface приведена выше. Только с небольшой поправочкой: вместо строки Поставив MessageBox-ы во всех ветках свитча этой функции я и обнаружил, что приходят запросы на нереализованные интерфейсы. Лог всего процесса следующий: Вызов CProtection::QueryInterface Запрошен интерфейс IClassFactory: 00000001-0000-0000-C000-000000000046 Вызов CProtection::QueryInterface Запрошен интерфейс IUnknown: 00000000-0000-0000-C000-000000000046 Вызов CProtection::QueryInterface Запрошен интерфейс IUnknown: 00000000-0000-0000-C000-000000000046 Вызов CProtection::QueryInterface Запрошен неизвестный интерфейс: 00000126-0000-0000-C000-000000000046 Вызов CProtection::QueryInterface Запрошен неизвестный интерфейс: 00020400-0000-0000-C000-000000000046
#44 by orefkov
Откуда у тебя разрушение CProtection ? Он же у тебя статический. И почему в DllGetClassObject не проверяешь, что CLSID приходит именно твой? В реестре все правильно прописано?
#45 by Смайл
"Откуда у тебя разрушение CProtection ? Он же у тебя статический. " -- Должен сказать, что в этом вопросе семёрка и восьмёрка ведут себя по-разному. Семёрка после ошибки создания объекта сразу вызывает DllCanUnloadNow, получает S_OK и выгружает DLL из памяти, попутно разрушая объект. Восьмёрка этого не делает. После ошибки создания объекта она ждёт, и только после закрытия 1С:Предприятия производит все приведенные выше действия. "И почему в DllGetClassObject не проверяешь, что CLSID приходит именно твой?" -- Добавил проверку, которая по сути ничего не изменила:
#46 by Смайл
-- Прописал следующие ключи: Обратный ключ: Даже на всякий случай сделал запись в библиотеке типов Смог увидеть свою библиотеку типов через OLE/COM Object Viewer.
#47 by Смайл
Вопрос с повестки дня снимается. COM-сервер реализован. Без MFC и ATL, хотя теперь понятно, почему авторы статьи ИТС рекомендуют эти библиотеки.
#48 by Смайл
Для интересующихся рассказываю. 1C включает в себя очень старательно написаный COM-клиент, который работает по всем канонам этой технологии. Поэтому разрабатываемый ко-класс должен в обязательном порядке реализовывать следующие интерфейсы: Последние два интерфейса обычно скрыты от пользователей библиотек ATL и MFC, поэтому даже не описываются в документации. Например, IDispatch в MFC реализован в составе COleDispatchDriver, а в ATL - в CComDispatchDriver (см. . Как реализовать IDispatch самостоятельно, можно прочесть у Дональда Бокса: Этот интерфейс работает с двумя свойствами типов ITypeLib* и ITypeInfo*. Первое - это ссылка на библиотеку типов, которую можно загрузить при помощи функции LoadRegTypeLib. Второе - это описание определённого интерфейса в библиотеке типов, извлекаемого из неё при помощи GetTypeInfoOfGuid. После этого Вы владеете всей информацией о свойствах и методах ко-класса. К этой информации 1C будет обращаться всякий раз, когда в коде её приложения встретит обращение к свойствам или методам COM-объекта. Обратите внимание на то, что библиотека типов должна быть зарегистрирована в системе! Сделать это можно либо вручную (см. пару постов выше), либо функцией RegTypeLib. Свою библиотеку типов Вы должны уметь открывать при помощи OLE/COM Object Viewer. Если библиотека не открывается и возвращает TYPE_E_CANTLOADLIBRARY, возможно, Вы не включили tlb-файл в состав dll. Сделайте это директивой 1 TYPELIB "Mydll.tlb" в своём ресурсе. При этом убедитесь в правильности указанного пути к этому файлу. В 1C создаём объект следующим образом: Лог обращений 1C-клиента (v77) к COM-серверу будет выглядеть так:
#49 by Смайл
В конце лога последние три строчки продублировались. Не обращайте внимания. :) Ещё замечу, что COM-клиент 1C 8.1 работает несколько иначе. У него немного другая последовательность запрашивания интерфейсов, но общая схема работы та же.
#50 by Смайл
Кстати, пока так и не заметил обращения к методу Init(IDispatсh*). В какой момент оно должно происходить?
#51 by Смайл
Как ни странно, метод Init вызывается только при обращении к DLL через ЗагрузитьВнешнююКомпоненту, но не через СоздатьОбъект. То есть, объект создаётся в обоих случаях, но Init вызывается только в первом. И тогда лог работы будет следующим:
#52 by Смайл
Надеюсь, что данные логи позволят увидеть логику работы COM-клиента 1C и данный материал будет кому-то в будущем полезен.
#53 by romix
Вот еще пара ссылок
#54 by pectopatop
на всякий случай - МЕТКА! )
#55 by orefkov
То что ты сделал - не внешняя компонента. Это обычный COM-сервер с реализацией IDispatch. 1С так будет работать с любым OLE объектом, когда ты напишешь в коде Вот когда ты напишешь в 1С ЗагрузитьВнешнююКомпоненту("путь к твоей длл"); вот тогда 1С будет запрашивать IInitDone и вызывать Init. И ни про какие IDispatch и IRunnableObject даже не заикнется. Естественно, если в твоей дллке будет правильный строковый ресурс № 100.
#56 by Смайл
Вот когда ты напишешь в 1С вот тогда 1С будет запрашивать IInitDone и вызывать Init. И ни про какие IDispatch и IRunnableObject даже не заикнется. --- Хотелось бы увидеть листинг ПОСЛЕ ЗагрузитьВнешнююКомпоненту. Ведь мне всё равно необходимо куда-то вернуть объект. Как-то обращаться к его свойствам и методам. Поэтому после загрузки компоненты я должен буду использовать СоздатьОбъект, не так ли? А эта функция неизбежно обратится к IDispatch, так как иначе будет не в состоянии идентифицировать свойства и методы ко-класса (см лог выше). И ещё хотелось бы услышать разницу между "обычным" COM-сервером и внешней компонентой. Она только в реализации IInitDone? Значит, если у меня нет необходимости обращаться к IDispatch самого 1C, то мне вообще необязательно реализовывать этот интерфейс?
#57 by Смайл
Дополнение ко второму абзацу Я имею в виду, что принципиально отличает внешнюю компоненту минимального состава от COM-сервера, с которым 1C всё равно будет работать. Я знаю о богатых возможностях ILanguageExtender и прочих интерфейсов, но не в этом суть. В чём принципиальная разница?
#58 by Sadovnikov
"Я знаю о богатых возможностях ILanguageExtender и прочих интерфейсов, но не в этом суть" - именно в этом как раз и суть. На сколько я для себя понимаю, ВК - это COM-сервер, реализующий специфические (1С-ные) интерфейсы.
#59 by Смайл
Мысль понятна. То есть, 1C способна работать и с обычными COM-объектами, и с ВК, которые в отличие от простых COM-объектов имеют дополнительные возможности, описанные в статье "Технология создания внешних компонент". При работе с простым COM-объектом 1C должна использовать функцию СоздатьОбъект, но ни в коем случае не использовать ЗагрузитьВнешнююКомпоненту, потому что во втором случае произойдёт обращение к реализации IInitDone. При работе с ВК НЕОБХОДИМО сперва использовать функцию ЗагрузитьВнешнююКомпоненту, которая: 2. У полученного объекта запросит интерфейс IClassFactory; 3. У него же запросит интерфейс IInitDone; 4. Вызовет метод Init с переданным идентификатором IDispatch 1C; 5. Вызовет GetInfo; 6. В дальнейшем обеспечит вызов Done перед выгрузкой приложения. И уже потом вызывать СоздатьОбъект, которая в свою очередь не тронет IInitDone, но обратится к IDispatch COM-сервера.
#60 by DmitrO
Смайл, ты бы хоть документацию по ВК почитал, там ведь все написано как идет загрузка компонент. При вызове ЗагрузитьВнешнююКомпоненту в первую очередь происходит загрузка библиотеки с вызовом DllRegisterServer, далее идет чтение строки №100 из ресурса dll, 1С там ищет части ProgID COM объектов, которые размещены в этой длл. Они должны быть в таком виде "MyObject1|MyObject2|MyObject3". Далее она пытается создать каждый из COM объектов по следующим ProgID: AddIn.MyObject1, AddIn.MyObject2, AddIn.MyObject3. Если строки с номером 100 в ресурсе она не находит, то она считает что объект будет один и с ProgID: AddIn.ИмяДЛЛ. Т.е. тут мы имеем обычное штатное создание COM объекта по ProgID, уж не знаю какой она при этом интерфейс запрашивает, возможно IUnknown, а может и сразу IInitDone т.к. по документации он обязательный. Содание экземпляра каждого объекта ей нужно для того чтобы: 1)Если у объекта есть интерфейс ILanguageExtender, то она РЕГИСТРИРУЕТ У СЕБЯ ОБЪЕКТ ВНЕШНЕЙ КОМПОНЕНТЫ для использования его в своих программных модулях. Имя этого объекта будет такое: "AddIn." + то что вернет ILanguageExtender::RegisterExtensionAs. Это имя вобщем-то ни как не связано с ProgID этого объекта. 2)Если у объекта есть интерфейс IPropertyPage, объект будет использован для обслуживания собственной страницы свойств в параметрах приложения (Сервис/Параметры). Заметим, что один и тот же объект может реализовать оба интерфейса, но экземпляры будут разные, обмен данными между ними ложится на плечи разработчика. Далее по использованию объектов ВК в модулях 1С. Надо сказать что тут "все правильно перепутано". - в 77: функцией СоздатьОбъект("ИмяОбъекта"); передавая имя объекта: "AddIn." + то что вернет ILanguageExtender::RegisterExtensionAs. Надо отметить, что этой же функцией создаются и обычные OLE объекты для работы с ними через IDispatch, в этом случае передается ProgID, отсюда путаница, ну если учесть что также создаются и внутренние объекты 1с, то бог с ним. - в 8.x: оператором Новый ("ИмяОбъекта"); передавая имя объекта: "AddIn." + то что вернет ILanguageExtender::RegisterExtensionAs. Надо отметить, что создание OLE объектов тут идет несколько иначе: Новый ComОбъект("ProgID"). Надо также отметить, что загрузка компоненты может быть еще через функцию ПодключитьВнешнююКомпоненту, с предачей ProgID, или нескольких ProgID через "|". В этом случае они должны быть уже зарегены в реестре. Отличие от ЗагрузитьВнешнююКомпоненту в том, что не требуется прав на устновку программ т.к. регистрации COM серверов не происходит, а также компонента может лежать где угодно (в 8.х, в отличии от 77, в ЗагрузитьВнешнююКомпоненту нельзя передавать полное имя длл включая путь, можно передавать только имя файла и искать она его будет только в каталоге BIN). Разница между объектом ВК и просто OLE объектом в том, что объекты ВК могут пользоваться интерфейсами самой 1С, предоставляемыми через IInitDone. В механике использования их в модулях, разница не существенна, ее практически нет. Разница просто в ее реализации: через IDispatch или через ILanguageExtender.
#61 by lanc2333
Нашел вот такой ответ про Кассовую книгу "Покупатель расплатился с организацией за товар с использованием кредитной карты. Нужно ли отражать в кассовой книге такую выручку? Нет, не нужно. Оплата товаров с помощью кредитных карт относится к безналичным расчетам (п. 5.3 Типовых правил эксплуатации контрольно-кассовых машин при осуществлении денежных расчетов с населением, утвержденных Письмом Минфина России от 30.08.1993 N 104). А в кассовой книге необходимо учитывать поступление и выдачу только наличных денег." .. Прокомментируй
#62 by orefkov
>> При работе с ВК НЕОБХОДИМО сперва использовать функцию ? >> ЗагрузитьВнешнююКомпоненту, которая: >> 1. Вызовет DllGetClassObject; >> 2. У полученного объекта запросит интерфейс IClassFactory; >> 3. У него же запросит интерфейс IInitDone; Не совсем верно. Dmitro уже подробно описал. От себя же добавлю, что сама 1С ни DllGetClassObject не вызывает, ни с IClassFactory не работает. Она просто вызывает CoCreateInstance с нужным CLSID и IID_IInitDone, и все эти вещи делает винда. Отличие ВК от обычного COM-объекта с IDispatch в том, что ВК получает указатель на интерфейс 1С, через который может делать многие вкусные вещи - выводить сообщения об ошибках, выводить текст в строку состояния, создавать объекты 1С, вызывать методы языка 1С и глобального модуля, создавать нормальные окна документа и тп. Хотя справедливости ради отмечу, что на 77 эти вещи (а также еще многие) можно делать, и не получая интерфейс 1С.
#63 by Masqyerade
если исходить из названий доплат, они не должны иметь каких то супер-пупер сложных алгоритмов начислений, поэтому легко могут быть реализованы в режиме предприятия. ЗЫ хотя кто его знает что думали когди их в конфигуратор пихали. . обрати внимание на расчет РК при увольнении. баг описан у vaicartana в ФАКе исправление тут
#64 by Смайл
"Не совсем верно. Dmitro уже подробно описал." -- Хм, честно говоря, не совсем понял его мысль. Ещё перечитаю, но он сакцентировался немного не на том. -- Спасибо за замечание, оно достаточно ценное. "Отличие ВК от обычного COM-объекта с IDispatch в том, что ВК получает указатель на интерфейс 1С, через который может делать многие вкусные вещи - выводить сообщения об ошибках, выводить текст в строку состояния, создавать объекты 1С, вызывать методы языка 1С и глобального модуля, создавать нормальные окна документа и тп." -- Ну, примерно к такому выводу несколькими постами ранее я и пришёл.
#65 by Смайл
Всем большое спасибо за помощь и обсуждение, тему считаю исчерпанной. :)
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С