Почему не работает метод НайтиПоРеквизиту для документов в 1С 7.7 и как найти подчиненный документ

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

При разработке и доработке конфигураций на платформе 1С:Предприятие 7.7 часто возникает необходимость найти определенный документ, опираясь на значение его реквизита — например, найти документ АктРазногласий, созданный на основании конкретной ТТН. Разработчики нередко пытаются применить привычный метод НайтиПоРеквизиту, однако при выполнении кода платформа выдает ошибку: Поле Агрегатного объекта не обнаружено (НайтиПоРеквизиту). Разберем, почему возникает эта ошибка, и рассмотрим правильные варианты поиска документов.

Причина возникновения ошибки

Проанализируем контекст вызова метода. В платформе 1С 7.7 метод НайтиПоРеквизиту() реализован исключительно для объекта Справочник (при условии, что у реквизита в метаданных включен признак сортировки/отбора). У объекта Документ такого метода в синтаксисе нет в принципе. Более того, для документов нельзя настроить произвольную индексацию отдельных реквизитов так же легко, как в справочниках.

Стоит отметить, что и в платформе 1С 8.x у менеджеров документов метод НайтиПоРеквизиту также отсутствует — там поиск по реквизитам выполняется через запросы или критерии отбора.

Выясним, какими способами можно быстро и корректно найти подчиненный документ в 1С 7.7, зная ссылку на документ-основание.

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

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

Рассмотрим по шагам, как устроен этот алгоритм:

  1. Инициализируем переменную для хранения найденного документа пустым значением через ПолучитьПустоеЗначение("Документ").
  2. Создаем объект типа Документ.
  3. Запускаем выборку подчиненных документов с помощью метода ВыбратьПодчиненныеДокументы, передавая в качестве третьего параметра наш документ-основание.
  4. В цикле обходим подчиненные документы, проверяя имя вида документа через функцию Вид().
  5. При нахождении нужного вида документа фиксируем ссылку через метод ТекущийДокумент() и прерываем цикл.

Посмотрим на пример программной реализации:


Акт = ПолучитьПустоеЗначение("Документ");
Док = СоздатьОбъект("Документ");

// Выбираем все подчиненные документы по известному основанию ДокОснование
Док.ВыбратьПодчиненныеДокументы(,, ДокОснование);

Пока Док.ПолучитьДокумент() = 1 Цикл
    Если Док.Вид() = "АктРазногласий" Тогда
        Акт = Док.ТекущийДокумент();
        Прервать; // Нужный документ найден, выходим из цикла
    КонецЕсли;
КонецЦикла;

Если Акт.Выбран() = 1 Тогда
    Сообщить("Найден акт: " + Строка(Акт));
    // Выполняем дальнейшие действия с найденным документом
Иначе
    Сообщить("Подчиненный акт разногласий не обнаружен!");
КонецЕсли;

Важные нюансы метода:

  1. Типизация реквизита: Метод опирается на системный журнал подчиненности платформы. Документ попадает в подчиненные только тогда, когда реквизит шапки имеет строго типизированный вид (тип Документ или конкретный вид документа). Если реквизит имеет тип Неопределенный, автоматическая фиксация подчиненности может не сработать.
  2. Оптимизация периода: Если вызывать метод без указания дат (как ,, ДокОснование), выборка будет производиться по всей глубине базы. Для ускорения работы рекомендуется ограничивать интервал: в качестве начальной даты указывать дату документа-основания (ДокОснование.ДатаДок), а в качестве конечной — актуальную дату или дату запрета редактирования.

Способ 2. Поиск через графу отбора

Если требуется выполнять частый и быстрый поиск документов по определенному реквизиту (в том числе по реквизиту ДокументОснование), можно задействовать Графу отбора.

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

  1. В конфигураторе открываем ветку Журналы -> Графы отбора и создаем новую графу отбора (или используем существующую, например, Основание).
  2. Включаем в состав графы нужный реквизит требуемых видов документов.
  3. В коде используем метод ВыбратьПоЗначению().

Посмотрим на пример кода выборки по графе отбора:


Док = СоздатьОбъект("Документ.АктРазногласий");
ДатаНач = ТТН.ДатаДок;
ДатаКон = ТекущаяДата();

// Выборка документов по зарегистрированной графе отбора
Док.ВыбратьПоЗначению(ДатаНач, ДатаКон, "Основание", ТТН);

Если Док.ПолучитьДокумент() = 1 Тогда
    Сообщить("Найден документ: " + Строка(Док.ТекущийДокумент()));
Иначе
    Сообщить("Документ по указанному основанию не найден.");
КонецЕсли;

Этот метод работает быстрее полного перебора, так как использует платформенные индексы графы отбора в базе данных.

Способ 3. Поиск с помощью встроенного языка запросов 1С 7.7

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

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


Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = 
"//{{ЗАПРОС(ПоискАкта)
|Период С ТТН.ДатаДок По ТекущаяДата();
|Акт = Документ.АктРазногласий.ТекущийДокумент;
|Основание = Документ.АктРазногласий.ДокументОснование;
|Группировка Акт;
|Условие(Основание = ТТН);
|"//}}ЗАПРОС
;

Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
    Пока Запрос.Группировка(1) = 1 Цикл
        НайденныйАкт = Запрос.Акт;
        Сообщить("Найден акт через запрос: " + Строка(НайденныйАкт));
    КонецЦикла;
КонецЕсли;

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

← На главную