При разработке алгоритмов поиска и выборки документов в платформе 1С 7.7 разработчики часто сталкиваются с ситуацией, когда метод Выполнить() отрабатывает без ошибок, однако получить ссылку на сам документ через свойство Запрос.ТекущийДокумент не удается. Разберем по шагам причины такого поведения, особенности работы с группировками и типизацией данных.
В платформе 1С 7.7 объект Запрос устроен таким образом, что обращение к полям запроса (например, Запрос.ТекущийДокумент, Запрос.Контрагент) возвращает пустое значение до тех пор, пока не будет выполнен вход в цикл выборки по конкретной группировке. Без объявления секции Группировка в тексте запроса и без вызова метода Группировка() в коде получить значения реквизитов невозможно.
Рассмотрим, как правильно составить текст запроса с группировкой по документу:
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|Период с ВыбДата по ВыбДата;
|ТекущийДокумент = Документ.ПоступлениеТоваров.ТекущийДокумент;
|Контрагент = Документ.ПоступлениеТоваров.Контрагент;
|Сумма = Документ.ПоступлениеТоваров.Всего;
|Группировка ТекущийДокумент без Групп;
|Условие(Контрагент = xml_Контрагент);
|Условие(Сумма = xml_Сумма);
|";
После успешного выполнения запроса необходимо организовать обход результатов в цикле с помощью метода Группировка():
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка("ТекущийДокумент") = 1 Цикл
Док = Запрос.ТекущийДокумент;
Сообщить("Найден документ: " + Строка(Док));
КонецЦикла;
Иначе
Сообщить("Ошибка выполнения запроса!");
КонецЕсли;
Важно: успешный возврат единицы методом Запрос.Выполнить() означает лишь то, что синтаксис запроса корректен и он успешно отработал. Это не гарантирует наличие найденных строк. Фактическое наличие данных проверяется внутри цикла Пока Запрос.Группировка(...) = 1 либо проверкой количества строк в выгруженной таблице значений.
Встроенный язык 1С 7.7 не выполняет неявное приведение типов при фильтрации данных внутри запроса. Если значение даты или ссылки получено из внешнего источника (например, при разборе XML-файла или текстового документа), оно может иметь строковый тип данных. Передача строки в условие или секцию Период с ... по ... приведет к тому, что запрос не найдет ни одной записи.
Проанализируем типичные ошибки типизации и способы их устранения:
Дата с помощью системной функции Дата():
Если ТипЗначенияСтр(xml_ДатаДок) = "Строка" Тогда
ИстиннаяДата = Дата(xml_ДатаДок);
Иначе
ИстиннаяДата = xml_ДатаДок;
КонецЕсли;
Период с ... по ..., дополнительное условие вида Условие(Дата = xml_ДатаДок); является лишним и может вызывать конфликты при фильтрации.Справочник.Контрагенты), а не строковым наименованием или кодом.Если требуется найти конкретный документ определенного вида за одну дату или короткий интервал, создание объекта Запрос может быть избыточным. Более производительным и простым решением является стандартная выборка через контекст документа:
Док = СоздатьОбъект("Документ.ПоступлениеТоваров");
Док.ВыбратьДокументы(ИстиннаяДата, ИстиннаяДата);
Пока Док.ПолучитьДокумент() = 1 Цикл
Если (Док.Контрагент = xml_Контрагент) И (Док.Всего = xml_Сумма) Тогда
Сообщить("Найден документ: " + Строка(Док.ТекущийДокумент()));
// Необходимые действия с документом
КонецЕсли;
КонецЦикла;
Если из внешних данных известен номер документа и его дата, оптимально применить метод прямого позиционирования Док.НайтиПоНомеру(НомерДок, ИстиннаяДата), что исключает необходимость полного перебора документов за день.