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

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

Обзор задачи и вариантов решения

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

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

Способ 1. Использование метода Выбрать с сортировкой по дате

Наиболее простой способ получить последний документ каждого вида — динамическое обращение к менеджеру конкретного документа через квадратные скобки и вызов метода Выбрать() с параметром обратной сортировки по дате.

Рассмотрим пример кода для обхода метаданных документов и регистрации полученных ссылок в плане обмена:


Узел = ПланыОбмена.бит_Полный.НайтиПоКоду("006");

Для Каждого Док Из Метаданные.Документы Цикл
    ВыборкаДок = Документы[Док.Имя].Выбрать(, , , "Дата Убыв");
    Если ВыборкаДок.Следующий() Тогда
        ПланыОбмена.ЗарегистрироватьИзменения(Узел, ВыборкаДок.Ссылка);
        Сообщить("Зарегистрирован: " + Док.Имя + " - " + ВыборкаДок.Ссылка);
    КонецЕсли;
КонецЦикла;

Проанализируем ключевые моменты в данном решении:

  1. Передача строки "Дата Убыв" в 4-й параметр метода Выбрать() гарантирует, что первая запись выборки будет содержать самый свежий документ по дате и времени.
  2. Проверка Если ВыборкаДок.Следующий() Тогда защищает код от падения. Если в базе данных еще не создано ни одного документа данного вида, выборка вернет Ложь. Попытка обратиться к свойствам выборки без этой проверки приведет к ошибке.

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

Вызов метода Выбрать() в цикле создает множество мелких обращений к базе данных. Для повышения производительности или при необходимости наложения дополнительных фильтров можно использовать язык запросов.

При сортировке документов в запросах важно учитывать, что упорядочивание только по полю Ссылка не всегда гарантирует хронологическую точность (например, если документы вводились задним числом). Для точного воспроизведения порядка моментов времени следует упорядочивать результат по дате и ссылке одновременно.

Рассмотрим пример формирования текста запроса:


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

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

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

Важные нюансы при работе с планами обмена

При решении описанной задачи важно учитывать спецификацию работы платформы с планами обмена:

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

2. Регистрация вида метаданных целиком. Если цель состоит в том, чтобы сделать доступными для обмена все объекты определенного вида, выбор конкретных ссылок через запросы не обязателен. Функция ЗарегистрироватьИзменения() может принимать сам объект описания метаданных (например, Метаданные.Документы.РеализацияТоваровУслуг), после чего платформа зарегистрирует абсолютно все существующие документы этого типа.

3. Отбор по состоянию документа. Обратите внимание, что методы Выбрать() и запросы без условий возвращают в том числе непроведенные документы и документы, помеченные на удаление. Если для проверки обмена требуются только проведенные документы, в текст запроса следует добавить явное условие: ГДЕ Т.Проведен = ИСТИНА И Т.ПометкаУдаления = ЛОЖЬ.

← На главную