Как в запросе 1С выбрать последнюю актуальную корректировку реализации

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При работе с документами корректировки реализации в 1С (особенно в конфигурациях ERP, УТ 11 или КА) часто возникает задача: получить только последний, актуальный документ из цепочки исправлений. Поскольку одна реализация может корректироваться несколько раз, простым запросом к таблице Документ.КорректировкаРеализации мы получим все документы, включая те, которые уже утратили актуальность. В этой статье мы разберем несколько профессиональных способов решения этой задачи, проанализируем их плюсы и минусы, а также узнаем, как сделать запрос максимально производительным.

Метод 1: Левое соединение таблицы самой с собой (Метод исключения)

Этот способ считается классическим и наиболее гибким. Основная идея заключается в том, чтобы попытаться соединить таблицу корректировок с этой же таблицей еще раз, но по условию, что дата второго документа больше даты первого. Если для конкретной корректировки "будущего" документа не нашлось, значит, она и есть последняя.

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


ВЫБРАТЬ
    Корр1.Ссылка КАК АктуальнаяКорректировка,
    Корр1.ИсходныйДокументРеализации КАК Реализация
ИЗ
    Документ.КорректировкаРеализации КАК Корр1
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.КорректировкаРеализации КАК Корр2
        ПО Корр1.ИсходныйДокументРеализации = Корр2.ИсходныйДокументРеализации
            И Корр1.Дата < Корр2.Дата
            И Корр2.Проведен = ИСТИНА
ГДЕ
    Корр1.Проведен = ИСТИНА
    И Корр2.Ссылка ЕСТЬ NULL
    И Корр1.ИсходныйДокументРеализации В (&МассивРеализаций)

Разберем по шагам, что происходит в этом запросе:

  1. Мы выбираем все проведенные корректировки (Корр1).
  2. Присоединяем к ним другие проведенные корректировки (Корр2) по тому же самому исходному документу.
  3. Условие соединения Корр1.Дата < Корр2.Дата ищет документы, созданные позже текущего.
  4. Фильтр Корр2.Ссылка ЕСТЬ NULL оставляет только те записи из Корр1, для которых "более позднего" документа не существует. Это и гарантирует нам получение финального звена в цепочке.

Важное замечание: Если в системе возможны корректировки с абсолютно идентичной датой и временем (до секунды), этот запрос может вернуть дубли. Чтобы этого избежать, в условии соединения вместо Дата лучше использовать комбинацию даты и ссылки или обратиться к понятию "Момент времени".

Метод 2: Группировка по максимальной ссылке

В платформе 1С идентификатор Ссылка содержит в себе временную составляющую. В большинстве случаев (хотя это и не документировано как абсолютное правило) более поздний документ будет иметь "большую" ссылку при сравнении. Это позволяет использовать агрегатные функции в группировках.

Проанализируем пример использования группировки:


ВЫБРАТЬ
    МАКСИМУМ(Корректировка.Ссылка) КАК Ссылка,
    Корректировка.ИсходныйДокументРеализации КАК Реализация
ИЗ
    Документ.КорректировкаРеализации КАК Корректировка
ГДЕ
    Корректировка.Проведен = ИСТИНА
ГРУППИРОВАТЬ ПО
    Корректировка.ИсходныйДокументРеализации

Этот метод работает быстрее, так как не требует тяжелых соединений. Однако он менее надежен в распределенных базах данных (РИБ) или при массовом переносе данных, где порядок генерации ссылок может не совпадать с хронологией создания документов. Используйте этот метод, если уверены в последовательности ввода данных в вашей системе.

Метод 3: Логика цепочки (Поле ДокументРеализации)

В типовых решениях (ERP, УТ 11) каждая корректировка может ссылаться либо на исходную реализацию, либо на предыдущую корректировку. Второе часто происходит при исправлении ошибок. В поле ДокументРеализации записывается тот документ, который мы правим в данный момент.

Выясним причину, по которой это поле помогает найти финал цепочки: актуальная корректировка — это та, на которую еще никто не сослался в качестве "исправляемого" документа. Посмотрим на пример кода:


ВЫБРАТЬ
    ВсеКорр.Ссылка
ИЗ
    Документ.КорректировкаРеализации КАК ВсеКорр
ГДЕ
    ВсеКорр.Проведен = ИСТИНА
    И НЕ ВсеКорр.Ссылка В (
        ВЫБРАТЬ
            Док.ДокументРеализации
        ИЗ
            Документ.КорректировкаРеализации КАК Док
        ГДЕ
            Док.Проведен = ИСТИНА
    )

Этот подход логически безупречен для конфигураций, использующих цепочки исправлений. Мы просто исключаем из выборки все ссылки, которые упоминаются в колонке ДокументРеализации у других корректировок.

Профессиональные советы по оптимизации

Чтобы ваш запрос не "вешал" систему при большом количестве данных, рекомендуем придерживаться следующих правил:

  1. Использование временных таблиц: Если вам нужно обрабатывать корректировки в рамках сложного отчета, сначала выгрузите список нужных реализаций во временную таблицу. Индексируйте поле Реализация.
  2. Индексация в запросе: При выполнении соединений убедитесь, что поля, по которым идет связь (ИсходныйДокументРеализации, ДокументРеализации), проиндексированы. В типовых конфигурациях эти поля обычно являются индексируемыми по умолчанию.
  3. Учет статусов: В последних версиях 1С:ERP документ может быть проведен, но иметь статус, например, "Ожидается согласование". Если ваша задача — получить данные, повлиявшие на учет, всегда добавляйте фильтр по статусу: Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКорректировокРеализации.Выполнена).
  4. Регистры вместо документов: Если цель запроса — получить финальные суммы или остатки после всех корректировок, рассмотрите возможность обращения к виртуальным таблицам остатков или оборотов регистров (например, ВыручкаИСебестоимостьПродаж). Платформа 1С делает это гораздо эффективнее, чем ручной перебор документов в запросе.

Рассмотрим, как правильно подготовить временную таблицу с индексами для повышения производительности:


// Помещаем исходные данные во временную таблицу
ВЫБРАТЬ
    Корр.Ссылка КАК Ссылка,
    Корр.Дата КАК Дата,
    Корр.ИсходныйДокументРеализации КАК ИсходныйДокумент
ПОМЕСТИТЬ ВТ_ВсеКорректировки
ИЗ
    Документ.КорректировкаРеализации КАК Корр
ГДЕ
    Корр.Проведен = ИСТИНА
    И Корр.Дата МЕЖДУ &НачалоПериода И &КонецПериода;

ИЗМЕНИТЬ ВТ_ВсеКорректировки
ДОБАВИТЬ ИНДЕКС ПО ИсходныйДокумент, Дата;

// Теперь выбираем актуальные записи
ВЫБРАТЬ
    Т1.Ссылка
ИЗ
    ВТ_ВсеКорректировки КАК Т1
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ВсеКорректировки КАК Т2
        ПО Т1.ИсходныйДокумент = Т2.ИсходныйДокумент
            И Т1.Дата < Т2.Дата
ГДЕ
    Т2.Ссылка ЕСТЬ NULL;

Подводя итог, можно сказать, что выбор метода зависит от конкретной конфигурации и требований к точности. Для простых задач подходит Метод 2 (Группировка), для сложных систем с длинными цепочками исправлений лучше использовать Метод 1 (Левое соединение) или Метод 3 (Исключение по ссылкам).

← На главную