При работе с черными запросами в платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с непониманием того, как хранятся и обрабатываются временные метки документов. В частности, при обращении к атрибуту ВремяДок запрос может возвращать значения вроде 432100000. Проанализируем, почему возникают такие числа, как перевести их в привычный формат и какими способами можно обходить документы с учетом их времени.
Выясним причину появления больших чисел в запросах. В платформе 1С 7.7 системный реквизит ВремяДок возвращает время документа, измеряемое в 10 000-х долях секунды от начала суток. Таким образом, одна секунда соответствует значению 10000.
Рассмотрим соответствие некоторых значений времени:
10000 — соответствует 00:00:01 (1 секунда от начала суток).432000000 — соответствует 12:00:00 (43 200 секунд от начала суток).863990000 — соответствует 23:59:59 (86 399 секунд от начала суток).На уровне базы данных (в файловом режиме DBF и в MS SQL) время документов хранится в общей таблице журналов 1SJOURN в поле TIME в виде 6-символьной строки в 36-ричной системе счисления. При выполнении черного запроса платформа автоматически преобразует это значение в 10-ричное число в 10 000-х долях секунды.
Если в запросе используется атрибут ВремяДок, его значение легко пересчитать в стандартный формат часов, минут и секунд при обходе результатов запроса. Рассмотрим пример построения запроса и алгоритм математического расчета:
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
|Период с ВыбНачПериода по ВыбКонПериода;
|ОбрабатыватьДокументы все;
|ТекущийДокумент = Документ.ПКО.ТекущийДокумент;
|ВремяДок = Документ.ПКО.ВремяДок;
|Группировка ВремяДок;
|Группировка ТекущийДокумент;
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Пока Запрос.Группировка(1) = 1 Цикл
ВсегоСекунд = Цел(Запрос.ВремяДок / 10000);
Час = Цел(ВсегоСекунд / 3600);
Мин = Цел((ВсегоСекунд - Час * 3600) / 60);
Сек = ВсегоСекунд - Час * 3600 - Мин * 60;
Пока Запрос.Группировка(2) = 1 Цикл
// Обработка конкретного документа
КонецЦикла;
КонецЦикла;
Если нет необходимости делать группировку по времени непосредственно в тексте запроса, можно получать время документа на этапе обхода выборки. Для этого применяется встроенный метод ПолучитьВремя() объекта документа.
Обратите внимание: метод ПолучитьВремя() не возвращает значение непосредственно как результат функции, а принимает три переменные по ссылке, в которые записываются полученные значения часов, минут и секунд.
Разберем пример на коде:
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
|Период с ВыбНачПериода по ВыбКонПериода;
|ОбрабатыватьДокументы все;
|Без итогов;
|ЧтоТоДокумент = Документ.ПКО.ТекущийДокумент;
|Группировка ЧтоТоДокумент;
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Пока Запрос.Группировка(1) = 1 Цикл
ПеремЧас = 0;
ПеремМин = 0;
ПеремСек = 0;
// Вызываем метод для объекта документа из запроса
Запрос.ЧтоТоДокумент.ПолучитьВремя(ПеремЧас, ПеремМин, ПеремСек);
Сообщить("Время документа: " + ПеремЧас + ":" + ПеремМин + ":" + ПеремСек);
КонецЦикла;
Посмотрим на практический нюанс работы группировок. При использовании конструкции Группировка ТекущийДокумент; платформа 1С 7.7 автоматически формирует выборку документов в строгом хронологическом порядке. Сортировка выполняется по позиции документа в системе, которая формируется на основе даты, времени и внутреннего уникального идентификатора документа.
Поэтому дополнительно указывать группировку по ВремяДок только ради сохранения временного порядка документов не требуется — стандартная группировка по самому документу уже гарантирует их хронологическую последовательность.