При работе с 1С:Предприятием часто возникает необходимость формировать отчеты, которые отображают актуальные статусы различных объектов, например, срок действия страховки контрагентов. В этой статье мы подробно разберем, как создать запрос для определения статуса страховки, сравнить ее дату окончания с текущей датой и вывести полученный результат в параметр макета внешнего отчета, работающего на управляемых формах.
Давайте пошагово рассмотрим процесс создания такого функционала, учитывая особенности работы с запросами и макетами в системе 1С:Предприятие.
Первоочередная задача – правильно составить запрос. Нам необходимо получить самую последнюю (актуальную) дату окончания страховки для конкретного договора контрагента и на основе этой даты определить, действует ли страховка или уже просрочена. Изначальная попытка использовать
МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания)
Чтобы получить актуальную дату страховки именно для того договора, который нас интересует, необходимо использовать агрегатную функцию МАКСИМУМ в сочетании с условием
ГДЕ Ссылка = &Договор
&Договор
Для определения статуса страховки прямо в запросе мы используем конструкцию
ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ
Рассмотрим пример запроса:
ВЫБРАТЬ
ВЫБОР
КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
ТОГДА "Страховка просрочена"
ИНАЧЕ "Страховка действует"
КОНЕЦ КАК СтатусСтраховки
ИЗ
Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
ГДЕ
ДоговорыКонтрагентовСтраховка.Ссылка = &Договор
В этом запросе:
ВЫБОР КОГДА
МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) находит последнюю дату окончания страховки для текущего договора.< &ТекущаяДата сравнивает эту максимальную дату с переданной текущей датой. Если дата окончания меньше текущей, то страховка просрочена.ИЗ Справочник.ДоговорыКонтрагентов.Страховка указывает, что мы работаем с табличной частью "Страховка" справочника "Договоры контрагентов".ГДЕ ДоговорыКонтрагентовСтраховка.Ссылка = &Договор – это критически важное условие, которое фильтрует данные по конкретному договору. Без него запрос вернет максимальную дату по всем договорам в базе, что не соответствует нашей задаче.После того как мы определили текст запроса, необходимо установить значения для его параметров. В нашем случае это
&ТекущаяДата
&Договор
Вот как это делается в коде 1С:
// Предположим, у нас есть ссылка на договор
// Например, это может быть реквизит формы или элемент списка
// СсылкаНаДоговор = Объект.Договор;
// Для примера возьмем первую попавшуюся ссылку на договор, или передадим как параметр функции
// Допустим, мы хотим получить статус для определенного договора (замените на реальное значение)
// Например: СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПоКоду("000000001");
// Получаем текущую дату для сравнения
ТекущаяДата = ТекущаяДата();
// Создаем новый запрос
Запрос = Новый Запрос;
// Устанавливаем параметры запроса
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата);
// Если нам нужно получить статус для конкретного договора
// Запрос.УстановитьПараметр("Договор", СсылкаНаДоговор);
// В данном контексте, если запрос нужен для одного конкретного договора,
// то параметр &Договор должен быть установлен.
// Однако, если вы хотите получить статусы для всех договоров,
// то условие ГДЕ ДоговорыКонтрагентовСтраховка.Ссылка = &Договор нужно удалить,
// а также добавить ГРУППИРОВАТЬ ПО ДоговорыКонтрагентовСтраховка.Ссылка
// и в ВЫБРАТЬ добавить ДоговорыКонтрагентовСтраховка.Ссылка КАК Договор.
// Давайте адаптируем запрос для получения по одному договору, как в примере.
// Добавим заглушку для СсылкаНаДоговор, если она не определена выше
// Для демонстрации, давайте предположим, что мы передаем ссылку на договор в функцию или получаем ее откуда-то.
// Например, СсылкаНаДоговор = ПараметрыВыполнения.ДоговорКонтрагента;
// Для примера, если мы запускаем это в контексте формы объекта "ДоговорКонтрагента"
// СсылкаНаДоговор = Объект.Ссылка;
// Если мы формируем отчет для списка договоров, то запрос будет немного другим (см. далее).
// Сейчас сосредоточимся на одном договоре.
// Для демонстрации, давайте просто возьмем любой договор из базы.
// Если это отчет, то СсылкаНаДоговор обычно передается как параметр формы отчета.
// Предположим, что СсылкаНаДоговор уже определена и содержит ссылку на интересующий нас договор.
// Например: СсылкаНаДоговор = НекийПараметрФормыОтчета.Договор;
// Добавляем текст запроса
Запрос.Текст = "ВЫБРАТЬ
| ВЫБОР
| КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
| ТОГДА ""Страховка просрочена""
| ИНАЧЕ ""Страховка действует""
| КОНЕЦ КАК СтатусСтраховки
|ИЗ
| Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
|ГДЕ
| ДоговорыКонтрагентовСтраховка.Ссылка = &Договор";
// Устанавливаем параметр для конкретного договора.
// !!! Важно: замените на реальный способ получения ссылки на договор !!!
// Например:
// Если мы формируем отчет по текущему элементу справочника:
// СсылкаНаДоговор = Объект.Ссылка;
// Если договор выбирается в форме отчета:
// СсылкаНаДоговор = МойРеквизитФормыДоговор;
// Для демонстрации возьмем первый попавшийся договор:
СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПервый();
Если СсылкаНаДоговор = Неопределено Тогда
Сообщить("Не найден ни один договор для демонстрации. Создайте хотя бы один договор.");
Возврат;
КонецЕсли;
Запрос.УстановитьПараметр("Договор", СсылкаНаДоговор);
// Выполняем запрос
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
// Получаем результат запроса
СтатусСтрахования = "";
Если ВыборкаЗапроса.Следующий() Тогда
СтатусСтрахования = ВыборкаЗапроса.СтатусСтраховки;
КонецЕсли;
Сообщить("Статус страховки для договора " + СсылкаНаДоговор + ": " + СтатусСтрахования);
// Если нам нужно получить статусы для множества договоров,
// то запрос будет выглядеть так (используем ГРУППИРОВАТЬ ПО):
ЗапросМножество = Новый Запрос;
ЗапросМножество.Текст = "ВЫБРАТЬ
| ДоговорыКонтрагентовСтраховка.Ссылка КАК Договор,
| ВЫБОР
| КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
| ТОГДА ""Страховка просрочена""
| ИНАЧЕ ""Страховка действует""
| КОНЕЦ КАК СтатусСтраховки
|ИЗ
| Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
|ГРУППИРОВАТЬ ПО
| ДоговорыКонтрагентовСтраховка.Ссылка";
ЗапросМножество.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
ТЗРезультат = ЗапросМножество.Выполнить().Выгрузить();
// Теперь ТЗРезультат содержит колонки "Договор" и "СтатусСтраховки" для всех договоров.
Важно отметить, что метод Запрос.Выполнить().Выгрузить() возвращает
ТаблицуЗначений
Теперь, когда мы умеем получать статус страховки, нам нужно вывести его в отчет. Для этого мы будем использовать макет отчета и объект
ТабличныйДокумент
В обычных формах функция ПолучитьМакет("ИмяМакета") вызывается напрямую. Однако в управляемых формах ПолучитьМакет является методом объекта отчета. Поэтому для получения макета нам нужно обратиться к текущему объекту формы. Обычно это делается так:
// В модуле формы отчета, например, в процедуре формирования отчета
&НаСервере
Функция ПолучитьМакетОтчетаНаСервере()
Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетОтчета");
КонецФункции
// В основной процедуре формирования отчета:
Макет = ПолучитьМакетОтчетаНаСервере();
Здесь
"Объект"
"МакетОтчета"
Макеты в 1С состоят из именованных областей (например, "Заголовок", "Шапка", "Строка"). Внутри этих областей вы можете определить параметры, которые будут заполняться программно. Параметры в макете обозначаются так:
[ИмяПараметра]
Для доступа к области используется метод Макет.ПолучитьОбласть("ИмяОбласти"). Затем параметры области можно заполнить напрямую:
ОбластьШапка.Параметры.strah = СтатусСтрахования;
Где
strah
СтатусСтрахования
Для отображения отчета пользователю мы используем объект
ТабличныйДокумент
ТабличныйДокумент
Теперь давайте соберем весь код вместе, включая запрос, получение макета и вывод в
ТабличныйДокумент
Представим, что у нас есть внешний отчет с макетом под названием "МакетОтчета", который содержит область "Заголовок" с параметром
strah
// Модуль формы отчета
// Функция для получения макета на сервере (для управляемых форм)
&НаСервере
Функция ПолучитьМакетОтчета()
Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетОтчета");
КонецФункции
// Основная процедура формирования отчета (например, по кнопке "Сформировать")
&НаКлиенте
Процедура СформироватьОтчет(Команда)
// Вызываем серверную процедуру для формирования и показа отчета
СформироватьИПоказатьОтчетНаСервере();
КонецПроцедуры
&НаСервере
Процедура СформироватьИПоказатьОтчетНаСервере()
// 1. Инициализация ТабличногоДокумента и получение макета
ТАБ = Новый ТабличныйДокумент;
Макет = ПолучитьМакетОтчета(); // Используем нашу серверную функцию
// Проверяем, что макет успешно получен
Если Макет = Неопределено Тогда
Сообщить("Макет 'МакетОтчета' не найден. Проверьте имя макета в конфигураторе.");
Возврат;
КонецЕсли;
// 2. Определение и установка параметров запроса
ТекущаяДата = ТекущаяДата();
// Предполагаем, что СсылкаНаДоговор передается как реквизит формы отчета
// Например: СсылкаНаДоговор = ЭтаФорма.Элементы.ПолеВводаДоговор.Значение;
// Или для демонстрации возьмем первый попавшийся договор
СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПервый();
Если СсылкаНаДоговор = Неопределено Тогда
Сообщить("Для формирования отчета необходимо выбрать договор контрагента.", СтатусСообщения.Важное);
Возврат;
КонецЕсли;
// 3. Создание и выполнение запроса
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) КАК ДатаОкончания,
| ВЫБОР
| КОГДА МАКСИМУМ(ДоговорыКонтрагентовСтраховка.ДатаОкончания) < &ТекущаяДата
| ТОГДА ""Страховка просрочена""
| ИНАЧЕ ""Страховка действует""
| КОНЕЦ КАК СтатусСтраховки
|ИЗ
| Справочник.ДоговорыКонтрагентов.Страховка КАК ДоговорыКонтрагентовСтраховка
|ГДЕ
| ДоговорыКонтрагентовСтраховка.Ссылка = &Договор";
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата);
Запрос.УстановитьПараметр("Договор", СсылкаНаДоговор);
РезультатЗапроса = Запрос.Выполнить().Выбрать();
// 4. Получение результата запроса
СтатусСтрахования = "Данные о страховке не найдены"; // Значение по умолчанию
Если РезультатЗапроса.Следующий() Тогда
// Проверяем, что ДатаОкончания не является NULL, то есть данные по страховке есть
Если РезультатЗапроса.ДатаОкончания <> NULL Тогда
СтатусСтрахования = РезультатЗапроса.СтатусСтраховки;
КонецЕсли;
КонецЕсли;
// 5. Получение области макета и заполнение параметров
// Предполагаем, что у нас есть область "Заголовок"
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
Если ОбластьЗаголовок = Неопределено Тогда
Сообщить("Область 'Заголовок' не найдена в макете. Проверьте макет.");
Возврат;
КонецЕсли;
// Заполняем параметр 'strah' в области Заголовок
// Убедитесь, что в макете в области "Заголовок" есть параметр с именем [strah]
ОбластьЗаголовок.Параметры.strah = СтатусСтрахования;
// Для примера, можно также добавить информацию о договоре
// Если в макете есть параметр [ДоговорНаименование]
// ОбластьЗаголовок.Параметры.ДоговорНаименование = СсылкаНаДоговор.Наименование;
// 6. Вывод области в табличный документ
ТАБ.Вывести(ОбластьЗаголовок);
// Если у вас есть другие области (шапка таблицы, строки, подвал),
// выводите их аналогичным образом.
// Пример для строк, если запрос возвращает много строк (например, для ТЗРезультат из примера выше)
// ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
// Для Каждого СтрокаТЗ Из ТЗРезультат Цикл
// ОбластьСтрока.Параметры.Заполнить(СтрокаТЗ); // Или по отдельным параметрам: ОбластьСтрока.Параметры.Статус = СтрокаТЗ.СтатусСтраховки;
// ТАБ.Вывести(ОбластьСтрока);
// КонецЦикла;
// 7. Показ сформированного табличного документа
ТАБ.Показать();
КонецПроцедуры
ОбластьЗаголовок.Параметры.strah
[strah]
Макет.ПолучитьОбласть("ИмяОбласти")
РеквизитФормыВЗначение("Объект").ПолучитьМакет("ИмяВашегоМакета")
"Данные о страховке не найдены"
Для Каждого ... Цикл
ВыборкаЗапроса.Следующий()
Следуя этим рекомендациям и подробно разобрав каждый шаг, вы сможете успешно реализовать задачу по определению статуса страховки и его выводу в отчет 1С:Предприятия.