Нови версии на „1C: Управление на търговията“: актуализиране без развитие. Оперативното счетоводство става регламентирано


Това се дължи на някои особености на функцията за глобален контекст ConnectExternalComponent().

Често програмистите имат проблеми със свързването на външни компоненти (например драйвери за търговско оборудване), когато потребителите работят с 1C, свързвайки се към сървъра чрез терминал.

В този случай потребителите виждат например тази снимка:

Докато при работа от локални компютри няма проблеми със свързването на външни компоненти.

С какво е свързано това? Това е така, защото когато потребителите работят през терминален сървър, те имат по-малко права, отколкото когато работят на локален компютър.

Можете лесно да проверите това, ако влезете в терминалния сървър с акаунт с администраторски права.

Причината за тази разлика е, че 1C не може да регистрира външен компонент в регистъра, когато потребителят работи в терминала с нормални права, т.к. обикновен потребител няма разрешение да пише в клона на системния регистър HKEY_CLASSES_ROOT.

Публикациите по темата за свързване на външни компоненти в терминала предлагат различни методи за решаване на този проблем.

Например тези:

1. Стартирайте 1C за първи път с административни права.

Тази опция не винаги работи. По-долу ще обясня защо.

2. Дайте разрешение на обикновените потребители на терминали да пишат в клона на системния регистър HKEY_CLASSES_ROOT.

По-добре е за недостатъчно „напреднали“ потребители да не правят това, в противен случай може да има проблеми.

3. Използвайки различни джаджи, регистрирайте VK от името на потребител с пълни права.

И това не е добре.

И така, какъв е най-добрият начин да излезете от тази ситуация?

Предлагам моето решение на този проблем. Според мен - просто и красиво.

Докато проучвах този проблем, си зададох въпроса: защо 1C дори се опитва да регистрира VK по нов път? В крайна сметка тя вече е регистрирана в системата.

Оказа се, че в типичните конфигурации на 1C (например „Управление на търговията“) се използва следният синтаксис за метода на глобалния контекст Connect External Component():

ConnectExternalComponent("Directory.ConnectedEquipment.Layout.DriverATOLBarcodeScanner", "ATOLScanner");

Както можете да видите, драйверът VC е свързан от оформлението "ATOLBarcode Scanner Driver" на директорията "Connected Equipment".

Какво се случва тогава?

1C запазва компонента във временната папка на потребителя, например "C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp"

и се опитва да го регистрира в клона на регистъра HKEY_CLASSES_ROOTточно по този път.

На терминала обикновените потребители нямат права да променят този клон на регистъра, така че компонентът не се свързва с тях.

Сега нека поговорим как да се измъкнем от тази ситуация.

Глобалният контекстен метод ConnectExternalComponent() има няколко опции за синтаксис. Това ще използваме.

И така, стъпка по стъпка:

1. Регистрирайте външния компонент с помощта на помощната програма regsvr32.exe на терминалния сървър в папката C:\WINDOWS\SYSTEM32 за 32-битова ОС или в папката C:\WINDOWS\SYSWOW64 за 64-битова ОС.

2. Използвайте една от двете допълнителни опции за синтаксис за метода ConnectExternalComponent():

Опция 1:

ConnectExternalComponent("C:\WINDOWS\SysWOW64\Scaner1C.dll", "ATOLScanner", ExternalComponentType.COM);

DriverObject = New("AddIn.ATOLScanner.Scaner45");

Вариант 2:

ProgID = "AddIn.Scaner45";

ConnectExternalComponent(ProgID);

DriverObject = Нов (ProgID);

Според мен вариант номер 2 е за предпочитане.

В същото време 1C не се опитва да пререгистрира VK, използвайки нов път в регистъра и по този начин всички проблеми са решени.

Е, това е всичко. Успех в работата!

[трябва да се регистрирате, за да видите връзката]

Въпрос: Външен компонент Native Api в C++ за Linux (Ubuntu x64) на 1C 8.3


Пиша на VK, но не мога да се свържа с 1c на ubuntu. Дори 1s exe не се свързва. Така че въпрос за това:

1) Опитвам се да свържа VK от примера VNCOMPS, даден в статията

(връзката може да бъде намерена в самия край: „Копиране“).
В проекта NativeApi има makefile. С негова помощ изграждам .so библиотека на Ununtu.
Но когато „Свързване на външен компонент“ 1c се срива.
По същия начин, ако изграждам с помощта на "build.sh" (в корена на проекта).

В самия makefile сменям флага от m32 на m64, т.к 1c и самата x64 система. (с параметър m32 така или иначе не се свързва)
Ето пример за извикване на VK от 1C 8.3:
Връзката е извършена = ConnectExternalComponent("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Има статия точно по тази тема.
Но доколкото виждам, всички тези точки вече са взети предвид и коригирани в примера на VNCOMPS.

Но по същество това е въпрос на параметри на компилация. MB 32-битов външен компонент се свързва към 32-битов 1c нормално, но аз го внедрих на Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. И искам да се свържа с нея във VK.

Някой има ли идеи как да се реши този проблем?)
Примерът за VNCOMPS трябва да работи, но параметрите на компилация трябва да бъдат коригирани или самата платформа, на която тествам, е неправилна.

Отговор:Чудя се, възможно ли е да напиша външен компонент в Java?

Въпрос: Външен компонент (Native) не може да бъде свързан


Компилирах пример с ITS за 64 и 32 битови системи.

Свързвам така:
Резултат от връзката = ConnectExternalComponent(KDLLPath, "Comp", ExternalComponentType.Native); Връзката работи на единия компютър, но не и на другия. Има разлика в ОС. Където се прави връзката има Win7, където няма Win10. В същото време на компютъра, където моят компонент не работи, стандартните компоненти работят.

Тестван на различни платформи (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Как да разбера защо не се свързва?

Отговор: vc_redist забравих?

Въпрос: 1C8 и външен компонент с тип Native


Добър ден.
Имам конфигурация BP 3.0.50.12 и желание да внедря претегляне от компанията Vesy-Soft с помощта на UniServerAuto в нея.
Разработчиците компилираха компонента в Native за Windows 32 и 64 и го архивираха с maifest файла. Има и пример за 1C как може да се изчисли теглото. В него, използвайки оформление с двоични данни, този архив е посочен, както разбирам. В примера всичко е наред: компонентът е инсталиран, свързан, след това връзката е установена и теглото е прочетено.
Но веднага щом започнете да го прехвърляте в 1C, теглото не се чете. Всичко изглежда просто написано, но не разбирам къде е рейкът.
Който има малко време - помагайте, погледнете с едно око, може би решението е на повърхността, но аз отивам някъде на грешното място и правя грешното нещо. Никога преди не ми се е налагало да работя с Native технология...

А в прикачения файл е моя текст за обработка

Отговор:

Е, имам новина...
Просто започнах да виждам стъпка по стъпка в кой момент ще започне да се проваля. За да направя това, създадох празна база данни и я обработих с командата. По аналогия с примера на доставчика прехвърлих оформлението в нова конфигурация - работи за втори път. Тези. първия път не, но втория път да. Това подтикна идеята, че при нашата обработка все пак ще е необходимо да се раздели връзката на компонента и обекта според различни процедури.
След това го прехвърлих в моята база данни с връзката на оформлението - работи. Уф, това е добре.... Но бих искал без да правя промени в конфигурацията, така че нека да продължим

Опитвам се да добавя оформлението към обработката. Размерът му веднага се увеличава от 10kb на 3mb и се забелязва значително забавяне на работата - не е подходящ. Започвам да копая към свързване на компоненти чрез dll. Тези. по същество същото като откъдето започнах. Но има едно „НО“: когато търся името на dll в папката на потребителя, забелязах, че тази dll се намира там, където (доколкото разбирам) се добавят dll, регистрирани в 1C:
C:\Users\USER\AppData\Roaming\1C\1cv8\ExtCompT
Съответно, няма нужда да използвате пълния път до dll, можете просто да въведете името му:
ConnectExternalComponent("Add1CUniServerAuto32.dll", "UniServerAuto", ExternalComponentType.Native);

Пробвам... псува при регистрация, но връща резултата от тегленето. Оказва се, че dll вече е регистриран и това означава, че просто трябва да го свържете. Махнах го и всичко работи.
Да го обобщим:
1. При обработката на претеглянето процедурата AtOpening включва свързване на външен компонент и свързване към обект.
2. Път до dll Не съм го написал, просто посочих името му.

Сега седя и си мисля, кога е инсталиран dll в 1C? По време на инсталирането на софтуера? Едва ли... По време на стартиране на конфигурацията на разработчиците на тази dll, къде се инсталира тя, когато се отвори формата? Не знам, но ми се струва близо... Вие как мислите?
И второ, на ново място, когато има нужда от инсталиране на същия терминал, какво трябва да се направи, за да работи всичко? Трябва ли да инсталирам напълно софтуера, да стартирам конфигурацията на доставчика, за да проверя операцията и след това (на теория) трябва ли моята обработка да работи? Нещо е някак сложно... Или трябва да направя Инсталиране на външен компонент веднъж в моята обработка след инсталиране на софтуера?

Бих искал да чуя вашите мисли по този въпрос...

Въпрос: Външен компонент.dll


Добър ден на всички
Въпрос.
Dll компонент, който работи чудесно в 1C 7.7
1s 8.1 изобщо не иска да стартира...
Опитах да го поставя в C:\Program Files\1cv81\bin\cache1c.dll
Опитах да се регистрирам с помощта на regsvr32 "C:\Program Files\1cv81\bin\cache1c.dll"
Регистрира се без проблеми.
Когато искам да го осъществя, получавам съобщение за грешка:

Грешка при зареждане на външен компонент! cache1c.dll
Процедура ButtonExecutePress(Button) Опит за зареждане на външен компонент( "C:\Програмни файлове\1cv81\bin\cache1c.dll"); Доклад за изключение ( „Грешка при зареждане на външен компонент!“+ "cache1c.dll" ); EndAttempt; Опит // Вземете компонентния обект. // m = Нов ("cache1c.GTMcmd"); m = Нов COMObject("cache1c.GTMcmd"); Доклад за изключение(); EndAttempt; EndProcedure

Отговор:Банално е до невъзможност...
Трябва да правите пауза между разговорите (милисекунди)...
Процедура ButtonExecutePress(Button) Опит // Получаване на компонентен обект. m = Нов COMObject("cache1c.GTMcmd"); Доклад за изключение ( „Неуспешно създаване на обект на външен компонент“); EndAttempt; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Connect(); m.Pause(100); ...... и т.н
За 1c 7.7 - това не е необходимо, оказва се, че обработката е по-бърза.

Въпрос: Работа с външен компонент с 1C сървър...


Добър ден,

Има външен компонент, написан на C++, чиято задача е да получи информация от външна база данни и да върне резултата от заявката под формата на таблица със стойности в 1C.
За генериране на таблица със стойности в текущия момент се използва интерфейсът IDispatch* pBackConnection, получен като параметър във функцията Init(). След това просто използвам 1C функции, за да създам таблица със стойности, да я попълня и да я върна към втория параметър в CallAsFunc(...).
Проблемите започнаха с прехода към 1C тънки клиенти. От страната на сървъра външният компонент не се стартира наистина. Можете да го стартирате от страна на клиента, но всичко изглежда като патерици и изпада от общата логика „клиент-сървър“ в 1C. Например, клиентът не разбира какво е таблица със стойности, проблеми с „глобални“ променливи, сесии и т.н.
NativeAPI е още по-ограничен в това отношение.
Танцуването с тамбурина доведе до факта, че успях да стартирам външен компонент под 1C сървъра, НО работата продължава, докато не се направи опит за извикване на Invoke на pBackConnection. 64-битовата версия на сървъра 8.2 се опитва да направи нещо, докато не изтече времето, 32-битовата версия (VK естествено също е 32-битова) просто пада веднага.
Предполагам, че сървърът 1C не поддържа този режим на работа.
Съответно възникват въпроси: това временно ли е или логиката на 1C се свежда до отмяна на тази схема на работа? Ако е невъзможно да се създадат вътрешни 1C структури (таблица със стойности) по този начин, има ли по принцип описание какво представлява таблица със стойности на ниво система, за да се опитаме да я създадем в C++, го попълнете и след това просто го плъзнете в 1C като параметър за връщане? Иска ми се поне да се ориентирам в коя посока да копая.

Благодаря ти.

Отговор:

Пишеш едно, а имаш предвид друго.
В средата на 1C декларирането на променливи, които ще бъдат видими в различни сесии, сега не е невъзможно, а преди не е имало такава възможност. Друга сесия е физически различен процес.
Сесията е сесия, свързваща се с база данни, т.е. потребителска сесия. Или влагате нещо свое в тази концепция?

В рамките на една сесия беше възможно и сега е възможно да се декларират променливи в модула на сесията, които ще живеят и ще бъдат видими в сесията от различни места... всъщност има 4 от тях.
- Сесиен модул;
- Модул за редовно приложение;
- Модул за управлявано приложение;
- Модул за външна връзка.

Е, разбира се, трябва да запомните контекста. Контекстът на сървъра не е директно достъпен от страна на клиента и обратно.

Всъщност архитектурата на 1C предвижда обменът на данни да става по следния начин:
- чрез параметри/връщане на процедури/функции;
- чрез т.нар. параметри на сесията (не могат да бъдат обекти, но реално видими в палитрата).

Таблица във формуляра... свързана ли е с някаква обектна таблица (обработка, например)? или не. Ако отговорът е да, значи е достъпен на сървъра (&OnServer) и редактирайте там....

И все пак, да, таблицата със стойности не е налична в UV от страна на клиента. Е, това реши 1C.

Хайде! Работи с Excel, работи с FSO и куп други неща, но не работи тук. Хванете грешката и анализирайте....

опит
...
вашите действия
...
Изключение
str = Описание на грешката();
EndAttempt;

При съвременните хардуерни възможности това изобщо не е аргумент.

Чисто твое лично мнение. Няма нищо общо с реалността. Не по никакъв начин. Повтарям още веднъж, 1C работи чудесно с COM. Както с in-proc, така и с out-proc.

Моля, предоставете кода, който използвате за изтегляне и се свържете с VK.

Между другото, VK... в твоя случай COM ли е или Native API?
Ако COM, тогава го регистрирате като... чрез regsvr32... как тогава "разрешавате" проблема с битовата дълбочина?

Въпрос: Инсталиране на външен компонент


Моля, кажете ми как да инсталирам външен компонент. При изпълнение на следния код се извежда грешка. В оформлението намерете NameDecl.dll

Опит за SetExternalComponent("GeneralLayout.Layout"); Изключение EndTry;
Грешка: Неуспешно инсталиране на външен компонент!

Отговор: ()
ConnectExternalComponent("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) връща FALSE.
New("AddIn.NameDecl.CNameDecl", Undefined) = (()): Тип недефиниран (AddIn.NameDecl.NameDecl)

Въпрос: Родният dll не се свързва с 1c 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


Здравейте.
1C актуализира dll за онлайн касови апарати atol за ffd 1.05 (включен в обработката на поддръжката fptrwin32_fz54_9_11_0_5549.dll).
Имам стар 1C 8.1. За разлика от 8.2, той не поддържа работа с външно оборудване по същия начин като 8.2, така че първо трябва да регистрирате dll в Windows и след това да го свържете само към 1C?

ProgID = "AddIn.IntegrationComponent.ATOL_KKT_1C83_V9"; LoadExternalComponent("C:\fptrwin32_fz54_9_11_0_5549.dll"); ConnectExternalComponent(progID); Драйвер = Нов (ProgID);

Старата обработка обаче беше написана в com "technology", а новата е родна. Съответно при регистриране на regsvr32 дава грешка:
Модулът е зареден, но входната точка на DllRegisterServer не е намерена. И предлага да проверите дали този файл е правилният dll или OCX файл.
Някой попадал ли е в подобна ситуация и как се измъкна? Разбирам, че 7.7 ще има подобен проблем.
Код 8.2:

Layout = GetLayout("IntegrationComponent"); Адрес = PlaceInTemporaryStorage(Layout); ConnectExternalComponent(Address, "IntegrationComponent", ExternalComponentType.Native); Driver = New("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
1C 8.1:
ConnectExternalComponent(<Идентификатор объекта>)
Настроики:
<Идентификатор объекта>(задължително)
Тип: низ. ProgID (програмен идентификатор) на външния компонентен обект. Трябва да съответства на информацията в регистрационната база данни на системата (Регистър).
Описание:
Свързва външни компонентни обекти към 1C:Enterprise.
Не се предлага на сървъра на 1C:Enterprise. Не се използва в модула за външна връзка.
Забележка:
Външните компоненти са съвместими с компонентите на 1C:Enterprise 7.7.
Пример:
опит
ConnectExternalComponent("AddinObject.Scanner");
Report("Компонентът за баркод скенера е зареден");
Изключение
Report("Компонентът за баркод скенера не е зареден");
EndAttempt

Има ли някакъв начин да свържа тази dll към 8.1 или не?

Благодаря ти!

Отговор:

Аз също наскоро се сблъсках с този проблем. Не беше възможно да се конвертира към по-късна версия на 1c, защото... dll, с който тази конфигурация работи, просто спря да работи и 1c се срина с грешка.
Реших проблема по следния начин:
Създадох празна база данни 8.3, в която обработих инициализацията на компонента и след това от 8.1 чрез COM връзка осъществих достъп до създадената преди това база данни и инициализирах компонента там. След това, вече в 8.1, извиках методите на този компонент.
Разбира се, това е патерица, но все още не съм намерил друг изход (

Пример за код 8.3:
Експортиране на променлив драйвер;
Функция ConnectionComponentsKKT() Експортиране
опит

Layout = GetLayout("IntegrationComponent");
Адрес = PlaceInTemporaryStorage(Layout);
ConnectExternalComponent(Address, "IntegrationComponent", ExternalComponentType.Native);
Driver = New("AddIn.IntegrationComponent.SMDrvFR1C20");
Резултат = Вярно;​

Изключение

Резултат = невярно;​

EndAttempt;
Връщане на резултат
EndFunction

Примерен код 8.1

Функция CreateDriverObject(Driver) Export

Резултат = Вярно;

опит

ConnectionString="File="""Път до база данни""";
ComObject = Нов COMObject("V83.ComConnector");
Connect = ComObject.Connect(ConnectionString);

Обработка = Connect.Processing.ConnectExternalComponent.Create();
Резултат от връзката = Processing.ConnectionCCPComponents();
Ако връзката Резултат Тогава
Драйвер = Обработка.Драйвер;
EndIf;​

Изключение
Всеки, който е правил това или се е сблъсквал с подобни решения, може да обясни самия принцип с прост пример. Изглежда, че всичко е ясно със свързването на външни компоненти.

// Пример за попълване на таблицата със стойности TK.Clear(); Заявка = Нова заявка; Query.Text = "ИЗБЕРЕТЕ | Номенклатура.Връзка КАК Номенклатура |ОТ | Directory.Nomenclature AS Nomenclature"; Резултат от заявка = Request.Execute(); Selection = Request Result.Select(); Докато Selection.Next() Cycle Page = TK.Add(); Fill inPropertyValues(Page, Selection); EndCycle;
Бихте ли използвали този пример, за да обясните каква част от кода обикновено се изважда? Би било логично да премахнем частта със заявката, но тогава как можем да получим достъп до базата данни от външния компонент, заобикаляйки платформата? Няма смисъл да вадя текста. Или извадете самото формиране на табличната част. Споделете опита си с всеки, който се е сблъсквал с това.

Отговор:И че думата „Несъвместим“ винаги означава думата „Лош“? Да, струва ми се, че ако нарекох стила си „1C: Най-лошото програмиране на тази скриптова машина, която съществува в природата (преведено на литературен език)!“ и тогава вероятно ще има хора, които искат да проверят този звяр. И изглежда като класика: "Не съм чел Пастернак, но напълно не съм съгласен с него!"

Въпрос: Свързване на външен компонент в 1s 8.3.6 и Win8


Трябва да свържете външния компонент vk_rs232.dll към персонализираната конфигурация. Изглежда, че е регистриран чрез regsvr32.exe. „Изглежда“, защото получих съобщение, че „компонентът е регистриран, но има нещо нередно със защитната стена“. Разчитайки на първата половина на съобщението, пиша кода в 1C
AfterConnecting = Ново описание на предупреждението ("AfterConnectingVK", ThisForm); StartInstallingExternalComponents(,"C:\Controller\vk_rs232.dll"); StartConnectingExternalComponents(AfterConnecting,"C:\Controller\vk_rs232.dll","DLL_Scales");
и получавам грешката, че
„Инсталирането на външен компонент е неуспешно! Компонент за клиентското приложение, което използвате, може да липсва!“

И сега не разбирам:
1. Може би компонентът не е регистриран в регистъра - как мога да го проверя там?
2. Може би неговата „версия“ не работи под Win8, въпреки че го имам 32-битов.
3. Може би самият 1C е твърде нов, т.е. Съответно не може да работи с тази dll?
4. Е, тривиално е - пиша нещо грешно.

Отговор:И всичко това ме доведе до следващия проблем. VneshComp е инсталиран, сега трябва да го свържете. И ето ги и двата варианта
ConnectExternalComponent("C:\Controller\vk_rs232.dll","Libra")
ConnectExternalComponent("GeneralLayout.Layout","Везни")

Опция за синтаксис: По име и местоположение

Синтаксис:

ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
Настроики:

<Местоположение>(задължително)

Тип: низ.
Местоположението на външния компонент.
Местоположението може да се използва:
път до файла на външния компонент във файловата система (не е наличен в уеб клиента), а не ZIP архив;
пълното име на оформлението, съхраняващо двоичните данни или ZIP архив;
URL адресът към външния компонент, като двоични данни или ZIP архив, във формат, подобен на GetNavigationLink.
<Имя>(задължително)

Тип: низ.
Символното име на външния компонент, който ще бъде свързан.
Името трябва да следва конвенциите за именуване на вградения език.
<Тип>(по избор)

Тип: ExternalComponentType.
Тип външен компонент за свързване.
Не се използва, ако компонентът е пакетиран в ZIP архив.
Описание на опцията за метод:

Свързва компоненти, направени чрез Native и COM технология.
Компонентът може да се съхранява в информационната база или конфигурационното оформление като двоични данни или в ZIP архив.
За режимите на стартиране "Тънък клиент" и "Уеб клиент" компонентът трябва първо да се инсталира чрез метода Инсталиране на външен компонент.
Опция за синтаксис: По ID

Синтаксис:

ConnectExternalComponent(<ИдентификаторОбъекта>)
Настроики:

<ИдентификаторОбъекта>(задължително)

Тип: низ.
Идентификатор на външния компонентен обект под формата на ProgID (Програмен идентификатор) ​​на системния регистър на MS Windows (например: "AddIn.Scanner").
Трябва да съответства на информацията в регистрационната база данни на системата (Регистър).
Описание на опцията за метод:

Компонентът трябва да бъде реализиран чрез COM технология и регистриран в регистъра на MS Windows.
Тези компоненти са съвместими с компонентите на 1C:Enterprise 7.7.
внимание! Опцията метод не работи на сървъра и във външната връзка.
Върната стойност:

Тип: Булев.
Вярно - връзката беше успешна.
Описание:

Свързва външен компонент към 1C:Enterprise.
Външните компоненти могат да се съхраняват в информационна база или конфигурационни оформления като ZIP архив или като двоични данни, или във файл на файловата система.
Когато работите на тънък клиент и уеб клиент, компонентът трябва да бъде предварително инсталиран.

Наличност:

Тънък клиент, уеб клиент, сървър, външна връзка.
Забележка:

Външните компоненти могат да бъдат внедрени с помощта на Native API или COM технология. Компонентите, направени с помощта на COM технология, са съвместими с компонентите на 1C:Enterprise 7.7.
Уеб клиентът може да работи само с компоненти в информационната база, които са пакетирани в архив.
Тънкият клиент може да работи с компоненти в информационната база, пакетирани в архив и компоненти, разположени във файловата система.
Дебелият клиент може да обработва всички опции за съхранение на компоненти. В този случай, ако даден компонент е инсталиран чрез метода Инсталиране на външен компонент, тогава се използва инсталираният компонент и ако не е инсталиран, компонентът ще бъде получен в момента на свързване.
Сървърът може да работи с всички компоненти. Компонентът се кешира на сървърна сесия.
Пример:

Ако ConnectExternalComponent("AddinObject.Scanner") Тогава
Доклад("Зареден е компонент за баркод скенер");
В противен случай
Report("Компонентът за баркод скенера не е зареден");
endIf;

  • Урок

Въведение

Тази статия дава представа как работят външните компоненти в системата 1C: Enterprise.
Ще бъде показан процесът на разработване на външен компонент за системата 1C: Enterprise версия 8.2, работеща под операционна система Windows с файлов режим на работа. Тази опция се използва в повечето решения, предназначени за малки фирми. VK ще бъде реализиран на езика за програмиране C++.

Външни компоненти "1C: Enterprise"

"1C: Enterprise" е разширяема система. Използват се външни компоненти (EC) за разширяване на функционалността на системата. От гледна точка на разработчика VC е външен обект, който има свойства и методи и може също да генерира събития за обработка от системата 1C: Enterprise.
Външни компоненти могат да се използват за решаване на клас проблеми, които са трудни или дори невъзможни за изпълнение в езика за програмиране, вграден в 1C: Enterprise. По-специално, този клас включва задачи, които изискват взаимодействие на ниско ниво с операционната система, например за работа със специфично оборудване.
Системата 1C: Enterprise използва две технологии за създаване на външни компоненти:
  • използвайки Native API
  • с помощта на COM технология
Като се имат предвид дадените ограничения, разликата между двете гореспоменати технологии е незначителна, така че ще разгледаме разработването на видеоигри, използващи Native API. Ако е необходимо, внедрените разработки могат да бъдат приложени за разработване на компютърен софтуер, използващ COM технология, а също и с незначителни модификации, приложени за използване в системата 1C: Enterprise с други опции за работа, различни от режима на работа с файлове.
VK структура
Външният компонент на системата 1C: Enterprise е представен под формата на DLL библиотека. Кодът на библиотеката описва наследствения клас IComponentBase. Създаденият клас трябва да дефинира методи, отговорни за изпълнението на функциите на външния компонент. Отменените методи ще бъдат описани по-подробно по-долу, когато материалът бъде представен.

Стартиране на демо VK

Задача:
  1. Сглобете външен компонент, доставен с ITS абонамент и предназначен да демонстрира основните възможности на механизма на външния компонент в 1C
  2. Свържете демонстрационния компонент към конфигурацията на 1C
  3. Уверете се, че декларираните функции работят правилно
Компилация
Демонстрационният VK се намира на ITS абонаментния диск в директорията „/VNCOMP82/example/NativeAPI“.
За изграждане на демонстрационния VC ще използваме Microsoft Visual Studio 2008. Други версии на този продукт не поддържат използвания формат на проекта Visual Studio.


Отворете проекта AddInNative. В настройките на проекта включваме директорията със заглавните файлове, необходими за изграждането на проекта. По подразбиране те се намират на ITS диска в директорията /VNCOMP82/включва.
Резултатът от изграждането е файлът /bind/AddInNative.dll. Това е компилираната библиотека за свързване към конфигурацията на 1C.
Свързване на VK към 1C конфигурация
Нека създадем празна 1C конфигурация.
По-долу е кодът за управлявания модул на приложението.
променлива DemoComp; Процедура при стартиране на системата() Connect External Component("...\bind\AddInNative.dll", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); EndProcedure
Ако не е отчетена грешка при стартиране на конфигурацията на 1C, тогава VK е свързан успешно.
В резултат на изпълнението на горния код се появява обект в глобалната видимост на конфигурацията DemoComp, който има свойства и методи, които са дефинирани в кода на външния компонент.
Демонстрация на вградената функционалност
Нека проверим функционалността на демонстрационния VK. За да направите това, нека се опитаме да зададем и прочетем някои свойства, да извикаме някои VK методи и също да получим и обработим VK съобщението.
Документацията, предоставена на ITS диска, посочва следната функционалност на демонстрационния VC:
  1. Управление на състоянието на компонентния обект
    Методи: Включи, Изключвам
    Имоти: Включени
  2. Управление с таймер
    Всяка секунда компонентът изпраща съобщение до системата 1C: Enterprise с параметри Компонент, Таймери линия на брояча на системния часовник.
    Методи: StartTimer, StopTimer
    Имоти: Има таймер
  3. Метод ShowInStatusLine, който показва текста, предаден на метода като параметри в реда на състоянието
  4. Метод Качване на снимка. Зарежда изображение от посочения файл и го прехвърля в системата 1C: Enterprise под формата на двоични данни.
Нека се уверим, че тези функции работят. За да направите това, изпълнете следния код:
променлива DemoComp; Процедура при стартиране на системата() ConnectExternalComponent(...); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Доклад(DemoComp.Enabled); DemoComp.Enable(); Доклад(DemoComp.Enabled); DemoComp.StartTimer(); Край на процедура Процедура Обработка на външно събитие (Източник, Събитие, Данни) Отчет (Източник + " " + Събитие + " " + Данни); EndProcedure
Резултатът от изпълнението на конфигурацията е показан на изображението


Панелът „Съобщения“ показва резултатите от извикванията на метод DemoComp.Disable()И Demo.Comp.Enable(). Следващите редове в същия панел съдържат резултатите от обработката на съобщения, получени от VK - Източник, СъбитиеИ Даннисъответно.

Персонализирано име на външен компонент

Задача: Променете името на външния компонент на произволно.
Предишният раздел използва идентификатора AddInNativeExtension, чийто смисъл не беше обяснен. В такъв случай AddInNativeExtension- това е името на разширението.
VK кодът дефинира метод RegisterExtensionAs, връщайки името в системата 1C: Enterprise, което е необходимо за последваща регистрация на VK в системата. Препоръчва се да се посочи идентификатор, който до известна степен разкрива същността на външния компонент.
Ето пълния код на метода RegisterExtensionAsс променено име на разширението:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* dest = 0; if (m_iMemory) ( if(m_iMemory->AllocMemory) ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, iActualSize) return false;
В дадения пример името на VK е променено на SomeName. След това, когато свързвате VK, трябва да посочите ново име:
DemoComp = New("AddIn.DemoVK.SomeName");

Разширяване на списъка с VK свойства

Задача:
  1. Проучете изпълнението на VK свойства
  2. Добавете свойство за четене/запис от тип низ
  3. Добавете свойство на низ за четене/запис, което съхранява типа данни на последния набор от свойства. При задаване на стойността на свойството не се предприемат действия

За да определи свойствата на създавания компонент, разработчикът трябва да внедри следните методи в кода на библиотеката AddInNative.cpp:
GetNProps
Връща броя свойства на това разширение, 0, ако няма свойства
FindProp
Връща серийния номер на свойството, чието име е предадено в параметрите
GetPropName
Връща името на свойството по неговия сериен номер и по подаден езиков идентификатор
GetPropVal
Връща стойността на свойството с посочения пореден номер
SetPropVal
Задава стойността на свойството с посочения пореден номер
IsPropReadable
Връща флага за четливост на свойството с посочения пореден номер
IsPropWritable
Връща флага за записваемост на свойството с посочения пореден номер


Нека разгледаме изпълнението на горните методи на класа CAddInNative.
В демонстрационния VC са дефинирани 2 свойства: ВключениИ Има таймер (е активираноИ IsTimerPresent).
В глобалния обхват на кода на библиотеката са дефинирани два масива:
статичен wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Активирано", L"Има таймер");
които съхраняват руски и английски имена на свойства. В заглавния файл AddInNative.hизброяването е определено:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Винаги последен );
ePropIsEnabledИ ePropIsTimerPresent, съответно със стойности 0 и 1, се използват за замяна на серийните номера на свойствата със смислени идентификатори. ePropLast, който има стойност 2, се използва за получаване на броя свойства (чрез метода GetNProps). Тези имена се използват само в кода на компонента и не са достъпни отвън.
Методите FindProp и GetPropName извършват търсене в масив g_PropNamesИ g_PropNamesRu.
За да съхранява стойностите на полетата в библиотечния модул, класът CAddInNative има свойства, които съхраняват стойността на свойствата на компонента. Методи GetPropValИ SetPropValвърнете и съответно задайте стойността на тези свойства.
Методи IsPropReadableИ IsPropWritableи обратно вярноили невярно, в зависимост от преминалия пореден номер на имота в съответствие с логиката на приложението.
За да добавите персонализирано свойство, трябва да:

  1. Добавете името на свойството, което се добавя към масивите g_PropNamesИ g_PropNamesRu(файл AddInNative.cpp)
  2. За изброяване Реквизит(файл AddInNative.h) преди ePropLastдобавете име, което уникално идентифицира свойството, което се добавя
  3. Организирайте паметта за съхраняване на стойностите на свойствата (създайте полета на модулни компоненти, които съхраняват съответните стойности)
  4. Направете промени в методите GetPropValИ SetPropValза взаимодействие с паметта, разпределена в предишната стъпка
  5. В съответствие с логиката на приложението, направете промени в методите IsPropReadableИ IsPropWritable
Точки 1, 2, 5 не се нуждаят от обяснение. Подробности за изпълнението на тези стъпки можете да намерите, като проучите приложението към статията.
Нека дадем имена на тестовите свойства ТестИ Проверка на типасъответно. След това, в резултат на стъпка 1, имаме:
статичен wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"); static wchar_t *g_PropNamesRu = (L"Активирано", L"Има таймер", L"Тест", L"Проверка на типа");
Трансфер Реквизитще изглежда така:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Винаги последен);
За значително опростяване на кода ще използваме STL C++. По-специално за работа с низове WCHAR, нека свържем библиотеката wstring.
За да запазите стойност на метод Тест, дефинираме в класа CAddInNativeв обхвата на частно поле:
низ тест1;
За прехвърляне на параметри на низ между 1C: Enterprise и външни компоненти се използва мениджърът на паметта 1C: Enterprise. Нека да разгледаме по-отблизо работата му. Функциите се използват съответно за разпределяне и освобождаване на памет Разпределяне на паметтаИ FreeMemory, дефинирани във файла ImemoryManager.h. Ако е необходимо да се предаде параметър на низ към системата 1C: Enterprise, външният компонент трябва да разпредели памет за него, като извика функцията Разпределяне на паметта. Прототипът му изглежда така:
виртуален bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;
Където pMemory- адреса на указателя, в който ще бъде поставен адресът на разпределената област на паметта,
ulCountByte- размер на разпределената област на паметта.
Пример за заделяне на памет за низ:
WCHAR_T *t1 = NULL, *test = L"TEST_STRING"; int iActualSize = wcslen(test1)+1; m_iMemory->AllocMemory((void**)&t1, iActualSize * sizeof(WCHAR_T)); ::convToShortWchar(&t1, test1, iActualSize);
За удобство при работа с низови типове данни ще опишем функцията wstring_to_p. Той получава wstring низ като параметър. Резултатът от функцията е запълнена структура tVariant. Функционален код:
bool CAddInNative::wstring_to_p(std::wstring str, tVariant* val) ( char* t1; TV_VT(val) = VTYPE_PWSTR; m_iMemory->AllocMemory((void**)&t1, (str.length()+1) * sizeof(WCHAR_T)); memcpy(t1, str.length()+1) * val -> pstrVal = t1; върне вярно)
След това съответния case раздел на оператора switch на метода GetPropValще приеме формата:
case ePropTest1: wstring_to_p(test1, pvarPropVal); прекъсване;
Метод SetPropVal:
case ePropTest1: if (TV_VT(varPropVal) != VTYPE_PWSTR) върне false; test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); прекъсване;
За да реализираме второто свойство, ние дефинираме поле за клас CaddInNative
uint8_t последен_тип;
в който ще запишем вида на последната прехвърлена стойност. За да направите това, добавете командата към метода CaddInNative::SetPropVal:
last_type = TV_VT(varPropVal);
Сега, когато поискаме да прочетем стойността на второто свойство, ще върнем стойността последен_тип, какво изисква определената задача.
Нека проверим функционалността на направените промени.
За да направите това, нека представим външния вид на конфигурацията 1C, както следва:
променлива DemoComp; Процедура при стартиране на системата() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.TypeCheck = 1; Доклад(низ(DemoComp.TypeCheck)); DemoComp.Test = "Вася"; Доклад(Низ(ДемоКомп.Тест)); DemoComp.Test = "Петя"; Доклад(Низ(ДемоКомп.Тест)); Доклад(низ(DemoComp.TypeCheck)); EndProcedure
В резултат на стартирането ще получим поредица от съобщения:
3
Вася
Петър
22

Второто и третото съобщение са резултат от четене на свойството, зададено в предишната стъпка. Първото и второто съобщение съдържат кода на типа на последния набор от свойства. 3 съответства на цяло число, 22 на низова стойност. Във файла се установява съответствието на видовете и техните кодове типове.ч, който се намира на ITS диска.

Разширяване на списъка с методи

Задача:
  1. Разширете функционалността на външния компонент със следната функционалност:
  2. Разгледайте начини за прилагане на методи на външни компоненти
  3. Добавете метод на функция Функция1, който приема два низа („Параметър1“ и „Параметър2“) като параметър. Резултатът е низ като: „Проверява се. Параметър1, Параметър2"
  4. Уверете се, че промените, които правите, работят.

За да дефинира методите на създавания компонент, разработчикът трябва да внедри следните методи в кода на библиотеката AddInNative:
GetNMethods, FindMethod, GetMethodName
Проектиран да получи съответния брой методи, потърсете номера и името на метода. Подобно на съответните методи за свойства
GetNParams
Връща броя на параметрите на метода с посочения пореден номер; ако метод с този номер липсва или няма параметри, връща 0
GetParamDefValue
Връща стойността по подразбиране на посочения параметър на посочения метод
HasRetVal
Връща флага за това дали методът с посочената редна върната стойност има върната стойност: вярно за методи с върната стойност и невярнов противен случай
CallAsProc
невярно, възниква грешка по време на изпълнение и изпълнението на модула 1C: Enterprise се прекратява. Паметта за масива от параметри се разпределя и освобождава от 1C: Enterprise.
CallAsFunc
Изпълнява метода с посочения пореден номер. Ако методът се върне невярно, възниква грешка по време на изпълнение и изпълнението на модула 1C: Enterprise се прекратява. Паметта за масива от параметри се разпределя от 1C: Enterprise. Ако върнатата стойност е низ или двоичен тип данни, компонентът разпределя памет с функцията Разпределяне на паметтамениджър на паметта, записва данни там и съхранява този адрес в съответното поле на структурата. 1C: Предприятието ще освободи тази памет чрез обаждане FreeMemory.
Пълно описание на методите, включително списък с параметри, е описано подробно в документацията, предоставена на ITS диска.
Нека разгледаме изпълнението на методите, описани по-горе.
В кода на компонента са дефинирани два масива:
статичен wchar_t *g_MethodNames = (L"Активиране", L"Деактивиране", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); статичен wchar_t *g_MethodNamesRu = (L"Активиране", L"Деактивиране", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage");
и изброяване:
enum Методи ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Винаги последен);
Те се използват във функции GetNMethods, FindMethodИ GetMethodName, по аналогия с описанието на имотите.
Методи GetNParams, GetParamDefValue, HasRetVal implement switch, в зависимост от предадените параметри и логиката на приложението, връща необходимата стойност. Метод HasRetValв своя код има списък само с методи, които могат да върнат резултат. За тях той се връща вярно. За всички стоманени методи за връщане невярно.
Методи CallAsProcИ CallAsFuncсъдържат директно изпълним код на метода.
За да добавите метод, който може да бъде извикан само като функция, трябва да направите следните промени в изходния код на външния компонент:
  1. Добавете име на метод към масиви g_MethodNamesИ g_MethodNamesRu(файл AddInNative.cpp)
  2. Добавете смислен идентификатор на метод към изброяването на методите (файл AddInNative.h)
  3. Направете промени в кода на функцията GetNParamsспоред логиката на програмата
  4. Ако е необходимо, направете промени в кода на метода GetParamDefValue, ако искате да използвате стойностите по подразбиране на параметрите на метода.
  5. Направете промени във функцията HasRetVal
  6. Направете промени в логиката на функциите CallAsProcили CallAsFunc, поставяйки директно изпълнимия код на метода там
Да представим масивите g_MethodNamesИ g_MethodNamesRu, както и листинг Методикъм формата:
статичен wchar_t *g_MethodNames = (L"Активиране", L"Деактивиране", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"); статичен wchar_t *g_MethodNamesRu = (L"Активиране", L"Деактивиране", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test");

Методи Enum ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Винаги последен);
Нека редактираме функцията GetNPropsтака че да връща броя на параметрите на метода „Тест“:
long CAddInNative::GetNParams(const long lMethodNum) ( switch(lMethodNum) ( case eMethShowInStatusLine: return 1; case eMethLoadPicture: return 1; case eMethTest: return 2; default: return 0; ) return 0; )
Нека направим промени във функцията:
bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) ( ​​​​TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) ( case eMethEnable: case eMethDisable: case eMethShowInStatusLi ne: case eMethStartTimer: case eMethStopTimer: case eMethTest : / / Няма стойности на параметрите по подразбиране break: return false;
Благодарение на добавената линия
случай eMethTest:
ако един или повече аргументи липсват, съответните параметри ще имат празна стойност ( VTYPE_EMPTY). Ако имате нужда от стойност по подразбиране за параметър, трябва да я зададете в секцията eMethTestизявление за превключване на функции CAddInNative::GetParamDefValue.
Тъй като тестовият метод може да върне стойност, трябва да направите промени в кода на функцията HasRetVal:
bool CAddInNative::HasRetVal(const long lMethodNum) ( switch(lMethodNum) ( case eMethLoadPicture: case eMethTest: return true; default: return false; ) return false; )
И добавете изпълнимия код на метода към функцията CallAsFunc:
bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) ( ... std::wstring s1, s2; switch(lMethodNum) ( case eMethLoadPicture: ... break; case eMethTest: if (!lSizeArray) return false; s1 = (paParams) -> pwstrVal; s2 = (paParams+1) -> pwstring(s1+s2), pvarRetValue; ;
Нека компилираме компонента и пренесем конфигурационния код във формата:
променлива DemoComp; Процедура при стартиране на системата() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); лента = DemoComp.Test("Здравей," "Свят!"); Доклад(на); EndProcedure
След като стартираме конфигурацията, ще получим съобщението: “Hello, World!”, което показва, че методът е работил успешно.

Таймер

Задача:
  1. Проучете изпълнението на таймера в демонстрационния VK
  2. Променете метода „StartTimer“, като добавите възможност за предаване в параметрите на интервала за отговор на таймера (в милисекунди)
  3. Уверете се, че промените, които правите, работят.

В WinAPI можете да използвате съобщението, за да работите с времето WM_TIMER. Това съобщение ще бъде изпратено до вашата програма в интервала от време, който сте задали при създаването на таймера.
За да създадете таймер, използвайте функцията SetTimer:
UINT SetTimer(HWND hWnd, // дескриптор на прозорец UINT nIDevent, // идентификатор на таймера (номер) UINT nElapse, // забавяне TIMERPROC lpTimerFunc); // указател към функция
Операционната система ще изпрати съобщение WM_TIMERв програмата с интервала, посочен в аргумента nИзтичане(в милисекунди). В последния параметър можете да зададете функция, която да се изпълнява при всяко задействане на таймера. Заглавката на тази функция трябва да изглежда така (името може да бъде каквото и да е):
void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Нека разгледаме внедряването на таймер в демонстрационния VC.
Тъй като обмисляме процеса на разработване на външен компонент за семейството на Windows OS, няма да разглеждаме внедряването на таймера в други операционни системи. По-специално за GNU/Linux OS реализацията ще се различава в синтаксиса на функцията SetTimerИ TimerProc.
Изпълнимият код извиква метода SetTimer, към който се предава функцията MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
Идентификационният номер на създадения таймер се поставя в променлива m_uiTimerтака че да може да бъде деактивиран по-късно.
функция MyTimerProcкакто следва:
VOID CALLBACK MyTimerProc(HWND hwnd, // манипулатор на прозорец за съобщения на таймера UINT uMsg, // WM_TIMER съобщение UINT idEvent, // идентификатор на таймера DWORD dwTime // текущо системно време) ( if (!pAsyncEvent) return; wchar_t *who = L "ComponentNative", *what = L"Timer"; wchar_t *wstime = new wchar_t; if (wstime) (wmemset(wstime, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(who , какво, wstime);
Същността на функцията е, че методът се извиква Външно събитие, който изпраща съобщение до системата 1C: Enterprise.
За разширяване на функционалността на метода StartTimerНека направим следното:
Промяна на кода на метода GetNParamsтака че да е за метода eMethStartTimerвърната стойност 1:
случай eMethStartTimer: връщане 1;
Ето кода на метода CallAsProcкъм формата:
case eMethStartTimer: if (!lSizeArray || TV_VT(paParams) != VTYPE_I4 || TV_I4(paParams)<= 0) return false; pAsyncEvent = m_iConnect; #ifndef __linux__ m_uiTimer = ::SetTimer(NULL,0,TV_I4(paParams),(TIMERPROC)MyTimerProc); #else // код для GNU/Linux #endif break;
Сега нека проверим функционалността. За да направим това, ще напишем кода в модула на управляваното приложение на конфигурацията:
променлива DemoComp; Процедура при стартиране на системата() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.StartTimer(2000); EndProcedure
След стартиране на конфигурацията, програмата ще получава съобщения на интервали от 2 секунди, което показва, че таймерът работи правилно.

Взаимодействие със системата 1C: Enterprise

За взаимодействие между външния компонент и системата 1C: Enterprise, методите на класа IAddInDefBase, описани във файла AddInDefBase.h. Ние изброяваме най-често използваните:
Генериране на съобщение за грешка
virtual bool ADDIN_API AddError(неподписан кратък wcode, const WCHAR_T* източник, const WCHAR_T* descr, дълъг scode)
wcode, scode- кодове за грешки (списък с кодове за грешки с описания можете да намерите на ITS диска)
източник- източник на грешка
описание- описание на грешката
Изпращане на съобщение до системата 1C: Enterprise
виртуален bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszSource- източник на съобщение
wszСъобщение- Текст на съобщението
wszData- предадени данни
Прихващането на съобщения се извършва чрез процедурата за обработка на външни събития
Регистрация на външен компонент в системата 1C: Enterprise
виртуален bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfileName- име на компонента.
Тези методи са достатъчни за пълно взаимодействие между VK и 1C. За да получи данни от външен компонент от системата 1C: Enterprise и обратно, външният компонент изпраща специално съобщение, което от своя страна се прихваща от системата 1C и, ако е необходимо, извиква методите на външния компонент за обратно предаване на данни .

tVariant тип данни

При обмен на данни между външния компонент и системата 1C: Enterprise се използва типът данни tVariant. Описано е във файла types.h, който може да се намери на ITS диска:
struct _tVariant ( _ANONYMOUS_UNION union ( int8_t i8Val; int16_t shortVal; int32_t lVal; int intVal; unsigned int uintVal; int64_t llVal; uint8_t ui8Val; uint16_t ushortVal; uint32_t ulVal; uint64_t; int32_t errCode; float fltVal; wch_t val; struct tmVal; __VARIANT_NAME_2/*iface*/; uint32_t strLen; //count of bytes __ANONYMOUS_STRUCT struct (WCHAR_T* pwstrVal; //count of symbol) __VARIANT_NAME_1 ; размерен масив в pvarVal TYPEVAR vt);
Тип tVariantе структура, която включва:
  • смес (обединение), предназначена директно за съхранение на данни
  • идентификатор на тип данни
Като цяло работата с променливи от тип tVariantсе извършва по следния алгоритъм:
  1. Определяне на типа данни, съхранявани в момента в променлива
  2. Достъп до съответното поле за смес за директен достъп до данните
Използване на типа tVariantзначително опростява взаимодействието на системата 1C: Enterprise и външните компоненти

Приложение

Директорията „примери“ съдържа примери за статията
examples/1 - стартира демо компонента
examples/2 - демонстрация на разширяване на списъка с имоти
examples/3 - демонстрация на разширяване на списъка с методи
Всяка директория съдържа проект VS 2008 и готова 1C конфигурация.