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

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

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

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

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

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

Ниже разобраны оба сценария с примерами кода для управляемых форм, способ через расширение конфигурации, проверка результата и типичные ошибки. Примеры ориентированы на платформу 1С:Предприятие 8.3 с управляемым интерфейсом.

Определяем, какой реквизит нужен: хранимый или временный

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

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

Маршрут решения

Как выбрать способ

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

Добавление хранимого реквизита через конфигуратор

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

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

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

Добавление реквизита через расширение конфигурации

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

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

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

Программное добавление реквизита на форму через ИзменитьРеквизиты

Динамический сценарий реализуется в модуле формы, обычно в обработчике ПриСозданииНаСервере. Метод формы ИзменитьРеквизиты() принимает два массива: добавляемые и удаляемые реквизиты. Каждый новый реквизит описывается объектом ОписаниеРеквизитаФормы (в новых версиях платформы — конструктор Новый ОписаниеРеквизитаФормы либо РеквизитФормы через ДобавитьРеквизитФормы, в зависимости от версии платформы).

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

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

ОписаниеТипа = Новый ОписаниеТипов("Булево");

НовыйРеквизит = Новый РеквизитФормы(

"Отобрана", // имя реквизита

ОписаниеТипа, // тип

"Объект.Товары", // путь к табличной части

"Отобрана", // заголовок

Ложь); // сохраняемые данные

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

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

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

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

bsl
НовыйРеквизит = Новый РеквизитФормы("Отобрана", Новый ОписаниеТипов("Булево"), "Объект.Товары", "Отобрана", Ложь); ДобавляемыеРеквизиты.Добавить(НовыйРеквизит); ИзменитьРеквизиты(ДобавляемыеРеквизиты);

Создание колонки таблицы и привязка к данным

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

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

НоваяКолонка.Вид = ВидПоляФормы.ПолеФлажка;

НоваяКолонка.ПутьКДанным = "Объект.Товары.Отобрана";

НоваяКолонка.Заголовок = "Отобрана";

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

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

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

Заполнение нового реквизита и обработка строк

После добавления реквизита к нему обращаются как к обычному полю строки табличной части. В серверном коде объекта — через Строка.Отобрана, на форме — через Элементы.Товары.ТекущиеДанные.Отобрана или перебором коллекции Объект.Товары.

Для Каждого СтрокаТовары Из Объект.Товары Цикл

Если СтрокаТовары.Количество > 0 Тогда

СтрокаТовары.Отобрана = Истина;

КонецЕсли;

КонецЦикла;

Если реквизит добавлен в метаданные и должен участвовать в проведении, дополните модуль объекта: обращение к новому полю в запросе по табличной части выполняется стандартно, как Товары.Отобрана. Не забудьте, что в уже существующих документах реквизит пуст — при необходимости выполните разовую обработку заполнения для исторических данных.

Проверка результата и типичные ошибки

Проверку выполняйте в три этапа. Сначала убедитесь, что форма открывается без ошибок и колонка видна. Затем проверьте ввод и сохранение значения: для хранимого реквизита — перезапишите и перепроведите документ, закройте и откройте форму; значение должно сохраниться. Для динамического реквизита поведение обратное: после переоткрытия формы значения обнуляются, и это норма. Наконец, проверьте сценарии проведения, печати и обменов, если реквизит в них задействован.

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

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

Открытие формы
Норма

Форма открывается, колонка отображается в таблице

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

Ошибка «Поле объекта не обнаружено» — несовпадение пути к данным

Сохранение значения (хранимый реквизит)
Норма

Значение сохраняется после записи и переоткрытия

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

Значение теряется — реквизит создан только на форме, а не в метаданных

Проведение документа
Норма

Движения формируются с учётом нового реквизита

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

Ошибка в запросе модуля проведения — реквизит не добавлен в метаданные

Обновление типовой конфигурации
Норма

Расширение применяется без конфликтов

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

Конфликт имён — реквизит добавлен без уникального префикса

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

Отдельного внимания заслуживает ситуация с обменами и подписками на события. Если новый хранимый реквизит должен передаваться в другие базы, его нужно добавить в план обмена и, при необходимости, в правила конвертации. Автоматически в обмен он не попадёт.

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

Ограничения и границы безопасной работы

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

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

Итог

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

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

Частые вопросы

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

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

Почему после ИзменитьРеквизиты() колонка не появилась в таблице?

Метод создаёт только данные, а не визуальный элемент. Нужно дополнительно добавить элемент формы типа ПолеФормы в таблицу и установить его свойство ПутьКДанным вида «Объект.Товары.ИмяРеквизита». Также проверьте, что путь при создании реквизита и путь к данным колонки совпадают полностью.

Как добавить реквизит в табличную часть типового документа, не снимая конфигурацию с поддержки?

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

Что будет со значениями нового реквизита в уже существующих документах?

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

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

Да, механизм тот же: реквизит добавляется с путём к реквизиту формы типа «ТаблицаЗначений», затем создаётся элемент-колонка. Для динамических списков состав полей определяется запросом, поэтому туда добавляют не реквизиты, а поля через настройки списка или схему компоновки данных.

Выдаётся ошибка «Реквизит с таким именем уже существует» при повторном вызове — что делать?

Перед повторным добавлением сформируйте массив удаляемых реквизитов с тем же именем и передайте его вторым параметром в ИзменитьРеквизиты() вместе с массивом добавляемых. Либо проверяйте существование реквизита через ПолучитьРеквизиты() и добавляйте только при отсутствии.