При изучении разработки в среде «1С:Предприятие 8» по методическим пособиям М.Г. Радченко начинающие программисты часто сталкиваются с трудностями при написании сложных запросов вручную или через конструктор. Одной из самых «непокорных» тем является использование вложенных запросов и кортежей (групп полей) в параметрах виртуальных таблиц. Разберем детально, как реализовать проверку остатков материалов с учетом дополнительных характеристик (наборов свойств).
Прежде чем переходить к технической реализации, проанализируем сам текст запроса. Нам необходимо получить отрицательные остатки материалов после того, как документ сделал движения по регистру. Это классическая «старая» методика проведения документа, где мы сначала записываем данные в регистр, а затем проверяем, не ушли ли остатки в минус.
Рассмотрим структуру исходного кода:
Запрос3.Текст = "ВЫБРАТЬ
| ОстаткиМатериаловОстатки.Материал,
| ОстаткиМатериаловОстатки.НаборСвойств,
| ОстаткиМатериаловОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.Остатки( , (Материал, НаборСвойств) В
| (ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура,
| НоменклатураДокумента.НаборСвойств
| ИЗ
| НоменклатураДокумента) И Склад = &Склад)
| КАК ОстаткиМатериаловОстатки
|ГДЕ
| ОстаткиМатериаловОстатки.КоличествоОстаток < 0";
Здесь мы видим использование виртуальной таблицы Остатки. Ключевая особенность заключается в том, что фильтр по материалам и их свойствам накладывается непосредственно в параметрах этой таблицы, а не в секции ГДЕ. Это позволяет платформе оптимизировать работу с СУБД, отсекая лишние записи на этапе расчета итогов.
Многие новички пытаются написать это выражение вручную, допуская ошибки в синтаксисе. Выясним, как сделать это правильно, используя визуальные инструменты платформы. Посмотрим на алгоритм действий:
РегистрНакопления.ОстаткиМатериалов.Остатки.(.Материал, затем поставим запятую , и перетащим поле НаборСвойств. Закроем скобку ). В ( ).В, нажмем правую кнопку мыши и выберем пункт Конструктор запроса. Платформа предложит создать вложенный запрос.НоменклатураДокумента. Если она еще не создана в пакете запросов, ее нужно предварительно описать в предыдущих запросах пакета.Номенклатура и НаборСвойств. Важно: порядок полей во вложенном запросе должен строго соответствовать порядку в кортеже перед оператором В (сначала номенклатура, потом свойства). И Склад = &Склад.В результате мы должны получить корректно сформированное условие, которое выглядит примерно так:
(Материал, НаборСвойств) В (ВЫБРАТЬ
НоменклатураДокумента.Номенклатура КАК Материал,
НоменклатураДокумента.НаборСвойств КАК НаборСвойств
ИЗ
НоменклатураДокумента)
И Склад = &Склад
Проанализируем ситуации, когда запрос выдает ошибку «Неверный псевдоним» или «Неверный параметр».
Ошибка сопоставления полей: Платформа 1С сопоставляет поля в конструкции (Поле1, Поле2) В (ВЫБРАТЬ ПолеА, ПолеБ) по их позиции, а не по именам. Однако для чистоты кода и во избежание неоднозначностей рекомендуется использовать псевдонимы КАК во вложенном запросе, чтобы имена полей совпадали с измерениями регистра.
Отсутствие временной таблицы: Если конструктор запроса «ругается» на таблицу НоменклатураДокумента, проверим, определена ли она выше в этом же пакете запросов. Временные таблицы доступны только в рамках одного объекта Запрос при использовании общего менеджера временных таблиц.
Индексация: Для повышения производительности, особенно если в документе много строк, рекомендуется индексировать поля временной таблицы НоменклатураДокумента. Это значительно ускорит выполнение операции В внутри виртуальной таблицы.
Разберем, почему мы проверяем именно КоличествоОстаток < 0. В методике Радченко логика следующая:
Запрос3.Отказ = Истина. Транзакция откатывается, и запись в базе не сохраняется.Эта методика проста в реализации и гарантирует отсутствие «минусов» на складе, даже если несколько пользователей проводят документы одновременно, так как проверка происходит внутри транзакции с соответствующими блокировками СУБД.
Рассмотрим ситуацию, когда материал ведется без учета свойств. В этом случае поле НаборСвойств будет содержать пустую ссылку. Наш запрос все равно отработает корректно, так как пустая ссылка — это тоже значение, которое будет сопоставлено в регистре. Однако, если мы забудем указать НаборСвойств в кортеже параметров, система выдаст агрегированный остаток по всем свойствам данного материала, что приведет к неверному результату контроля остатков.
Таким образом, мы выяснили, что использование конструктора запроса внутри окна параметров виртуальной таблицы является самым надежным способом избежать синтаксических ошибок при работе со сложными фильтрами в 1С.