Как правильно получить вид документа в запросе 1С:Предприятие 7.7?

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

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

Анализируем проблему: почему "Вид" документа пустой?

Рассмотрим ситуацию, описанную автором темы. В запросе перечисляется несколько видов документов (Инвентаризация, Перемещение, Приходная накладная и т.д.), и для каждого из них выбирается переменная Вид и Автор. Проблема заключается в том, что для части документов ВидДок заполняется, а для остальных остается пустым.

Первое, что нам необходимо понять: в платформе 7.7 встроенный язык запросов («черный запрос») имеет свои внутренние механизмы оптимизации. Если в тексте запроса не указана хотя бы одна агрегатная функция, система может некорректно обрабатывать группировки и выборку системных полей. Это происходит потому, что без функции запрос не видит необходимости «вычислять» данные для каждой строки таблицы, что приводит к пропускам.

Решение №1: Использование агрегатных функций

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


|Период с НачДата по КонДата;
|ВидДок = Документ.ИнвентаризацияТары.Вид, Документ.ПеремещениеМеждуКлиентами.Вид, Документ.ПриходнаяНакладная.Вид;
|Автор = Документ.ИнвентаризацияТары.Автор, Документ.ПеремещениеМеждуКлиентами.Автор, Документ.ПриходнаяНакладная.Автор;
|Функция КолДок = Счётчик();
|Группировка Автор без групп;
|Группировка ВидДок;

Добавление строки Функция КолДок = Счётчик(); заставляет ядро запросов платформы 7.7 перебирать записи физических таблиц базы данных более тщательно, что гарантирует инициализацию переменных в группировках. Это «золотое правило» разработки на 7.7: если в запросе есть группировки, в нем обязана быть хотя бы одна функция.

Решение №2: Использование ТекущийДокумент и метода Вид()

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

Наиболее надежным способом получения вида документа является обращение через ТекущийДокумент с последующей обработкой в цикле обхода результата. Посмотрим на пример правильного построения кода:


ТекстЗапроса = "
|Период с НачДата по КонДата;
|ТекДок = Документ.ПриходнаяНакладная.ТекущийДокумент, Документ.РасходнаяНакладная.ТекущийДокумент;
|Автор = Документ.ПриходнаяНакладная.Автор, Документ.РасходнаяНакладная.Автор;
|Функция К-во = Счётчик();
|Группировка Автор без групп;
|Группировка ТекДок;
|";

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

В данном примере мы не пытаемся заставить запрос вернуть строку с названием вида. Вместо этого мы получаем ссылку на сам документ ТекущийДокумент, а затем, при обходе результата, используем встроенный метод Вид(). Это гарантирует 100% результат, так как метод применяется к уже найденному объекту.

Решение №3: Проверка типизации реквизитов

Разберем ситуацию, когда в запросе объединяются разные типы документов. Когда мы пишем Автор = Документ.А.Автор, Документ.Б.Автор;, система пытается привести эти поля к одному типу данных. Если в документе «ПриходнаяНакладная» автор — это Справочник.Сотрудники, а в «ИнвентаризацияТары» — это Справочник.Пользователи, запрос может отработать некорректно.

Выясним причину: при выполнении UNION-запроса (объединения) в 1С 7.7, тип реквизита часто определяется по первой встреченной таблице. Если последующие таблицы имеют реквизиты другого типа или длины, данные могут «обрезаться» или возвращаться как NULL (пустое значение).

Рекомендация: убедитесь, что реквизит Автор (или любой другой, по которому идет группировка) во всех документах, участвующих в запросе, имеет идентичный тип данных в конфигураторе.

Особенности работы на SQL-версиях

Проанализируем технический нюанс: если ваша база 1С 7.7 работает на MS SQL Server, штатный механизм запросов может вести себя иначе, чем в DBF-версии. При перечислении большого количества видов документов в одной переменной (более 5-7), внутренний оптимизатор может построить неэффективный план выполнения, что приведет к потере данных в выборке.

В таких случаях опытные разработчики рекомендуют:

  1. Разбивать один сложный запрос на несколько простых, если количество видов документов слишком велико.
  2. Использовать внешние компоненты, такие как 1С++, для написания прямых SQL-запросов. Это позволяет избежать ограничений стандартного движка 7.7 и обращаться к таблицам базы данных напрямую.

Итоги и лучшие практики

Подводя итог, выделим основные правила для получения вида документа в запросе 1С 7.7:

Следуя этим шагам, вы сможете избежать пустых значений в отчетах и обеспечите стабильную работу ваших алгоритмов на платформе 1С:Предприятие 7.7.

← На главную