Как программно получить данные из реквизита формы документа «Событие» в 1С:УНФ?

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

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

Почему данные не попадают в отчет?

Проанализируем архитектуру документа Событие. В отличие от многих других документов, где поле «Контрагент» является реальным реквизитом объекта, в документе Событие в УНФ это зачастую реквизит формы. Это означает, что данные живут только в контексте открытого окна документа и не сохраняются напрямую в одноименное поле в таблице SQL.

Рассмотрим основные причины отсутствия данных в базе:

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

Способ 1. Синхронизация реквизитов формы с объектом

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

Посмотрим на пример процедуры, которая очищает текущих участников и записывает данные из реквизитов формы обратно в объект:


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

Эту логику следует вызывать в обработчике ПередЗаписьюНаСервере в модуле формы. Таким образом, при каждом сохранении документа данные будут гарантированно попадать в табличную часть Участники, которая уже доступна для запросов в отчетах.

Способ 2. Использование расширения для создания реального реквизита

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

  1. Создаем расширение и добавляем в него документ Событие.
  2. Добавляем новый реквизит объекта с типом СправочникСсылка.Контрагенты (или составным типом, если требуется).
  3. На форме документа связываем существующее поле ввода с этим новым реквизитом объекта вместо реквизита формы.
  4. Пишем обработку для разового заполнения этого нового поля на основе существующих данных из табличной части Участники.

Способ 3. Программное извлечение из системных настроек

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

Пример обращения к хранилищу (используется редко):


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

Проверка данных в регистре «Календарь событий»

Прежде чем приступать к кодингу, проанализируем ситуацию через консоль запросов. В УНФ существует регистр сведений Календарь событий. Часто система при проведении документа автоматически транслирует данные из формы или связанных структур в этот регистр. Если данные там есть, ваш отчет лучше строить не по документам, а по виртуальным таблицам этого регистра. Это обеспечит более высокую скорость работы и точность данных.

Рекомендации по исправлению существующих данных

Если документов накопилось много, и отчет по-прежнему пустой, необходимо написать простую обработку, которая «прогонит» документы. Алгоритм работы обработки должен быть следующим:

Важный нюанс: Помните, что в поле «Контакт» ТЧ Участники может храниться не только Контрагент, но и Контактное лицо. При написании запроса для отчета обязательно учитывайте тип данных и используйте конструкцию ВЫРАЗИТЬ(... КАК Справочник.Контрагенты), чтобы избежать пустых значений при обращении к реквизитам через точку.

← На главную