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