Как получить последний документ по контрагенту в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Способ 1. Обход документов в обратном порядке (метод ОбратныйПорядок)

Самый простой и наглядный способ — прочитать журнал документов, начиная с самых свежих записей, и вернуть первый же документ, содержащий нужного контрагента. Для этого используется метод ОбратныйПорядок(1) объекта типа Документ.

Проанализируем пример функции на встроенном языке 1С 7.7:


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

Важные особенности этого подхода:

  1. Обратите внимание, что функция должна возвращать ДокОбъект.ТекущийДокумент(), а не сам объект выборки ДокОбъект. Переменная выборки и объект конкретного документа в 7.7 являются разным контекстом.
  2. Всегда рекомендуется ограничивать выборку временными рамками в методе ВыбратьДокументы(ДатаНач, ДатаКон). Если этого не сделать, на больших базах без фильтрация по периоду обработка будет выполнять сплошной перебор всех документов с самого начала ведения учета, что приведет к значительным задержкам.

Способ 2. Использование граф отбора

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

Выясним, как работает данный механизм: платформа ищет записи непосредственно через системный индекс таблицы отбора (в файловых базах или таблицах типа _1scrdoc в SQL-версии), исключая сканирование документов тех видов, где контрагент не указан вовсе.

Способ 3. Поиск по движениям регистров

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

Разберем порядок действий при таком подходе:

  1. Создаем объект Регистр.Взаиморасчеты (или аналогичный регистр из вашей конфигурации).
  2. Устанавливаем фильтр по искомому контрагенту через метод УстановитьЗначениеФильтра("Контрагент", ИскомыйКонтрагент).
  3. Выбираем движения регистра и берем документ-регистратор последней записи.

Способ 4. Прямые SQL-запросы (для SQL-версий базы)

Для SQL-версий 1С:Предприятия 7.7 при использовании внешних компонент (например, 1CPP) наиболее эффективным решением является прямой SQL-запрос. Запрос соединяет общую таблицу журнала документов _1sjourn и таблицу графы отбора _1scrdoc, после чего выбирает одну самую верхнюю запись:

SELECT TOP 1 IDDOC FROM _1scrdoc WHERE VALUE = :ИскомыйКонтрагент ORDER BY DATE_TIME_IDDOC DESC

Такой подход обеспечивает мгновенный результат независимо от объема базы данных.

← На главную