Почему дополнительные реквизиты не отображаются на форме в 1С и как это исправить

Программист 1С v8.3 (Управляемые формы) Промышленность, строительство и АПК
← На главную

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

В чем заключается основная проблема?

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

Когда мы вызываем метод ПолучитьФорму(), платформа выполняет серверный вызов, в ходе которого подсистема управления свойствами анализирует объект, определяет нужный Набор свойств и программно добавляет на форму реквизиты и элементы (поля ввода). Если в момент этого вызова объект еще пустой, подсистема может не найти нужный набор свойств или не увидеть значений, которые нужно отобразить. Последующее заполнение табличной части ДополнительныеРеквизиты в коде на клиенте не приводит к автоматической «перерисовке» формы, так как элементы уже были созданы на основе исходного состояния объекта.

Рассмотрим пошагово, как обойти это ограничение и какие методы являются наиболее эффективными.

Способ 1. Прямое заполнение динамических реквизитов формы

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

Выполним следующие действия. Сначала создадим процедуру на клиенте, которая будет сопоставлять данные из объекта с реквизитами формы:


&НаКлиенте
Процедура УправлениеСвойствами_ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект)
    // В типовых формах описание созданных реквизитов хранится в специальной коллекции
    СписокСвойств = Форма.Свойства_ОписаниеДополнительныхРеквизитов;
    
    Если СписокСвойств.Количество() > 0 Тогда
        Для каждого СтрокаРеквизита Из Объект.ДополнительныеРеквизиты Цикл
            // Ищем описание свойства в динамической коллекции формы
            НайденныеСтроки = СписокСвойств.НайтиСтроки(Новый Структура("Свойство", СтрокаРеквизита.Свойство));
            
            Если НайденныеСтроки.Количество() > 0 Тогда
                // Получаем внутреннее имя реквизита формы
                ИмяРеквизитаНаФорме = НайденныеСтроки[0].ИмяРеквизитаЗначение;        
                // Устанавливаем значение напрямую в реквизит формы
                Форма[ИмяРеквизитаНаФорме] = СтрокаРеквизита.Значение;
            КонецЕсли;         
        КонецЦикла; 
    КонецЕсли; 
КонецПроцедуры

Теперь проанализируем, как правильно вызвать эту логику при программном открытии формы:


&НаКлиенте
Процедура ОткрытьФормуСДопРеквизитами()
    // 1. Получаем форму объекта
    Форма = ПолучитьФорму("Справочник.ДоговорыМеждуОрганизациями.ФормаОбъекта");
    
    // 2. Извлекаем объект из формы для заполнения
    ДанныеОбъекта = Форма.Объект;
    
    // 3. Заполняем данные (на сервере или клиенте)
    // Предположим, здесь происходит заполнение ДанныеОбъекта.ДополнительныеРеквизиты
    ЗаполнитьДанныеДоговораНаСервере(ДанныеОбъекта);
    
    // 4. Копируем заполненные данные обратно в объект формы
    КопироватьДанныеФормы(ДанныеОбъекта, Форма.Объект);
    
    // 5. КРИТИЧЕСКИЙ ШАГ: принудительно заполняем динамические поля формы
    УправлениеСвойствами_ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Форма.Объект);
    
    // 6. Открываем форму
    Форма.Открыть();
КонецПроцедуры

Способ 2. Использование параметров заполнения (Рекомендуемый путь БСП)

Вместо того чтобы вручную манипулировать формой после её получения, мы можем использовать стандартный механизм 1С — параметры заполнения. Подсистема свойств БСП интегрирована в процесс создания новой формы и умеет обрабатывать структуру ЗначенияЗаполнения.

Разберем, как это реализовать. Вместо ПолучитьФорму() используем ОткрытьФорму() с передачей параметров. В ключе ЗначенияЗаполнения можно передать структуру, где будут указаны значения как основных, так и дополнительных реквизитов.


&НаКлиенте
Процедура ОткрытьЧерезПараметры()
    ПараметрыЗаполнения = Новый Структура;
    ПараметрыЗаполнения.Вставить("Организация", СсылкаНаОрганизацию);
    
    // Для доп. реквизитов БСП ожидает массив структур или определенную структуру
    // Однако самый простой способ - передать их через обработку заполнения в модуле объекта
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
    
    ОткрытьФорму("Справочник.ДоговорыМеждуОрганизациями.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры

Если логика заполнения сложная, лучше всего реализовать её в модуле объекта в процедуре ОбработкаЗаполнения. Тогда при открытии формы подсистема свойств автоматически увидит уже заполненную табличную часть ДополнительныеРеквизиты на самом раннем этапе инициализации формы на сервере и корректно создаст все элементы интерфейса.

Способ 3. Использование параметра «ЗначенияСвойств»

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


&НаКлиенте
Процедура ОткрытьСПараметромЗначенияСвойств()
    СвойстваДляЗаполнения = Новый Структура;
    СвойстваДляЗаполнения.Вставить(СсылкаНаСвойствоПроект, ЗначениеПроекта);
    СвойстваДляЗаполнения.Вставить(СсылкаНаСвойствоСрокДействия, ТекущаяДата());
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗначенияСвойств", СвойстваДляЗаполнения);
    
    ОткрытьФорму("Справочник.ДоговорыМеждуОрганизациями.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры

Почему Форма.Прочитать() не помогает?

Многие разработчики пытаются вызвать метод Форма.Прочитать(), надеясь, что форма обновит свои данные. Выясним причину неудачи. Метод Прочитать() предназначен для перечитывания данных из базы данных в объект формы. Если вы создаете новый объект и еще не записали его, то в базе данных ничего нет. Вызов Прочитать() просто очистит все программные изменения, которые вы внесли в Форма.Объект перед открытием, вернув его в исходное (пустое) состояние.

Также важно помнить о контексте вызовов. Процедура УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме() является серверной и часто находится в общем модуле, который не доступен на клиенте. Более того, передать объект Форма с клиента на сервер напрямую нельзя. Именно поэтому решение из Способа 1 предполагает работу в контексте клиента с использованием доступных свойств формы.

Важные рекомендации по работе с БСП

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

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

← На главную