ТСД в 1С — это терминал сбора данных: карманный компьютер со сканером штрихкодов, с которым кладовщик принимает товар, собирает заказы и пересчитывает склад, не возвращаясь к компьютеру. Сам по себе терминал базу 1С не «видит»: нужны программа на ТСД и способ обмена с базой. Ниже разобраны варианты для УТ 11, ERP и Розницы: чем они отличаются по затратам и что обычно дорабатывают под ордерную схему и инвентаризацию.
Первая часть статьи — для владельца и руководителя склада. Вторая — для программиста: настройка и код сверки отсканированного с документом.
На складе в 1С ТСД чаще всего используют для четырёх операций.
Главный выигрыш — меньше ошибок: артикул не перепутать, если товар подтверждается сканированием. Условие для любого варианта одно — у товаров в 1С заведены штрихкоды. Без них терминал бесполезен.
В 1С:Управление торговлей 11, КА 2, ERP 2 и Рознице 3.0 встроена Библиотека подключаемого оборудования (БПО), и терминал сбора данных — один из её типов устройств. Схема такая: на ТСД выгружают базу товаров со штрихкодами, кладовщик работает без связи с 1С, затем в документе нажимают «Загрузить данные из ТСД». Команда есть в большинстве складских и торговых документов: в ордерах, перемещении, поступлении, реализации, заказе клиента, пересчёте товаров. Она добавляет отсканированное в табличную часть, как ручной сканер. Сверку «положено — отсканировано» типовая делает в приходном и расходном ордере: кнопка «Проверить» открывает проверку количества, куда тоже загружают данные из ТСД.
Нужен драйвер ТСД для БПО — его поставляет разработчик программы для терминала. Плюсы: Wi-Fi на складе не обязателен, лицензии 1С на терминалы не нужны. Минусы: справочник на ТСД устаревает с момента выгрузки, а ошибки видны только после загрузки.
Самый бюджетный путь: мобильный ТСД для 1С на Android с приложением-сканером, которое сохраняет файл «штрихкод;количество». Файл копируют на компьютер и загружают в 1С обработкой. Типового механизма для таких файлов в УТ нет, но обработка несложная — пример ниже. Подходит для инвентаризации и нечастой приёмки.
В этом варианте работа ТСД через 1С идёт в реальном времени: терминал сразу видит задания и остатки, а ошибка ловится в момент сканирования. В УТ 11.5, КА 2.5 и ERP 2.5 для этого есть «Мобильное рабочее место кладовщика» (МРМК) — обработка для мобильного клиента 1С: приходные и расходные ордера, отбор, размещение по ячейкам, пересчёт товаров. Мобильный клиент работает с базой, опубликованной на веб-сервере, и каждый его сеанс занимает клиентскую лицензию 1С. Для терминалов на Windows CE в типовой есть «Рабочее место работника склада» с формами под экраны 240×320, 320×320 и 480×640. В обоих случаях нужен устойчивый Wi-Fi по всему складу.
Mobile SMARTS от Клеверенс («Склад 15», «Магазин 15») — программа для ТСД плюс обработка обмена с 1С: готовые сценарии приёмки, отбора, инвентаризации, адресного хранения и маркировки, пакетный и онлайн-режим, лицензии на терминалы — у вендора. «1С:Мобильная торговля» — продукт 1С для ТСД Urovo и Meferi на Android; по описанию на сайте 1С он обменивается с ERP, КА, УТ, Розницей и УНФ. Для Розницы и УНФ есть ещё приложение «1С:Кладовщик»: сборка заказов, приёмка, инвентаризация торгового зала, связь нужна только для обмена. Для большого адресного склада 1С его не рекомендует.
| Вариант | Что покупать | Wi-Fi | Ордерная схема и инвентаризация | Что обычно дорабатывают |
|---|---|---|---|---|
| Пакетный обмен через БПО | ТСД и программа к нему с драйвером | Не нужен | Загрузка в документы, проверка количества в ордерах, пересчёт товаров | Сверку с заказом и документами без типовой проверки |
| Файл из приложения | ТСД, приложение-сканер | Не нужен | Только через свою обработку | Обработку загрузки и сверки |
| Онлайн (МРМК, рабочее место работника склада) | ТСД, лицензии 1С на сеансы, веб-сервер | Обязателен | Приёмка, отбор, размещение и пересчёт в реальном времени | Публикацию базы, сценарии под свои процессы |
| Клеверенс, приложения 1С | ТСД и лицензии вендора | Зависит от режима | Готовые сценарии | Обмен с доработанной конфигурацией, нестандартные операции |
Цены лицензий сверяйте с прайсами вендоров. Небольшому складу без ячеек обычно хватает пакетного обмена. Для адресного склада со сборкой по ячейкам выбирают онлайн.
Устройства в БПО привязаны к рабочему месту: ТСД, настроенный на одном компьютере, на соседнем «не подключен», пока его не добавят и там. Как устроены склады с ордерной схемой, рассказано в статье о складах в УТ 11, про ячейки — в статье об адресном хранении.
Типовая проверка количества есть только в ордерах, а файлы простых приложений типовые формы не читают. Частая доработка — обработка, которая принимает данные из ТСД или из файла, находит товары по штрихкодам и показывает расхождение с любым документом: заказом клиента, перемещением, поступлением на склад без ордерной схемы. Документ она не меняет: кладовщик видит, чего не хватает, и досканирует.
Создайте внешнюю обработку с управляемой формой. Реквизиты: Документ составного типа из нужных документов, таблицы значений Сверка (Номенклатура, Характеристика, ПоДокументу, Отсканировано, Расхождение) и НеизвестныеШтрихкоды (Штрихкод, Количество). Выведите их на форму и добавьте команды ЗагрузитьИзТСД и ЗагрузитьИзФайла.
// Внешняя обработка «Сверка данных ТСД с документом»: модуль управляемой формы.
// УТ 11.5, КА 2.5, ERP 2.5 (есть БПО и БСП 3.x), платформа 8.3.10 и выше.
// Реквизиты формы:
// Документ - составной тип из документов с табличной частью Товары
// (Номенклатура, Характеристика, Количество), например
// ДокументСсылка.ЗаказКлиента, ДокументСсылка.ПеремещениеТоваров,
// ДокументСсылка.ПриобретениеТоваровУслуг;
// Сверка - ТаблицаЗначений: Номенклатура, Характеристика,
// ПоДокументу, Отсканировано, Расхождение (Число 15.3);
// НеизвестныеШтрихкоды - ТаблицаЗначений: Штрихкод (Строка 200), Количество (Число 15.3).
// Команды формы: ЗагрузитьИзТСД, ЗагрузитьИзФайла.
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ЗагрузитьИзТСД(Команда)
ОчиститьСообщения();
// В БПО 3.x метод помечен устаревшим (замена - ОборудованиеТерминалыСбораДанныхКлиент),
// но его вызывают типовые формы и он есть в старых версиях библиотеки.
Оповещение = Новый ОписаниеОповещения("ЗагрузитьИзТСДЗавершение", ЭтотОбъект);
МенеджерОборудованияКлиент.НачатьЗагрузкуДанныеИзТСД(Оповещение, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьИзТСДЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Не Результат.Результат Тогда
ПоказатьПредупреждение(, "Не удалось загрузить данные из ТСД: "
+ Строка(Результат.ОписаниеОшибки));
Возврат;
КонецЕсли;
// ТаблицаТоваров - массив структур: Штрихкод, Количество (строкой) и служебные поля
ЗаполнитьСверку(Результат.ТаблицаТоваров);
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьИзФайла(Команда)
ОчиститьСообщения();
ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
ПараметрыЗагрузки.ИдентификаторФормы = УникальныйИдентификатор;
ПараметрыЗагрузки.Диалог.Фильтр = "Выгрузка ТСД (*.csv;*.txt)|*.csv;*.txt";
Оповещение = Новый ОписаниеОповещения("ЗагрузитьИзФайлаЗавершение", ЭтотОбъект);
ФайловаяСистемаКлиент.ЗагрузитьФайл(Оповещение, ПараметрыЗагрузки);
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьИзФайлаЗавершение(ПомещенныйФайл, ДополнительныеПараметры) Экспорт
Если ПомещенныйФайл = Неопределено Тогда
Возврат; // файл не выбран
КонецЕсли;
ЗагрузитьФайлНаСервере(ПомещенныйФайл.Хранение);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаСервере
Процедура ЗагрузитьФайлНаСервере(АдресФайла)
ДанныеФайла = ПолучитьИзВременногоХранилища(АдресФайла);
УдалитьИзВременногоХранилища(АдресФайла);
// Строка файла: «штрихкод;количество» или «штрихкод», разделитель - точка с запятой
// или табуляция. Строка без количества считается одним сканированием.
ДанныеСканирования = Новый Массив;
Поток = ДанныеФайла.ОткрытьПотокДляЧтения();
Чтение = Новый ЧтениеТекста(Поток, КодировкаТекста.UTF8);
СтрокаФайла = Чтение.ПрочитатьСтроку();
Пока СтрокаФайла <> Неопределено Цикл
Части = СтрРазделить(СтрЗаменить(СтрокаФайла, Символы.Таб, ";"), ";");
Позиция = Новый Структура("Штрихкод, Количество", Части[0], "");
Если Части.Количество() > 1 Тогда
Позиция.Количество = Части[1];
КонецЕсли;
ДанныеСканирования.Добавить(Позиция);
СтрокаФайла = Чтение.ПрочитатьСтроку();
КонецЦикла;
Чтение.Закрыть();
Поток.Закрыть();
ЗаполнитьСверку(ДанныеСканирования);
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьСверку(ДанныеСканирования)
Сверка.Очистить();
НеизвестныеШтрихкоды.Очистить();
// 1. Сканирования - в таблицу с типизированными колонками, чтобы передать ее в запрос
Скан = Новый ТаблицаЗначений;
Скан.Колонки.Добавить("Штрихкод", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200)));
Скан.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
Пропущено = 0;
Для Каждого Позиция Из ДанныеСканирования Цикл
// Символ(65279) - метка порядка байтов в начале файла, ее оставляют некоторые программы
Штрихкод = СокрЛП(СтрЗаменить(Строка(Позиция.Штрихкод), Символ(65279), ""));
Если ПустаяСтрока(Штрихкод) Тогда
Продолжить;
КонецЕсли;
Количество = КоличествоИзТСД(Позиция.Количество);
Если Количество = Неопределено Тогда
Пропущено = Пропущено + 1; // заголовок файла или испорченная строка
Продолжить;
КонецЕсли;
НоваяСтрока = Скан.Добавить();
НоваяСтрока.Штрихкод = Штрихкод;
НоваяСтрока.Количество = Количество;
КонецЦикла;
Скан.Свернуть("Штрихкод", "Количество");
// 2. Штрихкод дает товар и упаковку; количество переводим в единицы хранения,
// как поле Количество в табличной части документа
ТекстКоэффициента = Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаКоэффициентаУпаковки(
"Штрихкоды.Упаковка", "Штрихкоды.Номенклатура");
ТекстЗапроса =
"ВЫБРАТЬ
| Скан.Штрихкод КАК Штрихкод,
| Скан.Количество КАК Количество
|ПОМЕСТИТЬ ВТСкан
|ИЗ
| &Скан КАК Скан
|
|ИНДЕКСИРОВАТЬ ПО
| Штрихкод
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Штрихкоды.Номенклатура КАК Номенклатура,
| Штрихкоды.Характеристика КАК Характеристика,
| 0 КАК ПоДокументу,
| Скан.Количество * ЕСТЬNULL(" + ТекстКоэффициента + ", 1) КАК Отсканировано
|ПОМЕСТИТЬ ВТСтроки
|ИЗ
| ВТСкан КАК Скан
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
| ПО Скан.Штрихкод = Штрихкоды.Штрихкод";
Если ЗначениеЗаполнено(Документ) Тогда
ТекстЗапроса = ТекстЗапроса + "
|
|ОБЪЕДИНИТЬ ВСЕ
|
|" + ТекстЗапросаСтрокДокумента(Документ);
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Строки.Номенклатура КАК Номенклатура,
| Строки.Характеристика КАК Характеристика,
| СУММА(Строки.ПоДокументу) КАК ПоДокументу,
| СУММА(Строки.Отсканировано) КАК Отсканировано,
| СУММА(Строки.Отсканировано - Строки.ПоДокументу) КАК Расхождение
|ИЗ
| ВТСтроки КАК Строки
|
|СГРУППИРОВАТЬ ПО
| Строки.Номенклатура,
| Строки.Характеристика
|
|УПОРЯДОЧИТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Скан.Штрихкод КАК Штрихкод,
| Скан.Количество КАК Количество
|ИЗ
| ВТСкан КАК Скан
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
| ПО Скан.Штрихкод = Штрихкоды.Штрихкод
|ГДЕ
| Штрихкоды.Штрихкод ЕСТЬ NULL";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Скан", Скан);
Запрос.УстановитьПараметр("Документ", Документ);
Результаты = Запрос.ВыполнитьПакет();
// Пакет: 0 - ВТСкан, 1 - ВТСтроки, 2 - сверка, 3 - неизвестные штрихкоды
ЗначениеВРеквизитФормы(Результаты[2].Выгрузить(), "Сверка");
ЗначениеВРеквизитФормы(Результаты[3].Выгрузить(), "НеизвестныеШтрихкоды");
Если Пропущено > 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Пропущено строк с нечитаемым количеством: " + Формат(Пропущено, "ЧГ=0");
Сообщение.Сообщить();
КонецЕсли;
Если НеизвестныеШтрихкоды.Количество() > 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Штрихкодов нет в базе: " + Формат(НеизвестныеШтрихкоды.Количество(), "ЧГ=0")
+ ". Зарегистрируйте их у товаров и загрузите данные повторно.";
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция КоличествоИзТСД(Значение)
Если ТипЗнч(Значение) = Тип("Число") Тогда
Возврат Значение;
КонецЕсли;
// Драйвер БПО отдает количество строкой; в файлах бывают десятичная запятая
// и пробелы (в том числе неразрывные) между разрядами
Текст = СтрЗаменить(СокрЛП(Строка(Значение)), ",", ".");
Текст = СтрЗаменить(СтрЗаменить(Текст, " ", ""), Символы.НПП, "");
Если ПустаяСтрока(Текст) Тогда
Возврат 1; // количество не передано: строка = одно сканирование
КонецЕсли;
Попытка
Возврат Число(Текст);
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
&НаСервереБезКонтекста
Функция ТекстЗапросаСтрокДокумента(Документ)
МетаданныеДокумента = Документ.Метаданные();
Товары = МетаданныеДокумента.ТабличныеЧасти.Найти("Товары");
Если Товары = Неопределено
Или Товары.Реквизиты.Найти("Номенклатура") = Неопределено
Или Товары.Реквизиты.Найти("Характеристика") = Неопределено
Или Товары.Реквизиты.Найти("Количество") = Неопределено Тогда
ВызватьИсключение "В документе «" + МетаданныеДокумента.Синоним
+ "» нет табличной части Товары с полями Номенклатура, Характеристика, Количество.";
КонецЕсли;
// Услуги и работы не сканируют; отмененные строки заказа не отгружают
ТекстЗапроса =
"ВЫБРАТЬ
| Товары.Номенклатура,
| Товары.Характеристика,
| Товары.Количество,
| 0
|ИЗ
| " + МетаданныеДокумента.ПолноеИмя() + ".Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Документ
| И Товары.Номенклатура.ТипНоменклатуры В
| (ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Товар),
| ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.МногооборотнаяТара))";
Если Товары.Реквизиты.Найти("Отменено") <> Неопределено Тогда
ТекстЗапроса = ТекстЗапроса + "
| И НЕ Товары.Отменено";
КонецЕсли;
Возврат ТекстЗапроса;
КонецФункции
#КонецОбласти
МенеджерОборудованияКлиент.НачатьЗагрузкуДанныеИзТСД сам предложит выбрать терминал, если их несколько, и вернёт структуру с полями Результат, ОписаниеОшибки и массивом ТаблицаТоваров, где у каждой позиции есть Штрихкод и Количество. В БПО 3.x метод помечен устаревшим в пользу ОборудованиеТерминалыСбораДанныхКлиент.НачатьЗагрузкуДанныеИзТСД, но типовые формы пока вызывают его.КоличествоИзТСД переводит строку в число и понимает десятичную запятую.ШтрихкодыНоменклатуры: измерение Штрихкод, ресурсы Номенклатура, Характеристика, Упаковка.Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаКоэффициентаУпаковки возвращает выражение коэффициента упаковки с учётом весовых и объёмных единиц, поэтому сверка идёт в единицах хранения, как поле Количество табличной части.ТекстЗапросаСтрокДокумента берёт из документа только товары и многооборотную тару: услуги в заказе не сканируют, иначе они висели бы недостачей. Если в табличной части есть реквизит Отменено, как в заказе клиента, отменённые строки тоже отбрасываются.ОБЪЕДИНИТЬ ВСЕ и группируются: лишний товар попадает в сверку с плюсом, недостающий — с минусом.Число() с запятой или пробелом.Технически да: мобильный клиент 1С и многие программы для ТСД работают на обычном Android. Но камера сканирует медленнее встроенного сканера, а корпус не рассчитан на склад. Для редкой инвентаризации смартфон подойдёт, для ежедневной приёмки — нет.
Сначала выберите вариант работы, потом модель: программа для ТСД ограничивает список поддерживаемых устройств. Для онлайн-режима нужен Android, для маркированных товаров — сканер, который читает 2D-коды.
На складе с ордерной схемой — через документ «Пересчёт товаров»: выгрузите базу на терминал, пересчитайте склад или его часть и загрузите результат кнопкой «Загрузить данные из ТСД». Излишки и недостачи затем оформляют отдельными документами. Сверить итог помогут отчёты по остаткам товаров на складе.
Складывается из терминалов, лицензий программы для ТСД или 1С и работы программиста. Настройка пакетного обмена на типовой УТ — небольшая задача, внедрение адресного склада с онлайн-отбором — проект. Ориентиры по работам — на странице стоимости доработки 1С.
Если терминал не видит 1С, данные нужно загружать в нетиповые документы или приёмку и сборку надо перестроить под ордерную схему, нужен программист, знающий БПО и складской контур УТ. Опишите задачу в разделе услуг по доработке 1С или сразу разместите задачу: оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.