Работа с запросами в платформе 1С:Предприятие 7.7 существенно отличается от современной восьмой версии. Программисты часто сталкиваются с ситуацией, когда запрос, написанный по всем правилам логики, возвращает пустые значения для некоторых полей или работает нестабильно при объединении нескольких видов документов. В данной статье мы подробно разберем, почему запрос может не определять Вид документа, и как правильно составить текст запроса, чтобы получить корректные данные.
Рассмотрим ситуацию, описанную автором темы. В запросе перечисляется несколько видов документов (Инвентаризация, Перемещение, Приходная накладная и т.д.), и для каждого из них выбирается переменная Вид и Автор. Проблема заключается в том, что для части документов ВидДок заполняется, а для остальных остается пустым.
Первое, что нам необходимо понять: в платформе 7.7 встроенный язык запросов («черный запрос») имеет свои внутренние механизмы оптимизации. Если в тексте запроса не указана хотя бы одна агрегатная функция, система может некорректно обрабатывать группировки и выборку системных полей. Это происходит потому, что без функции запрос не видит необходимости «вычислять» данные для каждой строки таблицы, что приводит к пропускам.
Самый простой и зачастую самый эффективный способ заставить запрос 1С 7.7 работать корректно — это добавить в него фиктивную или полезную функцию, например Счётчик(). Рассмотрим, как изменится текст запроса после модификации:
|Период с НачДата по КонДата;
|ВидДок = Документ.ИнвентаризацияТары.Вид, Документ.ПеремещениеМеждуКлиентами.Вид, Документ.ПриходнаяНакладная.Вид;
|Автор = Документ.ИнвентаризацияТары.Автор, Документ.ПеремещениеМеждуКлиентами.Автор, Документ.ПриходнаяНакладная.Автор;
|Функция КолДок = Счётчик();
|Группировка Автор без групп;
|Группировка ВидДок;
Добавление строки Функция КолДок = Счётчик(); заставляет ядро запросов платформы 7.7 перебирать записи физических таблиц базы данных более тщательно, что гарантирует инициализацию переменных в группировках. Это «золотое правило» разработки на 7.7: если в запросе есть группировки, в нем обязана быть хотя бы одна функция.
Проанализируем другой важный аспект. В 1С 7.7 обращение Документ.ИмяВида.Вид может интерпретироваться системой двояко. Если в метаданных документа программист вручную не создал реквизит с идентификатором «Вид», то такое обращение в запросе может работать нестабильно. Важно помнить: Вид() — это метод объекта, а в теле запроса мы оперируем полями таблиц.
Наиболее надежным способом получения вида документа является обращение через ТекущийДокумент с последующей обработкой в цикле обхода результата. Посмотрим на пример правильного построения кода:
ТекстЗапроса = "
|Период с НачДата по КонДата;
|ТекДок = Документ.ПриходнаяНакладная.ТекущийДокумент, Документ.РасходнаяНакладная.ТекущийДокумент;
|Автор = Документ.ПриходнаяНакладная.Автор, Документ.РасходнаяНакладная.Автор;
|Функция К-во = Счётчик();
|Группировка Автор без групп;
|Группировка ТекДок;
|";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка(1) = 1 Цикл
// Группировка по автору
Пока Запрос.Группировка(2) = 1 Цикл
// Получаем вид документа через метод объекта
ИмяВида = Запрос.ТекДок.Вид();
Сообщить("Автор: " + Запрос.Автор + ", Документ: " + ИмяВида);
КонецЦикла;
КонецЦикла;
КонецЕсли;
В данном примере мы не пытаемся заставить запрос вернуть строку с названием вида. Вместо этого мы получаем ссылку на сам документ ТекущийДокумент, а затем, при обходе результата, используем встроенный метод Вид(). Это гарантирует 100% результат, так как метод применяется к уже найденному объекту.
Разберем ситуацию, когда в запросе объединяются разные типы документов. Когда мы пишем Автор = Документ.А.Автор, Документ.Б.Автор;, система пытается привести эти поля к одному типу данных. Если в документе «ПриходнаяНакладная» автор — это Справочник.Сотрудники, а в «ИнвентаризацияТары» — это Справочник.Пользователи, запрос может отработать некорректно.
Выясним причину: при выполнении UNION-запроса (объединения) в 1С 7.7, тип реквизита часто определяется по первой встреченной таблице. Если последующие таблицы имеют реквизиты другого типа или длины, данные могут «обрезаться» или возвращаться как NULL (пустое значение).
Рекомендация: убедитесь, что реквизит Автор (или любой другой, по которому идет группировка) во всех документах, участвующих в запросе, имеет идентичный тип данных в конфигураторе.
Проанализируем технический нюанс: если ваша база 1С 7.7 работает на MS SQL Server, штатный механизм запросов может вести себя иначе, чем в DBF-версии. При перечислении большого количества видов документов в одной переменной (более 5-7), внутренний оптимизатор может построить неэффективный план выполнения, что приведет к потере данных в выборке.
В таких случаях опытные разработчики рекомендуют:
Подводя итог, выделим основные правила для получения вида документа в запросе 1С 7.7:
Функция Кол = Счётчик();, даже если вам не нужно количество документов. Это «будит» движок запроса.Вид используйте ТекущийДокумент и получайте вид методом Вид() при обработке результата.Следуя этим шагам, вы сможете избежать пустых значений в отчетах и обеспечите стабильную работу ваших алгоритмов на платформе 1С:Предприятие 7.7.