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