Как определить статус страховки контрагента и вывести результат в параметр макета отчета в 1С (Управляемые формы)?

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

При работе с 1С:Предприятием часто возникает необходимость формировать отчеты, которые отображают актуальные статусы различных объектов, например, срок действия страховки контрагентов. В этой статье мы подробно разберем, как создать запрос для определения статуса страховки, сравнить ее дату окончания с текущей датой и вывести полученный результат в параметр макета внешнего отчета, работающего на управляемых формах.

Давайте пошагово рассмотрим процесс создания такого функционала, учитывая особенности работы с запросами и макетами в системе 1С:Предприятие.

1. Понимание логики запроса: получение актуальной даты страховки и определение статуса

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


МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания)
без дополнительных условий может привести к некорректному результату, поскольку вернет максимальную дату по всем договорам, а не по выбранному нами.

Чтобы получить актуальную дату страховки именно для того договора, который нас интересует, необходимо использовать агрегатную функцию МАКСИМУМ в сочетании с условием


ГДЕ Ссылка = &Договор
. Параметр

&Договор
будет передавать ссылку на конкретный элемент справочника "Договоры контрагентов", для которого мы хотим узнать статус страховки. Если же нам требуется получить статусы по нескольким договорам, мы можем сгруппировать результат по полю договора.

Для определения статуса страховки прямо в запросе мы используем конструкцию


ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ
. Мы будем сравнивать максимальную дату окончания страховки с текущей датой.

Рассмотрим пример запроса:


ВЫБРАТЬ
    ВЫБОР
        КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
            ТОГДА "Страховка просрочена"
        ИНАЧЕ "Страховка действует"
    КОНЕЦ КАК СтатусСтраховки
ИЗ
    Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
ГДЕ
    ДоговорыКонтрагентовСтраховка.Ссылка = &Договор

В этом запросе:

  1. Мы выбираем статус страховки, используя условное выражение
    
    ВЫБОР КОГДА
    
    .
  2. МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) находит последнюю дату окончания страховки для текущего договора.
  3. < &ТекущаяДата сравнивает эту максимальную дату с переданной текущей датой. Если дата окончания меньше текущей, то страховка просрочена.
  4. ИЗ Справочник.ДоговорыКонтрагентов.Страховка указывает, что мы работаем с табличной частью "Страховка" справочника "Договоры контрагентов".
  5. ГДЕ ДоговорыКонтрагентовСтраховка.Ссылка = &Договор – это критически важное условие, которое фильтрует данные по конкретному договору. Без него запрос вернет максимальную дату по всем договорам в базе, что не соответствует нашей задаче.

2. Установка параметров запроса и его выполнение

После того как мы определили текст запроса, необходимо установить значения для его параметров. В нашем случае это


&ТекущаяДата
и

&Договор
. Мы всегда рекомендуем использовать параметры в запросах, так как это повышает безопасность, читаемость и производительность кода.

Вот как это делается в коде 1С:


// Предположим, у нас есть ссылка на договор
// Например, это может быть реквизит формы или элемент списка
// СсылкаНаДоговор = Объект.Договор; 
// Для примера возьмем первую попавшуюся ссылку на договор, или передадим как параметр функции
// Допустим, мы хотим получить статус для определенного договора (замените на реальное значение)
// Например: СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПоКоду("000000001");

// Получаем текущую дату для сравнения
ТекущаяДата = ТекущаяДата();

// Создаем новый запрос
Запрос = Новый Запрос;

// Устанавливаем параметры запроса
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата);
// Если нам нужно получить статус для конкретного договора
// Запрос.УстановитьПараметр("Договор", СсылкаНаДоговор); 

// В данном контексте, если запрос нужен для одного конкретного договора, 
// то параметр &Договор должен быть установлен. 
// Однако, если вы хотите получить статусы для всех договоров, 
// то условие ГДЕ ДоговорыКонтрагентовСтраховка.Ссылка = &Договор нужно удалить,
// а также добавить ГРУППИРОВАТЬ ПО ДоговорыКонтрагентовСтраховка.Ссылка
// и в ВЫБРАТЬ добавить ДоговорыКонтрагентовСтраховка.Ссылка КАК Договор.
// Давайте адаптируем запрос для получения по одному договору, как в примере.
// Добавим заглушку для СсылкаНаДоговор, если она не определена выше
// Для демонстрации, давайте предположим, что мы передаем ссылку на договор в функцию или получаем ее откуда-то.
// Например, СсылкаНаДоговор = ПараметрыВыполнения.ДоговорКонтрагента;

// Для примера, если мы запускаем это в контексте формы объекта "ДоговорКонтрагента"
// СсылкаНаДоговор = Объект.Ссылка;

// Если мы формируем отчет для списка договоров, то запрос будет немного другим (см. далее).
// Сейчас сосредоточимся на одном договоре.
// Для демонстрации, давайте просто возьмем любой договор из базы.
// Если это отчет, то СсылкаНаДоговор обычно передается как параметр формы отчета.
// Предположим, что СсылкаНаДоговор уже определена и содержит ссылку на интересующий нас договор.
// Например: СсылкаНаДоговор = НекийПараметрФормыОтчета.Договор;

// Добавляем текст запроса
Запрос.Текст = "ВЫБРАТЬ
    |    ВЫБОР
    |        КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
    |            ТОГДА ""Страховка просрочена""
    |        ИНАЧЕ ""Страховка действует""
    |    КОНЕЦ КАК СтатусСтраховки
    |ИЗ
    |    Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
    |ГДЕ
    |    ДоговорыКонтрагентовСтраховка.Ссылка = &Договор";

// Устанавливаем параметр для конкретного договора. 
// !!! Важно: замените на реальный способ получения ссылки на договор !!!
// Например:
// Если мы формируем отчет по текущему элементу справочника:
// СсылкаНаДоговор = Объект.Ссылка;
// Если договор выбирается в форме отчета:
// СсылкаНаДоговор = МойРеквизитФормыДоговор;
// Для демонстрации возьмем первый попавшийся договор:
СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПервый(); 
Если СсылкаНаДоговор = Неопределено Тогда
    Сообщить("Не найден ни один договор для демонстрации. Создайте хотя бы один договор.");
    Возврат;
КонецЕсли;

Запрос.УстановитьПараметр("Договор", СсылкаНаДоговор); 

// Выполняем запрос
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();

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

Сообщить("Статус страховки для договора " + СсылкаНаДоговор + ": " + СтатусСтрахования);

// Если нам нужно получить статусы для множества договоров, 
// то запрос будет выглядеть так (используем ГРУППИРОВАТЬ ПО):
ЗапросМножество = Новый Запрос;
ЗапросМножество.Текст = "ВЫБРАТЬ
    |    ДоговорыКонтрагентовСтраховка.Ссылка КАК Договор,
    |    ВЫБОР
    |        КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
    |            ТОГДА ""Страховка просрочена""
    |        ИНАЧЕ ""Страховка действует""
    |    КОНЕЦ КАК СтатусСтраховки
    |ИЗ
    |    Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
    |ГРУППИРОВАТЬ ПО
    |    ДоговорыКонтрагентовСтраховка.Ссылка";

ЗапросМножество.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
ТЗРезультат = ЗапросМножество.Выполнить().Выгрузить();

// Теперь ТЗРезультат содержит колонки "Договор" и "СтатусСтраховки" для всех договоров.

Важно отметить, что метод Запрос.Выполнить().Выгрузить() возвращает


ТаблицуЗначений
, что удобно для последующей итерации по результатам, особенно если ожидается несколько строк.

3. Работа с макетами и вывод данных в ТабличныйДокумент (Управляемые формы)

Теперь, когда мы умеем получать статус страховки, нам нужно вывести его в отчет. Для этого мы будем использовать макет отчета и объект


ТабличныйДокумент
. В управляемых формах есть свои особенности при получении макета.

3.1. Получение макета в управляемых формах

В обычных формах функция ПолучитьМакет("ИмяМакета") вызывается напрямую. Однако в управляемых формах ПолучитьМакет является методом объекта отчета. Поэтому для получения макета нам нужно обратиться к текущему объекту формы. Обычно это делается так:


// В модуле формы отчета, например, в процедуре формирования отчета
&НаСервере
Функция ПолучитьМакетОтчетаНаСервере()
    Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетОтчета");
КонецФункции

// В основной процедуре формирования отчета:
Макет = ПолучитьМакетОтчетаНаСервере();

Здесь


"Объект"
– это стандартный реквизит формы, который представляет собой объект отчета, а

"МакетОтчета"
– это имя вашего макета, которое вы задали в конфигураторе.

3.2. Получение областей макета и заполнение параметров

Макеты в 1С состоят из именованных областей (например, "Заголовок", "Шапка", "Строка"). Внутри этих областей вы можете определить параметры, которые будут заполняться программно. Параметры в макете обозначаются так:


[ИмяПараметра]
.

Для доступа к области используется метод Макет.ПолучитьОбласть("ИмяОбласти"). Затем параметры области можно заполнить напрямую:


ОбластьШапка.Параметры.strah = СтатусСтрахования;

Где


strah
— это имя параметра, определенного в макете, а

СтатусСтрахования
— это значение, полученное из запроса.

3.3. Вывод данных в ТабличныйДокумент

Для отображения отчета пользователю мы используем объект


ТабличныйДокумент
. В него последовательно выводятся области макета. В конце работы

ТабличныйДокумент
отображается пользователю.

Теперь давайте соберем весь код вместе, включая запрос, получение макета и вывод в


ТабличныйДокумент
. Предположим, что наш отчет формируется по одному выбранному договору, и мы хотим вывести статус страховки в область "Заголовок" макета.

4. Полный пример кода для формирования отчета

Представим, что у нас есть внешний отчет с макетом под названием "МакетОтчета", который содержит область "Заголовок" с параметром


strah
.


// Модуль формы отчета

// Функция для получения макета на сервере (для управляемых форм)
&НаСервере
Функция ПолучитьМакетОтчета()
    Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетОтчета");
КонецФункции

// Основная процедура формирования отчета (например, по кнопке "Сформировать")
&НаКлиенте
Процедура СформироватьОтчет(Команда)
    // Вызываем серверную процедуру для формирования и показа отчета
    СформироватьИПоказатьОтчетНаСервере();
КонецПроцедуры

&НаСервере
Процедура СформироватьИПоказатьОтчетНаСервере()

    // 1. Инициализация ТабличногоДокумента и получение макета
    ТАБ = Новый ТабличныйДокумент;
    Макет = ПолучитьМакетОтчета(); // Используем нашу серверную функцию
    
    // Проверяем, что макет успешно получен
    Если Макет = Неопределено Тогда
        Сообщить("Макет 'МакетОтчета' не найден. Проверьте имя макета в конфигураторе.");
        Возврат;
    КонецЕсли;

    // 2. Определение и установка параметров запроса
    ТекущаяДата = ТекущаяДата();
    
    // Предполагаем, что СсылкаНаДоговор передается как реквизит формы отчета
    // Например: СсылкаНаДоговор = ЭтаФорма.Элементы.ПолеВводаДоговор.Значение;
    // Или для демонстрации возьмем первый попавшийся договор
    СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПервый(); 

    Если СсылкаНаДоговор = Неопределено Тогда
        Сообщить("Для формирования отчета необходимо выбрать договор контрагента.", СтатусСообщения.Важное);
        Возврат;
    КонецЕсли;

    // 3. Создание и выполнение запроса
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    |    МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) КАК ДатаОкончания,
    |    ВЫБОР
    |        КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
    |            ТОГДА ""Страховка просрочена""
    |        ИНАЧЕ ""Страховка действует""
    |    КОНЕЦ КАК СтатусСтраховки
    |ИЗ
    |    Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
    |ГДЕ
    |    ДоговорыКонтрагентовСтраховка.Ссылка = &Договор";

    Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата);
    Запрос.УстановитьПараметр("Договор", СсылкаНаДоговор);

    РезультатЗапроса = Запрос.Выполнить().Выбрать();

    // 4. Получение результата запроса
    СтатусСтрахования = "Данные о страховке не найдены"; // Значение по умолчанию
    Если РезультатЗапроса.Следующий() Тогда
        // Проверяем, что ДатаОкончания не является NULL, то есть данные по страховке есть
        Если РезультатЗапроса.ДатаОкончания <> NULL Тогда
            СтатусСтрахования = РезультатЗапроса.СтатусСтраховки;
        КонецЕсли;
    КонецЕсли;

    // 5. Получение области макета и заполнение параметров
    // Предполагаем, что у нас есть область "Заголовок"
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    
    Если ОбластьЗаголовок = Неопределено Тогда
        Сообщить("Область 'Заголовок' не найдена в макете. Проверьте макет.");
        Возврат;
    КонецЕсли;

    // Заполняем параметр 'strah' в области Заголовок
    // Убедитесь, что в макете в области "Заголовок" есть параметр с именем [strah]
    ОбластьЗаголовок.Параметры.strah = СтатусСтрахования;
    
    // Для примера, можно также добавить информацию о договоре
    // Если в макете есть параметр [ДоговорНаименование]
    // ОбластьЗаголовок.Параметры.ДоговорНаименование = СсылкаНаДоговор.Наименование;

    // 6. Вывод области в табличный документ
    ТАБ.Вывести(ОбластьЗаголовок);

    // Если у вас есть другие области (шапка таблицы, строки, подвал), 
    // выводите их аналогичным образом.
    // Пример для строк, если запрос возвращает много строк (например, для ТЗРезультат из примера выше)
    // ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    // Для Каждого СтрокаТЗ Из ТЗРезультат Цикл
    //     ОбластьСтрока.Параметры.Заполнить(СтрокаТЗ); // Или по отдельным параметрам: ОбластьСтрока.Параметры.Статус = СтрокаТЗ.СтатусСтраховки;
    //     ТАБ.Вывести(ОбластьСтрока);
    // КонецЦикла;

    // 7. Показ сформированного табличного документа
    ТАБ.Показать();

КонецПроцедуры

5. Важные рекомендации и возможные ошибки

  1. Консоль запросов: Всегда используйте консоль запросов для отладки и проверки правильности ваших запросов. Это позволяет быстро убедиться, что запрос возвращает ожидаемые данные, прежде чем интегрировать его в основной код.
  2. Отладчик: Не пренебрегайте использованием отладчика 1С. Пошаговое выполнение кода помогает понять, на каком этапе возникают ошибки, какие значения принимают переменные, и как происходит взаимодействие с макетом и табличным документом.
  3. Параметры макета: Убедитесь, что имена параметров в коде (например,
    
    ОбластьЗаголовок.Параметры.strah
    
    ) точно соответствуют именам параметров, указанным в макете (например,
    
    [strah]
    
    ). Любая опечатка приведет к тому, что параметр не будет заполнен.
  4. Имена областей: Аналогично, проверяйте правильность имен областей при вызове
    
    Макет.ПолучитьОбласть("ИмяОбласти")
    
    .
  5. Управляемые формы: Помните, что в управляемых формах для получения макета необходимо использовать
    
    РеквизитФормыВЗначение("Объект").ПолучитьМакет("ИмяВашегоМакета")
    
    и что это должна быть серверная функция, если вы вызываете её из клиентского кода.
  6. Обработка пустого результата: Всегда предусматривайте сценарии, когда запрос может не вернуть данных. В нашем примере мы установили значение по умолчанию
    
    "Данные о страховке не найдены"
    
    , если запрос не нашел информацию о страховке.
  7. Сложные отчеты: Если ваш отчет состоит из нескольких таблиц или динамических секций, вам потребуется более сложная логика для итерации по результатам запроса (используя циклы
    
    Для Каждого ... Цикл
    
    или
    
    ВыборкаЗапроса.Следующий()
    
    ) и вывода соответствующих областей.

Следуя этим рекомендациям и подробно разобрав каждый шаг, вы сможете успешно реализовать задачу по определению статуса страховки и его выводу в отчет 1С:Предприятия.

← На главную