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

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

Каждый оператор ввода данных, менеджер по продажам или бухгалтер сталкивался с рутинной задачей — заполнением табличной части документа вручную. Когда позиций много, а подбор по каким-то причинам не используется, стандартный сценарий выглядит так: пользователь нажимает клавишу Insert или кнопку (+) Добавить, нажимает кнопку выбора («...») и начинает искать товар в справочнике Номенклатура.

Однако здесь нас подстерегает крайне неприятное поведение системы: при создании каждой новой строки платформа сбрасывает фокус выбора в корневой каталог справочника. Пользователю приходится заново открывать нужные папки, искать нужную группу и тратить драгоценное время. В этой статье мы подробно разберем, почему так происходит, почему стандартные настройки интерфейса не помогают решить проблему и как исправить это поведение программным путем раз и навсегда — как в обычных формах (например, в «Управлении торговлей 10.3»), так и в современных управляемых формах.


Выясняем причину: почему не работает стандартная настройка восстановления позиции?

В платформе «1С:Предприятие» у форм списков справочников есть стандартная пользовательская настройка. Если открыть форму списка номенклатуры, нажать на ней правой кнопкой мыши и выбрать пункт «Настройка списка», там можно обнаружить флажок «При открытии восстанавливать позицию».

Казалось бы, это именно то, что нужно! Но на практике при добавлении новой строки в табличную часть документа эта настройка абсолютно бесполезна. Давайте разберем по шагам физику процесса, происходящего в системе:

  1. Пользователь добавляет новую строку в табличную часть документа (например, «Заказ покупателя» или «Реализация товаров и услуг»).
  2. Новая строка создается абсолютно пустой. Поле Номенклатура в этой строке содержит так называемую пустую ссылку (СправочникСсылка.Номенклатура.ПустаяСсылка).
  3. Когда пользователь нажимает на кнопку выбора («...»), платформа инициирует событие начала выбора и передает текущее значение поля ввода в открывающуюся форму списка в качестве начального ориентира для позиционирования.
  4. Поскольку значение в поле ввода пустое, платформа считает, что никакого предварительного выбора сделано не было. Она принудительно игнорирует настройку «Восстанавливать позицию» и открывает справочник с самого начала — то есть с корня.

Таким образом, стандартное восстановление позиции работает только в двух случаях: если форма списка открывается обособленно (не для выбора в поле), либо если в поле ввода уже была выбрана конкретная номенклатура и мы решили ее изменить.


Программное решение для обычных форм (на примере УТ 10.3)

Если мы работаем в конфигурации на обычных формах (толстый клиент), нам необходимо вмешаться в процесс выбора элемента табличной части. Основная идея заключается в том, чтобы перехватить событие начала выбора, найти значение номенклатуры в предыдущей строке документа и принудительно передать его в открываемую форму справочника как начальное значение.

Проанализируем программный код, который решает эту задачу. Нам потребуется обработчик события ПриНачалеВыбора (или НачалоВыбора) для поля табличной части:


Процедура ТоварыНоменклатураНачалоВыбора(Элемент, СтандартнаяОбработка)
    
    // 1. Отключаем стандартный механизм открытия формы выбора платформой
    СтандартнаяОбработка = Ложь;
    
    // 2. Получаем данные текущей (строки, которую мы сейчас заполняем)
    ТекущаяСтрока = ЭлементыФормы.Товары.ТекущиеДанные;
    
    // 3. Вычисляем индекс текущей строки в табличной части
    ИндексТекущейСтроки = Товары.Индекс(ТекущаяСтрока);
    
    // Инициализируем переменную для хранения предыдущего товара
    ПредыдущаяНоменклатура = Справочники.Номенклатура.ПустаяСсылка();
    
    // 4. Если текущая строка не самая первая, получаем товар из предыдущей строки
    Если ИндексТекущейСтроки > 0 Тогда
        ПредыдущаяНоменклатура = Товары[ИндексТекущейСтроки - 1].Номенклатура;
    КонецЕсли;
    
    // 5. Получаем форму выбора справочника "Номенклатура"
    ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);
    
    // 6. Если предыдущий товар заполнен, настраиваем позиционирование формы
    Если ЗначениеЗаполнено(ПредыдущаяНоменклатура) Тогда
        
        // Способ А: Позиционируемся непосредственно на сам предыдущий товар.
        // Форма автоматически раскроет дерево групп и сфокусируется на этой позиции.
        ФормаВыбора.НачальноеЗначениеВыбора = ПредыдущаяНоменклатура;
        
        // Способ Б (альтернативный): Если вы хотите, чтобы открывалась папка 
        // предыдущего товара, но сам товар не выделялся (фокус оставался на всей папке):
        // ФормаВыбора.ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Истина;
        // ФормаВыбора.ЭлементыФормы.СправочникСписок.ТекущийРодитель = ПредыдущаяНоменклатура.Родитель;
        
    КонецЕсли;
    
    // 7. Открываем форму выбора для пользователя
    ФормаВыбора.Открыть();
    
КонецПроцедуры

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


Программное решение для управляемых форм (УТ 11, ERP, БП 3.0, УНФ)

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

Рассмотрим, как решить нашу задачу в управляемом приложении. Нам понадобится использовать клиентское событие НачалоВыбора для реквизита табличной части:


&НаКлиенте
Процедура ТоварыНоменклатураНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Предотвращаем стандартное поведение платформы
    СтандартнаяОбработка = Ложь;
    
    // Получаем внутренний идентификатор текущей строки табличной части
    ТекСтрокаИд = Элементы.Товары.ТекущиеДанные.ПолучитьИдентификатор();
    
    Если ТекСтрокаИд > 0 Тогда
        // Находим предыдущую строку по ее идентификатору (ИдентификаторТекущей - 1)
        ПредСтрока = Объект.Товары.НайтиПоИдентификатору(ТекСтрокаИд - 1);
        
        Если ПредСтрока <> Неопределено И ЗначениеЗаполнено(ПредСтрока.Номенклатура) Тогда
            
            // Формируем параметры для открытия формы выбора справочника
            ПараметрыФормы = Новый Структура;
            
            // Параметр "ТекущаяСтрока" указывает платформе, на какой элемент 
            // необходимо спозиционировать курсор при открытии формы списка
            ПараметрыФормы.Вставить("ТекущаяСтрока", ПредСтрока.Номенклатура);
            
            // Программно открываем форму выбора с нашими параметрами
            ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
            Возврат;
            
        КонецЕсли;
    КонецЕсли;
    
    // Если предыдущая строка не найдена или товар в ней не заполнен, 
    // открываем форму выбора в стандартном режиме
    ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора",, Элемент);
    
КонецПроцедуры

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


Использование стандартного механизма «Подбор» как альтернатива

Нельзя не упомянуть встроенный инструмент, который изначально задумывался разработчиками фирмы «1С» как раз для решения подобных задач пакетного ввода. Речь идет о механизме «Подбор» (кнопка над табличной частью документа).

Давайте проанализируем, почему «Подбор» может быть удобнее программных доработок:

Тем не менее, если бизнес-процесс компании требует именно последовательного построчного ввода документов «с клавиатуры» через клавишу Insert, использование приведенных выше программных доработок для обычных или управляемых форм станет наилучшим решением, существенно повышающим эргономику работы пользователей.

← На главную