При разработке обработчиков обмена данными в Конвертации данных 2.0 для платформы 1С 7.7 часто возникает необходимость найти существующий документ в базе по значению произвольного реквизита (например, уникальному идентификатору, внешнему коду или значению, переданному в комментарии). Начинающие разработчики сталкиваются с ошибками синтаксиса встроенного языка запросов или с ограничениями платформы при попытке найти документ.
Рассмотрим подробно способы поиска документов в платформе 1С 7.7, разберем частые ошибки при составлении запросов и проанализируем пример решения этой задачи в обработчике обмена.
Выясним причину популярной ошибки при выполнении встроенного запроса. Допустим, нам необходимо найти документ вида ПоступлениеТМЦ по реквизиту ВнутреннийКод8, значение которого хранится в локальной переменной лВнутреннийКод8.
Распространенная ошибка заключается в том, что переменная реквизита сразу передается в секцию Условие() без предварительного описания в теле запроса:
лВнутреннийКод8 = Объект.Комментарий;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|ТекущийЭлемент = Документ.ПоступлениеТМЦ.ТекущийДокумент;
|ДатаИзменения = Документ.ПоступлениеТМЦ.ДатаДок;
|Группировка ТекущийЭлемент;
|Условие(ВнутреннийКод8 = лВнутреннийКод8);";
Запрос.Выполнить(ТекстЗапроса);
При выполнении такого кода платформа 1С 7.7 выдаст ошибку: «Переменная не определена (ВНУТРЕННИЙКОД8)». Это связано со спецификой языка запросов 1С 7.7: любое поле, по которому накладывается фильтр в секции Условие(), должно быть обязательно объявлено в тексте запроса и связано с реквизитом объекта метаданных.
Разберем по шагам правильный вариант составления запроса:
ВнутреннийКод8 = Документ.ПоступлениеТМЦ.ВнутреннийКод8;.Группировка ТекущийЭлемент;.Условие(ВнутреннийКод8 = лВнутреннийКод8);.Посмотрим на исправленный и рабочий код:
лВнутреннийКод8 = Объект.Комментарий;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|ТекущийЭлемент = Документ.ПоступлениеТМЦ.ТекущийДокумент;
|ДатаИзменения = Документ.ПоступлениеТМЦ.ДатаДок;
|ВнутреннийКод8 = Документ.ПоступлениеТМЦ.ВнутреннийКод8;
|Группировка ТекущийЭлемент;
|Условие(ВнутреннийКод8 = лВнутреннийКод8);";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка(1) = 1 Цикл
Сообщить("Найден документ: " + Запрос.ТекущийЭлемент);
КонецЦикла;
КонецЕсли;
В платформе 1С 7.7 помимо запросов существует встроенный метод выборки документов по значению реквизита — ВыбратьПоЗначению() объекта Документ.
Для применения этого метода должны соблюдаться следующие условия:
Проанализируем пример использования этого метода:
Док = СоздатьОбъект("Документ.ПоступлениеТМЦ");
ДатаНач = '01.01.2023';
ДатаКон = РабочаяДата();
Если Док.ВыбратьПоЗначению(ДатаНач, ДатаКон, "ВнутреннийКод8", лВнутреннийКод8) = 1 Тогда
Пока Док.ПолучитьДокумент() = 1 Цикл
Сообщить("Найден документ № " + Док.НомерДок + " от " + Док.ДатаДок);
КонецЦикла;
КонецЕсли;
Если реквизит является локальным реквизитом конкретного вида документа, а не общим с флагом отбора, данный метод применить нельзя. В этом случае поиск осуществляется исключительно с помощью объекта Запрос.
При написании логики в обработчиках обмена (например, в событии После загрузки правила конвертации объектов) важно помнить следующие моменты:
ВыбратьСтроки() и ПолучитьСтроку()), для сохранения изменений необходимо явно вызывать метод Объект.Записать().