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