Итак, если произошла такая ситуация, то нельзя отчаиваться. 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 и ниже обозначает, что конфигурация должна работать на соответствующих платформах с ограничением функционала (именно такого, который мы используем в данной статье).
ВОПРОС: Можно ли использовать расширения в базовой конфигурации?
ОТВЕТ: К сожалению нельзя. Оно и понятно. Она бы тогда перестала быть базовой. В основном.