При разработке учетных механизмов нередко возникает задача: предоставить пользователю возможность выбрать в качестве основания либо один документ, либо сразу несколько, чтобы затем выполнить автоматическое заполнение табличных частей. Разберем, почему нельзя просто назначить реквизиту шапки списочный тип и какие варианты реализации существуют в платформе 1С:Предприятие.
В платформе 1С реквизиты объектов метаданных (документов, справочников), сохраняемые в базе данных, могут иметь только примитивные (Число, Строка, Дата, Булево, ХранилищеЗначения) или ссылочные типы. Коллекции значений (такие как СписокЗначений, Массив или ТаблицаЗначений) не могут выступать в качестве типа реквизита объекта.
Попытки обойти это ограничение путем сериализации ссылок в строку через разделители или сохранения массива в ХранилищеЗначения приводят к серьезным архитектурным проблемам:
Рассмотрим правильные подходы к реализации в зависимости от бизнес-логики задачи.
Если список выбранных документов нужен исключительно в момент нажатия кнопки «Заполнить» и сохранять связи между документами в базе не требуется, используем элементы управления формы, а не реквизиты объекта.
Разберем по шагам, как это реализовать:
СписокЗначений (это доступно, так как реквизиты формы не сохраняются напрямую в таблицу СУБД).
СписокДокументов = Новый СписокЗначений;
// Заполняем список доступными для выбора документами
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Проведен = ИСТИНА";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
СписокДокументов.ЗагрузитьЗначения(РезультатЗапроса.ВыгрузитьКолонку("Ссылка"));
// Открываем диалог множественного выбора с флажками
Если СписокДокументов.ОтметитьЭлементы("Выберите документы для заполнения") Тогда
МассивВыбранных = Новый Массив;
Для Каждого ЭлементСписка Из СписокДокументов Цикл
Если ЭлементСписка.Пометка Тогда
МассивВыбранных.Добавить(ЭлементСписка.Значение);
КонецЕсли;
КонецЦикла;
// Передаем массив в процедуру заполнения
ЗаполнитьПоДокументам(МассивВыбранных);
КонецЕсли;
Также можно открыть форму журнала или списка документов в режиме множественного выбора. Для этого перед открытием формы списка устанавливается свойство МножественныйВыбор = Истина, а результат обрабатывается в процедуре ОбработкаВыбора.
Если информацию о документах-основаниях необходимо сохранять в базе данных, единственным стандартным и надежным решением является создание табличной части (например, ДокументыОснования) с реквизитом ссылочного типа ДокументСсылка.
Преимущества данного подхода:
Если отображение целой таблицы в интерфейсе кажется громоздким, визуальную часть формы можно оптимизировать:
ДокументыОснования скрываем на отдельную вкладку или делаем невидимой на форме.
Процедура ОбновитьПредставлениеОснований()
Если ДокументыОснования.Количество() = 0 Тогда
ЭлементыФормы.НадписьОснования.Заголовок = "Не выбрано";
ИначеЕсли ДокументыОснования.Количество() = 1 Тогда
ЭлементыФормы.НадписьОснования.Заголовок = Строка(ДокументыОснования[0].Документ);
Иначе
ЭлементыФормы.НадписьОснования.Заголовок = "Выбрано документов: " + Строка(ДокументыОснования.Количество());
КонецЕсли;
КонецПроцедуры
В конфигурациях со сложной структурой взаимосвязей, когда не хочется изменять метаданные самого документа, можно использовать отдельный непериодический Регистр сведений. В таком регистре создаются два измерения:
Документ (тип: ссылка на текущий документ);ДокументОснование (тип: ссылка на документ-основание).Запись связей в регистр выполняется при проведении или записи документа. Этот вариант сохраняет строгую ссылочную целостность и удобство выборок в запросах, позволяя реализовывать связь «многие ко многим».