1с запрос по таблице значений

Очень часто это порождает распространенную ошибку — запрос в цикле. То есть разработчик не умеет включать таблицу значений в запрос и поэтому начинает обходить её в цикле и делать на каждую итерацию свой запрос. Рассмотрим на простом примере, как это сделать.

Пример

В качестве примера размещения таблицы значения в запросе 1С 8.3 возьмем простую ситуацию — есть , в которой содержится список номенклатуры. Необходимо получить данные по остаткам на складах по каждой номенклатурной позиции.

Получите 267 видеоуроков по 1С бесплатно:

Может быть две ситуации, как создана таблица значений, — программно и уже получена откуда-то (например, ТЧ документа). Если таблица создана программно, необходимо установить тип колонки , сделать это несложно

Т.е. при добавление колонки необходимо вторым параметром указать типы данных с помощью конструктора объекта «ОписаниеТипов».

Перейдем к построению запроса. Таблицу значений можно передать в запрос простым &Параметром.

Обязательный нюанс — созданную таблицу необходимо поместить результат во временную таблицу, в противном случае система выдаст сообщение: «Ошибка при вызове метода контекста (Выполнить): Содержимое объекта данных может быть выбрано только во временную таблицу ».

Таким образом, мы помещаем первый запрос во временную таблицу, а потом соединяем её с регистром остатков номенклатуры.

Вот и всё, проблема решена.

43
NULL – отсутствующие значения. Не путать с нулевым значением! NULL – это не число, не равно пробелу, пустой ссылке, Неопределено. NULL – типообразующее значение, т.е. есть тип NULL и единственное значение этого типа. NULL... 26
Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос. Создается этот объект вызовом конструкции Новый Запрос. Запрос удобно... 18
В статье приведены полезные приемы при работе с запросами 1С v.8.2, а также сведения, которые не так хорошо известны о языке запросов. Я не стремлюсь дать полное описание языка запросов, а хочу остановиться лишь на... 13
ПОДОБНО - Оператор проверки строки на подобие шаблону. Аналог LIKE в SQL. Оператор ПОДОБНО позволяет сравнить значение выражения, указанного слева от него, со строкой шаблона, указанной справа. Значение выражения...

У нас есть номенклатура, находящаяся в группе "Запрещенная номенклатура", которую нужно запретить пользователям использовать в документе "Заказ поставщику" в табличной части "Товары". При этом стоит учитывать тот факт, что позиция номенклатуры может находиться не в самой группе "Запрещенная номенклатура", а в подчиненных ей группах. В этом случае запрет также должен действовать. Плюс ко всему нужно добавить проверку заполнения внутреннего заказа.

Проверку следует выполнять перед записью документа в базу данных, если текущий режим записи "проведение".

Реализация

Перейдем в модуль объекта документа, в событие "ПередЗаписью". Здесь нам и нужно реализовать проверку корректности заполнения. Поскольку запись в этом событии мы имеем лишь объект документа еще не помещенный в базу данных, то выполнить запрос непосредственно к таблице документа "Товары" у нас не получится.

Почему выполнять проверку нужно именно запросом? Дело в том, что при использовании объектной модели доступа к данным подобная проверка обойдется достаточно не затратной по ресурсам для серверной машины. Если мы будем выполнять конструкции типа:

Если СтрокаТаблицы. Номенклатура. Родитель. Родитель. Родитель = ЗапрещеннаяГруппа Тогда // Действия КонецЕсли ;

то время выполнения события "ПередЗаписью" может резко увеличится.

Наиболее оптимальный вариант решения - это использования запроса для проверки корректности заполнения, ведь в нем мы можем использовать конструкцию

" В ИЕРАРХИИ () "

Которая позволяет получать все элементы справочника, входящие в проверямую группу или элемент. Теперь самое интересное. Вот так мы можем передать таблицу значений в запрос и в дальнейшем обработать ее:

Если РежимЗаписи = РежимЗаписиДокумента. Проведение Тогда // Выгружаем таб. документа в таблицу значений с нужными колонками ТабТовары = Товары. Выгрузить(, " НомерСтроки, Номенклатура, Заказ " ) ; Запрос = Новый Запрос; // Передаем таб. значений в запрос в качестве параметра Запрос. УстановитьПараметр(" ТабДок " , ТабТовары) ; // Устанавливаем запрещенную группу номенклатуры Запрос. УстановитьПараметр(" ЗапрещеннаяГруппа " , Справочники. Номенклатура. НайтиПоНаименованию(" Запрещенная номенклатура " , Истина ) ) ; Запрос. Текст = " ВЫБРАТЬ | Т. НомерСтроки, | Т. Номенклатура, | ВЫБОР | КОГДА Т | | | ИЛИ Т. Заказ = НЕОПРЕДЕЛЕНО | ТОГДА ИСТИНА | ИНАЧЕ ЛОЖЬ | КОНЕЦ КАК ЗаказНеЗаполнен |ПОМЕСТИТЬ Таб |ИЗ // Переданную таблицу подставляем в секцию "ИЗ" в качестве параметра | & ТабДок КАК Т |ГДЕ | (Т. Номенклатура В ИЕРАРХИИ (& ЗапрещеннаяГруппа) | ИЛИ ВЫБОР | КОГДА Т. Заказ = ЗНАЧЕНИЕ(Документ. ЗаказНаПроизводство. ПустаяСсылка) | ИЛИ Т. Заказ = ЗНАЧЕНИЕ(Документ. ЗаказПокупателя. ПустаяСсылка) | ИЛИ Т. Заказ = ЗНАЧЕНИЕ(Документ. ВнутреннийЗаказ. ПустаяСсылка) | ИЛИ Т. Заказ = Неопределено | ТОГДА ИСТИНА | ИНАЧЕ ЛОЖЬ | КОНЕЦ) |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Таб. Номенклатура, | Таб. НомерСтроки, | Таб. ЗаказНеЗаполнен |ИЗ | Таб КАК Таб " ; Выборка = Запрос. Выполнить () . Выбрать() ; // Обрабатываем результат Пока Выборка. Следующий() Цикл ОбщегоНазначения. СообщитьОбОшибке(" В строке " + Выборка. НомерСтроки + " используется запрещенная номенклатура " + " " " " + Выборка. Номенклатура + " " " " + ? (Выборка. ЗаказНеЗаполнен, " , а также не заполнен заказ! " , " " ) , Отказ) ; КонецЦикла ; КонецЕсли ;

В запрос таблица значений передается в качестве параметра. Если открыть такой запрос в конструкторе, то подобная таблица будет определена как "Описание временной таблицы" и выглядеть следующим образом:

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

Также важно понимать, что организовать получение данных из таблицы значений с помощью конструктора запросов не получится. В конструкторе мы можем определить лишь описание временной таблицы. Указать, что выборка будет выполняться из переданного параметра в конструкторе не удастся - появятся синтаксические ошибки.

Вывод

Задача была решена. Пример сработанной проверки перед записью документа:

Конечно, приведенный пример достаточно простой. Задачу можно было решить переместив проверку в событие "ПриЗаписи", тогда мы бы обошлись простым запросам к базе данных без передачи в запрос таблицы значений. О том, чтобы судить о правильности использования описанного способа нужно знать конкретные условия задачи.