При реализации проектов на 1С зачастую приходится сталкиваться с разного рода устройствами и их сопряжением. Покуда будут существовать устройства на древним RS232 будет необходимость во внешних компонентах такого рода. Как правило с устройством идет документация, которая нередко содержит систему команд и некий драйвер который распространяется «так как есть». Очень часто драйвера «так как они есть» оставляют ожидать лучшего. Я предлагаю немного окунутся в системное программирование и решить для себя сей вопрос раз и навсегда.
Прекрасная статья содержит пример и достаточное описание что к чему, что где менять. Пример компилируется. Для быстрого старта замечательная статья. Подобный пример свободно распространяется фирмой 1С и валяется в куче хлама на диске ИТС. Много раз мелькало в глазах но было заложено на дальнюю полку с ярлыком «обязательно изучить».
Для простоты внешнюю компоненту далее по тексту буду называть драйвером.
1. Отказ от OLE32 в пользу Native API.
Тяжелые воспоминания об регистрации OLE32 компонент, и ужас их регистрации под Windows 7, натолкнул на соображение, что драйвер должен поддерживать Native API. Регистрация такой внешней компоненты выглядит:
ПодключитьВнешнююКомпоненту(ИмяФайлаДравера, "prn", ТипВнешнейКомпоненты.Native);
ДемоКомп = Новый("AddIn.prn.Maria2");
При этом предварительно никаких действий типа regsvr32. Да и на сколько мне известно, OLE32 ужа давно не флагманская технология Microsoft.
2. Хранение самого драйвера в составе обработки или конфигурации.
Файл драйвера вставляем в макет 1С как двоичные данные и по надобности распаковываем его в временный каталог пользователя.
Макет = ПолучитьОбщийМакет("Драйвер");
ИмяФайлаДравера = КаталогВременныхФайлов() + "AddInNewMaria.dll";
Макет.Записать(ИмяФайлаДравера);
ПодключитьВнешнююКомпоненту(ИмяФайлаДравера, "prn", ТипВнешнейКомпоненты.Native);
ДемоКомп = Новый("AddIn.prn.Maria2");
3. Реализация интерфейса драйвера. Вынос логики команд на сторону 1С.
Первоначально при написании драйвера, была использована идеология существующих драйверов. ДемоКомп.ЗделайЧтото(МногоРаз).
ДемоКомп.NullCheck();
ДемоКомп.CancelCheck();
По-сути был повторен драйвер, разумеется без ограничений наложенных производителем. Но сия наследственность оказалась мучительной и пагубной. Раз в пол года возникает необходимость добавления каких-то команд, изменении существующих.
Был написан универсальный драйвер RS232 порта для 1С. Он был протестирован usb-модемом Huawei-1550 и с Марией. Для этого драйвера необходимо переписать сервис обработку для 1С.
После очередного «усовершенствования» родилась идея выноса логики команд на сторону 1С. Драйвер занимается только реализацией транспортного протокола. Системные программисты ликуют. Теперь команда драйвера выглядит:
ДемоКомп.Команда("NULL"); //печать нулевого чека
И да на радость каждому программисту 1С Native API дает возможность вызывать функции по-русски (русские псевдонимы функций).
4. Запись протокола обмена.
Для записи в файл maria.log в каталог временных файлов пользователя команд и реакций на них необходимо:
ДемоКомп = Новый("AddIn.prn.Maria2");
ДемоКомп.Логирование();
В файле пишется время и вид события: с — команда; а — ответ; u — соединение; t — количество циклов для получения ответа; e — ошибка.
[20150210205009]t: 1 8
[20150210205009]u:эREADYю
[20150210205009]c:эSYNCю
[20150210205009]t: 1 29
[20150210205009]a:эWAITюэSYNCюэDONEюэREADYю
[20150210205009]c:эCNALю
[20150210205009]t: 1 141
[20150210205009]a:эWAITюэCNAL2013120510200020150210200500000000000000000000000000000000000000000000000000000000000000000000000020131205800000uюэDONEюэREADYю
[20150210205009]c:эUPAS1111111111‘в ¦Ґаю
[20150210205009]t: 1 22
[20150210205009]a:эWAITюэDONEюэREADYю
[20150210205009]c:эNREPю
[20150210205012]t: 18 52
[20150210205012]a:эWAITюэNREP5100 юэPRNюэSOFTREGISTюэDONEюэREADYю
[20150210205012]e:35
Да вот минимальный набор необходимого чтоб «заработало». Теперь немного о будущем:
5. Другие устройства такого класса.
По задумке не сложно заменить транспортный протокол Марии на протокол например ИКС-а. Можно было б говорить о семействе драйверов. Сам скелет основных необходимых функций готов.
6. Внешние события.
В процедурах реализации транспортного протокола стоит перейти на threads, а сигнализацию о завершении работы команды делать внешним событием. Хочу сделать именно так, но немножко чего-то не хватает: времени или знаний или того и другого. И рок «уже работает так», " работает не трогай" немного охлаждает пыл порыва.
7. Совместная работа.
В планах написание простого web-сервиса, который бы принимал команды, организовывал очередь команд и перенаправлял их на устройство. Сервисная обработка в таком случае будет выглядеть аналогично, команды не поменяются. Изменится только инициализация объекта.
Ссылка на проект на github
Проект состоит из проекта Visual Studio, демонстрации команд на 1С (в модуле управляемого приложения) и сервис обработки для 1С.
Автор: tarasii