А для интеграции с программами семейства 1С компании «Штрих-М» пришлось подготовить дополнительный драйвер, который довольно сложно называется: «ПО «ШТРИХ-М: Драйвер ФР» в соответствии с «требованиями к разработке драйверов для фискальных регистраторов» компании 1С».
Это предыстория. А история в том, что, используя драйвер 1С, невозможно выполнить некоторые команды, которые имеет стандартный драйвер «Штрих-М». Например, вывести штрих код.
Для решения таких ситуаций, когда возможностей драйвера 1С не хватает, есть несколько решений:
- Отказаться от драйвера 1С и полностью перейти на драйвер «Штрих-М»
- В нужные моменты отключать драйвер 1С, подключать драйвер «Штрих-М», выполнять нужные команды, отключать драйвер «Штрих-М», подключать драйвер 1С.
- Использовать низкоуровневые команды с помощью метода DeviceControlHEX.
Пункты 1 и 2 мне показались достаточно неудобными, поэтому переходим к пункту 3.
Сначала описание метода, которое дает 1С:
DeviceControlHEX (DeviceID, TxData, RxData): WordBool УправлениеУстройствомХекс (ИДУстройства, ВхДанные, ВыхДанные)
Команда аналогична команде DeviceControl. Передает низкоуровневую команду устройству. Отличие заключается в том, что входные и выходные данные передаются в виде HEX-строки.
Параметры:
DeviceID: WideString [IN]
ИДУстройства [ВХ]
Идентификатор устройства
TxData:
WideString [IN]
ВхДанные [ВХ]
Последовательность байт команды, передаваемой в ФР. (см. описание протокола). Например, для команды «гудок» последовательность будет такая (в шестнадцатеричном виде): «13 1E 00 00 00». То есть, последовательность начинается с кода команды (в данном случае «13»), за ним следуют параметры команды (в данном случае – пароль оператора: «1E 00 00 00»). Последовательность задается в виде строки в HEX-формате (разделенные пробелами двузначные шестнадцатеричные числа). RxData: Integer [OUT] ВыхДанные [ВЫХ] Строка с последовательностью байт ответа ФР. Также возвращается в HEX-формате. Возвращаемое значение: Метод возвращает True в случае успешного выполнения операции, в случае ошибки – False
Теперь можно потренироваться в употреблении этого метода.
Приведу пример печати штрих-кода EAN13 с помощью данного метода.
Для этого заглянем в мануал под названием «Протокол работы ФР». Там написано:
Печать штрих-кода
Команда: C2H. Длина сообщения: 10 байт.
Пароль оператора (4 байта)
Штрих-код (5 байт) 000000000000…999999999999
Ответ: С2H. Длина сообщения: 3 байта.
Код ошибки (1 байт)
Порядковый номер оператора (1 байт) 1…30
Получаем такую функцию, для печать штрих-кода:
Функция DeviceControlHEX_ПечатьШтрихкода(Объект, РезультатКоманды, Штрихкод)Экспорт
//Исходный штрих-код:
//2000988614846
//Отсекаем контрольный символ:
//200098861484
//Переводим в шестнадцатеричное
//2E96D251AC
//Меняем порядок:
//AC 51 D2 96 2E
ШтрихкодФР = Лев(Штрихкод, СтрДлина(Штрихкод) - 1);
ШтрихкодФР = ЧислоВФорматеФР(ШтрихкодФР);
КомандаКВыполнению = "C2" +
" 1E 00 00 00" +
ШтрихкодФР;
КомандаВыполнена = Объект.Драйвер.DeviceControlHEX(Объект.ИДУстройства, КомандаКВыполнению, РезультатКоманды);
КонецФункции
Вспомогательные функции:
Функция ЧислоВФорматеФР(_Число)
Если _Число = 0 Тогда
Возврат " 00";
КонецЕсли;
// десятичное число в шестнадцатеричное
Шестнадцатеричное = Строка(DecToHex(_Число));
// Если один символ, добавим 0
Если СтрДлина(Шестнадцатеричное) = 1 Тогда
Шестнадцатеричное = "0" + Шестнадцатеричное;
КонецЕсли;
// Если длина не четная добавить ноль
Если СтрДлина(Шестнадцатеричное) % 2 <> 0 Тогда
Шестнадцатеричное = Шестнадцатеричное + "0";
КонецЕсли;
ЧислоФР = "";
Пока СтрДлина(Шестнадцатеричное) > 0 Цикл
ЧислоФР = ЧислоФР + " " + Прав(Шестнадцатеричное, 2);
Шестнадцатеричное = Лев(Шестнадцатеричное, СтрДлина(Шестнадцатеричное) - 2);
КонецЦикла;
Возврат ЧислоФР;
КонецФункции
Функция DecToHex(Знач _Число)
База = 16;
Результат = "";
Пока _Число <> 0 Цикл
Поз =_Число % База;
Результат = Сред("0123456789ABCDEF", Поз + 1, 1) + Результат;
_Число = Цел(_Число / База);
КонецЦикла;
Возврат Результат;
КонецФункции // DecToHex()
Пример еще одной функции, печатающей произвольный текст нужным шрифтом:
Функция DeviceControlHEX_СтрокиДаннымШрифтом(Объект, РезультатКоманды, Стр, НомерШрифта)Экспорт
// Номер штрифта от 1 до 7
//Печать строки данным шрифтом
//Команда: 2FH. Длина сообщения: 47 байт.
//Пароль оператора(4 байта)
//Флаги(1 байт) Бит0 – контрольная лента, Бит1
//Номер шрифта(1 байт) 0…255
//Печатаемые символы(40 байт)
//Ответ: 2FH. Длина сообщения: 3 байта.
//Код ошибки(1 байт)
//Порядковый номер оператора(1 байт) 1…30
СтрФР = СтрокаВФорматеФР(Стр);
КомандаКВыполнению = "2F" +
" 1E 00 00 00" +
" 01" +
" 0" + НомерШрифта +
СтрФР;
КомандаВыполнена = Объект.Драйвер.DeviceControlHEX(Объект.ИДУстройства, КомандаКВыполнению, РезультатКоманды);
Возврат КомандаВыполнена;
КонецФункции
Получается, что если немного напрячься, можно выполнить любою команду, заложенную в "Протоколе работы ФР".
Замечание: насколько я знаю, метод появился с версии драйвера 4.10
Изменения: Добавлена обработка с реальными примерами работы с методом DeviceControlHEX.
Обновление 23.05.2024
Добавлен пример проверки наличности в кассе перед записью чека возврата.
Т.к. время от времени бывали ситуации когда документ "ЧекККМ в информационной базе провелся, а чек на ФР не пробился.
Мсье знает толк в извращениях! (с) ))
Переход на работу по упомянутому выше пункту №1, на порядок проще, быстрее и правильнее, чем извращаться с HEX-ами. Ну, разве что для овладения использования данного метода от 1С, но не более того 🙂
(1) bigmal, конечно проще, но с оговоркой, что нужные методы есть в родном драйвере.
Я также использовал и п.2 и п.3 при разработке печати на подкладных документах.
Подробностей уже и не вспомню, но точно также приходилось играть с HEX-ами. Ес-но, предварительно общался со службой поддержки Штрих-М. Именно они мне сказали, что HEX в некоторых случаях — единственный вариант.
(1) bigmal, возможно и так :-), но я могу привести свои аргументы.
1. Используя решение из пункта 3. можно решить все необходимые вопросы с минимальными изменениями типового кода.
Для меня это было принципиально важно.
2. Переписать все функции на другой драйвер, это не такое и быстрое решение, с учетом возможных последствий…
Надо и писать нормально 🙂 и тестировать.
3. Ну и как уже упомянул комрад JohnyDeath, работа напрямую с протоколом позволяет все что описано в протоколе.
Добавил примеры. В том числе как в человекочитабельном виде получать строковые данные от ФР.
А почему бы не связаться с ребятами из «Штрих-М» и подать заявку на доработку драйвера «ПО «ШТРИХ-М: Драйвер ФР» в соответствии с «требованиями к разработке драйверов для фискальных регистраторов» компании 1С»- что бы в следующей версии все нужные вам функции были.
а пункты 1, 2, 3 — получается временное решение.
(5) kostik_love, потому что именно на форуме Штриха от сотрудников Штриха я и получил ответ использовать DeviceControlHEX.
(1)Дописать одну функцию или переписать весь функционал работы с ФР? Хм какой сложный выбор…
Бодрого времени суток. Пробовал данный метод на версии драйвера 4.13 и получил сообщение:
{ВнешняяОбработка.ШтрихМФискальныеРегистраторы.МодульОбъекта(921)}: Метод объекта не обнаружен (DeviceControlHEX)
КомандаВыполнена = Объект.Драйвер.DeviceControlHEX(Объект.ИДУстройства, КомандаКВыполнению, РезультатКоманды);
У вас на какой версии работает?
Привет!
На кассах стоит 4.10.
Но, насколько я помню работала и на 4.12.
А что за конфигурация? Название обработки намекает, что это УТ 11 или Розница 2.
Насколько я понимаю в этих конфигурациях логика работы торгового оборудования немного изменена.
Отсюда пара вопросов:
1. Объект это действительно объект? 🙂
2. Драйвер действительно драйвер Штриха (DrvFR), а не DrvFR1C?
Бодрого времени суток.
Конфигурация УТ 10.3. Для проверки засунул код в стандартную обработку фискального регистратора ShtrihMFiscalPrinters_v2.
Драйвер наверно используется DrvFR1C из стандартной обработки.
Мне нужно в момент закрытия чека узнать подитог и назначить скидку суммой, а стандартные команды согласно «требований к разработке драйверов для фискальных регистраторов компании 1С» этого не умеют, переписывать конфигурацию не хочу.
Мне показалось что представленный тобой способ подойдет.
(10) Привет!
Затестил 4.13. У меня тоже не взлетело.
Ошибок не выдает. И даже частично печатает. Но частично.
А у меня другая печаль).Медленная печать с rdp. Весь штриховский форум кишит сообщениями что надо добавить
BeginDocument и EndDocument для буферизации.
Но в DrvFR1C их нету.. .
И костыль описанный тобой тут не всунуть ибо мне воздействовать на сам драйвер надо… Я правильно понимаю ?
p.s. интересно можно ли декомпильнуть и пересобрать дллку эту =\r
(12) По идее, костыль может все что может протокол «Протокол работы ФР».
ftp://ftp.shtrih-m.ru/download/FR/Doc/ProtocolFR_1_12.pdf
Описание протокола можно посмотреть тут:
// Функция переводит обычную cтроку в шестнадцатеричное представление
// Параметры:
// ТекстСообщения — Строка — Текст сообщения
// ТипКодировки — Число — Тип кодировки (1 — каждый символ представляется 2 байтами, 0 — 1 байтом)
// Возвращаемое значение: Строка — Строка после перекодировки
//
Функция Str2Hex(ТекстСообщения, ТипКодировки)
СтрокаЗнаков = «»;
Если ТипКодировки = 1 Тогда
ДлинаКодаСимвола = 4;
Иначе
ДлинаКодаСимвола = 2;
КонецЕсли;
Для К = 1 По СтрДлина(ТекстСообщения) Цикл
СтрокаЗнаков = СтрокаЗнаков + Padl(DecToHex(КодСимвола(Сред(ТекстСообщения, К, 1))), ДлинаКодаСимвола, «0»);
КонецЦикла;
Возврат СтрокаЗнаков;
КонецФункции // Str2Hex()
// Функция переводит cтроку из шестнадцатеричного представления в обычную строку
// Параметры:
// СтрокаСимволов — Строка — Текст в шестнадцатеричном виде
// ПризнакКода — Строка — Тип кодировки («0» — каждый символ представляется 1 байтами, «1» — 2 байтами)
// Возвращаемое значение: Строка — Строка после перекодировки
//
Функция StrHexToStr(СтрокаСимволов, ПризнакКода) Экспорт
Если Число(ПризнакКода) = 0 Тогда
КоличествоСимволов = 2;
Иначе
КоличествоСимволов = 4;
КонецЕсли;
к = 1;
Результат = «»;
Пока к < СтрДлина(СтрокаСимволов) Цикл
Строка = Сред(СтрокаСимволов, к, КоличествоСимволов);
Результат = Результат + Символ(HexToDec(Строка));
к = к + КоличествоСимволов;
КонецЦикла;
Возврат Результат;
КонецФункции // StrHexToStr()
Подскажите, можно ли воспользоваться данным методом в текущих конфигурациях, где общение программы с устройством идет через компоненту 1С? Не вижу там команды DeviceControlHEX…
(15) Юрий, в компоненте а-ля 1С нет практически ничего. Это заусенец на верхушке айсберга в сравнении с возможностями нормального драйвера ))
(15) В компоненте DrvFR1C такой метод есть, в SMDrvFR1C20 для ККТ такого метода нет.
А с Атоллами ничего подобного не проделывали? Столкнулся с бедой, что при переходе с 8-ых драйверов Атолла на 9-е перестал работать код печати ШК, который раньше работал, вот ищу пути решения проблемы…
Подскажите, а как отлаживать такие обработки для фискальников и для ККМ? На примере ут 10.3
Сейчас делаю так, произвел изменения во внешней обработки и потом загрузил ее в справочники ОбработкиТО. Проверил, если не взлетело то опять подправляю и загружаю.
Может есть какой то метод, чтобы в 10.3 не выгружать и загружать обработки каждый раз, может они могут подхватываться прямо из кода? Из встроенных обработок конфигуратора?