Как программно заполнить дополнительные колонки табличных частей в 1С, чтобы данные сразу отобразились на форме

Программист 1С v8.3 (Управляемые формы)
← На главную

В конфигурациях, построенных на базе прикладных решений для государственных учреждений (например, БГУ), существует мощный механизм дополнительных табличных частей. Он позволяет пользователю в режиме «1С:Предприятие» добавлять новые колонки в существующие документы без изменения конфигурации. Однако перед разработчиками часто встает задача: как сделать так, чтобы эти колонки заполнялись автоматически при изменении других данных (например, номенклатуры), и при этом значения сразу появлялись на экране без перезаписи документа?

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

Анализ проблемы: почему данные не видны в интерфейсе

Рассмотрим ситуацию: разработчик создает событие ПриИзменении для номенклатуры. В коде он находит нужную дополнительную колонку через запрос к справочнику КолонкиДополнительныхТабличныхЧастей и записывает новое значение напрямую в регистр сведений ЗначенияКолонокДополнительныхТабличныхЧастей. С точки зрения базы данных всё верно — запись создана. Но пользователь видит пустую ячейку.

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

  1. Дополнительные колонки не являются частью метаданных документа. Они добавляются на форму динамически в момент ее создания на сервере.
  2. Для отображения этих данных платформа создает программные реквизиты формы.
  3. Когда вы записываете данные напрямую в регистр, вы меняете состояние базы данных (на диске), но не меняете состояние данных формы (в оперативной памяти). Форма «не знает», что в регистре что-то изменилось, пока вы не перечитаете объект целиком или не обновите данные программно.

Проанализируем типичный (но не совсем полный) код получения метаданных колонки:


ЗапросДОП = Новый Запрос;
ЗапросДОП.Текст =
"ВЫБРАТЬ
|    ДополнительныеТабличныеЧастиДокументов.Ссылка КАК ТаблЧасть,
|    КолонкиДополнительныхТабличныхЧастей.Ссылка КАК КолонкаТаблЧасть
|ИЗ
|    Справочник.КолонкиДополнительныхТабличныхЧастей КАК КолонкиДополнительныхТабличныхЧастей
|    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДополнительныеТабличныеЧастиДокументов КАК ДополнительныеТабличныеЧастиДокументов
|        ПО КолонкиДополнительныхТабличныхЧастей.Владелец = ДополнительныеТабличныеЧастиДокументов.Ссылка
|ГДЕ
|    ДополнительныеТабличныеЧастиДокументов.ИмяТабличнойЧасти = ""Материалы""
|    И ДополнительныеТабличныеЧастиДокументов.ИдентификаторДокумента.ПолноеИмя = ""Документ.АктСписанияМЗ""
|    И КолонкиДополнительныхТабличныхЧастей.Наименование = ""КФО""";

Результат = ЗапросДОП.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
    КФО = Результат.КолонкаТаблЧасть;
    ТаблЧасть = Результат.ТаблЧасть;
КонецЕсли;

Решение №1: Работа с программными реквизитами формы

Чтобы данные отобразились немедленно, нам нужно обратиться к строке табличной части на форме и установить значение в ту колонку, которая была создана динамически. Самое сложное здесь — выяснить имя реквизита, который платформа присвоила этой колонке.

Обычно в БГУ программные колонки именуются по определенному шаблону, включающему уникальный идентификатор или имя из справочника. Разберем алгоритм действий:

  1. Выясним имя программного реквизита. Это можно сделать в отладчике, исследовав коллекцию Элементы.Материалы.ПодчиненныеЭлементы или структуру ЭтотОбъект (реквизиты формы).
  2. В обработчике ПриИзменении получим текущую строку.
  3. Присвоим значение непосредственно реквизиту строки.

Пример правильного подхода в коде формы:


&НаКлиенте
Процедура МатериалыНоменклатураПриИзменении(Элемент)
    
    СтрокаТЧ = Элементы.Материалы.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Вызываем серверную процедуру для получения метаданных и заполнения
    ЗаполнитьДопКолонкуНаСервере(СтрокаТЧ.НомерСтроки);
    
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДопКолонкуНаСервере(НомерСтроки)
    
    // Находим строку в объекте (данные формы)
    ТекущаяСтрока = Объект.Материалы.НайтиСтрокуПоНомеру(НомерСтроки);
    
    // Здесь определяем имя динамического реквизита. 
    // В БГУ это часто выглядит как "ДополнительнаяКолонка_" + ID
    ИмяРеквизита = "ДопКолонка_КФО"; // Имя нужно уточнить в вашей конфигурации
    
    Попытка
        // Устанавливаем значение прямо в данные формы
        ТекущаяСтрока[ИмяРеквизита] = ПредопределенноеЗначение("Перечисление.КВД.ВременноеРаспоряжение");
    Исключение
        // Если реквизит не найден, возможно, стоит использовать типовой метод
    КонецПопытки;
    
КонецПроцедуры

Решение №2: Использование типовых методов конфигурации

Выясним, существуют ли в вашей программе специализированные модули для управления этим механизмом. В типовых решениях часто встречаются общие модули, такие как ДополнительныеТабличныеЧастиСервер или УправлениеДополнительнымиРеквизитамиИСведениями.

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

Решение №3: Метод ОбновитьИнтерфейс и ОповеститьОбИзменении

Если вы всё же решили записывать данные напрямую в регистр (например, из фонового процесса или сложной логики, не связанной напрямую с текущей строкой), вам потребуется заставить форму «перерисоваться».

Метод ОбновитьИнтерфейс() заставляет систему пересчитать видимость и доступность, но редко помогает обновить данные в строках. Более эффективным может быть использование механизма оповещений:


// После записи в регистр на сервере
ОповеститьОбИзменении(Тип("РегистрСведенийКлючЗаписи.ЗначенияКолонокДополнительныхТабличныхЧастей"));

Однако помните, что это приведет к обновлению всех открытых форм, работающих с этим регистром, что может вызвать кратковременное «замирание» интерфейса у пользователя.

Почему не стоит добавлять колонку в конфигураторе (как "костыль")

Иногда разработчики сдаются и просто добавляют нужную колонку в метаданные документа в конфигураторе. Проанализируем последствия этого шага:

Итоги и рекомендации

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

  1. Выясните внутреннее имя динамического реквизита формы, отвечающего за дополнительную колонку.
  2. В обработчике ПриИзменении основной колонки (например, Номенклатуры) на сервере обращайтесь к Объект.ИмяТабличнойЧасти.
  3. Устанавливайте значение непосредственно в строку табличной части через имя динамического реквизита.
  4. Не используйте МенеджерЗаписи регистра сведений внутри формы документа для изменения текущих строк — предоставьте форме самой записать эти данные при сохранении документа.

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

← На главную