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