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