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