gifts2017

Работа с драйвером ФР "Штрих-М" на уровне протокола

Опубликовал Галахад (dmt) в раздел Оборудование - Фискальный регистратор

Для работы со своими фискальными регистраторами компания «Штрих-М» написала свой драйвер «Штрих-М: Драйвер ФР».
А для интеграции с программами семейства 1С компании «Штрих-М» пришлось подготовить дополнительный драйвер, который довольно сложно называется: «ПО «ШТРИХ-М: Драйвер ФР» в соответствии с «требованиями к разработке драйверов для фискальных регистраторов» компании 1С».
Это предыстория. А история в том, что, используя драйвер 1С, невозможно выполнить некоторые команды, которые имеет стандартный драйвер «Штрих-М». Например, вывести штрих код.

 Для решения таких ситуаций, когда возможностей драйвера 1С не хватает, есть несколько решений:

  1. Отказаться от драйвера 1С и полностью перейти на драйвер «Штрих-М»
  2. В нужные моменты отключать драйвер 1С, подключать драйвер «Штрих-М», выполнять нужные команды, отключать драйвер «Штрих-М», подключать драйвер 1С.
  3. Использовать низкоуровневые команды с помощью метода 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.2016 
Добавлен пример проверки наличности в кассе перед записью чека возврата.
Т.к. время от времени бывали ситуации когда документ "ЧекККМ в информационной базе провелся, а чек на ФР не пробился.

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Примеры работы с DeviceControlHEX
.epf 7,24Kb
25.03.16
12
.epf 7,24Kb 12 Скачать
Проверка наличности в кассе
.epf 5,60Kb
23.05.16
0
.epf 5,60Kb 0 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Дмитрий (bigmal) 23.03.16 08:18
Мсье знает толк в извращениях! (с) ))

Переход на работу по упомянутому выше пункту №1, на порядок проще, быстрее и правильнее, чем извращаться с HEX-ами. Ну, разве что для овладения использования данного метода от 1С, но не более того :)
2. Евгений Мартыненков (JohnyDeath) 23.03.16 08:26
(1) bigmal, конечно проще, но с оговоркой, что нужные методы есть в родном драйвере.
Я также использовал и п.2 и п.3 при разработке печати на подкладных документах.
Подробностей уже и не вспомню, но точно также приходилось играть с HEX-ами. Ес-но, предварительно общался со службой поддержки Штрих-М. Именно они мне сказали, что HEX в некоторых случаях - единственный вариант.
3. Галахад (dmt) 23.03.16 12:29
(1) bigmal, возможно и так :-), но я могу привести свои аргументы.

1. Используя решение из пункта 3. можно решить все необходимые вопросы с минимальными изменениями типового кода.
Для меня это было принципиально важно.
2. Переписать все функции на другой драйвер, это не такое и быстрое решение, с учетом возможных последствий...
Надо и писать нормально :-) и тестировать.
3. Ну и как уже упомянул комрад JohnyDeath, работа напрямую с протоколом позволяет все что описано в протоколе.
4. Галахад (dmt) 28.03.16 03:44
Добавил примеры. В том числе как в человекочитабельном виде получать строковые данные от ФР.
5. Константин Воробьёв (kostik_love) 28.03.16 05:17
А почему бы не связаться с ребятами из "Штрих-М" и подать заявку на доработку драйвера «ПО «ШТРИХ-М: Драйвер ФР» в соответствии с «требованиями к разработке драйверов для фискальных регистраторов» компании 1С»- что бы в следующей версии все нужные вам функции были.
а пункты 1, 2, 3 - получается временное решение.
6. Галахад (dmt) 28.03.16 05:50
(5) kostik_love, потому что именно на форуме Штриха от сотрудников Штриха я и получил ответ использовать DeviceControlHEX.
7. Роман Ложкин (webester) 27.05.16 13:35
(1)Дописать одну функцию или переписать весь функционал работы с ФР? Хм какой сложный выбор...
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа