Как разработать подбор из регистра сведений в табличную часть документа в интерфейсе Такси

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

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

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

В чем сложность копирования типового механизма подбора

В типовых конфигурациях на платформе 1С:Предприятие 8.3 (особенно в ERP) подбор часто завязан на механизмы БСП (Библиотеки стандартных подсистем). Попытка просто скопировать код открытия формы, как это показано в сообщении 5, обычно приводит к тому, что форма подбора открывается, но при двойном клике на строку ничего не происходит. Данные не переносятся в документ.

Происходит это потому, что в типовых документах обработка выбора делегирована сложным общим модулям и подсистемам, которые ожидают строго определенные структуры данных и типы объектов (обычно ссылки на справочники). Когда мы пытаемся подставить туда регистр сведений, стандартные обработчики БСП «не понимают» этот тип данных и игнорируют выбор. Поэтому для нетиповых задач или подбора из регистров сведений нам необходимо реализовать этот алгоритм вручную. Рассмотрим его по шагам.

Шаг 1. Проектирование формы подбора в регистре сведений

Прежде всего, нам нужно создать форму, из которой пользователь будет выбирать данные. Поскольку регистр сведений не является ссылочным объектом (у него нет ссылки, как у справочника или документа), стандартная форма выбора регистра вернет объект типа РегистрСведенийКлючЗаписи. Работать с ключом записи в документе крайне неудобно, так как придется делать дополнительный запрос к базе данных, чтобы извлечь ресурсы.

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

  1. В конфигураторе найдем наш регистр сведений и добавим новую форму. Укажем тип формы — Произвольная форма. Назовем ее, например, ФормаПодбора.
  2. Добавим на форму реквизит с типом ДинамическийСписок. В свойствах динамического списка укажем основную таблицу — наш регистр сведений. Если нам нужно собирать данные из нескольких таблиц, включим флаг Произвольный запрос и настроим связь регистра со справочниками через левое соединение.
  3. Перетащим этот реквизит на форму, чтобы создать таблицу формы. Назовем этот элемент, например, Список.
  4. В свойствах самой формы снимем флаг ЗакрыватьПриВыборе, если мы хотим реализовать множественный подбор (чтобы пользователь мог кликать по строкам, добавляя их в документ, а форма оставалась открытой). Если нужен одиночный выбор — флаг можно оставить.

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


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

Метод ОповеститьОВыборе — это ключевой инструмент платформы 1С для возврата данных из подчиненной формы в форму-владелец. Мы передаем в него нашу структуру ДанныеВыбора.

Шаг 2. Вызов формы подбора из документа

Теперь перейдем к форме нашего документа. Нам нужно разместить кнопку «Подбор» над табличной частью и описать алгоритм открытия нашей созданной формы регистра.

Добавим команду формы Подбор, выведем ее на командную панель табличной части (например, таблицы ЗемельныеУчастки) и напишем обработчик действия команды на клиенте:


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

Разберем важный нюанс. Обратите внимание на третий параметр метода ОткрытьФорму. Мы передаем туда элемент Элементы.ЗемельныеУчастки (это наша таблица на форме). Благодаря этому, когда в форме подбора сработает метод ОповеститьОВыборе(), платформа автоматически направит возвращаемые данные в обработчик события этой таблицы.

Шаг 3. Обработка полученных данных в документе

Чтобы документ принял данные, отправленные формой подбора через ОповеститьОВыборе(), нам необходимо настроить обработку события выбора у таблицы формы документа.

Выделим таблицу ЗемельныеУчастки на форме документа, перейдем в палитру свойств, найдем событие ОбработкаВыбора и создадим процедуру на клиенте:


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

&НаКлиенте
Процедура ДобавитьСтрокуВТабличнуюЧасть(ДанныеСтроки)
    
    // Добавляем новую строку в табличную часть документа
    НоваяСтрока = Объект.ЗемельныеУчастки.Добавить();
    
    // Заполняем реквизиты строки из переданной структуры
    ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки);
    
КонецПроцедуры

Метод ЗаполнитьЗначенияСвойств() автоматически сопоставит ключи нашей структуры (ЗемельныйУчасток, КадастровыйНомер, Площадь) с одноименными реквизитами табличной части документа и перенесет значения. Это избавляет нас от написания рутинного кода присвоения для каждого поля.

Оптимизация: Реализация "корзины" подбора

Рассмотрим ситуацию, когда пользователю нужно не просто кликать дважды по строкам, а сначала собрать сложный список позиций во временную "корзину" в форме подбора, визуально оценить выбор, а затем одной кнопкой «Перенести в документ» отправить все строки сразу. Это очень популярный и удобный сценарий работы в ERP-системах.

Для реализации этого механизма выполним следующие шаги:

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

Посмотрим, как будет выглядеть код кнопки переноса данных на форме подбора:


&НаКлиенте
Процедура ПеренестиВДокумент(Команда)
    
    МассивВыбранныхСтрок = Новый Массив;
    
    Для Каждого СтрокаКорзины Из Объект.Корзина Цикл
        
        ДанныеСтроки = Новый Структура;
        ДанныеСтроки.Вставить("ЗемельныйУчасток", СтрокаКорзины.ЗемельныйУчасток);
        ДанныеСтроки.Вставить("КадастровыйНомер", СтрокаКорзины.КадастровыйНомер);
        ДанныеСтроки.Вставить("Площадь",          СтрокаКорзины.Площадь);
        
        МассивВыбранныхСтрок.Добавить(ДанныеСтроки);
        
    КонецЦикла;
    
    // Оповещаем документ и передаем массив
    ОповеститьОВыборе(МассивВыбранныхСтрок);
    
    // После успешного переноса закрываем форму подбора
    Закрыть();
    
КонецПроцедуры

В документе наш обработчик ЗемельныеУчасткиОбработкаВыбора, который мы написали ранее, уже готов к приему массива. Он успешно обойдет его в цикле и добавит все строки в табличную часть за один проход.

Рекомендации по повышению производительности

Когда вы разрабатываете подбор на базе регистра сведений, особенно в крупных базах данных ERP, необходимо помнить о производительности:

Мы подробно разобрали, как устроена механика подбора в управляемом интерфейсе 1С. Понимание принципа связки «ОткрытьФорму с указанием владельца-таблицы -> ОповеститьОВыборе -> ОбработкаВыбора на таблице» позволяет легко решать задачи переноса любых данных из любых интерфейсных окон в документы без привязки к громоздким и жестким механизмам типовых конфигураций.

← На главную