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