При интеграции 1С с торговым оборудованием, например, фискальными регистраторами марки MG, часто возникает задача выгрузки данных о чеках и товарах напрямую в интерфейс программы. В данной статье мы подробно разберем, как правильно организовать цикл получения данных через библиотеку UniUNSDLL, как избежать типичных ошибок при заполнении табличных частей и как обеспечить корректную вложенность данных «чек-товар».
Представим ситуацию: нам необходимо получить список чеков из памяти устройства и отобразить их в табличной части на форме 1С. Для каждого чека нам также нужно получить список проданных позиций (товаров). Основным инструментом взаимодействия выступает библиотека UniUNSDLL, которая предоставляет методы ПолучитьЧекV4 и ПолучитьТоварЧека.
Рассмотрим основные проблемы, с которыми сталкиваются разработчики на начальном этапе:
Перед тем как начать заполнение, крайне важно очистить существующие данные в табличных частях. Если этого не сделать, при каждом повторном вызове процедуры данные будут дублироваться, что приведет к ошибкам в отчетах.
Проанализируем пример кода для инициализации процесса:
// Очищаем табличные части на форме перед заполнением
Чеки.Очистить();
Товары.Очистить();
// КоличествоЧеков должно быть получено заранее из свойств драйвера
ВсегоЧеков = Число(КоличествоЧеков);
Для перебора чеков мы используем классический цикл Для ... По. Важно помнить, что в 1С при работе с коллекциями, получаемыми от внешних компонент, индекс часто начинается с единицы. Метод ПолучитьЧекV4 возвращает статус выполнения (0 — успешно) и заполняет переменные, переданные по ссылке.
Рассмотрим правильную структуру заполнения основной таблицы «Чеки»:
Для НомерЧека = 1 По ВсегоЧеков Цикл
// Вызываем метод DLL. Переменные (ЧекСумма, ЧекДата и т.д.) заполнятся автоматически
Если UniUNSDLL.ПолучитьЧекV4(НомерЧека, ЧекКоличествоТоваров, ЧекНомерРРО, ЧекСумма, ЧекДатаВремя, ЧекТип, ЧекКоличествоОплат, ЧекИдентификатор, ЧекКассирИд, ЧекФискалНомер) = 0 Тогда
// Фильтруем типы чеков, если нужно (например, ЧекТип = 0 — это только продажи)
НоваяСтрокаЧек = Чеки.Добавить();
НоваяСтрокаЧек.НомерЧека = НомерЧека;
НоваяСтрокаЧек.ЧекКоличествоТоваров = ЧекКоличествоТоваров;
НоваяСтрокаЧек.ЧекСумма = Число(ЧекСумма); // Приведение к числу обязательно
НоваяСтрокаЧек.ЧекФискалНомер = ЧекФискалНомер;
// ... заполнение остальных реквизитов
Иначе
Сообщить("Ошибка получения данных чека №" + НомерЧека + ": " + UniUNSDLL.ТекстОшибки);
КонецЕсли;
КонецЦикла;
Наиболее частая ошибка — выносить цикл по товарам за пределы цикла по чекам. Библиотека UniUNSDLL работает по принципу «указателя»: после успешного вызова ПолучитьЧекV4 внутренние механизмы драйвера настраиваются на чтение товаров именно этого конкретного чека.
Разберем, как реализовать «цикл в цикле» для корректной привязки товаров:
Для НомерЧека = 1 По ВсегоЧеков Цикл
Если UniUNSDLL.ПолучитьЧекV4(НомерЧека, ЧекКоличествоТоваров, ЧекНомерРРО, ...) = 0 Тогда
// Заполняем данные чека (как в предыдущем примере)
НоваяСтрокаЧек = Чеки.Добавить();
// ...
// Вложенный цикл по количеству товаров в текущем чеке
Для НомерТовара = 1 По Число(ЧекКоличествоТоваров) Цикл
Если UniUNSDLL.ПолучитьТоварЧека(НомерТовара, ТоварШтрихКод, ТоварКод, ТоварИмя, ТоварСумма, ТоварКоличество, ТоварЦена, ТоварНалогГруппа, ТоварОтменен) = 0 Тогда
СтрокаТовар = Товары.Добавить();
СтрокаТовар.СвязьСЧеком = ЧекФискалНомер; // Создаем идентификатор связи
СтрокаТовар.ТоварИмя = ТоварИмя;
СтрокаТовар.ТоварКоличество = Число(ТоварКоличество);
СтрокаТовар.ТоварЦена = Число(ТоварЦена);
СтрокаТовар.ТоварСумма = Число(ТоварСумма);
Иначе
Сообщить("Ошибка товара в чеке " + НомерЧека + ": " + UniUNSDLL.ТекстОшибки);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Проанализируем несколько критических моментов, которые помогут сделать ваш код надежным:
String. Если в табличной части реквизит имеет тип Число, используйте функцию Число(), предварительно заменив запятые на точки (если драйвер использует западный формат): Число(СтрЗаменить(ТоварЦена, ",", ".")).ЧекДатаВремя возвращается в строке вида "ГГГГ-ММ-ДД ЧЧ:ММ:СС", для записи в 1С используйте функции работы со строками, чтобы сконструировать объект типа Дата.Связь по владельцу для табличного поля или используйте событие ПриАктивизацииСтроки таблицы чеков, устанавливая отбор в таблице товаров.ТаблицаЗначений в памяти, а в конце одним махом загрузить ее: Чеки.Загрузить(ВременнаяТаблицаЧеков).Всегда проверяйте возвращаемое значение функций драйвера. Если оно не равно нулю, это не всегда означает фатальный сбой. Например, если в чеке нет товаров (служебный чек), метод ПолучитьТоварЧека может вернуть ошибку, которую нужно корректно обработать, не прерывая выполнение общего цикла.
Используйте Сообщить(UniUNSDLL.ТекстОшибки) для отладки. Часто это помогает понять, почему, например, возвращается только один чек вместо 18 — возможно, драйвер ожидает подтверждения связи или авторизации кассира перед началом массового чтения данных.
Таким образом, правильное заполнение табличных частей в 1С при работе с внешними компонентами требует строгого соблюдения иерархии вызовов методов и внимательного отношения к типам данных. Следуя приведенным примерам, вы сможете реализовать стабильный обмен данными с любым торговым оборудованием.