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