Нестандартный способ подключения оборудования с использованием Расширения

Программирование - Практика программирования

Как подключить оборудование к новой конфигурации 1С, если оно не имеет драйвера по стандарту 1С-Совместимо, а очень нужно.

Итак, если произошла такая ситуация, то нельзя отчаиваться. 1С с версии платформы 8.3.9 предоставляет великолепную возможность исправить эту проблему без изменения конфигурации.

Основные требования:

1. Версия конфигурации Проф.

2. Платформа 8.3.9 и выше

3. Наличие библиотеки (dll) для подключения к 1С

Рассмотрим на примере моего опыта подключения дисплея покупателя LPOS-II-VFD  USB  к 1С Розница 2.2.

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

Решение нашлось в использовании расширения конфигурации.

Итак по порядку.

1. Создадим дисплей покупателя в оборудовании. Откроем 1С Розница в режиме предприятия. Администрирование-Подключаемое оборудование - Подключаемое оборудование - Дисплеи покупателя - Создать. 

Драйвер - 1С Дисплеи покупателя, имя любое.

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

2. Отладчик. Ищем места с попыткой подключения к дисплею (ДП). Проще всего, запустить конфигуратор, и поставить режим отладки с остановками по ошибкам. При возникновении ошибки при попытке связаться с несуществующим ДП она точно появится. После останова откроем стек вызовов и поднимемся к тому месту, откуда происходит вызов обработки обслуживания ДП. В моем случае при запуске РМК вызов передавался на процедуры "ПолучитьПараметрыВывода", "ВывестиСтрокуНаДисплейПокупателя", "ПодключитьУстройство" и "ОчиститьДисплейПокупателя" общего модуля "ПодключаемоеОборудованиеУниверсальныйДрайверКлиент" каждая из которых вызывала ошибку связи.

3. Ну, вы уже сами догадались, что делать дальше. 

 - Добавляем новое расширение. Называем его, к примеру, "ДП". Режим безопасности - галка снята, т.к. будем подключать сторонний COMобъект.

 - Находим общий модуль  ПодключаемоеОборудованиеУниверсальныйДрайверКлиент,  ПКМ -добавить в расширение.

 - Копируем содержимое процедур и/или функций общего модуля в модуль нашего расширения ("ПолучитьПараметрыВывода", "ВывестиСтрокуНаДисплейПокупателя", "ПодключитьУстройство" и "ОчиститьДисплейПокупателя").

 - в модуле расширения используем аннотацию &Вместо

&Вместо("ВывестиСтрокуНаДисплейПокупателя") 
Функция ВывестиСтрокуНаДисплейПокупателя_(ОбъектДрайвера, Параметры, ПараметрыПодключения, СтрокаТекста, ВыходныеПараметры)

аннотация &Вместо выполнит вместо встроенной функции ВывестиСтрокуНаДисплейПокупателя  нашу функцию из расширения "ВывестиСтрокуНаДисплейПокупателя_".

Также поступим и с остальными из перечисленных.

- теперь самое главное!

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

Я сделал так:

&Вместо("ПодключитьУстройство")
Функция ПодключитьУстройство_(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Экспорт
	Если ПараметрыПодключения.ТипОборудования = "ДисплейПокупателя" Тогда	
		ВыходныеПараметры = Новый Массив();
		ПараметрыПодключения.Вставить("ИДУстройства", "");
		Возврат Истина;
	Иначе 
		 Результат = ПродолжитьВызов(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); 
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Обратите внимание на важный момент. Конструкция

		 Результат = ПродолжитьВызов(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); 

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

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

Далее сам вывод строк. 

&Вместо("ВывестиСтрокуНаДисплейПокупателя") 
Функция ВывестиСтрокуНаДисплейПокупателя_(ОбъектДрайвера, Параметры, ПараметрыПодключения, СтрокаТекста, ВыходныеПараметры)
	Результат = Истина;
	
	нн= ПодключитьВнешнююКомпоненту("AddIn.lpos_usb_vfd");
	Компонент= Новый("AddIn.lpos_usb_vfd_extension");
	СтрОшибка = "";	
	ИДУстройства =1;	
	МассивЗначений = Новый Массив();
	КодоваяСтраница = 12; 
	МассивЗначений.Добавить(КодоваяСтраница);
	Если (Компонент.Подключить(МассивЗначений, ИДУстройства) <> Истина) Тогда
		Компонент.ПолучитьОшибку(СтрОшибка);
		Результат = Ложь;
	Иначе
		СтрОшибка = "Ок";
	КонецЕсли;

	Разделитель = Найти(СтрокаТекста,Символы.ПС);
	Стр1 = Лев(СтрокаТекста,Разделитель-1);
	Стр2 = Прав(СтрокаТекста,СтрДлина(СтрокаТекста)-Разделитель);
	МассивСтрок = Новый Массив();
	СтруктураСтр1=Новый  Структура;
	СтруктураСтр2=Новый Структура;
	СтруктураСтр1.Вставить("Текст", Стр1);
	СтруктураСтр2.Вставить("Текст", Стр2);
	СтруктураСтр1.Вставить("БегущаяСтрока", Ложь); // если флаг  установлен, текст в строке прокручивается
	СтруктураСтр2.Вставить("БегущаяСтрока", Ложь);
	МассивСтрок.Добавить(СтруктураСтр1);
	МассивСтрок.Добавить(СтруктураСтр2);
	Если(Компонент.ВывестиСтрокуНаДисплейПокупателя(ИДУстройства, МассивСтрок) <>  Истина) Тогда
		Компонент.ПолучитьОшибку(СтрОшибка);
		Результат = Ложь;
	Иначе 
		СтрОшибка = "OK";
	КонецЕсли; 
	Если не Результат Тогда
		ВыходныеПараметры.Очистить();
		ВыходныеПараметры.Добавить(999);
		ВыходныеПараметры.Добавить("");
	КонецЕсли;
	Возврат Результат;	
КонецФункции

Мы полностью заменили содержимое стандартной функции своим кодом.

Не забудем зарегистрировать библиотеки (в моем случае lpos_usb_vfd.dll)

Сохраняем, проверяем!

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

Итог.

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

Рад был помочь.

Вопросы, которые могут возникать при использовании расширений.

ВОПРОС       Добавил в расширение Общий модуль и в нем прописал для заменяемой функции общегомодуля свою функцию. 

&Вместо("ПолучитьФорматЗаписиИзДереваФормата")
Функция _ПолучитьФорматЗаписиИзДереваФормата(Знач ДеревоФормата, Знач ИмяЗаписи)

Однако при проверке получаю ошибку: Ожидается определение процедуры/функции &Вместо<<?>>("ПолучитьФорматЗаписиИзДереваФормата" (Проверка: Сервер) 
Платформа 8.3.9.2033. Режим совместимости в конфе и расширении ИДЕНТИЧЕН.

ОТВЕТ:   Режим совместимости, вероятно, 8.3.8 и в расширении и в конфигурации. Его нужно отключить и там, и там. Перехват работает некорректно. Для нормальной работы аннотаций требуется снять совместимость и у конфигурации, и у расширения. Тогда платформа будет использовать свой новый функционал для работы с нашим расширением. В данном случае как раз 8.3.9. В противном случае она работает в режиме функционала 8.3.8, что и вызвало данную ошибку.

ВОПРОС: Конфигурация стоит на поддержке без права на редактирование. И там стоит режим совместимости 8.3.8. Получается, чтобы реализовать Расширение с изменением ОбщегоМодуля ее надо снять с поддержки.... 

ОТВЕТ: С поддержки снимать не надо. В Вашем случае Вы как раз и создаете расширение с перехватом функции из ОбщегоМодуля, чтобу не вносить изменения в конфигурацию (за исключением режима совместимости, что никакой роли не играет). Нужно в настройке поддержки включить возможность изменения с сохранением поддержки.  В данном режиме конфигурация открывается для изменения, но с поддержки не снимается. И, что самое главное, при обновлении наше расширение остается без изменений и продолжает работать и обходить стандартную функцию. Для  большей увереноости сделайте архив и выгрузите конфигуразию в файл, чтобы можно было из ".cf" потом восстановить структуру конфигурации, как было до включения поддержки без изменения и потери данных. Режим совместимость 8.3.8 и ниже обозначает, что конфигурация должна  работать на соответствующих платформах с ограничением функционала (именно такого, который мы используем в данной статье).   

ВОПРОС: Можно ли использовать расширения в базовой конфигурации?

ОТВЕТ: К сожалению нельзя. Оно и понятно. Она бы тогда перестала быть базовой. В основном. 

См. также

Комментарии
1. Евгений Плешивцев (infosoft-v) 197 18.01.17 14:43 Сейчас в теме
Это отлично. Спасибо за хорошую идею.
2. Ахмад Алиев (baracuda) 3 20.01.17 09:47 Сейчас в теме
Расширения вообще мега вещь.
3. Игорь Мирошниченко (igormiro) 692 20.01.17 14:03 Сейчас в теме
Что то я так понял и защиту можно обходить?
4. Артём Шарипов (borodatii) 1 20.01.17 14:25 Сейчас в теме
(3) если защита реализована через вызов кода из ключа защиты, то не особо поможет.
Возможно что-то в плане противодействие обхода защиты можно будет придумать через "профиль безопасности" http://v8.1c.ru/o7/201603module/index.htm, в самом конце. Хотя эта штука, вроде, для облачный решений больше нужна.
5. Евгений Абдуразаков (asdfgcom) 106 20.01.17 17:11 Сейчас в теме
(3) Защита защите рознь.
В некоторых случаях можно.
*шепотом: Если Вы знаете, что находится в скрытых модулях, их можно вынести в расширения и переназначить вызовы процедур и функций обращения к закрытым модулям.
А вообще, обходить защиту - плохо. Вы же в чужие дома не вламываетесь с целью взять что-то "не нужное хозяину"?

6. Евгений Абдуразаков (asdfgcom) 106 20.01.17 17:16 Сейчас в теме
Кстати, у меня в руках сейчас ТЗ: на БГУ сделать в ПКО доп. табличную часть с услугами (чтобы не оформлять кучу документов, накладную, потом акт, потом договор) и сделать это так, чтобы не менять конфигурацию. Встроенные доп.таблицы не подходят, они не считают и реквизитов маловато описано.
Опять помогли расширения.
Закончу - опишу методику, как добавить что угодно куда угодно и хранить данные своих таблиц.
Она уже добавляет таблицу, сохраняет данные и при следующем открытии поднимает. И считает количество на сумму, НДС и т.д.
7. Александр Дмитриев (МимохожийОднако) 119 25.01.17 07:44 Сейчас в теме
(6) Посмотри у Чистова Павла. Он кое-что выкладывал на эту тему
8. Евгений Абдуразаков (asdfgcom) 106 25.01.17 11:07 Сейчас в теме
(7) Не читал, но сделал так:
В БГУ есть структуры, позволяющие хранить и выводить на форму "Дополнительные табличные части":
СправочникСсылка.ДополнительныеТабличныеЧастиДокументов
СправочникСсылка.КолонкиДополнительныхТабличныхЧастей
РегистрСведений.ЗначенияКолонокДополнительныхТабличныхЧастей
Добавил расширение формы документа ПКО, которое создает программно ТЧ, созданную в описанных структурах вместо автоматического создания доп. ТЧ.
Привязал события к расширению на подбор, пересчет, печать и т.д.
Написал заполнение этого регистра при сохранении и восстановление из него при открытии.
Пришлось описать свою табличную часть в справочнике "ДополнительныеТабличныеЧастиДокументов" стандартным способом, но пометить на удаление, чтобы не выводилась. Т.к. регистр требует явно указывать ее и значения полей в измерениях.
9. Роман Ершов (MRAK) 707 25.01.17 17:49 Сейчас в теме
(8) "СправочникСсылка.ДополнительныеТабличныеЧастиДокументов "
круто!
давно это появилось?
в прочих типовых типа УТ, ЗУП и БП пока нет(
10. Евгений Абдуразаков (asdfgcom) 106 25.01.17 18:12 Сейчас в теме
(9) Да, наконец-то пошли навстречу. Новая БГУ на УФ. Имеет кроме дополнительных реквизитов еще и дополнительные табличные части. Правда, события с табличных частей и доп. реквизитов не создаются и не обрабатываются, поэтому пришлось "чудить", чтобы считалось. Точнее, табличная часть создается каждый раз программно при открытии формы. Даже если события и создавались бы, я не уверен, что их можно перехватить в расширение. Это, кстати, отдельная тема для разбирательства.
11. Роман Ершов (MRAK) 707 25.01.17 22:16 Сейчас в теме
(10) в 8.3.9 перехватываются, правда, не без плясок с бубном.
например, бывало, что не срабатывало "Вместо" при перехвате функции в модуле менеджера. Но при принудительной модификации модуля (добавить пробел и убрать) и его пересохранении заработало
12. Артём Мётра (user649320_artemubaitaev) 29.06.17 00:13 Сейчас в теме
Подключить данный дисплей к 1с Рознице 2.2 базовая совсем никак нельзя?
13. Евгений Абдуразаков (asdfgcom) 106 29.06.17 09:14 Сейчас в теме
(12) У производителя на сайте без изменений? Может драйвер обновили?
14. Артём Мётра (user649320_artemubaitaev) 29.06.17 10:27 Сейчас в теме
(13) честно говоря не знаю, были ли изменения в драйверах после написания вашей статьи, так как на сайте они не указывают дату изменений.
15. Евгений Абдуразаков (asdfgcom) 106 30.06.17 09:30 Сейчас в теме
(14) К сожалению нет сейчас таких на складе. Попробуйте через драйвер АТОЛ. Должно получиться.
Оставьте свое сообщение