Как программно найти последнюю корректировку реализации в цепочке документов в 1С:УТ 10.3

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

В типовой конфигурации «Управление торговлей», редакция 10.3 (а также в КА 1.1 и УПП 1.3) часто возникает ситуация, когда на основании одной РеализацииТоваровУслуг создается КорректировкаРеализации. В свою очередь, на основании этой корректировки может быть создана следующая, и так далее. Такая «матрешка» из документов может достигать десятков уровней вложенности. Стандартные механизмы платформы позволяют легко увидеть всю структуру подчиненности, но для программной обработки данных нам часто требуется получить именно конечный (актуальный) документ в этой цепочке.

В рамках данной статьи мы разберем, как эффективно решить эту задачу, проанализируем различные подходы (включая такие частные случаи, как корректировка серий и характеристик товаров) и выберем наиболее оптимальный вариант с точки зрения производительности и чистоты кода.

Постановка задачи и анализ структуры данных

Рассмотрим ситуацию: у нас есть ссылка на исходный документ РеализацияТоваровУслуг. Нам необходимо найти самую «свежую» корректировку, которая была сделана последней в иерархии. Важно понимать, что в УТ 10.3 связь между документами реализуется через реквизит ДокументОснование (в некоторых версиях — ДокументРеализации). Каждая последующая корректировка ссылается на предыдущий документ цепочки.

Решение 1: Последовательный обход в цикле (самый надежный метод)

Поскольку глубина цепочки заранее неизвестна, наиболее логичным подходом является использование цикла Пока...КонецЦикла. Мы будем последовательно искать подчиненный документ, пока запрос не перестанет возвращать новые результаты. Проанализируем пример кода, который реализует данную логику:


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

КонецФункции

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

  1. Мы инициализируем переменную ТекДокумент ссылкой на исходную реализацию.
  2. Внутри бесконечного цикла мы выполняем запрос к таблице Документ.КорректировкаРеализации.
  3. Ключевым условием фильтрации является Корректировка.ДокументРеализации = &ТекущийДокумент. Мы ищем документ, для которого текущее звено является основанием.
  4. Мы обязательно проверяем флаг Проведен, чтобы не попасть на черновики или помеченные на удаление объекты, которые не влияют на учет.
  5. Используем УПОРЯДОЧИТЬ ПО Дата УБЫВ и ВЫБРАТЬ ПЕРВЫЕ 1. Это необходимо на случай «ветвления» цепочки (если ошибочно создали две корректировки на один документ), чтобы выбрать наиболее актуальную по времени версию (важно при восстановлении хронологии документов).
  6. Если подчиненный документ найден, он становится «текущим» для следующей итерации. Если нет — цикл завершается, и мы возвращаем последнее найденное звено.

Решение 2: Использование типовых функций конфигурации

В конфигурации УТ 10.3 существуют встроенные механизмы для работы с цепочками корректировок, сосредоточенные в общем модуле УчетНДС. Например, функция УчетНДС.ПолучитьИсправляемыйДокументРеализации позволяет найти «вершину» цепочки (самую первую реализацию). Однако для движения «вниз» к последней корректировке часто приходится писать собственную надстройку.

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

Оптимизация производительности: «Запрос в цикле»

В среде разработчиков 1С часто звучит фраза: «Запрос в цикле — это плохо». Рассмотрим, применимо ли это здесь. В данном конкретном случае использование запроса внутри цикла оправдано по нескольким причинам:

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

  1. Выгружаем все возможные корректировки одним запросом в ТаблицуЗначений, используя фильтр по списку исходных документов.
  2. Строим дерево связей в оперативной памяти, используя метод НайтиСтроки().
  3. Это позволит выполнить ровно один запрос к базе данных вместо сотен или тысяч.

Решение 3: Метод Join-соединений (для фиксированной глубины)

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


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

Проанализируем ситуацию: этот запрос вернет нам самую глубокую ссылку, которая не является NULL. Это работает очень быстро, но имеет существенный недостаток — если появится четвертая корректировка, запрос её «не увидит». Поэтому данный метод рекомендуется использовать только в специфических задачах с жестким регламентом бизнес-процессов.

Важные нюансы и подводные камни

При реализации поиска последней корректировки всегда учитывайте следующие моменты:

1. Статус проведения: Всегда добавляйте условие Проведен = ИСТИНА. Отмененные или помеченные на удаление документы не должны участвовать в цепочке учета.

2. Дублирование цепочек: Теоретически пользователь может создать две разные корректировки на одну и ту же реализацию. В этом случае цепочка раздваивается. Рассмотренный нами первый алгоритм с сортировкой по дате выберет ту, что была создана позже. Выясним причину такого поведения: бизнес-логика обычно предполагает, что каждое последующее исправление отменяет или дополняет предыдущее, поэтому более поздний документ считается приоритетным.

3. Типы документов: В поле ДокументОснование могут попадать не только Корректировки реализации, но и Возвраты товаров от покупателя. Если ваша задача — найти финальный финансовый документ, обязательно проверяйте метаданные или используйте массив типов в условии запроса ССЫЛКА Документ.КорректировкаРеализации.

Итоги

Мы рассмотрели три способа поиска последней корректировки в УТ 10.3. Для большинства повседневных задач разработки Решение №1 (цикл с запросом) является наиболее сбалансированным. Оно простое в отладке, надежное и корректно обрабатывает любую глубину вложенности документов. При работе с большими массивами данных следует отдавать предпочтение предварительной выгрузке данных в таблицу значений для обработки в памяти.

← На главную