При оформлении поступлений и реализаций товаров иногда возникает специфическая задача: отразить в одной строке табличной части сразу несколько связанных объектов — например, перечень номеров вагонов, цистерн или подразделений через запятую. Поскольку стандартный ссылочный реквизит табличной части позволяет выбрать только одно значение, разработчики сталкиваются с вопросом корректной архитектурной и программной реализации такого ввода.
Разберем детально, как решить эту задачу в конфигурациях на обычных формах (в частности, в 1С:Управление торговлей 10.3), выясним ограничения строкового хранения и рассмотрим типовые альтернативы.
Прежде чем приступать к доработке формы, проанализируем последствия решения хранить список подразделений в виде простой текстовой строки:
Подразделения будет переименован или помечен на удаление, в строках уже проведенных документов текст останется прежним.ПОДОБНО "%номер%" не только замедляет выполнение запроса (не используются индексы), но и приводит к ложным срабатываниям (например, строка со значением "15" найдется при поиске по "115" или "150").Если данные необходимы исключительно в справочных целях для печатных форм, строковый реквизит допустим. Если же требуется раздельный количественный или суммовой учет по каждому вагону, стандартная практика платформы 1С предполагает разбиение документа построчно (одна строка — один вагон) либо использование типового механизма Серии номенклатуры, где в качестве серии выступает номер вагона или транспортной партии.
Рассмотрим по шагам реализацию пользовательского интерфейса, когда в табличную часть добавлен реквизит строкового типа, а заполнение выполняется выбором нескольких элементов из справочника.
Шаг 1. Настройка метаданных и формы
Товары) добавим реквизит НомераВагоновПодразделения с типом Строка достаточной длины (например, 150 или неограниченной длины).Истина).НачалоВыбора.Шаг 2. Перехват стандартной обработки и интерактивный выбор с флажками
Для удобного выбора нескольких элементов пользователю можно предложить диалоговое окно с флажками (чекбоксами). Для этого используем объект СписокЗначений и метод ОтметитьЭлементы().
Посмотрим на пример реализации обработчика события в модуле формы документа:
Процедура ТоварыНомераВагоновПодразделенияНачалоВыбора(Элемент, СтандартнаяОбработка)
// Отключаем стандартное открытие формы выбора справочника
СтандартнаяОбработка = Ложь;
// Получаем текущую строку табличной части
ТекущаяСтрока = ЭлементыФормы.Товары.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Формируем список значений для интерактивного выбора
СписокПодразделений = Новый СписокЗначений;
Выборка = Справочники.Подразделения.Выбрать();
Пока Выборка.Следующий() Цикл
СписокПодразделений.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
// Открываем модальное окно с флажками
Если СписокПодразделений.ОтметитьЭлементы("Выберите подразделения (вагоны)") Тогда
СтрокаРезультат = "";
Для Каждого ЭлементСписка Из СписокПодразделений Цикл
Если ЭлементСписка.Пометка Тогда
СтрокаРезультат = СтрокаРезультат + ?(ПустаяСтрока(СтрокаРезультат), "", ", ") + СокрЛП(ЭлементСписка.Представление);
КонецЕсли;
КонецЦикла;
// Записываем результат в текущую строку
ТекущаяСтрока.НомераВагоновПодразделения = СтрокаРезультат;
КонецЕсли;
КонецПроцедуры
Разберем второй вариант: открытие формы списка справочника подразделений с включенным режимом множественного выделения строк. В обычном приложении табличное поле формы списка поддерживает свойство МножественныйВыбор.
Посмотрим на пример программного открытия формы и обработки массива выбранных ссылок:
Процедура ТоварыНомераВагоновПодразделенияНачалоВыбора(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТекущаяСтрока = ЭлементыФормы.Товары.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ФормаВыбора = Справочники.Подразделения.ПолучитьФормуВыбора();
// Включаем возможность множественного выделения строк в форме выбора
ФормаВыбора.ЭлементыФормы.СправочникСписок.МножественныйВыбор = Истина;
// При множественном выборе ОткрытьМодально() возвращает объект Массив
ВыбранныеЭлементы = ФормаВыбора.ОткрытьМодально();
Если ТипЗнч(ВыбранныеЭлементы) = Тип("Массив") И ВыбранныеЭлементы.Количество() > 0 Тогда
СтрокаРезультат = "";
Для Каждого СсылкаПодразделение Из ВыбранныеЭлементы Цикл
СтрокаРезультат = СтрокаРезультат + ?(ПустаяСтрока(СтрокаРезультат), "", ", ") + СокрЛП(СсылкаПодразделение.Наименование);
КонецЦикла;
ТекущаяСтрока.НомераВагоновПодразделения = СтрокаРезультат;
КонецЕсли;
КонецПроцедуры
При использовании этого способа пользователь может выделить необходимые строки в открывшемся окне, зажав клавиши Ctrl или Shift, и нажать кнопку «Выбрать».
Если требуется не только отображать названия через запятую, но и сохранять ссылки на выбранные элементы без потери структуры, рассмотрим вариант с добавлением дополнительного реквизита в табличную часть:
ХранилищеПодразделений с типом ХранилищеЗначения (реквизит не выводится на форму).ХранилищеЗначения:
ТекущаяСтрока.ХранилищеПодразделений = Новый ХранилищеЗначения(ВыбранныеЭлементы);
Получить() у сохраненного хранилища.Такой подход защитит алгоритмы от проблем при переименовании элементов справочника и позволит при необходимости восстановить точный ссылочный состав данных строки документа.