В платформе 1С:Предприятие 7.7 встроенный язык запросов не позволяет сделать единый простой выбор всех документов неопределенного вида с сортировкой по дате, как это реализовано в более новых версиях платформы. По этой причине задача поиска последнего документа конкретного контрагента в произвольной или самописной конфигурации требует применения специальных приемов.
Рассмотрим подробно основные методы решения этой задачи: от стандартного обхода выборки в обратном порядке до использования механизмов регистров и граф отбора.
Самый простой и наглядный способ — прочитать журнал документов, начиная с самых свежих записей, и вернуть первый же документ, содержащий нужного контрагента. Для этого используется метод ОбратныйПорядок(1) объекта типа Документ.
Проанализируем пример функции на встроенном языке 1С 7.7:
Функция ПоискПоследнегоДокумента(КонтрагентИскомый, ДатаНач = 0, ДатаКон = 0)
Перем ДокОбъект, ВидДок;
ДокОбъект = СоздатьОбъект("Документ");
// Устанавливаем выборку документов от самых новых к старым
ДокОбъект.ОбратныйПорядок(1);
// Задаем период выборки для оптимизации скорости
ДокОбъект.ВыбратьДокументы(ДатаНач, ДатаКон);
Пока ДокОбъект.ПолучитьДокумент() = 1 Цикл
ВидДок = ДокОбъект.Вид();
// Проверяем наличие реквизита "Контрагент" в шапке документа
Если глЕстьРеквизитШапки("Контрагент", ВидДок) = 1 Тогда
Если ДокОбъект.Контрагент = КонтрагентИскомый Тогда
// Возвращаем ссылку на найденный документ
Возврат ДокОбъект.ТекущийДокумент();
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат 0;
КонецФункции
Важные особенности этого подхода:
ДокОбъект.ТекущийДокумент(), а не сам объект выборки ДокОбъект. Переменная выборки и объект конкретного документа в 7.7 являются разным контекстом.ВыбратьДокументы(ДатаНач, ДатаКон). Если этого не сделать, на больших базах без фильтрация по периоду обработка будет выполнять сплошной перебор всех документов с самого начала ведения учета, что приведет к значительным задержкам.Если в конфигурации создана графа отбора (например, по контрагенту), поиск выполняется гораздо быстрее за счет использования существующих индексов базы данных. Если реквизит Контрагент вынесен в общий реквизит с включенным признаком отбора, скорость работы такой выборки увеличивается в разы по сравнению со сплошным обходом.
Выясним, как работает данный механизм: платформа ищет записи непосредственно через системный индекс таблицы отбора (в файловых базах или таблицах типа _1scrdoc в SQL-версии), исключая сканирование документов тех видов, где контрагент не указан вовсе.
В подавляющем большинстве конфигураций документы, связанные с контрагентами, формируют движения по регистрам взаиморасчетов или остатков товаров. Если необходимо найти последний проведенный документ, изменивший состояние расчетов, оптимальнее обратиться к регионам учета.
Разберем порядок действий при таком подходе:
Регистр.Взаиморасчеты (или аналогичный регистр из вашей конфигурации).УстановитьЗначениеФильтра("Контрагент", ИскомыйКонтрагент).Для SQL-версий 1С:Предприятия 7.7 при использовании внешних компонент (например, 1CPP) наиболее эффективным решением является прямой SQL-запрос. Запрос соединяет общую таблицу журнала документов _1sjourn и таблицу графы отбора _1scrdoc, после чего выбирает одну самую верхнюю запись:
SELECT TOP 1 IDDOC FROM _1scrdoc WHERE VALUE = :ИскомыйКонтрагент ORDER BY DATE_TIME_IDDOC DESC
Такой подход обеспечивает мгновенный результат независимо от объема базы данных.