Как найти документ по реквизиту Автор в 1С 7.7 и исправить ошибку Поле агрегатного объекта не обнаружено

Программист 1С v7.7
← На главную

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

Разбор основной ошибки: почему не работает НайтиПоРеквизиту

Проанализируем ситуацию, описанную пользователем. В коде была предпринята попытка найти документ внутри цикла перебора документов, используя метод НайтиПоРеквизиту. Выясним причину неудачи:

  1. Отсутствие метода у объекта: В платформе 1С 7.7 объект типа Документ не обладает методом НайтиПоРеквизиту. Этот метод предназначен исключительно для объектов типа Справочник.
  2. Методологическая ошибка: Использование поиска внутри цикла Пока Док.ПолучитьДокумент()=1 Цикл лишено смысла. Если мы уже перебираем документы, нам не нужно «искать» их — нам нужно просто проверять условие соответствия реквизита.
  3. Неверный метод позиционирования: Метод ПолучитьЭлемент() также относится к справочникам. Для документов используется ПолучитьДокумент().

Проблема типов данных: Автор — это не строка

Одной из скрытых ловушек является тип значения реквизита Автор. Как правило, это не просто текстовое поле с фамилией, а ссылка на элемент справочника (например, Справочник.Пользователи или Справочник.Сотрудники).

Если в форме обработки в поле ФамАвтора введена строка «Иванов», а реквизит Автор в документе хранит ссылку на объект, то прямое сравнение Док.Автор = ФамАвтора всегда будет выдавать «Ложь», так как нельзя приравнять объект к строке. Рассмотрим, как правильно подготовить данные для поиска.


// Сначала найдем объект автора в соответствующем справочнике
СпрПользователи = СоздатьОбъект("Справочник.Пользователи");
Если СпрПользователи.НайтиПоНаименованию(ФамАвтора, 0, 1) = 1 Тогда
    НужныйАвтор = СпрПользователи.ТекущийЭлемент();
Иначе
    Предупреждение("Пользователь с такой фамилией не найден!");
    Возврат;
КонецЕсли;

Только после того, как мы получили ссылку на объект в переменную НужныйАвтор, мы можем приступать к поиску документов.

Способ №1: Использование метода ВыбратьПоЗначению

Если нам нужно найти документы по конкретному значению реквизита (в нашем случае по Автору), и этот реквизит является общим или для него в конфигураторе установлен признак «Отбор по реквизиту» или «Сортировка», то самым эффективным методом будет ВыбратьПоЗначению.

Рассмотрим пример реализации этого метода:


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

Важно: Если в Конфигураторе для реквизита Автор не включен «Отбор», программа выдаст ошибку при выполнении этого метода. В таком случае придется использовать другие подходы.

Способ №2: Использование объекта Запрос

Использование запросов — это «золотой стандарт» разработки в 1С 7.7, когда требуется выборка данных по условиям. Запросы работают быстрее, чем перебор документов в цикле, особенно на больших базах данных.

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


Процедура ПоискЧерезЗапрос()
    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса = 
    "//{{ЗАПРОС(ПоискПоАвтору)
    |Период с ВыбДатаНач по ВыбДатаКон;
    |ТекДок = Документ.ВизированиеТребованиеТМЦиОС.ТекущийДокумент;
    |АвторДока = Документ.ВизированиеТребованиеТМЦиОС.Автор;
    |Группировка ТекДок;
    |Условие(АвторДока = НужныйАвтор);
    |"//}}ЗАПРОС
    ;
    
    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
        Возврат;
    КонецЕсли;

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

Способ №3: Прямой перебор (с исправлениями)

Если по каким-то причинам вы не можете использовать запрос или метод ВыбратьПоЗначению (например, сложная логика или отсутствие индексов), можно использовать перебор всех документов, но делать это нужно правильно. Разберем исправленный вариант кода автора:


Процедура ПоискДокументаПеребором()
    // 1. Получаем объект-ссылку для сравнения
    Спр = СоздатьОбъект("Справочник.Пользователи");
    Если Спр.НайтиПоНаименованию(ФамАвтора, 0, 1) = 0 Тогда
        Сообщить("Автор не найден в справочнике");
        Возврат;
    КонецЕсли;
    ТекАвтор = Спр.ТекущийЭлемент();

    // 2. Создаем объект документа
    Док = СоздатьОбъект("Документ.ВизированиеТребованиеТМЦиОС"); 
    
    // 3. Выбираем документы за период
    Док.ВыбратьДокументы(ДатаНач, ДатаКон);
    
    Пока Док.ПолучитьДокумент() = 1 Цикл
        // 4. Сравниваем ссылку в документе с нашей ссылкой
        Если Док.Автор = ТекАвтор Тогда
            // Никаких НайтиПоРеквизиту и ПолучитьЭлемент тут быть не должно!
            Сообщить("Документ найден: " + Док.Автор + " | " + Док.ДатаДок);
        КонецЕсли;    
    КонецЦикла;
КонецПроцедуры

Подведем итоги

Мы проанализировали основные причины возникновения ошибки и рассмотрели три способа поиска документов. Помните следующие правила работы в 1С 7.7:

Соблюдение этих простых правил поможет вам писать чистый, быстрый и лишенный досадных ошибок код на платформе «семерки».

← На главную