К статье
Практический материал

Разработка и Конфигурация · 10 мин

1С: как программно добавить колонку реквизита

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

Задача добавить колонку реквизита программно возникает, когда структуру формы нельзя задать статически в конфигураторе: состав колонок зависит от настроек пользователя, данных в базе или внешних источников. В управляемых формах 1С это делается через программное изменение реквизитов формы и элементов формы, а в обычных формах — через коллекции колонок табличного поля.

Важно различать три разные ситуации, которые часто путают. Первая — добавить колонку в таблицу значений или табличную часть объекта (изменение состава данных). Вторая — добавить реквизит формы и связанную с ним колонку таблицы на форме (изменение представления). Третья — изменить состав колонок динамического списка или отчёта на СКД. В каждом случае используются свои объекты и методы платформы.

Ниже разобраны основные сценарии с готовым кодом, ограничениями платформы и способами проверить результат. Примеры ориентированы на управляемое приложение, но раздел про обычные формы тоже приведён.

Добавление колонки в таблицу значений и табличную часть

Самый простой случай — колонка нужна только в данных, без отображения на форме. Для таблицы значений используется коллекция Колонки с методом Добавить(), которому передаются имя колонки, описание типа, заголовок и ширина.

ТаблицаДанных = Новый ТаблицаЗначений;

ТаблицаДанных.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТаблицаДанных.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), "Цена", 12);

ТаблицаДанных.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200)));

У табличной части объекта (документа, справочника) состав колонок фиксируется в конфигураторе — программно добавить в неё новый реквизит в режиме предприятия нельзя. Если колонки должны меняться динамически, используют реквизит формы типа «ТаблицаЗначений», а не табличную часть объекта. Это принципиальное ограничение платформы, и попытка обойти его через изменение конфигурации кодом приведёт к необходимости обновления конфигурации базы данных.

Имя колонки должно удовлетворять правилам имён переменных: начинаться с буквы, не содержать пробелов и спецсимволов. Если имя уже существует, метод вернёт существующую колонку, поэтому перед добавлением полезно проверять наличие через Колонки.Найти(ИмяКолонки).

Добавление реквизита формы и колонки в управляемой форме

В управляемой форме отображение отделено от данных. Чтобы вывести новую колонку в таблицу на форме, нужно сначала добавить реквизит в таблицу значений формы, а затем создать элемент формы, который этот реквизит покажет. Всё это делается на сервере, обычно в обработчике ПриСозданииНаСервере или в отдельной серверной процедуре.

&НаСервере

Процедура ДобавитьКолонкуНаСервере()

ДобавляемыеРеквизиты = Новый Массив;

НовыйРеквизит = Новый РеквизитФормы("Скидка",

Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2)),

"Товары", "Скидка", Истина);

ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);

ИзменитьРеквизиты(ДобавляемыеРеквизиты);

НовыйЭлемент = Элементы.Добавить("ТоварыСкидка", Тип("ПолеФормы"), Элементы.Товары);

НовыйЭлемент.ПутьКДанным = "Товары.Скидка";

НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;

НовыйЭлемент.Заголовок = "Скидка";

КонецПроцедуры

Ключевые моменты кода: конструктор РеквизитФормы принимает имя, тип, путь (имя таблицы-владельца), заголовок и признак сохраняемости. Метод ИзменитьРеквизиты() применяет изменения — до его вызова реквизита в данных формы не существует, и обращение к Товары.Скидка вызовет ошибку. Только после изменения реквизитов создаётся элемент формы с привязкой ПутьКДанным.

Если колонок много и их состав известен заранее, удобно формировать массив реквизитов в цикле по описанию структуры, а затем вызывать ИзменитьРеквизиты() один раз — это быстрее и меньше нагружает форму, чем последовательные изменения.

Удаление и повторное добавление колонок

Типичный сценарий — колонки перестраиваются при изменении настройки. Здесь есть тонкость: удалить реквизит формы можно тем же методом ИзменитьРеквизиты(), передав вторым параметром массив удаляемых имён (полных путей), а элемент формы удаляется через Элементы.Удалить().

УдаляемыеРеквизиты = Новый Массив;

УдаляемыеРеквизиты.Добавить("Товары.Скидка");

ИзменитьРеквизиты(Новый Массив, УдаляемыеРеквизиты);

Элементы.Удалить(Элементы.ТоварыСкидка);

Порядок важен: сначала удаляют элемент формы или реквизит, но не пытаются удалить элемент, чей ПутьКДанным уже указывает на несуществующий реквизит в момент перерисовки. Безопасная последовательность — удалить элемент формы, затем удалить реквизит. При повторном добавлении используйте те же имена или генерируйте уникальные, чтобы не получить конфликт имён.

Порядок действий
  1. 1
    Определите, где нужна колонка: в данных (таблица значений) или на форме
  2. 2
    Для формы: создайте РеквизитФормы и примените ИзменитьРеквизиты() на сервере
  3. 3
    Добавьте элемент формы через Элементы.Добавить() с указанием родителя-таблицы
  4. 4
    Установите ПутьКДанным, Вид, Заголовок и при необходимости ширину
  5. 5
    Проверьте заполнение данных и отображение в режиме предприятия

Добавление колонки в динамический список и отчёт СКД

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

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

Сравнение вариантов

Колонки.Добавить() таблицы значений

Подходит для программных данных без формы. Быстро, но не отображается автоматически.

ИзменитьРеквизиты() + Элементы.Добавить()

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

Настройки СКД

Для отчётов и списков на компоновке. Гибко, но поле обязано быть в наборе данных.

Изменение конфигурации

Единственный способ добавить реквизит в табличную часть объекта. Требует обновления конфигурации БД.

Обычные формы: добавление колонки в табличное поле

В обычном приложении механика другая: у табличного поля есть коллекция Колонки, и колонка добавляется напрямую с привязкой к данным через свойство Данные или ДанныеФлажка.

НоваяКолонка = ЭлементыФормы.Товары.Колонки.Добавить("Скидка", "Скидка");

НоваяКолонка.Данные = "Скидка";

НоваяКолонка.Ширина = 10;

НоваяКолонка.ЭлементУправления.ТипЗначения = Новый ОписаниеТипов("Число");

Если табличное поле связано с табличной частью объекта, добавленная вручную колонка не получит данные автоматически — источником должен быть реквизит, существующий в данных. Поэтому в обычных формах чаще привязывают табличное поле к таблице значений, где состав колонок полностью контролируется кодом.

Частые ошибки и как их проверить

Наиболее распространённая ошибка — создание элемента формы до вызова ИзменитьРеквизиты(). Платформа не найдёт путь к данным и выдаст ошибку «Поле не найдено». Вторая типичная проблема — попытка добавить реквизит на клиенте: метод ИзменитьРеквизиты() недоступен в клиентском контексте, директива &НаСервере обязательна.

Ещё одна группа ошибок связана с именами: кириллица в именах допустима, но смешение с уже существующими именами элементов приводит к исключению «Элемент с таким именем уже существует». При динамической генерации добавляйте префикс или проверяйте Элементы.Найти(Имя) перед добавлением.

Типичные ошибки
01
Создание элемента формы до ИзменитьРеквизиты() — ошибка «Поле не найдено»
02
Вызов ИзменитьРеквизиты() на клиенте — метод недоступен, нужен серверный контекст
03
Добавление колонки с именем, которое уже занято — исключение при выполнении
04
Попытка программно добавить реквизит в табличную часть объекта — это возможно только через конфигуратор
05
Забытый ПутьКДанным у нового элемента — колонка видна, но пустая

Проверка результата проста: откройте форму в режиме предприятия, убедитесь, что колонка отображается, содержит данные и позволяет редактирование (если задан вид «Поле ввода»). Дополнительно проверьте сценарий повторного открытия формы и смены настроек — именно там всплывают конфликты имён и утечки старых реквизитов.

Контрольные точки

Как проверить результат

Колонка видна в таблице формы
Норма

Отображается с заданным заголовком и шириной

Тревожный признак

Колонки нет или ошибка при открытии формы

Данные в колонке
Норма

Значения заполняются и редактируются

Тревожный признак

Колонка пустая при заполненных данных

Повторное открытие формы
Норма

Нет ошибок, состав колонок корректен

Тревожный признак

Исключение о дублировании имени элемента

FAQ

Можно ли программно добавить реквизит в табличную часть документа?

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

Почему после ИзменитьРеквизиты() пропали настройки динамического списка?

Метод пересоздаёт данные формы, и часть динамических настроек может сбрасываться. Сохраните настройки перед вызовом и восстановите после, либо вызывайте изменение реквизитов один раз при создании формы, до инициализации настроек.

Как добавить колонку с флажком, а не с полем ввода?

При создании элемента формы установите Вид = ВидПоляФормы.ПолеФлажка, а тип реквизита задайте как Булево. Тогда колонка отобразится в виде флажков без дополнительной настройки.

Можно ли добавить колонку в форму списка справочника?

Да, если список — динамический с разрешённым произвольным запросом: измените текст запроса, добавьте поле, затем создайте элемент формы с соответствующим ПутьКДанным. Для основного списка без произвольного запроса состав полей ограничен метаданными.

Как задать ширину и порядок новой колонки?

Ширина задаётся свойством элемента формы Ширина (в символах). Порядок определяется позицией среди подчинённых элементов таблицы — переместить элемент можно методом Элементы.Переместить() относительно соседней колонки.

Работает ли ИзменитьРеквизиты() во внешней обработке?

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

Итог

Что важно запомнить

Колонка на управляемой форме создаётся парой действий: РеквизитФормы + ИзменитьРеквизиты() на сервере, затем Элементы.Добавить() с ПутьКДанным. Для таблицы значений достаточно Колонки.Добавить(). Табличную часть объекта программно изменить нельзя — только через конфигуратор. Всегда проверяйте повторное открытие формы на конфликт имён.