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