При разработке отчетов в системе 1С:Предприятие часто возникает задача не просто вывести список документов, но и подсчитать их количество по определенным критериям: общее число за период, количество выполненных (закрытых) заявок или объем просроченных обращений. В этой статье мы подробно разберем, как реализовать такой функционал программным способом, проанализируем структуру запросов и выясним, как правильно передавать параметры для получения корректных итогов.
Представим ситуацию: у нас есть документ Журнал9 (обращения). Нам необходимо сформировать отчет, в котором будут отображаться не только детальные записи, но и суммарные показатели. Мы будем использовать Запрос для получения данных из базы и Табличный документ для вывода результата. Основная сложность для начинающих разработчиков заключается в правильной фильтрации данных по типу Булево и корректном обращении к результатам выборки запроса.
Рассмотрим самый простой вариант — получение общего числа документов, попавших в выбранный пользователем интервал дат. Для этого в тексте запроса нам необходимо использовать условие ГДЕ по полю Дата.
Разберем пример кода, который инициализирует запрос и устанавливает границы периода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Журнал9.Ссылка) КАК ВсегоОбращений
|ИЗ
| Документ.Журнал9 КАК Журнал9
|ГДЕ
| Журнал9.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
ОбщееКоличество = Выборка.ВсегоОбращений;
КонецЕсли;
В данном примере мы используем агрегатную функцию КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Ссылка). Это гарантирует, что даже если в запросе возникнут дубли из-за соединения таблиц (в более сложных случаях), система посчитает только уникальные документы.
Для того чтобы выделить из общей массы только просроченные или только закрытые обращения, мы добавляем в блок ГДЕ дополнительное условие по соответствующему реквизиту. Важно помнить, что в 1С параметры типа Булево следует передавать явно через метод УстановитьПараметр.
Проанализируем ситуацию, когда нам нужно посчитать закрытые заявки (реквизит Закрыто имеет значение Истина):
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Журнал9.Ссылка) КАК КоличествоЗакрытых
|ИЗ
| Документ.Журнал9 КАК Журнал9
|ГДЕ
| Журнал9.Дата МЕЖДУ &НачалоПериода И &КонецПериода
| И Журнал9.Закрыто = &СтатусЗакрыто";
// Устанавливаем параметры
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.УстановитьПараметр("СтатусЗакрыто", Истина); // Передаем логическое значение
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Сообщить("Количество закрытых обращений: " + Выборка.КоличествоЗакрытых);
КонецЕсли;
Важный нюанс: Не используйте зарезервированные слова (например, "Булево") в качестве имен параметров внутри запроса. Это может привести к трудночитаемости кода и ошибкам. Используйте понятные имена, такие как &СтатусЗакрыто или &ЭтоПросрочка.
Иногда нам нужно вывести и детальные записи (строки отчета), и их общее количество. В этом случае удобно использовать свойство Выборка.Количество() или итоги в самом запросе.
Рассмотрим подробнее вариант с получением количества строк из результата выполнения запроса:
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Документ.Журнал9 ГДЕ Дата МЕЖДУ &Начало И &Конец");
// ... установка параметров ...
Результат = Запрос.Выполнить();
// Мы можем узнать количество записей сразу, не обходя выборку в цикле
ВсегоСтрок = Результат.Выбрать().Количество();
// Или через саму выборку
ВыборкаДетали = Результат.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
// Вывод строк в макет
КонецЦикла;
Однако стоит учитывать, что Выборка.Количество() вернет общее число записей, удовлетворяющих фильтру запроса. Если вам нужно посчитать разные показатели (итого, закрыто, просрочено) в рамках одного формирования отчета, эффективнее использовать один запрос с группировками или несколькими временными таблицами.
Проанализируем основные причины, по которым отчет может работать некорректно или "зацикливаться":
Запрос.Выполнить(), пытаясь обратиться к выборке, которая еще не создана.ТабличныйДокумент убедитесь, что имена параметров в макете (например, &Количество) точно совпадают с именами, которые вы присваиваете в коде через Область.Параметры.Количество = ....ИТОГИ, обычный метод Выбрать() вернет сначала итоговую строку. Чтобы добраться до детальных записей, нужно использовать Выборка.Выбрать() повторно или указывать тип обхода ОбходРезультатаЗапроса.ПоГруппировкам.Выясним, как сделать наш отчет более профессиональным. Вместо прямого обращения к документам в больших системах рекомендуется использовать Регистры сведений или Регистры накопления. Это значительно ускоряет получение итоговых данных (сумм и количеств), так как система обращается к заранее просчитанным итогам, а не перебирает каждый документ заново.
Также, если вы работаете на платформе 8.3, рассмотрите возможность использования СКД (Системы компоновки данных). В СКД подсчет количеств реализуется через вкладку "Ресурсы", где достаточно выбрать поле Ссылка и функцию Количество(). Платформа сама сгенерирует оптимальный запрос и выведет итоги в нужные области отчета, избавив вас от необходимости писать код вывода в макет вручную.
Подводя итог, можно сказать, что ключ к успешному созданию отчета по обращениям — это четкое понимание того, как работают условия в языке запросов 1С и внимательное отношение к типам данных параметров. Используя агрегатные функции и правильные методы обработки выборки, вы сможете быстро и точно предоставлять пользователям необходимую статистическую информацию.