Как выбрать все документы за период в хронологическом порядке без учета вида документа в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке универсальных механизмов, отчетов или процедур перепроведения часто возникает задача получить единую выборку всех документов платформы 1С за определенный интервал времени. Главное требование при этом — строгое соблюдение хронологической последовательности независимо от того, к какому виду принадлежит конкретный документ.

Разберем основные подходы к решению этой задачи, проанализируем их плюсы и минусы, а также рассмотрим примеры программного кода.

Способ 1. Динамическое формирование запроса по метаданным

Рассмотрим наиболее универсальный вариант, который позволяет охватить абсолютно все документы конфигурации. Суть метода заключается в обходе коллекции Метаданные.Документы в цикле, динамическом построении текста запроса с использованием оператора ОБЪЕДИНИТЬ ВСЕ и последующей сортировке полученных данных по дате.

Разберем по шагам реализацию данного алгоритма:

  1. Обходим коллекцию метаданных всех документов.
  2. Проверяем права текущего пользователя на чтение каждого документа с помощью функции ПравоДоступа("Чтение", МетаданныеДокумента).
  3. Формируем части текста запроса для каждого документа вида ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка, Дата ИЗ Документ.ИмяДокумента.
  4. Склеиваем блоки текста с помощью оператора ОБЪЕДИНИТЬ ВСЕ.
  5. В конце текста запроса добавляем конструкцию УПОРЯДОЧИТЬ ПО Дата, Ссылка.

Посмотрим на пример программного кода:


ТекстЗапроса = "";
ПервыйИтератор = Истина;

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

Если НЕ ПустаяСтрока(ТекстЗапроса) Тогда
    
    ТекстЗапроса = ТекстЗапроса + "
    |УПОРЯДОЧИТЬ ПО
    |    Дата,
    |    Ссылка";
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
    Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Обработка полученных документов в хронологическом порядке
    КонецЦикла;
    
КонецЕсли;

Особенности и ограничения данного подхода:

Детерминированная сортировка: Если у нескольких документов дата совпадает с точностью до секунды, сортировка только по полю Дата не гарантирует постоянный порядок. Для однозначной хронологической сортировки в секции УПОРЯДОЧИТЬ ПО необходимо указывать два поля: Дата, Ссылка.

Производительность: Если в конфигурации создано несколько сотен видов документов, итоговый текст запроса получается очень объемным. Это может привести к долгой генерации плана выполнения на стороне СУБД и высокому расходу оперативной памяти.

Способ 2. Выборка через журналы документов

Выясним, как быстро получить хронологический список документов без сборки сложных динамических запросов. Для этого в платформе 1С предназначен объект ЖурналДокументов.

Обращение непосредственно к таблице общего журнала документов — наиболее производительный способ, так как СУБД задействует одну готовую индексированную таблицу. Пример запроса к журналу документов:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ
    |    Журнал.Ссылка КАК Ссылка,
    |    Журнал.Дата КАК Дата
    |ИЗ
    |    ЖурналДокументов.Общий КАК Журнал
    |ГДЕ
    |    Журнал.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
    |УПОРЯДОЧИТЬ ПО
    |    Дата,
    |    Ссылка";

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);

Результат = Запрос.Выполнить();

Ограничение журналов: В журнал попадают только те виды документов, которые явно включены в его состав в конфигураторе. Если какой-то документ не зарегистрирован в журнале, запрос к нему его не вернет.

Альтернативные варианты решения

Проанализируем ситуации, когда стандартный запрос не является оптимальным:

  1. Последовательности документов: Если хронологическая выборка необходима для восстановления последовательности или перепроведения документов с учетом движения ресурсов, следует использовать объект конфигурации Последовательность. Выборка через границу последовательности гарантирует обработку только тех документов, которые влияют на учет.
  2. Динамические списки: Если задача состоит в том, чтобы просто отобразить хронологический список всех документов пользователю в интерфейсе управляемого приложения, рекомендуется настроить Динамический список с основным источником — соответствующим журналом документов. Это обеспечивает постраничное считывание данных из базы без нагрузки на память.
← На главную