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

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

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

Разберем детально, как решить эту задачу в конфигурациях на обычных формах (в частности, в 1С:Управление торговлей 10.3), выясним ограничения строкового хранения и рассмотрим типовые альтернативы.

Архитектурные ограничения хранения списка через запятую

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

  1. Утрата ссылочной целостности: если элемент справочника Подразделения будет переименован или помечен на удаление, в строках уже проведенных документов текст останется прежним.
  2. Сложности в отчетах и выборках: в языке запросов 1С нет штатных функций для разбиения строки на подстроки (парсинга списка). Найти данные через конструкцию ПОДОБНО "%номер%" не только замедляет выполнение запроса (не используются индексы), но и приводит к ложным срабатываниям (например, строка со значением "15" найдется при поиске по "115" или "150").
  3. Невозможность распределения учета: если в одной строке табличной части указано 100 тонн товара и три вагона через запятую, типовые механизмы проведения не смогут распределить количество и себестоимость списания между этими вагонами.

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

Реализация множественного выбора через строку и событие НачалоВыбора

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

Шаг 1. Настройка метаданных и формы

  1. В табличную часть документа (например, Товары) добавим реквизит НомераВагоновПодразделения с типом Строка достаточной длины (например, 150 или неограниченной длины).
  2. Разместим колонку в табличном поле на форме документа.
  3. В свойствах элемента управления колонки включим свойство КнопкаВыбора (установим в значение Истина).
  4. Для колонки назначим обработчик события НачалоВыбора.

Шаг 2. Перехват стандартной обработки и интерактивный выбор с флажками

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

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


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

Реализация через стандартную форму списка справочника

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

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


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

При использовании этого способа пользователь может выделить необходимые строки в открывшемся окне, зажав клавиши Ctrl или Shift, и нажать кнопку «Выбрать».

Сохранение ссылочной структуры данных

Если требуется не только отображать названия через запятую, но и сохранять ссылки на выбранные элементы без потери структуры, рассмотрим вариант с добавлением дополнительного реквизита в табличную часть:

  1. Добавим в табличную часть реквизит ХранилищеПодразделений с типом ХранилищеЗначения (реквизит не выводится на форму).
  2. При подтверждении выбора поместим массив выбранных ссылок в объект ХранилищеЗначения:
    
    ТекущаяСтрока.ХранилищеПодразделений = Новый ХранилищеЗначения(ВыбранныеЭлементы);
    
  3. В строковый реквизит выведем наименования через запятую для пользователя. При необходимости получить ссылки программно достаточно вызвать метод Получить() у сохраненного хранилища.

Такой подход защитит алгоритмы от проблем при переименовании элементов справочника и позволит при необходимости восстановить точный ссылочный состав данных строки документа.

← На главную