Как реализовать удобный и быстрый подбор товаров в мобильном приложении 1С?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

Разработка интерфейсов для мобильной платформы 1С существенно отличается от проектирования обычных управляемых форм для настольных компьютеров. Главное ограничение — это минимальное экранное пространство (обычно смартфоны с диагональю экрана около 6 дюймов) в сочетании с жесткостью стандартных платформенных механизмов. Типичный сценарий «открыл подбор, перешел по дереву папок, выбрал товар, ввел количество в отдельном окне, перенес в документ» на мобильном устройстве превращается в медленный и раздражающий процесс для торгового представителя или кладовщика.

В этой статье мы подробно разберем, почему стандартные механизмы динамических списков и деревьев не подходят для быстрого мобильного подбора, и рассмотрим несколько эффективных архитектурных и интерфейсных альтернатив, которые сделают работу пользователей максимально быстрой и удобной.

---

Почему стандартное дерево и Динамический список не подходят для мобильного подбора?

При стандартном подходе разработчики часто пытаются использовать ДинамическийСписок с режимом отображения Дерево или Иерархический список. Однако на практике вы неизбежно столкнетесь со следующими проблемами:

  1. Смещение текста в дереве: При глубине вложенности папок более 3 уровней каждый новый уровень сдвигает наименование номенклатуры вправо. На 6-дюймовом экране в вертикальной ориентации текст просто обрезается, и пользователь не видит, какой товар он выбирает.
  2. Мерцание экрана при навигации: В режиме иерархического списка при переходе из одной папки в другую платформа полностью перерисовывает экран. Это выглядит как раздражающее мигание интерфейса и замедляет работу.
  3. Невозможность прямого ввода данных в Динамический список: Пользователь не может ввести количество заказываемого товара непосредственно в ячейку динамического списка. Платформа требует открытия модального окна редактирования строки или вызова диалога ВвестиЧисло(), что требует от пользователя совершения минимум 2–3 лишних кликов на каждую позицию.

Давайте рассмотрим три эффективных способа решения этой задачи.

---

Способ 1. Использование Таблицы значений в памяти устройства

Если объем вашей номенклатуры относительно невелик (в пределах 3 000 – 5 000 позиций), лучшим решением будет полный отказ от динамического списка в форме подбора. Современные смартфоны обладают достаточным объемом оперативной памяти, чтобы мгновенно обработать такой объем данных в обычной таблице значений на форме.

Преимущества: Данные в Таблице значений (ТЗ) полностью интерактивны. Мы можем добавить в ТЗ колонки Количество, Цена и Сумма, позволив пользователю редактировать их напрямую, без открытия дополнительных окон.

Рассмотрим по шагам, как это реализовать.

Шаг 1. Создание реквизитов формы. Добавим на форму подбора реквизит ТаблицаТоваров с типом ТаблицаЗначений и колонками:

Шаг 2. Заполнение таблицы при открытии. Напишем код, который при открытии формы считывает данные из локальной базы данных мобильного устройства:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Считываем товары, их остатки и цены в ТЗ формы
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.Ссылка КАК Номенклатура,
        |	Номенклатура.Наименование КАК Наименование,
        |	Номенклатура.Родитель КАК Родитель,
        |	Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
        |	ЕСТЬNULL(ТоварыНаСкладахОстатки.ВНаличииОстаток, 0) КАК Остаток,
        |	ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
        |	0 КАК Количество,
        |	0 КАК Сумма
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
        |		ПО ТоварыНаСкладахОстатки.Номенклатура = Номенклатура.Ссылка
        |		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
        |		ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = Номенклатура.Ссылка
        |ГДЕ
        |	НЕ Номенклатура.ПометкаУдаления";
    
    РезультатЗапроса = Запрос.Выполнить();
    ТаблицаТоваров.Загрузить(РезультатЗапроса.Выгрузить());
    
КонецПроцедуры

Шаг 3. Быстрый ввод количества по клику. Чтобы пользователю не приходилось целиться в мелкую ячейку на экране телефона, переопределим событие выбора строки таблицы, чтобы при клике на строку сразу открывалась числовая клавиатура:


&НаКлиенте
Процедура ТаблицаТоваровВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отменяем стандартное открытие карточки
    
    ТекущиеДанные = Элементы.ТаблицаТоваров.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Или ТекущиеДанные.ЭтоГруппа Тогда
        Возврат;
    КонецЕсли;
    
    // Быстрый вызов платформенного ввода числа
    ПараметрыОповещения = Новый ОписаниеОповещения("ПослеВводаКоличества", ЭтотОбъект, ТекущиеДанные);
    ПоказатьВводЧисла(ПараметрыОповещения, ТекущиеДанные.Количество, "Укажите количество заказа:", 10, 0);
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаКоличества(Результат, ДополнительныеПараметры) Экспорт
    
    Если Результат = Неопределено Тогда
        Возврат; // Пользователь закрыл окно ввода
    КонецЕсли;
    
    СтрокаДанных = ДополнительныеПараметры;
    СтрокаДанных.Количество = Результат;
    СтрокаДанных.Сумма = СтрокаДанных.Количество * СтрокаДанных.Цена;
    
КонецПроцедуры

Шаг 4. Перенос данных в документ. По кнопке «ОК» или «Перенести в документ» мы просто собираем все строки таблицы, где количество больше нуля, и передаем их обратно в форму документа:


&НаКлиенте
Процедура ПеренестиВДокумент(Команда)
    
    МассивПодобранныхТоваров = Новый Массив;
    
    Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
        Если СтрокаТовара.Количество > 0 Тогда
            СтруктураТовара = Новый Структура("Номенклатура, Количество, Цена, Сумма");
            ЗаполнитьЗначенияСвойств(СтруктураТовара, СтрокаТовара);
            МассивПодобранныхТоваров.Добавить(СтруктураТовара);
        КонецЕсли;
    КонецЦикла;
    
    Если МассивПодобранныхТоваров.Количество() = 0 Тогда
        ПоказатьПредупреждение(, "Вы не выбрали ни одного товара!");
        Возврат;
    КонецЕсли;
    
    Закрыть(МассивПодобранныхТоваров);
    
КонецПроцедуры

---

Способ 2. Плоский список с «хлебными крошками» (имитация иерархии)

Если вы хотите оставить использование ДинамическогоСписка (например, для оптимизации работы с очень большой базой данных или динамического наложения сложных отборов), то для мобильного экрана лучше всего отказаться от стандартного отображения дерева папок. Вместо этого спроектируем интерфейс по принципу современных интернет-магазинов — плоский список с хлебными крошками.

Суть метода: Мы выводим на экран обычный одноуровневый плоский список. Если строка является папкой, то при клике на нее мы «проваливаемся» внутрь: очищаем экран и показываем только элементы этой папки. Вверху формы программно формируем строку пути, например: Главная > Продукты > Бакалея.

Реализация по шагам:

Шаг 1. Настройка динамического списка. В запросе динамического списка установим жесткое условие отбора по родителю:

ГДЕ Номенклатура.Родитель = &ТекущийРодитель

Шаг 2. Навигация «внутрь» папки. В обработчике выбора строки динамического списка проверяем, является ли элемент папкой:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Если ТекущиеДанные.ЭтоГруппа Тогда
        // Переходим на уровень ниже
        УстановитьФильтрПоРодителю(ТекущиеДанные.Ссылка);
    Иначе
        // Обработка выбора товара (например, добавление в корзину)
        ДобавитьТоварВЗаказ(ТекущиеДанные);
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура УстановитьФильтрПоРодителю(НовыйРодитель)
    
    Список.Параметры.УстановитьЗначениеПараметра("ТекущийРодитель", НовыйРодитель);
    ТекущийРодительНаФорме = НовыйРодитель;
    
    // Обновляем строку навигации (Хлебные крошки)
    ОбновитьСтрокуПути();
    
КонецПроцедуры

Шаг 3. Навигация «наверх». Для возврата на уровень вверх можно использовать кнопку «Назад» в шапке формы или сделать интерактивное текстовое поле «Хлебные крошки». Нажатие на эту строку будет считывать родителя текущего родителя и устанавливать его в качестве параметра списка.

Этот подход полностью решает проблему мерцания экрана при перерисовке дерева и гарантирует, что наименования товаров всегда будут занимать 100% ширины экрана без каких-либо сдвигов вправо.

---

Способ 3. Схема «Папки отдельно, товары отдельно»

Классическая схема подбора из настольной версии конфигурации «Управление торговлей» также может быть успешно адаптирована под мобильный экран. Мы разделяем интерфейс на две независимые области:

  1. Левая (или верхняя) область: Дерево или список, содержащий исключительно группы (папки) номенклатуры без самих товаров.
  2. Правая (или нижняя) область: Динамический список или таблица значений, отображающая элементы только из текущей активной папки.

На 6-дюймовом смартфоне в вертикальной ориентации делить экран на левую и правую части неудобно — колонки будут слишком узкими. Поэтому используем вертикальное разделение:

При активации строки в верхней таблице (папки) срабатывает событие ПриАктивизацииСтроки, которое накладывает быстрый фильтр на нижнюю таблицу (товары). Для выбора товара пользователю достаточно прокрутить нижний список и кликнуть на нужную позицию.

---

Оптимизация UX стандартными средствами мобильной платформы

Чтобы форма подбора была максимально «дружелюбной» для торговых представителей, обязательно примените следующие настройки элементов формы:

Используя предложенные подходы, вы сможете создать быстрое и интуитивно понятное мобильное приложение 1С, с которым торговые представители смогут комфортно работать одной рукой на ходу.

← На главную