Как программно заполнить реквизиты, которых нет в структуре объекта 1С

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

При разработке в среде 1С программисты часто сталкиваются с ситуацией, когда на форме элемента (например, справочника «Проектные задачи») присутствуют поля, которые крайне важны для заполнения, но при попытке обратиться к ним через Объект.ИмяРеквизита в коде возникает ошибка. Разберемся, почему это происходит и как правильно передать данные в такие «невидимые» для основного объекта поля.

Поймем разницу между данными объекта и реквизитами формы

Прежде всего, нам необходимо проанализировать, где именно «живут» данные. В системе 1С существует четкое разделение:

  1. Реквизиты объекта: Они определены в конфигураторе в структуре справочника или документа. Эти данные физически хранятся в основной таблице базы данных. К ним мы обращаемся напрямую: НовыйОбъект.Наименование = "Текст";.
  2. Реквизиты формы: Это временные переменные, которые существуют только пока открыто окно (форма). Они могут использоваться для промежуточных расчетов, визуализации или управления интерфейсом.
  3. Дополнительные реквизиты (БСП): Это механизм «Библиотеки стандартных подсистем», который позволяет пользователям добавлять новые поля без изменения конфигурации. Визуально они выглядят как обычные поля, но программно хранятся в табличной части ДополнительныеРеквизиты.

Рассмотрим ситуацию, описанную в теме: автор пытается заполнить ДлительностьФакт, но этого поля нет в объекте ПланПроекта. Выясним причину и найдем способы решения.

Способ 1. Работа с дополнительными реквизитами (ТЧ объекта)

Если ваша конфигурация построена на базе БСП (ERP, КА, УНФ, Документооборот), то с высокой долей вероятности «скрытые» поля являются дополнительными реквизитами. Они не видны в структуре справочника в конфигураторе, но их можно увидеть в режиме «1С:Предприятие» в настройках состава дополнительных реквизитов.

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


// Создаем новый элемент справочника
НовыйПлан = Справочники.ПроектныеЗадачи.СоздатьЭлемент();
НовыйПлан.Наименование = "Новая задача проекта";

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

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

НовыйПлан.Записать();

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

Способ 2. Использование коллекции ДополнительныеСвойства

Иногда поле на форме не связано напрямую ни с реквизитом, ни с доп. реквизитами БСП, но оно влияет на логику записи. В таких случаях данные из формы передаются в модуль объекта через коллекцию ДополнительныеСвойства. Это «транспорт», который живет в памяти во время процесса записи.

Если мы создаем объект программно, мы можем вручную поместить туда данные, чтобы обработчики в модуле объекта (например, ПередЗаписью) их подхватили. Рассмотрим ситуацию:


ПланПроекта = Справочники.ПроектныеЗадачи.СоздатьЭлемент();
ПланПроекта.Наименование = "Этап 1";

// Передаем значение, которое ожидает логика модуля объекта
ПланПроекта.ДополнительныеСвойства.Вставить("ДлительностьФакт", 24);

// При вызове Записать() сработает внутренний код модуля, 
// который может записать это значение в связанный регистр или файл
ПланПроекта.Записать();

Способ 3. Запись в связанные регистры сведений

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

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


// Сначала создаем и записываем сам объект, чтобы получить ссылку
НоваяЗадача = Справочники.ПроектныеЗадачи.СоздатьЭлемент();
НоваяЗадача.Наименование = "Монтажные работы";
НоваяЗадача.Записать();

// Теперь записываем данные в регистр, который хранит показатели задач
МенеджерЗаписи = РегистрыСведений.ЗначенияПоказателейЗадач.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ПроектнаяЗадача = НоваяЗадача.Ссылка;
МенеджерЗаписи.Показатель = Справочники.ПоказателиЗадач.ДлительностьФакт;
МенеджерЗаписи.Значение = 48; // Значение в часах
МенеджерЗаписи.Записать();

Способ 4. Анализ логики вычисляемых полей

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

Рассмотрим порядок действий для проверки этой версии:

  1. Откроем модуль формы справочника в конфигураторе.
  2. Найдем процедуру ПриЧтенииНаСервере или ПриСозданииНаСервере.
  3. Посмотрим, не вычисляется ли значение реквизита формы программно на основе других дат.

Если это так, то ваша задача упрощается: вам не нужно искать реквизит «Длительность». Вам нужно просто программно заполнить базовые даты в объекте, а поле на форме заполнится само при открытии пользователем.

Рекомендации по поиску решения

Если вы все еще не нашли, куда записываются данные, воспользуйтесь Замером производительности:

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

Подведем итог. В 1С «просто полей на форме» не бывает, если они сохраняют свое значение. Они всегда куда-то записываются. Ваша задача как разработчика — проследить путь данных от элемента управления на форме до таблицы в базе данных. Чаще всего этим путем является либо табличная часть дополнительных реквизитов, либо связанный регистр сведений.

← На главную