Как программно добавить дополнительные сведения в документ 1С 8.3?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При разработке и доработке конфигураций на платформе 1С (особенно в типовых решениях, таких как "Бухгалтерия предприятия") часто возникает необходимость расширить состав данных документа без изменения самой конфигурации. Для этого используется механизм дополнительных реквизитов и сведений. Давайте подробно разберем, как программно создавать и заполнять дополнительные сведения, проанализируем частые ошибки новичков и рассмотрим лучшие практики разработки.

Разбор типичной ошибки при записи в регистр

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


&НаСервере
Процедура СоздатьДопСведенияНаСервере()
    Набор = РегистрыСведений.ДополнительныеСведения.СоздатьНаборЗаписей();
    НоваяСтрокаНабора = Набор.Добавить();
    НоваяСтрокаНабора.Объект = Документы.АктСверкиВзаиморасчетов; // ОШИБКА ЗДЕСЬ
    НоваяСтрокаНабора.Свойство = "Свойство";
    НоваяСтрокаНабора.Значение = "лалала";
    Набор.Записать();
КонецПроцедуры

Этот код вызовет ошибку: Запись не верна! Значение поля "Объект" не может быть пустым!. Выясним причину. В коде в поле Объект передается Документы.АктСверкиВзаиморасчетов, что является объектом типа Менеджер документа. Однако измерение Объект в регистре сведений ДополнительныеСведения имеет тип Ссылка на документ. Нам необходимо передавать ссылку на конкретный экземпляр документа, для которого формируются эти допсведения, а не весь класс документов.

Кроме того, в поле Свойство передается обычная строка, в то время как там должна быть ссылка на элемент Плана видов характеристик (ПВХ).

Понимание архитектуры механизма

Прежде чем писать правильный код, проанализируем, как устроен этот механизм в 1С. Важно понимать разницу между терминами:

  1. Дополнительные реквизиты — хранятся внутри самого объекта (в специальной табличной части). Визуально они располагаются прямо на форме документа. Если их изменить, сам документ становится модифицированным, и его нужно перепроводить/записывать.
  2. Дополнительные сведения — хранятся в независимом регистре сведений ДополнительныеСведения. Они открываются по отдельной кнопке (значок с папкой и листом) на форме. Их главное преимущество: для добавления отметки пользователю не нужно перепроводить документ (достаточно прав на изменение самих доп. сведений).

Чтобы сведение появилось в системе, нам нужно взаимодействовать с тремя объектами:

Программное создание свойства в ПВХ и привязка к набору

Рассмотрим по шагам, как программно создать новое дополнительное сведение, если его еще нет в базе. В примере ниже мы создаем сведение для документа ЗаказНаряд.


Процедура ДобавлениеДополнительныхСведений()
    ИмяРеквизита = "TOS_Test";
    
    // Включим константу использования, если она выключена
    Если Не Константы.ИспользоватьДополнительныеРеквизитыИСведения.Получить() Тогда
        Константы.ИспользоватьДополнительныеРеквизитыИСведения.Установить(Истина);
    КонецЕсли;

    // Попробуем найти реквизит по наименованию
    ДопРеквизитСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию(ИмяРеквизита);
    
    Если НЕ ЗначениеЗаполнено(ДопРеквизитСсылка) Тогда
        // Создаем новый элемент ПВХ
        ДопРеквизитОбъект = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.СоздатьЭлемент();
        ДопРеквизитОбъект.Наименование = ИмяРеквизита;
        ДопРеквизитОбъект.ТипЗначения = Новый ОписаниеТипов("Строка",,,,Новый КвалификаторыСтроки(250));
        ДопРеквизитОбъект.Виден = Истина;
        ДопРеквизитОбъект.Доступен = Истина;
        ДопРеквизитОбъект.Заголовок = ИмяРеквизита;
        ДопРеквизитОбъект.Имя = СтрЗаменить(ИмяРеквизита," ","");
        ДопРеквизитОбъект.НаборСвойств = Справочники.НаборыДополнительныхРеквизитовИСведений.Документ_ЗаказНаряд;
        ДопРеквизитОбъект.ЭтоДополнительноеСведение = Истина;
        ДопРеквизитОбъект.ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеСведения;
        
        ДопРеквизитОбъект.Записать();
        ДопРеквизитСсылка = ДопРеквизитОбъект.Ссылка;
    КонецЕсли;

    // Добавим наше сведение в набор дополнительных реквизитов документа
    НаборДополнительныхРеквизитов = Справочники.НаборыДополнительныхРеквизитовИСведений.Документ_ЗаказНаряд.ПолучитьОбъект();
    
    Если НаборДополнительныхРеквизитов.ДополнительныеСведения.Найти(ДопРеквизитСсылка, "Свойство") = Неопределено Тогда
        Стр = НаборДополнительныхРеквизитов.ДополнительныеСведения.Добавить();
        Стр.Свойство = ДопРеквизитСсылка;
        НаборДополнительныхРеквизитов.Записать();
    КонецЕсли;
КонецПроцедуры

Запись значения с помощью менеджера записи (базовый подход)

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


// Получаем нужный номер для печати
нм = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(ЭтотОбъект.Номер, Истина, Истина); 

// Находим нужное свойство в ПВХ
ДополнительныеСведения = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("№ счета 1С (Печатный)", Истина); 

// Записываем значение в независимый регистр
МенеджерЗаписи = РегистрыСведений.ДополнительныеСведения.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = ЭтотОбъект.Ссылка; // Передаем корректную ссылку на документ!
МенеджерЗаписи.Свойство = ДополнительныеСведения;
МенеджерЗаписи.Значение = нм;
МенеджерЗаписи.Записать(Истина);

Лучшие практики и работа через БСП (Библиотеку стандартных подсистем)

Хотя пример с менеджером записи работает, в современных конфигурациях на базе БСП (например, в Бухгалтерии 3.0) не рекомендуется писать данные напрямую в регистр. Для этих целей существует готовый программный интерфейс (API).

Рассмотрим подробнее правильный метод записи через БСП. Для записи значений используется общий модуль УправлениеСвойствами. Этот метод автоматически обрабатывает все проверки, блокировки и транзакции.


ТаблицаСвойств = Новый ТаблицаЗначений;
ТаблицаСвойств.Колонки.Добавить("Свойство");
ТаблицаСвойств.Колонки.Добавить("Значение");

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.Свойство = СсылкаНаНашеСвойство;
НоваяСтрока.Значение = "Наше значение";

// Вызов стандартного метода БСП
УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(СсылкаНаДокумент, ТаблицаСвойств);

Важные замечания:

  1. Выбор типа данных: Если перед вами стоит задача создать сведение для отметки (например, бухгалтер хочет помечать "Документ с ошибкой"), не используйте тип Строка. Гораздо правильнее при создании ПВХ указать тип Булево. Это позволит легко делать отборы в динамических списках и отчетах. В коде это выглядит так: ДопРеквизитОбъект.ТипЗначения = Новый ОписаниеТипов("Булево");.
  2. Обновление формы: Если ваша обработка записывает значение в регистр, пока документ открыт у пользователя на экране, визуально ничего не изменится. Чтобы новые данные отобразились сразу, на клиенте после серверного вызова нужно выполнить метод ОповеститьОбИзменении(СсылкаНаДокумент);.
  3. Исторические данные: Создание свойства в ПВХ и привязка к набору не заполнит это свойство в старых документах. У них значение будет Неопределено. Если по логике задачи у всех прошлых документов должно стоять значение по умолчанию (например, Ложь для "Есть ошибка"), потребуется написать разовую обработку для пакетной записи значений во все нужные документы через цикл.
← На главную