Как получить последнее согласующее лицо для автозаполнения шаблона файла в 1С

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

Анализ проблемы и ошибки в скрипте

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


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

Запрос.УстановитьПараметр("Предмет", Файл.ВладелецФайла);
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();

Если ВыборкаЗапроса.Следующий() Тогда
    ПоследнийИсполнитель = ВыборкаЗапроса[ВыборкаЗапроса.Количество - 1].Исполнитель;
    РезультатОбработки = ПоследнийИсполнитель.ПредставлениеВДокументах;
КонецЕсли;

Выясним причину возникшей ошибки. В данном фрагменте кода разработчик обращается к объекту ВыборкаИзРезультатаЗапроса так, будто это индексируемая коллекция (таблица значений или массив), используя квадратные скобки ВыборкаЗапроса[...] и попытку считывания свойства Количество. Однако объект выборки не содержит свойства Количество и не поддерживает квадратные скобки для обращения по индексу. В результате платформа выводит сообщение о некорректно заданном скрипте.

Правильный подход к получению последней записи

Проанализируем, как исправить алгоритм. Самый простой и эффективный способ получить последнюю запись — это изменить порядок сортировки в запросе на обратный (по убыванию), добавить ограничение ПЕРВЫЕ 1 и считывать данные из первой строки выборки напрямую.

Разберем исправленный вариант кода:


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

Запрос.УстановитьПараметр("Предмет", Файл.ВладелецФайла);
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();

Если ВыборкаЗапроса.Следующий() Тогда
    РезультатОбработки = ВыборкаЗапроса.Исполнитель.ПредставлениеВДокументах;
КонецЕсли;

В этом варианте вызов Следующий() считывает первую строку результат-запроса (которая из-за сортировки УБЫВ является последней визой), после чего мы сразу же получаем реквизит Исполнитель без вызова индексов.

Важные подводные камни при работе с визами согласования

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

  1. Проверка фактического визирования: Записи в справочнике ВизыСогласования могут создаваться автоматически при старте бизнес-процесса — еще до того, как пользователь вынес решение. Чтобы исключить участников, которые еще не выполнили задачу, стоит проверять заполненость результата (например, ВизыСогласования.РезультатСогласования <> ЗНАЧЕНИЕ(Перечисление.РезультатыСогласования.ПустаяСсылка)).
  2. Повторные циклы согласования: При отправке документа на повторный круг прошлые визы помечаются флагом Удалена = Истина, хотя пометка удаления объекта на них не ставится. Обязательно добавляйте условие ВизыСогласования.Удалена = ЛОЖЬ.
  3. Точная сортировка по времени: При параллельном согласовании значение поля Порядок у нескольких согласующих может совпадать. Для точного определения лица, вынесшего решение последним по времени, сортировку лучше выполнять по реквизиту ДатаУстановкиРезультата УБЫВ.
  4. Тип возвращаемого значения: В скриптах автозаполнения шаблонов переменная РезультатОбработки должна возвращать строковое значение. Если реквизит ПредставлениеВДокументах не заполнен, целесообразно предусмотреть получение альтернативного строкового представления (например, Строка(ВыборкаЗапроса.Исполнитель)).

Альтернативные варианты решения

Проанализируем другие способы решения этой задачи:

  1. Использование метода Выгрузить(): Если требуется именно обход коллекции по индексам, результат запроса можно сначала выгрузить в таблицу значений с помощью Запрос.Выполнить().Выгрузить(). В этом случае обращение к последнему элементу пишется как ТаблицаЗапроса[ТаблицаЗапроса.Количество() - 1] (обратите внимание, что у таблицы значений Количество() — это метод со скобками).
  2. Использование функций общего модуля: В конфигурации 1С:Документооборот доступен программный интерфейс общего модуля РаботаСВизамиСогласования, который позволяет штатно выгружать актуальные визы объекта с учетом всех циклов.
  3. Запрос к выполненным задачам: Определить исполнителя, завершившего согласование последним, можно также через запрос к таблице Задача.ЗадачаИсполнителя с фильтрацией по предмету и сортировкой по полю ДатаИсполнения УБЫВ.
← На главную