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