Как правильно настроить запрос с параметрами виртуальной таблицы и вложенным запросом по методике Радченко

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При изучении разработки в среде «1С:Предприятие 8» по методическим пособиям М.Г. Радченко начинающие программисты часто сталкиваются с трудностями при написании сложных запросов вручную или через конструктор. Одной из самых «непокорных» тем является использование вложенных запросов и кортежей (групп полей) в параметрах виртуальных таблиц. Разберем детально, как реализовать проверку остатков материалов с учетом дополнительных характеристик (наборов свойств).

Разбор логики запроса

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

Рассмотрим структуру исходного кода:


Запрос3.Текст = "ВЫБРАТЬ
| ОстаткиМатериаловОстатки.Материал,
| ОстаткиМатериаловОстатки.НаборСвойств,
| ОстаткиМатериаловОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.Остатки( , (Материал, НаборСвойств) В
| (ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура,
| НоменклатураДокумента.НаборСвойств
| ИЗ
| НоменклатураДокумента) И Склад = &Склад)
| КАК ОстаткиМатериаловОстатки
|ГДЕ
| ОстаткиМатериаловОстатки.КоличествоОстаток < 0";

Здесь мы видим использование виртуальной таблицы Остатки. Ключевая особенность заключается в том, что фильтр по материалам и их свойствам накладывается непосредственно в параметрах этой таблицы, а не в секции ГДЕ. Это позволяет платформе оптимизировать работу с СУБД, отсекая лишние записи на этапе расчета итогов.

Пошаговая настройка в конструкторе запроса

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

  1. Откроем Конструктор запроса.
  2. На вкладке Таблицы и поля выберем виртуальную таблицу РегистрНакопления.ОстаткиМатериалов.Остатки.
  3. Нажмем кнопку Параметры виртуальной таблицы (значок с изображением таблицы над списком выбранных таблиц).
  4. В открывшемся окне найдем поле Условие и нажмем кнопку выбора (три точки), чтобы открыть диалог Произвольное выражение.
  5. В нижней части окна (текстовое поле) начнем вводить конструкцию. Сначала напишем открывающую скобку (.
  6. Перетащим из списка доступных полей (слева вверху) поле Материал, затем поставим запятую , и перетащим поле НаборСвойств. Закроем скобку ).
  7. Допишем оператор В ( ).
  8. Теперь самое важное: установим курсор внутри пустых скобок после оператора В, нажмем правую кнопку мыши и выберем пункт Конструктор запроса. Платформа предложит создать вложенный запрос.
  9. В новом окне конструктора выберем нашу временную таблицу НоменклатураДокумента. Если она еще не создана в пакете запросов, ее нужно предварительно описать в предыдущих запросах пакета.
  10. Выберем поля Номенклатура и НаборСвойств. Важно: порядок полей во вложенном запросе должен строго соответствовать порядку в кортеже перед оператором В (сначала номенклатура, потом свойства).
  11. Нажмем ОК. В тексте произвольного выражения появится вложенный селект.
  12. Добавим условие по складу в конец выражения: И Склад = &Склад.

В результате мы должны получить корректно сформированное условие, которое выглядит примерно так:


(Материал, НаборСвойств) В (ВЫБРАТЬ
    НоменклатураДокумента.Номенклатура КАК Материал,
    НоменклатураДокумента.НаборСвойств КАК НаборСвойств
ИЗ
    НоменклатураДокумента)
И Склад = &Склад

Типичные ошибки и способы их решения

Проанализируем ситуации, когда запрос выдает ошибку «Неверный псевдоним» или «Неверный параметр».

Ошибка сопоставления полей: Платформа 1С сопоставляет поля в конструкции (Поле1, Поле2) В (ВЫБРАТЬ ПолеА, ПолеБ) по их позиции, а не по именам. Однако для чистоты кода и во избежание неоднозначностей рекомендуется использовать псевдонимы КАК во вложенном запросе, чтобы имена полей совпадали с измерениями регистра.

Отсутствие временной таблицы: Если конструктор запроса «ругается» на таблицу НоменклатураДокумента, проверим, определена ли она выше в этом же пакете запросов. Временные таблицы доступны только в рамках одного объекта Запрос при использовании общего менеджера временных таблиц.

Индексация: Для повышения производительности, особенно если в документе много строк, рекомендуется индексировать поля временной таблицы НоменклатураДокумента. Это значительно ускорит выполнение операции В внутри виртуальной таблицы.

Зачем нужна проверка на отрицательный остаток?

Разберем, почему мы проверяем именно КоличествоОстаток < 0. В методике Радченко логика следующая:

  1. Документ записывает свои движения в регистр «вслепую».
  2. Сразу после записи (в той же транзакции) выполняется наш Запрос3.
  3. Запрос ищет только те записи по материалам из нашего документа, по которым на текущем складе итоговый остаток стал меньше нуля.
  4. Если такие записи найдены, мы выводим сообщение пользователю о нехватке и устанавливаем Отказ = Истина. Транзакция откатывается, и запись в базе не сохраняется.

Эта методика проста в реализации и гарантирует отсутствие «минусов» на складе, даже если несколько пользователей проводят документы одновременно, так как проверка происходит внутри транзакции с соответствующими блокировками СУБД.

Работа с пустыми свойствами

Рассмотрим ситуацию, когда материал ведется без учета свойств. В этом случае поле НаборСвойств будет содержать пустую ссылку. Наш запрос все равно отработает корректно, так как пустая ссылка — это тоже значение, которое будет сопоставлено в регистре. Однако, если мы забудем указать НаборСвойств в кортеже параметров, система выдаст агрегированный остаток по всем свойствам данного материала, что приведет к неверному результату контроля остатков.

Таким образом, мы выяснили, что использование конструктора запроса внутри окна параметров виртуальной таблицы является самым надежным способом избежать синтаксических ошибок при работе со сложными фильтрами в 1С.

← На главную