Новые релизы «1С: Управление торговлей»: обновление без развития. Решение проблем с регистрацией внешних компонент в терминале Оперативный учет становится регламентированным

Вариант синтаксиса: По имени и местоположению

Синтаксис:

ПодключитьВнешнююКомпоненту(<Местоположение>, <Имя>, <Тип>)
Параметры:

<Местоположение> (обязательный)

Тип: Строка.
Местоположение внешнего компонента.
В качестве местоположения может использоваться:
путь к файлу внешнего компонента в файловой системе (недоступно на веб-клиенте), не ZIP-архив;
полное имя макета, хранящего двоичные данные или ZIP-архив;
URL к внешнему компоненту, в виде двоичных данных или ZIP-архива, в , аналогичном ПолучитьНавигационнуюСсылку.
<Имя> (обязательный)

Тип: Строка.
Символическое имя подключаемой внешнего компонента.
Имя должно удовлетворять правилам именования встроенного языка.
<Тип> (необязательный)

Тип: ТипВнешнейКомпоненты.
Тип подключаемого внешнего компонента.
Не используется, если компонент упакован в ZIP-архив.
Описание варианта метода:

Подключает компоненты, выполненные по технологии Native и COM.
Компонент может храниться в информационной базе или макете конфигурации в виде двоичных данных или в ZIP-архиве.
Для режимов запуска "Тонкий клиент" и "Веб-клиент", компонент должен быть предварительно установлен методом УстановитьВнешнююКомпоненту.
Вариант синтаксиса: По идентификатору

Синтаксис:

ПодключитьВнешнююКомпоненту(<ИдентификаторОбъекта>)
Параметры:

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

Тип: Строка.
Идентификатор объекта внешнего компонента в виде ProgID (Programmatic Identifier) реестра MS Windows (например: "AddIn.Scanner").
Должно соответствовать информации, находящейся в регистрационной базе данных системы (Registry).
Описание варианта метода:

Компонент должен быть выполнен по технологии COM и зарегистрирован в реестре MS Windows.
Эти компоненты совместимы с компонентами 1С:Предприятия 7.7.
Внимание! Вариант метода не работает на сервере и во внешнем соединении.
Возвращаемое значение:

Тип: Булево.
Истина - подключение прошло успешно.
Описание:

Подключает внешний компонент к 1С:Предприятию.
Внешние компоненты могут храниться в информационной базе или макетах конфигурации в виде ZIP-архива или в виде двоичных данных, а также в файле файловой системы.
При работе на тонком клиенте и веб-клиенте компонент должен быть предварительно установлен.

Доступность:

Тонкий клиент, веб-клиент, сервер, внешнее соединение.
Примечание:

Внешние компоненты могут быть выполнены по технологии Native API или COM. Компоненты, выполненные по технологии COM, совместимы с компонентами 1С:Предприятия 7.7.
Веб-клиент может работать только с компонентами в информационной базе, упакованными в архив.
Тонкий клиент может работать с компонентами в информационной базе, упакованными в архив, и компонентами, расположенными в файловой системе.
Толстый клиент может работать со всеми вариантами хранения компонентов. При этом, если компонент установлен методом УстановитьВнешнююКомпоненту, то используется установленный компонент, а если не установлен, то компонент будет получен в момент подключения.
Сервер может работать со всеми компонентами. Компонент кэшируется на сеанс работы сервера.
Пример:

Если ПодключитьВнешнююКомпоненту("AddinObject.Scanner") Тогда
Сообщить("Компонента для сканера штрихкодов загружена");
Иначе
Сообщить("Компонента для сканера штрихкодов не загружена");
КонецЕсли;

Например, не получится переписать компоненту, если вы не её автор и исходников просто нет. Либо если для ее работы недостаточно поддерживаемых технологией Native API простейших типов (число, строка, булево, дата).

При работе с файловой базой особых проблем нет. Регламентное задание вызывается в фоновом процессе обычного пользователя. Поэтому ему доступны клиенские вызовы. В серверной базе при запуске регламентного задания клиентского контекста нет, соответственно вызов ПодключитьВнешнююКомпоненту() недоступен.

В этом случае можно вызывать компоненту на клиенте. Для этого достаточно выполнить из регламентного задания на сервере запуск еще одного сеанса 1С в котором на клиенте выполнить нужные действия. Ну и не забыть потом завершить запущенный сеанс.

Допустим, у нас в регламентном задании выполняется формирование и сохранение отчета, использующего для склонения ФИО внешнюю COM-компоненту NameDeclension.dll. На файловой базе такое регламентное задание будет работать корректно, на серверной компоненту подключить не получится.

Для устранения проблемы добавим в модуль регламентных заданий процедуру, которая в серверном режиме запустит еще один сеанс и в нем выполнит из внешней обработки вызов формирования отчета на клиенте.

#Если Клиент Тогда Процедура ВыполнитьФормированиеИСохранениеОтчета() Экспорт Если ПодключитьВнешнююКомпоненту("ОбщийМакет.NAMEDECL","Скл",ТипВнешнейКомпоненты.COM) Тогда Компонента = Новый ("AddIn.Скл.NameDeclension"); //Тут код формирования и сохранения отчета Иначе ЗаписьЖурналаРегистрации("РеглЗадания", УровеньЖурналаРегистрации.Ошибка, "Не удалось подключить внешнюю компоненту на клиенте"); КонецЕсли; КонецПроцедуры #Иначе Процедура ВыполнитьФормированиеИСохранениеОтчета() Экспорт ВыполнитьОперациюНаКлиенте("РеглЗадания.ВыполнитьФормированиеИСохранениеОтчета()"); КонецПроцедуры Процедура ВыполнитьОперациюНаКлиенте(ПараметрДляВыполнения) Экспорт ИмяПользователя = ""; ПарольПользователя = ""; ПутьКВнешнейОбработке = "c:/temp/Автозапуск.epf"; Кавычка = """"; КаталогBIN = КаталогПрограммы(); ПутьККонфигурации = СтрокаСоединенияИнформационнойБазы(); ПутьККонфигурации = СтрЗаменить(ПутьККонфигурации, Кавычка, Кавычка + Кавычка); СтрокаЗапуска = Кавычка + КаталогBIN + "1cv8.exe" + Кавычка + " ENTERPRISE" + " /IBConnectionString " + Кавычка + ПутьККонфигурации + Кавычка + " /N " + Кавычка + ИмяПользователя + Кавычка + " /P " + Кавычка + ПарольПользователя + Кавычка + " /Execute " + Кавычка + ПутьКВнешнейОбработке + Кавычка + " /C " + Кавычка + ПараметрДляВыполнения + Кавычка; ЗапуститьПриложение(СтрокаЗапуска); КонецПроцедуры #КонецЕсли

Код внешней обработки, которая просто вызовет в контексте клиента печать нужного отчета из модуля регламентных заданий и завершит сеанс после формирования отчета.

Попытка Выполнить(ПараметрЗапуска); Исключение КонецПопытки; ЗавершитьРаботуСистемы(Ложь);

Удобство решения в том, что при настройке регламентных заданий не важно, в каком режиме будет выполняться запуск задания. Если база файловая, то сразу запустится нужная процедура. Если база серверная и при запуске клиентский контекст отсутствует, то выполнится инициализация нового сеанса и в нем процедура корректно отработает в контексте клиента.

Код для обычного приложения. Теоретически полностью аналогично будет работать и в управляемом.

p.s. Также этот подход можно использовать для выполнения любых клиентских процедур в регламентных заданиях.

  • Tutorial

Введение

Эта статья дает представление о работе внешних компонент в системе «1С: Предприятие».
Будет показан процесс разработки внешней компоненты для системы «1С: Предприятие» версии 8.2, работающей под управлением ОС семейства Windows с файловым вариантом работы. Такой вариант работы используется в большинстве решений, предназначенных для предприятий малого бизнеса. ВК будет реализована на языке программирования C++.

Внешние компоненты «1C: Предприятие»

«1С: Предприятие» является расширяемой системой. Для расширения функциональных возможностей системы используются внешние компоненты (ВК). С точки зрения разработчика ВК представляет собой некоторый внешний объект, который имеет свойства и методы, а также может генерировать события для обработки системой «1С: Предприятие».
Внешние компоненты можно использовать для решения класса задач, которые сложно или даже невозможно реализовать на встроенном в «1C: Предприятие» языке программирования. В частности, к такому классу можно отнести задачи, требующие низкоуровневого взаимодействия с операционной системой, например, для работы с специфичным оборудованием.
В системе «1С: Предприятие» используются две технологии создания внешних компонент:
  • с использованием Native API
  • с использованием технологии COM
При заданных ограничениях между двумя вышеозначенными технологиями разница незначительна, поэтому будем рассматривать разработку ВК с использованием Native API. При необходимости, реализованные наработки могут быть применены для разработки ВК с использованием технологии COM, а также, с незначительными доработками, применены для использования в системе «1С: Предприятие» с другими вариантами работы, отличными от файлового режима работы.
Структура ВК
Внешняя компонента системы «1С: Предприятие» представлена в виде DLL-библиотеки. В коде библиотеки описывается класс-наследник IComponentBase. В создаваемом классе должны быть определены методы, отвечающие за реализацию функций внешней компоненты. Более подробно переопределяемые методы будут описаны ниже по ходу изложения материала.

Запуск демонстрационной ВК

Задача:
  1. Выполнить сборку внешней компоненты, поставляемой с подпиской ИТС и предназначенной для демонстрации основных возможностей механизма внешних компонент в 1С
  2. Подключить демонстрационную компоненту к конфигурации 1С
  3. Убедиться в корректной работоспособности заявленных функций
Компиляция
Демонстрационная ВК расположена на диске подписки ИТС в каталоге «/VNCOMP82/example/NativeAPI».
Для сборки демонстрационной ВК будем использовать Microsoft Visual Studio 2008. Другие версии данного продукта не поддерживают используемый формат проекта Visual Studio.


Открываем проект AddInNative. В настройках проекта подключаем каталог с заголовочными файлами, необходимыми для сборки проекта. По умолчанию они располагаются на диске ИТС в каталоге /VNCOMP82/include .
Результатом сборки является файл /bind/AddInNative.dll . Это и есть скомпилированная библиотека для подключения к конфигурации 1С.
Подключение ВК к конфигурации 1С
Создадим пустую конфигурацию 1С.
Ниже приведен код модуля управляемого приложения.
перем ДемоКомп; Процедура ПриНачалеРаботыСистемы() ПодключитьВнешнююКомпоненту("...\bind\AddInNative.dll", "DemoVK", ТипВнешнейКомпоненты.Native); ДемоКомп = Новый("AddIn.DemoVK.AddInNativeExtension"); КонецПроцедуры
Если при запуске конфигурации 1С не было сообщено об ошибке, то ВК была успешно подключена.
В результате выполнения приведенного кода в глобальной видимости конфигурации появляется объект ДемоКомп , имеющий свойства и методы, которые определены в коде внешней компоненты.
Демонстрация заложенного функционала
Проверим работоспособность демонстрационной ВК. Для этого попробуем установить и прочитать некоторые свойства, вызвать некоторые методы ВК, а также получить и обработать сообщение ВК.
В документации, поставляемой на диске ИТС заявлен следующий функционал демонстрационной ВК:
  1. Управление состоянием объекта компоненты
    Методы: Включить , Выключить
    Свойства: Включен
  2. Управлением таймером
    Каждую секунду компонента посылает сообщение системе «1C: Предприятие» с параметрами Component , Timer и строкой счетчика системных часов.
    Методы: СтартТаймер , СтопТаймер
    Свойства: ЕстьТаймер
  3. Метод ПоказатьВСтрокеСтатуса , который отображает в строке статуса текст, переданный методу в качестве параметров
  4. Метод ЗагрузитьКартинку . Загружает изображение из указанного файла и передает его в систему «1C: Предприятие» в виде двоичных данных.
Убедимся в работоспособности этих функций. Для этого исполним следующий код:
перем ДемоКомп; Процедура ПриНачалеРаботыСистемы() ПодключитьВнешнююКомпоненту(...); ДемоКомп = Новый("AddIn.DemoVK.AddInNativeExtension"); ДемоКомп.Выключить(); Сообщить(ДемоКомп.Включен); ДемоКомп.Включить(); Сообщить(ДемоКомп.Включен); ДемоКомп.СтартТаймер(); КонецПроцедуры Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные) Сообщить(Источник + " " + Событие + " " + Данные); КонецПроцедуры
Результат запуска конфигурации приведен на изображении


На панель «Сообщения» выведены результаты вызовов методов ДемоКомп.Выключить() и Демо.Комп.Включить() . Последующие строки на той же панели содержат результаты обработки полученных от ВК сообщений - Источник , Событие и Данные соответственно.

Произвольное имя внешней компоненты

Задача: Изменить имя внешней компоненты на произвольное.
В предыдущем разделе использовался идентификатор AddInNativeExtension , смысл которого не был пояснен. В данном случае AddInNativeExtension - это наименование расширения.
В коде ВК определен метод RegisterExtensionAs , возвращающий системе «1С: Предприятие» имя, которое необходимо для последующей регистрации ВК в системе. Рекомендуется указывать идентификатор, который в известной мере раскрывает суть внешней компоненты.
Приведем полный код метода 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, wsExtension, iActualSize); return true; } return false; }
В приведенном примере имя ВК изменено на SomeName . Тогда при подключении ВК необходимо указывать новое имя:
ДемоКомп = Новый("AddIn.DemoVK.SomeName");

Расширение списка свойств ВК

Задача:
  1. Изучить реализацию свойств ВК
  2. Добавить свойство строкового типа, доступное для чтения и записи
  3. Добавить свойство строкового типа, доступное для чтения и записи, которое хранит тип данных последнего установленного свойства. При установке значения свойства никаких действий не производится

Для определения свойств создаваемой компоненты разработчику необходимо реализовать следующие методы в коде библиотеки AddInNative.cpp:
GetNProps
Возвращает количество свойств данного расширения, 0 – при отсутствии свойств
FindProp
Возвращает порядковый номер свойства, имя которого передается в параметрах
GetPropName
Возвращает имя свойства по его порядковому номеру и по переданному идентификатору языка
GetPropVal
Возвращает значение свойства с указанным порядковым номером
SetPropVal
Устанавливает значение свойства с указанным порядковым номером
IsPropReadable
Возвращает флаг флаг возможности чтения свойства с указанным порядковым номером
IsPropWritable
Возвращает флаг флаг возможности записи свойства с указанным порядковым номером


Рассмотрим реализацию приведенных методов класса CAddInNative .
В демонстрационной ВК определены 2 свойства: Включен и ЕстьТаймер (IsEnabled и IsTimerPresent ).
В глобальной области видимости кода библиотеки определено два массива:
static wchar_t *g_PropNames = {L"IsEnabled", L"IsTimerPresent"}; static wchar_t *g_PropNamesRu = {L"Включен", L"ЕстьТаймер"};
которые хранят русское и английское названия свойств. В заголовочном файле AddInNative.h определяется перечисление:
enum Props { ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Always last };
ePropIsEnabled и ePropIsTimerPresent , соответственно имеющие значения 0 и 1 используются для замены порядковых номеров свойств на осмысленные идентификаторы. ePropLast, имеющее значение 2, используется для получения количества свойств (методом GetNProps). Эти имена используются только внутри кода компоненты и недоступны извне.
Методы FindProp и GetPropName осужествляют поиск по массивам g_PropNames и g_PropNamesRu .
Для хранения значения полей в модуле библиотеки у класса CAddInNative определены свойства, которые хранят значение свойств компоненты. Методы GetPropVal и SetPropVal соответственно возвращают и устанавливают значение этих свойств.
Методы IsPropReadable и IsPropWritable и возвращают trure или false , в зависимости от переданного порядкового номера свойства в соответствии с логикой приложения.
Для того, чтобы добавить произвольное свойство необходимо:

  1. Добавить имя добавляемого свойства в массивы g_PropNames и g_PropNamesRu (файл AddInNative.cpp )
  2. В перечисление Props (файл AddInNative.h ) перед ePropLast добавить имя, однозначно идентифицирующее добавляемое свойство
  3. Организовать память под хранение значений свойств (завести поля модуля компоненты, хранящие соответствующие значения)
  4. Внести изменения в методы GetPropVal и SetPropVal для взаимодействия с выделенной на предыдущем шаге памятью
  5. В соответствии с логикой приложения внести изменения в методы IsPropReadable и IsPropWritable
Пункты 1, 2, 5 не нуждаются в пояснении. С деталями реализации этих шагов можно ознакомиться, изучив приложение к статье.
Дадим названия тестовым свойствам Тест и ПроверкаТипа соответственно. Тогда в результате выполнения пункта 1 имеем:
static wchar_t *g_PropNames = {L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"}; static wchar_t *g_PropNamesRu = {L"Включен", L"ЕстьТаймер", L"Тест", L"ПроверкаТипа"};
Перечисление Props будет иметь вид:
enum Props { ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Always last };
Для значительного упрощения кода будем использовать STL C++. В частности, для работы со строками WCHAR , подключим библиотеку wstring .
Для сохранения значения метода Тест , определим в классе CAddInNative в области видимости private поле:
string test1;
Для передачи строковых параметров между «1С: Предприятие» и внешней компонентов используется менеджер памяти «1С: Предприятие». Рассмотрим его работу подробнее. Для выделения и освобождения памяти соответственно используются функции AllocMemory и FreeMemory , определенные в файле ImemoryManager.h . При необходимости передать системе «1С: Предприятие» строковый параметр, внешняя компонента должна выделить под нее память вызовом функции AllocMemory . Ее прототип выглядит следующим образом:
virtual 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.c_str(), (str.length()+1) * sizeof(WCHAR_T)); val -> pstrVal = t1; val -> strLen = str.length(); return true; }
Тогда соответствующая секция case оператора switch метода GetPropVal примет вид:
case ePropTest1: wstring_to_p(test1, pvarPropVal); break;
Метода SetPropVal :
case ePropTest1: if (TV_VT(varPropVal) != VTYPE_PWSTR) return false; test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); break;
Для реализации второго свойства определим поле класса CaddInNative
uint8_t last_type;
в котором будем сохранять тип последнего переданного значения. Для этого в метод CaddInNative::SetPropVal добавим команду:
last_type = TV_VT(varPropVal);
Теперь при запросе чтения значения второго свойства будем возвращать значение last_type , чего требует обозначенное задание.
Проверим работоспособность произведенных изменений.
Для этого приведем внешний вид конфигурации 1С к виду:
перем ДемоКомп; Процедура ПриНачалеРаботыСистемы() ПодключитьВнешнююКомпоненту("...", "DemoVK", ТипВнешнейКомпоненты.Native); ДемоКомп = Новый("AddIn.DemoVK.SomeName"); ДемоКомп.ПроверкаТипа = 1; Сообщить(Строка(ДемоКомп.ПроверкаТипа)); ДемоКомп.Тест = "Вася"; Сообщить(Строка(ДемоКомп.Тест)); ДемоКомп.Тест = "Петя"; Сообщить(Строка(ДемоКомп.Тест)); Сообщить(Строка(ДемоКомп.ПроверкаТипа)); КонецПроцедуры
В результате запуска получим последовательность сообщений:
3
Вася
Петя
22

Второе и третье сообщения являются результатом чтения свойства, установленного на предыдущем шаге. Первое и второе сообщения содержат код типа последнего установленного свойства. 3 соответствует целочисленному значению, 22 - строковому. Соответствие типов и их кодов устанавливается в файле types.h , который находится на диске ИТС.

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

Задача:
  1. Расширить функционал внешней компоненты следующим функционалом:
  2. Изучить способы реализации методов внешней компоненты
  3. Добавить метод-функцию Функц1 , которая в качестве параметра принимает две строки («Параметр1» и «Параметр2»). В качестве результата возвращается строка вида: «Проверка. Параметр1, Параметр2»
  4. Убедиться в работоспособности произведенных изменений

Для определения методов создаваемой компоненты разработчику необходимо реализовать следующие методы в коде библиотеки AddInNative:
GetNMethods , FindMethod , GetMethodName
Предназначены для получения соответственно количества методов, поиска номера и имени метода. Аналогичны соответствующим методам для свойств
GetNParams
Возвращает количество параметров метода с указанным порядковым номером; если метод с таким номером отсутствует или не имеет параметров, возвращает 0
GetParamDefValue
Возвращает значение по умолчанию указанного параметра указанного метода
HasRetVal
Возвращает флаг наличия у метода с указанным порядковым номером возвращаемого значения: true для методов с возвращаемым значением и false в противном случае
CallAsProc
false , возникает ошибка времени выполнения и выполнение модуля 1С: Предприятия прекращается. Память для массива параметров выделяется и освобождается 1С: Предприятием.
CallAsFunc
Выполняет метод с указанным порядковым номером. Если метод возвращает false , возникает ошибка времени выполнения и выполнение модуля 1С: Предприятия прекращается. Память для массива параметров выделяется 1С: Предприятием. Если возвращаемое значение имеет тип строка или двоичные данные, компонента выделяет память функцией AllocMemory менеджера памяти, записывает туда данные и сохраняет этот адрес в соответствующем поле структуры. 1С: Предприятие освободит эту память вызовом FreeMemory .
Полное описание методов, включая список параметров подробно описан в документации, поставляемой на диске ИТС.
Рассмотрим реализацию описанных выше методов.
В в коде компоненты определены два массива:
static wchar_t *g_MethodNames = {L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"}; static wchar_t *g_MethodNamesRu = {L"Включить", L"Выключить", L"ПоказатьВСтрокеСтатуса", L"СтартТаймер", L"СтопТаймер", L"ЗагрузитьКартинку"};
и перечисление:
enum Methods { eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Always last };
Они используются в функциях GetNMethods , FindMethod и GetMethodName , по аналогии с описанием свойств.
Методы GetNParams , GetParamDefValue , HasRetVal реализуют switch, в зависимости от переданных параметров и логики приложения возвращают требуемое значение. Метод HasRetVal в своем коде имеет список только методов, которые могут возвращать результат. Для них он возвращает true . Для всехо стальных методов возвращается false .
Методы CallAsProc и CallAsFunc содержат непосредственно исполняемый код метода.
Для добавления метода, который может вызываться только как функция необходимо произвести следующие изменения в исходном коде внешней компоненты:
  1. Добавить имя метода в массивы g_MethodNames и g_MethodNamesRu (файл AddInNative.cpp )
  2. Добавить осмысленный идентефикатор метода в перечисление Methods (файл AddInNative.h )
  3. Внести изменения в код функции GetNParams в соответствии с логикой программы
  4. При необходимости внести изменения в код метода GetParamDefValue , если требуется использовать значения по умолчанию параметров метода.
  5. Внести изменения в функцию HasRetVal
  6. Внести изменения в логику работы функций CallAsProc или CallAsFunc , поместив туда непосредственно исполняемый код метода
Приведем массивы g_MethodNames и g_MethodNamesRu , а также перечисление Methods к виду:
static wchar_t *g_MethodNames = {L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"}; static wchar_t *g_MethodNamesRu = {L"Включить", L"Выключить", L"ПоказатьВСтрокеСтатуса", L"СтартТаймер", L"СтопТаймер", L"ЗагрузитьКартинку", L"Тест"};

Enum Methods { eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Always last };
Отредактируем функцию 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 eMethShowInStatusLine: case eMethStartTimer: case eMethStopTimer: case eMethTest: // There are no parameter values by default break; default: return false; } return false; }
Благодаря добавленной строке
case eMethTest:
в случае отсутствия одного или нескольких аргументов соответствующие параметры будут иметь пустое значение (VTYPE_EMPTY ). Если необходимо наличие значения по умолчанию для параметра, следует задать его в секции eMethTest оператора switch функции 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 || !paParams) return false; s1 = (paParams) -> pwstrVal; s2 = (paParams+1) -> pwstrVal; wstring_to_p(std::wstring(s1+s2), pvarRetValue); ret = true; break; } return ret; }
Скомпилируем компоненту и приведем код конфигурации к виду:
перем ДемоКомп; Процедура ПриНачалеРаботыСистемы() ПодключитьВнешнююКомпоненту("...", "DemoVK", ТипВнешнейКомпоненты.Native); ДемоКомп = Новый("AddIn.DemoVK.SomeName"); пер = ДемоКомп.Тест("Привет, ", "Мир!"); Сообщить(пер); КонецПроцедуры
После запуска конфигурации получим сообщение: «Привет, Мир!», что говорит о том, что метод отработал успешно.

Таймер

Задача:
  1. Изучить реализацию таймера в демонстрационной ВК
  2. Модифицировать метод «СтартТаймер», добавив возможность передавать в параметрах интервал срабатывания таймера (в миллисекундах)
  3. Убедиться в работоспособности произведенных изменений

В WinAPI для работы со временем можно воспользоваться сообщением WM_TIMER . Данное сообщение будет посылаться вашей программе через интервал времени, который вы зададите при создании таймера.
Для создания таймера используется функция SetTimer :
UINT SetTimer(HWND hWnd, // описатель окна UINT nIDevent, // идентификатор (номер) таймера UINT nElapse, // задержка TIMERPROC lpTimerFunc); // указатель на функцию
Операционная система будет посылать сообщение WM_TIMER в программу с интервалом указанным в аргументе nElapse (в миллисекундах). В последнем параметре можно указать функцию, которая будет выполняться при каждом срабатывании таймера. Заголовок этой функции должен выглядеть так (имя может быть любым):
void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Рассмотрим реализацию таймера в демонстрационной ВК.
Так как мы рассматриваем процесс разработки внешней компоненты для ОС семейства Windows, не будем рассматривать реализацию таймера в других операционных системах. Для ОС GNU/Linux, в частности, реализация будет отличаться синтаксисом функции SetTimer и TimerProc .
В исполняемом коде вызывается метод SetTimer , в который передается функция MyTimerProc :
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
Идентефикатор созданного таймера помещается в переменную m_uiTimer , чтобы в последствии его можно было отключить.
Функция MyTimerProc выглядит следующим образом:
VOID CALLBACK MyTimerProc(HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // current system time) { if (!pAsyncEvent) return; wchar_t *who = L"ComponentNative", *what = L"Timer"; wchar_t *wstime = new wchar_t; if (wstime) { wmemset(wstime, 0, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(who, what, wstime); delete wstime; } }
Суть функции сводится к тому, что вызывается метод ExternalEvent , который посылает сообщение системе «1С: Предприятие».
Для расширения функционала метода СтартТаймер произведем следующие действия:
Модифицируем код метода GetNParams так, чтобы он для метода eMethStartTimer возвращал значение 1:
case eMethStartTimer: return 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;
Теперь проверим работоспособность. Для этого в модуле управляемого приложения конфигурации напишем код:
перем ДемоКомп; Процедура ПриНачалеРаботыСистемы() ПодключитьВнешнююКомпоненту("...", "DemoVK", ТипВнешнейКомпоненты.Native); ДемоКомп = Новый("AddIn.DemoVK.SomeName"); ДемоКомп.СтартТаймер(2000); КонецПроцедуры
После запуска конфигурации в программу будут поступать сообщения с интервалом в 2 секунды, что говорит о корректной работе таймера.

Взаимодействие с системой «1С: Предприятие»

Для взаимодействия между внешней компонентой и системой «1С: Предприятие» используются методы класса IAddInDefBase, описанного в файле AddInDefBase.h . Перечислим наиболее часто используемые:
Генерация сообщения об ошибке
virtual bool ADDIN_API AddError(unsigned short wcode, const WCHAR_T* source, const WCHAR_T* descr, long scode)
wcode , scode - коды ошибки (список кодов ошибок с описанием можно найти на диске ИТС)
source - источник ошибки
descr - описание ошибки
Отправка сообщения системе «1С: Предприятие»
virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszSource - источник сообщения
wszMessage - текст сообщения
wszData - передаваемые данные
Перехват сообщения осуществляется процедурой ОбработкаВнешнегоСобытия
Регистрация внешней компоненты в системе «1С: Предприятие»
virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfileName - имя компоненты.
Этих методов достаточно для полноценного взаимодействия ВК и 1С. Для получения данных внешней компонентой от системы «1С: Предприятие» и наоборот внешняя компонента отправляет специальное сообщение, которое в свою очередь перехватывается системой «1С» и, при необходимости вызывает методы внешней компоненты для обратной передачи данных.

Тип данных tVariant

При обмене данными между внешней компонентой и системой «1С: Предприятие» используется тип данных tVariant. Он описан в файле types.h, который можно найти на диске с ИТС:
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 ullVal; int32_t errCode; long hRes; float fltVal; double dblVal; bool bVal; char chVal; wchar_t wchVal; DATE date; IID IDVal; struct _tVariant *pvarVal; struct tm tmVal; _ANONYMOUS_STRUCT struct { void* pInterfaceVal; IID InterfaceID; } __VARIANT_NAME_2/*iface*/; _ANONYMOUS_STRUCT struct { char* pstrVal; uint32_t strLen; //count of bytes } __VARIANT_NAME_3/*str*/; _ANONYMOUS_STRUCT struct { WCHAR_T* pwstrVal; uint32_t wstrLen; //count of symbol } __VARIANT_NAME_4/*wstr*/; } __VARIANT_NAME_1; uint32_t cbElements; //Dimension for an one-dimensional array in pvarVal TYPEVAR vt; };
Тип tVariant представляет из себя структру, которая включает себя:
  • смесь (union), предназначенную непосредственно для хранения данных
  • идентификатор типа данных
В общем случае работа с переменными типа tVariant происходит по следующему алгоритму:
  1. Определение типа данных, которые в данный момент хранятся в переменной
  2. Обращение к соответствующему полю смеси, для непосредственного доступа к данным
Использование типа tVariant значительно упрощает взаимодействие системы «1С: Предприятие» и внешней компоненты

Приложение

Каталог «examples» содержит примеры к статье
examples/1 - запуск демонстрационной компоненты
examples/2 - демонстрация расширения списка свойств
examples/3 - демонстрация расширения списка методов
Каждый каталог содержит проект VS 2008 и готовую конфигурацию 1C.

23 октября вышел новый релиз конфигурации «1С: Управление торговлей» . В очередной раз в обновление вошли изменения по ВетИС, ЕГАИС, и почти никак не была затронута общая функциональность конфигурации.

Что изменилось?

Если посмотреть на структуру изменений, которые включены в последний релиз конфигурации «1С: Управление торговлей» , то больше половины - это обновление по ЕГАИС, ВетИС, и лишь несколько строк в описании релиза посвящено расширению функциональных возможностей программного продукта, которые не обусловлены никакими законодательными актами.

Разделы, в которых произошли изменения:

    в розничных продажах добавлена поддержка считывания двухмерного штрихового кода акцизных и федеральных специальных марок нового образца, содержащего цифровой идентификатор ЕГАИС;

    доработана интеграция с системой ветеринарного контроля (ВетИС);

    доработан обмен с системой ЕГАИС;

    добавлены новые возможности сервиса обмена электронными документами;

    выполнены доработки в части сервиса 1С:Бизнес-сеть;

    доработана интеграция с Яндекс.Кассой.

Что касается общей функциональности, здесь было внесено несколько изменений в блоке планирования и казначейства. И традиционно постоянные дополнения по учету НДС.

При этом, последний актуальный релиз конфигурации «1С: Управление торговлей» не является исключением - сейчас развитие конфигурации для оперативного учета идет в основном по пути закрытия задач, которые возникают вследствие законодательного регулирования в сфере торговли. Логично, что поддержка требований регуляторов становится более приоритетной, и, в конечном итоге, определяет направление развития программного решения в целом.

Оперативный учет становится регламентированным?

Традиционно конфигурация «1С: Управление торговлей» используется для автоматизации оперативного учета. При этом в связке с «1С: Бухгалтерией» принято было «сгружать» все требования по модификации типового функционала в «1С: УТ», чтобы сохранить возможность обновления бухгалтерской программы с минимальными трудозатратами.

Учитывая объем регламентирующих документов для оперативного учета в торговле и отражение этих требований в типовой конфигурации, есть причины более бережно подходить к внесению изменений в типовой функционал торговой конфигурации. Например, проблемы с обменом с системой Меркурий могут если не парализовать деятельность целого ряда предприятий, то привести к длительным простоям, как минимум.

В качестве одного из вариантов решения можно рассматривать использование механизма расширений, тем более что фирма «1С» активно этот функционал. Безусловно, такой подход потребует дополнительных трудозатрат от разработчиков. Но это оптимальный способ поддержки изменений в современных конфигурациях.

Более радикальным будет распределение функционала между типовой конфигурацией «1С: Управление торговлей» и какими-то внешними учетными или аналитическими системами. Здесь со стороны «1С» опять-таки сделано достаточно для эффективного решения такого рода задач на уровне платформы.

В любом случае, теперь при проектировании корпоративных учетных систем и распределении функциональных возможностей между конфигурациями, нужно иметь ввиду: не исключено, что обновлять «1С: Управление торговлей» придется если не так же часто, как «1С: Бухгалтерию» , то уже точно не 1-2 раза в год, как очень многие делали это раньше.

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


Пишу ВК, не могу подключить к 1с на ubuntu. Даже экзапл от 1с не подключается. Поэтому вопрос по нему:

1) Пытаюсь подключи ВК из примера VNCOMPS, приведённым в статье

(ссылку можно найти в самом конце: «Копирование»).
Внутри в проекте NativeApi есть makefile. С его помощью я собираю.so библиотеку на Ununtu.
Но при "ПодключитьВнешнююКомпоненту" 1с вылетает.
Аналогично, если собираю при помощи "build.sh" (в корне проекта).

В самом makefile меняю флаг с m32 на m64, т.к. 1с и сама система x64. (с параметром m32 не подцепляется всё равно)
Вот пример вызова ВК из 1С 8.3:
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту ("/home/alexeyubuntux64-20 gb/Документы/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ТипВнешнейКомпоненты.Native); Есть статейка как раз на эту тему.
Но, насколько я вижу, все эти моменты уж учтены исправили в VNCOMPS примере.

Но по сути дело в параметрах компиляции. Мб 32битная внешняя компонента подцепляется к 32-x битной 1с нормально, но я развернул на Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. И хочу к ней подцепить ВК.

Есть у кого мысли, как решить этот вопрос?)
VNCOMPS-пример должен работать, но походу надо поправить параметры сборки, или сама платформа, на которой я тестирую - некорректна.

Ответ: Интересно, а на яве можно внешнюю компоненту написать?

Вопрос: Не подключается внешняя компонента (Native)


Скомпилировал пример c ИТС, для 64 и 32 битной системы.

Подключаю так:
РезультатПодключения = ПодключитьВнешнююКомпоненту(ПутьКДЛЛ, "Comp", ТипВнешнейКомпоненты.Native); На одном ПК подключение проходит, на другом нет. Есть разница в ос. Где подключение проходит, там стоит Win7, где нет Win10. При этом на ПК, где не работает моя компонента, работают типовые компоненты.

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

Как понять почему не подключается?

Ответ: vc_redist не забыл?

Вопрос: 1С8 и внешняя компонента с типом Native


Добрый день.
Имеется конфигурация БП 3.0.50.12 и желание внедрить в нее взвешивание от компании Весы-Софт с помощью UniServerAuto.
Разработчики скомпилировали компоненту на Native для Windows 32 и 64, и с файлом maifest сложили в архив. Так же есть пример для 1С, как можно считать вес. В нём с помощью макета с двоичными данными указан, я так понимаю, архив этот. В примере всё неплохо: устанавливается компонента, подключается, потом устанавливается связь и считывается вес.
Но как только начинаешь себе в 1С переносить - вес не считывается. Вроде всё просто написано, но где грабли не пойму.
У кого будет немного времени - помогите, гляньте одним глазком, может решение на поверхности, а я хожу где-т не там и делаю не то. Раньше мне не приходилось с технологией Native работать...

А во вложении мой текст обработки

Ответ:

Ну что, есть новости у меня...
Начал просто по шажкам смотреть в какой момент начнет сбоить. Для этого создал пустую базу и обработку с командой. По аналогии с примером поставщика перенес макет в новую конфу - работает со второго раза. Т.е. с первого раза нет, а со второго да. Это натолкнуло на мысль, что всё-таки надо будет в своей обработке развести подключение компоненты и объекта по разным процедурам.
Далее перенес это в свою базу с подключением макета - работает. Фух, уже хорошо.... Но хотелось бы без внесения изменений в конфигурацию, значит идём дальше

Пробую макет добавить в обработку. Её размер сразу увеличивается с 10кб до 3мб и замечается существенное замедление работы - не подходит. Начинаю копать в сторону подключения компоненты через dll. Т.е. по сути к тому же с чего начал. Но тут есть одно "НО": поиском по имени dll по папке пользователя заметил, что эта dll лежит там, где (я так понял) складываются зарегистрированные в 1С dll-ки:
C:\Users\USER\AppData\Roaming\1C\1cv8\ExtCompT
соответственно нет нужды использовать полный путь к dll, можно просто прописать ее имя:
ПодключитьВнешнююКомпоненту("Add1CUniServerAuto32.dll", "UniServerAuto", ТипВнешнейКомпоненты.Native);

Пробую... ругается на регистрацию, но результат взвешивания возвращает. Получается, что уже dll зарегистрирована и значит ее нужно просто подключать. Убираю и всё работает.
Подвожу итог:
1. В обработку взвешивания в процедуру ПриОткрытии внёсподключение внешней компоненты и подключение к объекту.
2. Путь к dll Не писал, указал просто ее имя.

Теперь сижу и думаю, а когда dll установилась в 1С? В момент установки ПО? Вряд ли... В момент запуска конфигурации разработчика этой dll, где она устанавливается при открытии формы? Не знаю, но мне кажется близко... Вы как думаете?
И второе, На новом месте, когда появится нужда установки такого же терминала, что надо сделать чтобы всё заработало? Установить полностью ПО,запустить конфу поставщика чтобы проверить работу и потом (в теории) моя обработка должна заработать? Че-то как-то сложновато... Или же после установки ПО в моей обработке сделать УстановитьВнешнююКомпоненту один раз?

Ваши мысли на этот счет хотелось бы услышать...

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


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

Ошибка загрузки внешней компоненты! cache1c.dll
Процедура КнопкаВыполнитьНажатие(Кнопка) Попытка ЗагрузитьВнешнююКомпоненту("C:\Program Files\1cv81\bin\cache1c.dll" ); Исключение Сообщить("Ошибка загрузки внешней компоненты!" + " cache1c.dll" ); КонецПопытки; Попытка // Получить объект компоненты. // m = Новый ("cache1c.GTMcmd" ); m = Новый COMОбъект("cache1c.GTMcmd" ); Исключение Сообщить(); КонецПопытки; КонецПроцедуры

Ответ: Банально до невозможности...
Нужно выдержать паузы между вызовами (миллисекунды)...
Процедура КнопкаВыполнитьНажатие(Кнопка) Попытка // Получить объект компоненты. m = Новый COMОбъект("cache1c.GTMcmd" ); Исключение Сообщить("Не удалось создать объект внешней компоненты" ); КонецПопытки; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Подключить(); m.Пауза(100); ...... итд
Для 1с 7.7 - это не нужно, получается, что шустрее обращение.

Вопрос: Работа внешней компоненты с сервером 1С...


Добрый день,

Имеется внешняя компонента, написанная на С++, задача которой получение информации из внешней базы данных и возврат результата запроса в виде Таблицы значений в 1С.
Для формирования таблицы значений на текуший момент используется интерфейс IDispatch* pBackConnection, получаемый в качестве параметра в функции Init(). Далее я просто, используя функции 1С формирую таблицу значений, заполняю ее и возвращаю ее во второй параметр в CallAsFunc(...).
Проблемы начались с переходом на тонких клиентов 1С. На стороне сервера внешняя компонента толком не запускается. Можно запустить на стороне клиента, но это все выглядит как костыли и выпадает из общей логики "клиент-сервер" в 1С. Например клиент не понимает, что такое таблица значений, проблемы с "глобальными" переменными, сеансами и т.п.
NativeAPI еще более урезан в этом плане.
Танцы с бубном привели к тому, что я смог запустить внешнюю компоненту под сервером 1С, НО работа происходит до того момента, пока не производится попытка вызвать Invoke у pBackConnection. 64-битная версия сервера 8.2 что-то пытается делать, пока не отваливается по таймауту, 32-битная (ВК естественно тоже 32 битная) просто сразу отваливается.
Предполагаю, что сервер 1С не обслуживает этот режим работы.
Соответственно возникают вопросы, это временно или логика 1С сводится к отмене этой схемы работы? Если создать внутренние структуры 1С (таблицу значений) таким способом нельзя, есть ли в принципе описание, что из себя представляет таблица значений на системном уровне, чтобы попытаться создать ее на С++ , заполнить, а затем просто подсунуть 1С в качестве возвратного параметра? Хотелось бы хотя бы получить направление, в какую сторону копать.

Спасибо.

Ответ:

Вы пишите одно, и имеете в виду другое.
В среде 1С, объявление переменных, которые будут видны в разных сеансах не невозможна сейчас, и не было такой возможности ранее. Другой сеанс, это физически другой процесс.
Сеанс, это сеанс подключения к базе данных, т.е. сеанс работы пользователя. Или вы что-то своё вкладываете а это понятие?

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

Ну и естественно, нужно помнить про контекст. Серверный контекст напрямую не доступен на стороне клиента и наоборот.

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

Таблица на форме... а она связана с какой-либо таблицей объекта (обработки, например) ? или нет. Если да, то она доступна и на сервере (&НаСервере) там и редактируйте....

И таки да, ТаблицаЗначений не доступна в УФ на стороне клиента. Ну уж так решила 1С.

Да ладно! Вот с Excel работает, с FSO работает и кучей всего остального, а тут тут не работает. Отлавливайте ошибку и анализируйте....

Попытка
...
ваши действия
...
Исключение
стр = ОписаниеОшибки();
КонецПопытки;

При современных аппаратных возможностях, это вообще не аргумент.

Сугубо Ваше лично мнение. Ничего общего с реальностью не имеет. Ни в каком виде. Повторю ещё раз, 1С прекрасно работает с COM. Как с in-proc, так и с out-proc.

Приведите, код, которым вы загружаете и обращаетесь в ВК.

Кстати, ВК... в Вашем случае, это COM или Native API ?
Если COM, то вы регистрируете её как... через regsvr32... как тогда "разруливаете" вопрос разрядности?

Вопрос: Установка внешней компоненты


Подскажите плз как установить внешнюю компоненту. При исполнении следующего кода выдается ошибка. В макете находить NameDecl.dll

Попытка УстановитьВнешнююКомпоненту("ОбщийМакет.Макет"); Исключение КонецПопытки ;
Ошибка: Установка внешней компоненты не выполнена!

Ответ: ()
ПодключитьВнешнююКомпоненту("ОбщийМакет.Макет", "NameDecl", ТипВнешнейКомпоненты.Native) выдает ЛОЖЬ ,
Новый("AddIn.NameDecl.CNameDecl", Неопределено) = {()}: Тип не определен (AddIn.NameDecl.NameDecl)

Вопрос: Не подключается native dll на 1с 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


Здравствуйте.
1С обновил dll для онлайн-касс атол для ффд 1.05 (входит в обработку обслуживания fptrwin32_fz54_9_11_0_5549.dll).
У меня старая 1С 8.1. Она в отличии от 8.2 не поддерживает работу со внешним оборудованием аналогично 8.2, поэтому сначала нужно зарегистрировать dll в windows, а затем только в 1С подключать?

ПрогИД = "AddIn.ИнтеграционнаяКомпонента.ATOL_KKT_1C83_V9"; ЗагрузитьВнешнююКомпоненту("C:\fptrwin32_fz54_9_11_0_5549.dll"); ПодключитьВнешнююКомпоненту(ПрогИД); Драйвер = Новый (ПрогИД);

Однако старая обработка была написана на "технологии" com, а новая native. Соответственно при регистрации regsvr32 выдает ошибку:
Модуль загружен, но точка входа DllRegisterServer не найден. И предлагает проверить, что этот файл является правильным файлом dll или OCX.
Кто с подобной ситуацией сталкивался, как выкручивались? Понимаю что аналогичная проблема будет и у 7.7.
Код 8.2:

Макет = ПолучитьМакет("ИнтеграционнаяКомпонента"); Адрес = ПоместитьВоВременноеХранилище(Макет); ПодключитьВнешнююКомпоненту(Адрес, "ИнтеграционнаяКомпонента", ТипВнешнейКомпоненты.Native); Драйвер = Новый("AddIn.ИнтеграционнаяКомпонента.ATOL_KKT_1C83_V9");

1C 8.2:
ПодключитьВнешнююКомпоненту(<Местоположение>, <Имя>, <Тип>)
1С 8.1:
ПодключитьВнешнююКомпоненту(<Идентификатор объекта>)
Параметры:
<Идентификатор объекта> (обязательный)
Тип: Строка. ProgID (Programmatic Identifier) объекта внешней компоненты. Должно соответствовать информации, находящейся в регистрационной базе данных системы (Registry).
Описание:
Подключает объекты внешней компоненты к 1С:Предприятию.
Недоступен на сервере 1С:Предприятие. Не используется в модуле внешнего соединения.
Примечание:
Внешние компоненты совместимы с компонентами 1С:Предприятия 7.7.
Пример:
Попытка
ПодключитьВнешнююКомпоненту("AddinObject.Scanner");
Сообщить("Компонента для сканера штрих-кодов загружена");
Исключение
Сообщить("Компонента для сканера штрих-кодов не загружена");
КонецПопытки

Как-нибудь можно эту dll на 8.1 подключить или нет?

Спасибо!

Ответ:

У меня тоже недавно всплыла такая проблема. Конвертировать на более позднюю версию 1с не было возможности т.к. dll с которомыми данная конфигурация работает просто переставали работать и 1с вываливалась с ошибкой.
Проблему решил следующим образом:
Создал пустую базу 8.3 в которой сделал обработку инициализации компоненты и затем из 8.1 по COM соединению обращался к созданной ранее базе и там инициализировал компоненту. Затем уже в 8.1 вызывал методы этой компоненты.
Конечно это костыльно, но другого выхода пока не нашел(

Пример кода 8.3:
Перем Драйвер Экспорт;
Функция ПодключениеКомпонентыККТ() Экспорт
Попытка

Макет = ПолучитьМакет("ИнтеграционнаяКомпонента");
Адрес = ПоместитьВоВременноеХранилище(Макет);
ПодключитьВнешнююКомпоненту(Адрес, "ИнтеграционнаяКомпонента", ТипВнешнейКомпоненты.Native);
Драйвер = Новый("AddIn.ИнтеграционнаяКомпонента.SMDrvFR1C20");
Результат = Истина;​

Исключение

Результат = Ложь;​

КонецПопытки;
Возврат Результат
КонецФункции

Пример кода 8.1

Функция СоздатьОбъектДрайвера(Драйвер) Экспорт

Результат = Истина;

Попытка

СтрокаСоединения="File="""Путь к базе""";
КомОбъект= Новый COMОбъект("V83.ComConnector");
Коннект = КомОбъект.Connect(СтрокаСоединения);

Обработка = Коннект.Обработки.ПодключениеВнешнейКомпоненты.Создать();
РезультатПодключения = Обработка.ПодключениеКомпонентыККТ();
Если РезультатПодключения Тогда
Драйвер = Обработка.Драйвер;
КонецЕсли;​

Исключение
Кто занимался этим или сталкивался с подобными вынесениями обясните на простом примере сам принцип. Вроде с подключением внешних компонент все понятно.

// Пример заполнения таблицы значений ТЗ.Очистить(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка КАК Номенклатура |ИЗ | Справочник.Номенклатура КАК Номенклатура"; РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); Пока Выборка.Следующий() Цикл Стр = ТЗ.Добавить(); ЗаполнитьЗначенияСвойств(Стр, Выборка); КонецЦикла;
Не могли бы вы на этом примере объяснить, какую часть кода обычно выносят. Логично было бы вынести часть с запросом, но тогда как из внешней компоненты мы обратимся к БД из внешней компоненты в обход платформы? Текст выносить бессмысленно. Или выносить само формирование табличной части. Поделитесь опытом кто сталкивался с этим.

Ответ: А что слово «Несовместимо» всегда означает слово «Плохо»? Да мне кажется, что назови я свой стиль «1С:Самое плохое программирование на этом скриптовом движке, которое существует в природе (в переводе на литературный язык)!» и то наверняка найдутся желающие заценить этого зверя. А так похоже на классику: «Я Пастернака не читал, но я полностью с ним не согласен!»:)

Вопрос: Подключение внешней компоненты в 1с 8.3.6 и Win8


К самописной конфигурации надо подключить ВнешКомпоненту vk_rs232.dll. Вроде зарегистрировала через regsvr32.exe. "Вроде" потому, что получила сообщение что "компонента зарегистрирована, но чего-то там с брандмауэром". Понадеявшись на первую половину сообщения, пишу код в 1с
ПослеПодключения = Новый ОписаниеОповещения("ПослеПодключенияВК",ЭтаФорма); НачатьУстановкуВнешнейКомпоненты(,"C:\Controller\vk_rs232.dll"); НачатьПодключениеВнешнейКомпоненты(ПослеПодключения,"C:\Controller\vk_rs232.dll","ДЛЛ_Весы");
и получаю ошибку, что
"Установка внешней компоненты не выполнена! Возможно отсутствует компонента для используемого клиентского приложения!".

И теперь я не пойму:
1. Может все же компонента не зарегистрировалась в реестре - как ее там проверить?
2. Может ее "версия" не работает под Win8, хотя она у меня 32-бит.
3. Может сама 1с слишком новая, т.е. соответственно не может работать с этой dll-кой?
4. Ну и банальное - я пишу что-то не то.

Ответ: И все это привело меня в следующей проблеме. ВнешКомп Установлена, теперь ее надо Подключить. И тут оба варианта
ПодключитьВнешнююКомпоненту("C:\Controller\vk_rs232.dll","Весы")
ПодключитьВнешнююКомпоненту("ОбщийМакет.Макет","Весы")