Упорядочивание результатов запроса. Маленькие хитрости больших запросов 1с 8.3 упорядочить результат запроса из таблицы

/
Реализация обработки данных

Упорядочивание результатов запроса

1.1. Если алгоритм обработки результатов запроса зависит от порядка записей в запросе или если результат обработки запроса в той или иной форме представляется пользователю , то в тексте запроса следует использовать предложение УПОРЯДОЧИТЬ ПО . В отсутствие выражения УПОРЯДОЧИТЬ ПО невозможно сделать никаких предположений о том, в каком порядке будут представлены записи в результатах запроса.

Типичные примеры проблем, которые могут возникать:

  • разная последовательность строк табличной части при заполнении по результатам запроса;
  • разный порядок вывода данных (строк, колонок) в отчетах;
  • разное заполнение движений документа по результатам запроса (*).

Вероятность возникновения разных результатов при выполнении одинаковых действий повышается

  • при переносе информационной базы на другую СУБД
  • при смене версии СУБД
  • при изменении параметров СУБД

* Примечание: упорядочивание результатов запросов, по которым формируются движения, оправдано только в том случае, если упорядочивание является частью алгоритма формирования движений (например, списание остатков партий товаров по FIFO). В остальных случаях упорядочивать записи не следует, так как дополнительное упорядочивание будет создавать избыточную нагрузку на СУБД.

1.2. Если результаты запроса должны тем или иным образом отображаться пользователю, то

  • упорядочивать результаты таких запросов необходимо по полям примитивных типов;
  • упорядочивание по полям ссылочных типов нужно заменять на упорядочивание по строковым представлениям этих полей.

В противном случае порядок следования строк будет выглядеть для пользователя случайным (необъяснимым).

См. также: Сортировка строк таблиц значений

1.3. Отсутствие предложения УПОРЯДОЧИТЬ ПО оправдано только в тех случаях, когда

  • алгоритм обработки результатов запроса не рассчитывает на определенный порядок записей
  • результат обработки выполненного запроса не показывается пользователю
  • результат запроса - заведомо одна запись

Совместное использование с конструкцией РАЗЛИЧНЫЕ

2. Если в запросе используется конструкция РАЗЛИЧНЫЕ , упорядочивание следует выполнять только по полям, включенным в выборку (в секции ВЫБРАТЬ ).

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

Ограничения на использование конструкции АВТОУПОРЯДОЧИВАНИЕ

3. Использование конструкции ПЕРВЫЕ совместно с конструкцией АВТОУПОРЯДОЧИВАНИЕ запрещено.

В остальных случаях конструкцию АВТОУПОРЯДОЧИВАНИЕ также не рекомендуется использовать, так как разработчик не контролирует, какие именно поля будут использованы для упорядочивания. Применение такой конструкции оправдано только в тех случаях, когда получаемый порядок записей не важен, но при этом он должен быть одинаковым в не зависимости от применяемой СУБД.

Внимание! Перед вами ознакомительная версия урока, материалы которого могут быть неполными.

Войдите на сайт как ученик

Войдите как ученик, чтобы получить доступ к материалам школы

Язык запросов 1С 8.3 для начинающих программистов: упорядочивание

Давайте напишем запрос, который получает из таблицы Справочник.Еда код и название еды:

ВЫБРАТЬ Код, Наименование ИЗ Справочник. Еда

Как всегда, выполните этот запрос у себя на компьютере.

С большой долей вероятности у вас получится следующий результат:

Возможно вы удивитесь, но при таком написании запроса никто не гарантирует нам именно такого порядка выдачи записей в таблице. В случае использования клиент-серверного режима работы на различных СУБД результат мог бы быть и такой:

И..., ну в общем вы поняли, что если мы не указываем порядок сортировки (упорядочивания) результата запроса, то этот самый порядок может быть абсолютно любым.

Поэтому правилом хорошего тона при написании запросов считается упорядочивание результатов запроса даже тогда, когда нам этого не требуется явно.

Секция УПОРЯДОЧИТЬ ПО

Поля по которым требуется упорядочить запрос перечисляются в секции УПОРЯДОЧИТЬ ПО через запятую:

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

  • ВОЗР - упорядочивание по возрастанию.
  • УБЫВ - упорядочивание по убыванию.

Если не указывать ни одно из этих слов, считается, что сортировка идёт по возрастанию.

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

А теперь упорядочим следующую таблицу

так, чтобы сначала шла сортировка по полю Вкус по возрастанию, а затем (среди строчек с одинаковым значением поля Вкус ) шла сортировка по полю Цвет по убыванию:

ВЫБРАТЬ Вкус, Цвет ИЗ Справочник. Еда УПОРЯДОЧИТЬ ПО Вкус. Наименование ВОЗР, Цвет. Наименование УБЫВ

Отдельно обращаю ваше внимание на то, что мы указали сортировку не по самим полям Вкус и Цвет, а по их строковому реквизиту Наименование . Вы читаете ознакомительную версию урока, полноценные уроки находятся .

Это связано с тем, что сортировка возможна лишь по полям имеющим один из типов: Строка , Число , Дата .

А поля Вкус и Цвет являются ссылками на элементы справочников Вкус и Цвет , сортировать по которым не имеет смысла (в этом случае сортировка будет вестись по внутреннему идентификатору ссылки). Зато можно сделать сортировку по одному из реквизитов этих элементов. Наиболее подходящим в нашем случае будет строковый реквизит Наименование .

Возможность автоупорядочивания

Ключевое слово АВТОУПОРЯДОЧИВАНИЕ позволяет включить режим автоматического формирования полей для упорядочивания результатов запроса.

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

Итак, поехали.

Прежде всего, ключевое слово АВТОУПОРЯДОЧИВАНИЕ может быть расположено в запросе сразу за или вместо секции УПОРЯДОЧИТЬ ПО:

Автоупорядочивание работает по следующим принципам:

Случай #1

Если в запросе:

  • есть секция УПОРЯДОЧИТЬ ПО

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

Для таблиц документов полем сортировки по умолчанию является дата документа.

Рассмотрим пример:

Так как поле сортировки ЛюбимыйЦвет имеет тип Справочник.Цвета Наименование

Случай #2

Если в запросе:

  • но есть секция ИТОГИ ПО (её мы будем проходить )

В этом случае результат запроса будет упорядочен по полям итогов (в той же последовательности).

Случай #3

Если в запросе:

  • отсутствует секция УПОРЯДОЧИТЬ ПО
  • отсутствует секция ИТОГИ ПО
  • но есть секция СГРУППИРОВАТЬ ПО (группировку мы проходили )

В этом случае результат запроса будет упорядочен по полям группировки (в той же последовательности).

Рассмотрим пример:

Так как поле группировки Город имеет тип Справочник.Города , в настройках которого основным представлением выбрано поле Наименование , то этот запрос эквивалентен:

Случай #4

Наконец, если в запросе:

  • отсутствует секция УПОРЯДОЧИТЬ ПО
  • отсутствует секция ИТОГИ ПО
  • отсутствует секция СГРУППИРОВАТЬ ПО

В этом случае результат запроса будет упорядочен по полям сортировки по умолчанию для таблиц, из которых выбираются данные, в порядке их появления в запросе.

Рассмотрим пример:

Почему использование автоупорядочивания нежелательно

Автоупорядочивание подходит:

  • для универсальных запросов, когда разработчик не может предвидеть из каких таблиц будут запрашиваться данные
  • для случаев, когда получаемый порядок записей не важен, но при этом он должен быть одинаковым в независимости от применяемой СУБД

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

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

А завтра фирма "1С" (или другой разработчик) изменят настройки базы в конфигураторе так, что полем сортировки по умолчанию для справочника Еда станет, к примеру, поле Код . И, если мы использовали автоупорядочивание в запросе, то наш отчет сломается, ведь порядок сортировки уже будет другим. Вы читаете ознакомительную версию урока, полноценные уроки находятся .

Поэтому всегда старайтесь указывать конкретные поля и конкретный порядок сортировки по ним в секции УПОРЯДОЧИТЬ ПО , такой запрос уже не сломать просто так:

ВЫБРАТЬ Код, Наименование ИЗ Справочник. Еда УПОРЯДОЧИТЬ ПО Наименование ВОЗР

Пройдите тест

Начать тест

1. По умолчанию результаты запроса упорядочиваются

2. Результаты запроса можно упорядочивать по

3. "УПОРЯДОЧИТЬ ПО ИМЯ_ПОЛЯ" упорядочивает по

4. Чтобы упорядочить по возрастанию в секции УПОРЯДОЧИТЬ ПО необходимо указать имя поля и ключевое слово

5. Чтобы упорядочить по убыванию в секции УПОРЯДОЧИТЬ ПО необходимо указать имя поля и ключевое слово

6. Автоупорядочивание в запросах возможно

Язык запросов в 1С 8 — это упрощенный аналог широко известного «структурированного языка программирования» (как чаще его называют, SQL). Но в 1С он используется только для чтения данных, для изменения данных применяется объектная модель данных.

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

Пример запроса:

ВЫБРАТЬ
Банки.Наименование,
Банки.КоррСчет
ИЗ
Справочник.Банки КАК Банки

Данный запрос позволит увидеть нам информацию о наименовании и корреспондентском счете всех существующих в базе данных банков.

Язык запросов – самой простой и эффективный способ получения информации. Как видно из примера выше, в языке запросов нужно апеллировать именами метаданных ( – это список объектов системы, из которых состоит конфигурация, т.е справочники, документы, регистры и т.д.).

Описание конструкций языка запросов

Структура запросов

Для получения данных достаточно использовать конструкции «ВЫБРАТЬ» (select) и «ИЗ» (from). Простейший запрос выглядит следующим образом:

ВЫБРАТЬ * ИЗ Справочники.Номенклатура

Где «*» означает выбор всех полей таблицы, а Справочники.Номенклатура – имя таблицы в базе данных.

Рассмотрим более сложный и общий пример:

ВЫБРАТЬ
<ИмяПоля1> КАК <ПредставлениеПоля1>,
Сумма(<ИмяПоля2>) КАК <ПредставлениеПоля2>
ИЗ
<ИмяТаблицы1> КАК <ПредставлениеТаблицы1>
<ТипСоединения> СОЕДИНЕНИЕ <ИмяТаблицы2> КАК <ПредставлениеТаблицы2>
ПО <УсловиеСоединениеТаблиц>

ГДЕ
<УсловиеОтбораДанных>

СГРУППИРОВАТЬ ПО
<ИмяПоля1>

УПОРЯДОЧИТЬ ПО
<ИмяПоля1>

ИТОГИ
<ИмяПоля2>
ПО
<ИмяПоля1>

В данном запросе мы выбираем данные полей «ИмяПоля1» и «ИмяПоля1» из таблиц «ИмяТаблицы1» и «ИмяТаблицы», присваиваем полям синонимы с помощью оператора «КАК», соединяем их по некому условию «УсловиеСоединениеТаблиц».

Из полученных данных мы отбираем только данные, соответствующие условию из «ГДЕ» «УсловиеОтбораДанных».Далее мы группируем запрос по полю «ИмяПоля1», при этом суммируя «ИмяПоля2».Создаём итоги по полю «ИмяПоля1» и итоговым полем «ИмяПоля2».

Последним действием мы сортируем запрос с помощью конструкции «УПОРЯДОЧИТЬ ПО».

Общие конструкции

Рассмотрим общие конструкции языка запросов 1С 8.2.

ПЕРВЫЕ n

С помощью данного оператора можно получить n количество первых записей. Порядок записей определяется порядком в запросе.

ВЫБРАТЬ ПЕРВЫЕ 100
Банки.Наименование,
Банки.Код КАК БИК
ИЗ
Справочник.Банки КАК Банки
УПОРЯДОЧИТЬ ПО
Банки.Наименование

Запросом будет получено первых 100 записей справочника «Банки», упорядоченных по алфавиту.

РАЗРЕШЕННЫЕ

Эта конструкция актуальна для работы с механизмом . Суть механизма в ограничении чтения (и других действий) пользователям для конкретных записей в таблице базы данных, а не таблицы в целом.

Если пользователь пытается с помощью запроса прочитать записи недоступные ему, он получит сообщение об ошибке. Чтобы этого избежать, следует использовать конструкцию «РАЗРЕШЕННЫЕ», т.е запрос будет читать только разрешенные ему записи.

ВЫБРАТЬ РАЗРЕШЕННЫЕ
ХранилищеДополнительнойИнформации.Ссылка
ИЗ
Справочник.ХранилищеДополнительнойИнформации

РАЗЛИЧНЫЕ

Использование «РАЗЛИЧНЫЕ» позволит исключить попадание строк-дублей в результат запроса 1С. Дублирование означает совпадение всех полей запроса.

ВЫБРАТЬ ПЕРВЫЕ 100
Банки.Наименование,
Банки.Код КАК БИК
ИЗ
Справочник.Банки КАК Банки

ПустаяТаблица

Данная конструкция используется очень редко для объединения запросов. При объединении может возникнуть необходимость указать в одной из таблиц пустую вложенную таблицу. Для этого как раз подойдет оператор «ПустаяТаблица»

Пример из справки 1С 8:

ВЫБРАТЬ Ссылка.Номер, ПУСТАЯТАБЛИЦА.(Ном, Тов, Кол) КАК Состав
ИЗ Документ.РасхНакл
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ Ссылка.Номер, Состав.(НомерСтроки, Товар, Количество)
ИЗ Документ.РасхНакл Документ.РасходнаяНакладная.Состав.*

ЕСТЬNULL

Очень полезная функция, которая позволяет избежать многих ошибок. ЕстьNULL() позволяет заменить значение NULL на нужное. Очень часто используется в проверках на наличие значения в присоединенных таблицах, например:

ВЫБРАТЬ
НоменклатураСпр.Ссылка,
ЕстьNULL(ОстаткиТовара.КоличествоОстаток,0) КАК КоличествоОстаток
ИЗ


Можно использовать и по-другому. Например, если для каждой строки не известно, в какой таблице существует значение:

ЕСТЬNULL(СчетФактураПолученный.Дата, СчетФактураВыданный.Дата)

КАК – оператор, который позволяет нам присвоить имя (синоним) таблицы или полю. Пример использования мы видели выше.

Данные конструкции очень похожи – они позволяют получить строковое представление нужного значения. Единственное отличие в том, что ПРЕДСТАВЛЕНИЕ преобразует любые значения в строковый тип, а ПРЕДСТАВЛЕНИЕССЫЛКИ — только ссылочные. ПРЕДСТАВЛЕНИЕССЫЛКИ рекомендуется применять в запросах системы компоновки данных для оптимизации, если, конечно, поле ссылочных данных не планируется использовать в отборах .

ВЫБРАТЬ
Представление(Ссылка), //строка, например «Авансовый отчет №123 от 10.10.2015
Представление(ПометкаУдаления) КАК ПометкаУдаленияТекст, //строка, «Да» или «Нет»
ПредставлениеСсылки(ПометкаУдаления) КАК ПометкаУдаленияБулево //булево, Истина или Ложь
ИЗ
Документ.АвансовыйОтчет

ВЫРАЗИТЬ

Выразить позволяет преобразовать значения поля к нужному типу данных. Можно преобразовать значение как к примитивному типу, так и к ссылочному типу.

Выразить для ссылочного типа используется для ограничения запрашиваемых типов данных в полях составного типа, часто используется для оптимизации работы системы. Пример:

ВЫРАЗИТЬ(ТаблицаЗатрат.Субконто1 КАК Справочник.СтатьиЗатрат).ВидДеятельностиДляНалоговогоУчетаЗатрат

Для примитивных типов эта функция часто используется для ограничения количества символов в полях неограниченной длины (с такими полями нельзя сравнивать). Чтобы избежать ошибки «Неверные параметры в операции сравнения. Нельзя сравнивать поля
неограниченной длины и поля несовместимых типов
», необходимо выразить такие поля следующим образом:

ВЫРАЗИТЬ(Комментарий КАК Строка(150))

РАЗНОСТЬДАТ

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

Пример использования ЕСТЬ NULL в запросе 1С:

ВЫБРАТЬ * ИЗ
Спр
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ОстаткиТовара
ПО НоменклатураСпр.Ссылка = РеализованныеТоварыКомитентовОстатки.Номенклатура
ГДЕ НЕ ОстаткиТовара.КоличествоОстаток ЕСТЬ NULL

Тип данных в запросе можно определить следующим образом: с помощью функций ТИП() и ТИПЗНАЧЕНИЯ() или с помощью логического оператора ССЫЛКА. Эти две функции аналогичны.

Предопределенные значения

Помимо использования в запросах переданных параметров в языке запросов 1С можно использовать предопределенные значения или . Например, перечисления, предопределенные справочники, планы счетов и так далее.Для этого используется конструкция «Значение()».

Пример использования:

ГДЕ Номенклатура.ВидНоменклатуры = Значение(Справочник.ВидыНоменклатуры.Товар)

ГДЕ Контрагенты.ВидКонтактнойИнформации = Значение(Перечисление.ВидыКонтактнойИнформации.Телефон)

ГДЕ ОстаткиПоСчетам.СчетУчета = Значение(ПланСчетов.Хозрасчетный.ПрибылиУбытки)

Соединения

Соединения бывают 4 типов: ЛЕВОЕ , ПРАВОЕ , ПОЛНОЕ, ВНУТРЕННЕЕ .

ЛЕВОЕ и ПРАВОЕ СОЕДИНЕНИЕ

Соединения используются для связи двух таблиц по определенному условию. Особенность при ЛЕВОМ СОЕДИНЕНИИ в том, что мы берём первую указанную таблицу полностью и привязываем по условию вторую таблицу. Поля второй таблицы, которые не удалось привязать по условию, заполняются значением NULL .

Например:

Вернет всю таблицу Контрагентов и заполнит поле “Банк” лишь в тех местах, где будет соблюдаться условие “Контрагенты.Наименование = Банки.Наименование”. Если условие не соблюдается, в поле Банк будет установлено NULL .

ПРАВОЕ СОЕДИНЕНИЕ в языке 1С абсолютно аналогично ЛЕВОМУ соединению , за исключением одного отличия – в ПРАВОМ СОЕДИНЕНИИ “главная” таблица – вторая, а не первая.

ПОЛНОЕ СОЕДИНЕНИЕ

ПОЛНОЕ СОЕДИНЕНИЕ отличается от левого и правого тем, что выводит все записи из двух таблиц, соединяет лишь те, которые может соединить по условию.

Например:

ИЗ

ПОЛНОЕ СОЕДИНЕНИЕ
Справочник.Банки КАК Банки

ПО

Язык запросов вернет обе таблицы полностью лишь по выполненному условию соединить записи. В отличие от левого/правого соединения возможно появления NULL в двух полях.

ВНУТРЕННЕЕ СОЕДИНЕНИЕ

ВНУТРЕННЕЕ СОЕДИНЕНИЕ отличается от полного тем, что выводит только те записи, которые смогли соединить по заданному условию.

Например:

ИЗ
Справочник.Контрагенты КАК Клиенты

ВНУТРЕННЕЕ СОЕДИНЕНИЕ
Справочник.Банки КАК Банки

ПО
Клиенты.Наименование = Банки.Наименование

Данный запрос вернет только строки, в которых у банка и контрагента будет одинаковое наименование.

Объединения

Конструкция ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ объединяет два результата в один. Т.е. результат выполнения двух будет «слит» в один, общий.

Т.е система работает точно так же, как и обычные , только для временной таблицы.

Как использовать ИНДЕКСИРОВАТЬ ПО

Однако следует учесть один момент. Построение индекса временной таблицы также требует времени на выполнение. Поэтому целесообразно использовать конструкцию ” ”, только если точно известно, что во временной таблице будет не 1-2 записи. В противном случае эффект может быть обратным – быстродействие от индексированных полей не компенсирует времени построения индекса.

ВЫБРАТЬ
КурсыВалютСрезПоследних.Валюта КАК Валюта,
КурсыВалютСрезПоследних.Курс
ПОМЕСТИТЬ КурсыВалют
ИЗ
РегистрСведений.КурсыВалют.СрезПоследних(&Период,) КАК КурсыВалютСрезПоследних
ИНДЕКСИРОВАТЬ ПО
Валюта
;
ВЫБРАТЬ
ЦеныНоменклатуры.Номенклатура,
ЦеныНоменклатуры.Цена,
ЦеныНоменклатуры.Валюта,
КурсыВалют.Курс
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период,
Номенклатура В (&Номенклатура) И ТипЦен = &ТипЦен) КАК ЦеныНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ КурсыВалют КАК КурсыВалют
ПО ЦеныНоменклатуры.Валюта = КурсыВалют.Валюта

Группировка

Язык запросов 1С позволяет использовать специальные агрегатные функции при группировке результатов запросов. Группировку можно также использовать без агрегатных функций, для «устранения» дублей.

Существуют следующие функции:

Сумма, Количество, Количество разных, Максимум, Минимум, Среднее.

Пример №1:

ВЫБРАТЬ
РеализацияТоваровУслугТовары.Номенклатура,
СУММА(РеализацияТоваровУслугТовары.Количество) КАК Количество,
СУММА(РеализацияТоваровУслугТовары.Сумма) КАК Сумма
ИЗ

СГРУППИРОВАТЬ ПО
РеализацияТоваровУслугТовары.Номенклатура

Запрос получает все строки с товарами и суммирует их по количеству и суммам в разрезе номенклатуры.

Пример №2

ВЫБРАТЬ
Банки.Код,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Банки.Ссылка) КАК КоличествоДублей
ИЗ
Справочник.Банки КАК Банки
СГРУППИРОВАТЬ ПО
Банки.Код

Данный пример отобразит список БИКов справочника «Банки» и покажет, сколько дублей существует по каждому из них.

Итоги

Итоги – способ получения данных из системы с иерархической структурой. Для итоговых полей могут использоваться агрегатные функции, как для группировок.

Один из самых популярных способов использования итогов в практике – партионное списание товаров.

ВЫБРАТЬ




ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
УПОРЯДОЧИТЬ ПО

ИТОГИ
СУММА(Количество),
СУММА(Сумма)
ПО
Номенклатура

В результате запроса получится следующее иерархическое :

Общие итоги

Если необходимо получить итоги по всем «итогам», используйте оператор «ОБЩИЕ».

ВЫБРАТЬ
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
РеализацияТоваровУслугТовары.Ссылка КАК Документ,
РеализацияТоваровУслугТовары.Количество КАК Количество,
РеализацияТоваровУслугТовары.Сумма КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
УПОРЯДОЧИТЬ ПО
РеализацияТоваровУслугТовары.Ссылка.Дата
ИТОГИ
СУММА(Количество),
СУММА(Сумма)
ПО
ОБЩИЕ,
Номенклатура

В результате выполнения запроса получим следующий результат:

В котором 1 уровень группировки – агрегирование всех нужных полей.

Упорядочивание

Оператор УПОРЯДОЧИТЬ ПО используется для сортировки результата запроса.

Сортировка для примитивных типов (строка, число, булево) происходит по обычным правилам. Для полей ссылочных типов сортировка происходит по внутреннему представлению ссылки (уникальный идентификатор), а не по коду или по представлению ссылки.

ВЫБРАТЬ

ИЗ
Справочник.Номенклатура КАК Номенклатура
УПОРЯДОЧИТЬ ПО
Наименование

Запрос выведет список наименований справочника номенклатуры, отсортированного по алфавиту.

Автоупорядочивание

Результат запроса без сортировки представляет собой хаотично представленный набор строк. Разработчики платформы 1С не гарантируют вывод строк в одинаковой последовательности при выполнении одинаковых запросов.

Если необходимо выводить записи таблицы в постоянном порядке, необходимо использовать конструкцию «Автоупорядочивание».

ВЫБРАТЬ
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
АВТОУПОРЯДОЧИВАНИЕ

Виртуальные таблицы

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

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

  • срез первых;
  • срез последних.
  • остатки;
  • обороты;
  • остатки и обороты.
  • движения с субконто;
  • обороты;
  • обороты Дт Кт;
  • остатки;
  • остатки и обороты
  • субконто.
  • база;
  • данные графика;
  • фактический период действия.

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

ВЫБРАТЬ
ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток,
ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот,
ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход,
ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход,
ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК ТоварыНаСкладахОстаткиИОбороты

Такой запрос позволяет быстро получить большое количество данных.

Параметры виртуальных таблиц

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

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

Пример использования таких параметров:

РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Месяц, ДвиженияИГраницыПериода, Номенклатура = &НужнаяНоменклатура)

Алгоритм работы виртуальных таблиц

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

При использовании виртуальной таблицы система проделывает следующие манипуляции:

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


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

Использование конструктора запросов

Конструктор запросов – инструмент, встроенный в систему 1С предприятие, существенно облегчающий разработку запросов к базе данных.

Конструктор запроса имеет достаточно простой, интуитивно понятный интерфейс. Тем не менее рассмотрим применение конструктора запроса подробнее.

Запуск конструктора текста запроса производится контекстным меню (правой кнопкой мыши) в нужном месте программного кода.

Описание конструктора запроса 1С

Рассмотрим каждую вкладку конструктора подробнее. Исключение – вкладка Построитель, это тема для отдельного разговора.

Вкладка Таблицы и поля

На этой вкладке указывается источник данных и поля, которые необходимо выводить в отчет. По сути тут описываются конструкции ВЫБРАТЬ.. ИЗ.

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

В контекстном меню виртуальных таблиц можно задать параметры виртуальной таблицы:

Вкладка Связи

Вкладка служит для описания соединений нескольких таблиц, создает конструкции со словом СОЕДИНЕНИЕ.

Вкладка Группировка

На данной вкладке система позволяет группировать и суммировать нужные поля результата таблицы. Описывается использование конструкций СГРУППИРОВАТЬ ПО, СУММА, МИНИМУМ, СРЕДНЕЕ, МАКСИМУМ, КОЛИЧЕСТВО, КОЛИЧЕСТВО РАЗЛИЧНЫХ.

Вкладка Условия

Отвечает за всё, что идёт в тексте запроса после конструкции ГДЕ, т.е за все условия, накладываемые на получаемые данные.

Вкладка Дополнительно

Вкладка Дополнительно изобилует всевозможными параметрами, которые являются очень важными. Рассмотрим каждое из свойств.

Группировка Выборка записей :

  • Первые N – параметр, возвращающий в запрос только N записей (оператор ПЕРВЫЕ)
  • Без повторяющихся – обеспечивает уникальность полученных записей (оператор РАЗЛИЧНЫЕ)
  • Разрешенные – позволяет выбирать только те записи, которые позволяет выбрать система с учетом (конструкция РАЗРЕШЕННЫЕ)

Группировка Тип запроса определяет, какой будет тип запроса: выборка данных, создание временной таблицы или же уничтожение временной таблицы.

Ниже существует флаг Блокировать полученные данные для последующего изменения . Он позволяет включить возможность установки блокировки данных, которая обеспечивает сохранность данных от момента их чтения до изменения (актуально только для Автоматического режима блокировок, конструкция ДЛЯ ИЗМЕНЕНИЯ).

Вкладка Объединения/Псевдонимы

На этой вкладке конструктора запросов устанавливается возможность объединения разных таблиц и псевдонимов(конструкция КАК). В левой части указываются таблицы. Если установить флаги напротив таблицы, будет использоваться конструкция ОБЪЕДИНИТЬ, иначе – ОБЪЕДИНИТЬ ВСЕ (отличия двух способов ). В правой части указываются соответствия полей в разных таблицах, если соответствие не указано, запрос будет возвращать NULL.

Вкладка Порядок

Здесь указывается порядок сортировки значений (УПОРЯДОЧИТЬ ПО) – по убыванию (УБЫВ) или возрастанию(ВОЗР).

Также есть интересный флаг – Автоупорядочивание (в запросе – АВТОУПОРЯДОЧИВАНИЕ). По умолчанию система 1С выводит данные в “хаотичном” порядке. Если установить этот флаг, система будет сортировать данные по внутренним данным.

Вкладка Пакет запросов

На вкладке конструктора запросов можно создавать новые , а также использовать её в роли навигации. В тексте запроса пакеты разделяются символом “;”(точка запятая).

Кнопка “Запрос” в конструкторе запросов

В левом нижнем углу конструктора запроса есть кнопка Запрос, с помощью которого можно в любой момент просмотреть текст запроса:

В данном окне можно внести коррективы в запрос и выполнить его.


Использование консоли запросов

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

Рассмотрим этот инструмент подробнее.

Скачать консоль запросов 1С

Первым делом, чтобы начать работу с консолью запросов, её нужно откуда-то скачать. Обработки обычно делятся на два вида – на управляемых формах и обычных (или, иногда, их называют на 8.1 и на 8.2/8.3).

Я постарался объединить эти два вида в одной обработке – в нужном режиме работы открывается нужная форма (в управляемом режиме консоль работает только в толстом режиме).

Описание консоли запросов 1С

Начнем рассмотрение консоли запросов с описания главной панели обработки:

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

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

Слева, в поле “Запрос”, можно создавать новые запросы и сохранять их в древовидной структуре. Вторая группа кнопок как раз отвечает за управление списком запросов. С помощью неё можно создать, скопировать, удалить, переместить запрос.

  • Выполнить запрос – простое выполнение и получение результата
  • Выполнить пакет – позволяет просмотреть все промежуточные запросы в пакете запросов
  • Просмотр временных таблиц – позволяет увидеть результаты, которые возвращают временные запросы в таблице

Параметры запроса:

Позволяют установить текущие параметры для запроса.

В окне параметров запроса интересно следующее:

  • Кнопка Получить из запроса автоматически находит все параметры в запросе для удобства разработчика.
  • Флаг Единые параметры для всех запросов – при установке его обработка не очищает параметры при переходе от запроса к запросу в общем списке запросов.

Задать параметр списком значений очень просто, достаточно при выборе значения параметра нажать на кнопку очистки значения (крестик), система предложит выбрать тип данных, где надо выбрать “Список значения”:

Также в верхней панели очень есть кнопка вызова настроек консоли запросов:

Здесь можно указать параметры автосохранения запросов и параметры выполнения запроса.

В поле запроса консоли заносится текст запроса. Сделать это можно простым набором теста запроса или же вызовом специального инструмента – конструктора запросов.

Конструктор запроса 1С 8 вызывается из контекстного меню (правая кнопка мыши) при нажатии на поле ввода:

Также в этом меню есть такие полезные функции, как очистка или добавление в запрос символов переноса строки (“|”) или же получения кода запроса вот в таком удобном виде:

Запрос = Новый Запрос;
Запрос.Текст = ”
|ВЫБРАТЬ
| Валюты.Ссылка
|ИЗ
| Справочник.Валюты КАК Валюты”;
РезультатЗапроса = Запрос.Выполнить();

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



Также консоль запросов кроме списка умеет отображать данные в виде дерева — для запросов, содержащих итоги.

Оптимизация запросов

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

Отборы в виртуальной таблице с помощью конструкции ГДЕ

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

ПРАВИЛЬНО :

ВЫБРАТЬ

ИЗ
РегистрНакопления.ВзаиморасчетыСДепонентамиОрганизаций.Остатки(
,
Организация = &Организация
И Физлицо = &Физлицо) КАК ВзаиморасчетыСДепонентамиОрганизацийОстатки

НЕПРАВИЛЬНО :

ВЫБРАТЬ
ВзаиморасчетыСДепонентамиОрганизацийОстатки.СуммаОстаток
ИЗ
РегистрНакопления.ВзаиморасчетыСДепонентамиОрганизаций.Остатки(,) КАК ВзаиморасчетыСДепонентамиОрганизацийОстатки
ГДЕ
ВзаиморасчетыСДепонентамиОрганизацийОстатки.Организация = &Организация
И ВзаиморасчетыСДепонентамиОрганизацийОстатки.Физлицо = &Физлицо

Получение значения поля составного типа через точку

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

Например, крайне нежелательно для оптимизации обращаться к полю записи регистра – регистратор. Регистратор имеет составной тип данных, среди которых все возможные типы документов, которые могут писать данные в регистр.

НЕПРАВИЛЬНО:

ВЫБРАТЬ
НаборЗаписей.Регистратор.Дата,
НаборЗаписей.Количество
ИЗ
РегистрНакопления.ТоварыОрганизации КАК НаборЗаписей

Т.е по факту вот такой запрос будет обращаться не к одной таблице, а к 22 таблицам базы данных (у этого регистра 21 тип регистратора).

ПРАВИЛЬНО:

ВЫБРАТЬ
ВЫБОР
КОГДА ТоварыОрг.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
ТОГДА ВЫРАЗИТЬ(ТоварыОрг.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата
КОГДА ТоварыОрг.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
ТОГДА ВЫРАЗИТЬ(ТоварыОрг.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Дата
КОНЕЦ КАК Дата,
ТоварыОрг.Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрг

Либо второй вариант – добавление такой информации в реквизит, например, в нашем случае – добавление даты.

ПРАВИЛЬНО:

ВЫБРАТЬ
ТоварыОрганизаций.Дата,
ТоварыОрганизаций.Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций

Подзапросы в условии соединения

Для оптимизации недопустимо использовать подзапросы в условиях соединения, это существенно замедляет работу запроса. Желательно в таких случаях использовать ВТ. Для соединения нужно использовать только объекты метаданных и ВТ, предварительно проиндексировав их по полям соединения.

НЕПРАВИЛЬНО:

ВЫБРАТЬ …

ЛЕВОЕ СОЕДИНЕНИЕ (
ВЫБРАТЬ ИЗ РегистрСведений.Лимиты
ГДЕ …
СГРУППИРОВАТЬ ПО …
) ПО …

ПРАВИЛЬНО:

ВЫБРАТЬ …
ПОМЕСТИТЬ Лимиты
ИЗ РегистрСведений.Лимиты
ГДЕ …
СГРУППИРОВАТЬ ПО …
ИНДЕКСИРОВАТЬ ПО …;

ВЫБРАТЬ …
ИЗ Документ.РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ Лимиты
ПО …;

Соединение записей с виртуальными таблицами

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

Использование отборов по не индексируемым полям

Одна из самых распространенных ошибок при составления запросов – использование условий по не индексируемым полям, это противоречитправилам оптимизации запросов. СУБД не может выполнить запрос оптимально, если в запросе накладывается отбор по неиндексируемым полям. Если же берется временная таблица – также необходимо индексировать поля соединения.

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

  1. Индекс содержит все поля, перечисленные в условии.
  2. Эти поля находятся в самом начале индекса.
  3. Эти отборы идут подряд, то есть между ними не «вклиниваются» значения, не участвующие в условии запроса.

Если СУБД не подобрал правильные индексы, то будет просканирована таблица полностью – это очень негативно скажется на производительности и может привести к продолжительной блокировке всего набора записей.

Использование логического ИЛИ в условиях

Вот и всё, в данной статье были освещены основы аспекты оптимизации запросов, которые должен знать каждый эксперт 1С.

Очень полезный бесплатный видеокурс по разработке и оптимизации запросов, категорически рекомендую новичкам и не только!

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


Рис. 1

Списки

С какими списками сталкиваются пользователи? Это могут быть списки документов в соответствующих журналах. Практически любой справочник, заполненный данными, представляется в виде списка, в котором, как правило, есть иерархия (группы-папки или подчиненные элементы). Нередко для выбора какого-либо элемента программа формирует списки автоматически или подчиняясь заложенной разработчиками логике.

Практически во всех списках можно использовать механизмы отбора (если это явно не запрещено разработчиком) и разнообразной сортировки (рис. 1). В программе эти механизмы неразрывно связаны друг с другом. Рассмотрим, как их использовать правильно и эффективно.

Рис. 1

Механизм сортировки

Для чего нужен механизм сортировки? Во-первых, он, как следует из названия, позволяет отсортировать список по нужному критерию.

Во-вторых, в платформе "1С:Предприятие 8.1" активно используется механизм быстрого поиска. Этот механизм позволяет быстро найти в каком-либо списке нужный элемент, набрав первые символы (рис. 2). Но в динамических списках (например, список элементов справочника или список документов) быстрый поиск работает только по реквизитам, по которым доступна сортировка.

Рис. 2

Посмотреть все доступные для сортировки реквизиты списка можно, открыв окно "Отбор и сортировка". Это окно, как правило, доступно на панели действий (рис. 3) либо в контекстном меню списка, открывающемся правой кнопкой мыши (рис. 4). В окне "Отбор и сортировка" нужно перейти на закладку "Сортировка", где показаны все доступные реквизиты, по которым возможна сортировка.

Рис. 3

Рис. 4

На рисунке 3 видно, что для списка документов "Реализации товаров и услуг" доступна сортировка по двум реквизитам: "Дата" и "Номер". Однако информативность окна сортировок этим не ограничивается. Здесь можно посмотреть, какая сортировка включена в данный момент (левая часть окна) и список всех доступных для сортировки реквизитов (правая часть). Тут же можно настроить нужную сортировку и ее порядок. Обратите внимание: текущий реквизит сортировки будет помечен в списке специальным символом - стрелочкой, обозначающей направление сортировки. Три примера различной сортировки (в т. ч. комбинированной) и способы ее отображения в списке показаны на рисунке 5.

Рис. 5

Заметим, что нижний пример иллюстрирует возможность использования комбинированной сортировки (одновременно по нескольким реквизитам). В нашем случае, это сортировка по дате по убыванию (самые старые даты внизу) и по номерам по возрастанию (самые большие номера внизу).

В каждом списке можно индивидуально сохранить нужную сортировку. Достаточно включить галочку "Использовать эту настройку сортировки при открытии" и нажать "ОК". Система запомнит настройку и при следующем открытии этого списка установит сохраненную сортировку.

Быстро отсортировать список по нужному реквизиту можно, щелкнув мышкой по шапке с названием этого реквизита.

Например, в нашем случае, можно щелкнуть по реквизиту "Дата" (включится сортировка дат по возрастанию, и можно будет использовать быстрый поиск по дате) или по реквизиту "Номер" (будет переключена сортировка по номерам по возрастанию, после чего можно быстро искать по номеру). Инвертировать сортировку тоже просто - достаточно повторно щелкнуть по тому же реквизиту в шапке списка.

Механизм отбора

Отбор - мощный механизм платформы "1С:Предприятие 8.1", который позволяет эффективно работать со списками, даже если в них содержится не один десяток или сотня тысяч элементов. Для начала рассмотрим работу механизма отбора в общем случае.

Практически везде, где есть список (как правило, в виде таблицы), можно использовать механизм отбора, который активируется либо соответствующей кнопкой на панели действий, либо в контекстно-зависимом меню списка (рис. 3 и 4). Если отбор у нужного списка возможен, откроется окно "Отбор и сортировка". В нем будут отображены все возможные виды доступных для отбора реквизитов. Список доступных элементов отбора зависит от того, где этот отбор будет использован. В общем случае нужно найти один или несколько необходимых элементов для отбора, указать значения и активировать настроенную комбинацию критериев.

Список возможных условий для того или иного вида отбора зависит от типа элементов, используемых в нем. Например, для чисел и дат будет доступно указание диапазонов, для строк - поиск подстроки (условия "Содержит"/"Не содержит"), а для элементов справочников - заполнение списков и анализ иерархии.

Если указать одновременно несколько критериев отбора, в списке будут отображены только такие элементы, которые удовлетворяют всем указанным критериям.

Механизмы отбора и сортировки на примерах

Попробуем решить несколько задач в демонстрационной базе ("Бухгалтерия предприятия", редакция 1.6). Например, отобразим документы, сформированные для контрагента "Саймон и Шустер ООО" в журнале "Документы покупателей". Сразу оговоримся, что описывать будем стандартные для платформы "1С:Предприятие 8.1" правила и логику ведения отбора, без привязки к какой-либо конкретной конфигурации и дополнительным сервисным возможностям, в ней реализованным.

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

Нам нужно быстро посмотреть все документы контрагента "Саймон и Шустер ООО". Реализуется задача следующим образом - открывается окно отбора, в элементе "Контрагент" выбирается контрагент "Саймон и Шустер ООО" из справочника (рис. 6) и нажимается "ОК". Задача решена (рис. 7).

Рис. 6

Рис. 7

Для быстрого использования нужного отбора достаточно сразу приступать к выбору нужного критерия. Ставить галочку напротив используемого отбора не нужно. Программа сделает это сама после того, как будет указан необходимый критерий. Быстро применить настроенные критерии отбора можно, нажав комбинацию клавиш Ctrl+Enter*.

Обратите внимание еще и на то, что при указании значений в элементах отбора (в нашем примере - контрагент "Саймон и Шустер ООО"), в большинстве случаев будет работать механизм быстрого подбора, широко распространенный в платформе "1С:Предприятие 8.1". В нашем примере достаточно было набрать первые символы названия контрагента или его код прямо в поле значения отбора, нажать Enter или Tab и система автоматически бы "угадала" нужный нам элемент справочника.

Имейте в виду - быстрый подбор существенно ускоряет выбор известных вам значений. Используйте его, где это возможно.

Теперь отобразим список номенклатуры, в наименованиях которых содержится слово "Чайник". Для этого открываем справочник "Номенклатура", вызываем окно отбора, в элементе "Наименование" выбираем условие сравнения "Содержит" и указываем требуемое слово (рис. 8).

Рис. 8

Вид сравнения "Содержит" выбран не случайно. Именно он позволяет найти нужное слово (или его часть) в любом месте наименования номенклатуры. Если оставить вид сравнения "Равно", в списке будут отображены только такие элементы номенклатуры, которые называются точно так, как написан запрос. А таких в нашей демобазе нет (то есть не было бы отображено ни одного элемента).

Так как в нашей демобазе у номенклатуры есть реквизит "Полное наименование", оно присутствует в списке доступных отборов отдельной позицией. Но при этом в качестве условий сравнения доступно только "Содержит"/"Не содержит". Причина в том, что реквизит "Полное наименование" в нашей демобазе - строка неограниченной длины.

Если искать не по наименованию, а по полному наименованию, галочку использования отбора по наименованию лучше снять. Иначе отбор будет использован и по наименованию, и по полному наименованию, что не всегда может оказаться необходимым (рис. 9).

Рис. 9

Для удобства работы с элементами справочника при использовании отборов лучше на время отключать отображение иерархии (рис. 10).

Рис. 10

В качестве третьей задачи просмотрим в журнале документов "Документы покупателей" только документы "Реализация товаров и услуг". Решение этой задачи продемонстрирует особенность одного из видов отбора, доступного только в журналах документов.

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

Рис. 11

Аналогично отбору по виду документов платформа автоматически предложит элемент отбора "Структура подчиненности", если в конфигурации настроены взаимосвязи между документами.

Попробуем просмотреть в журнале документов "Документы покупателей" только документы "Счет-фактура" для контрагентов, находящихся в группе "Покупатели" справочника. Эта задача похожа на первую с тем лишь отличием, что мы не указываем конкретного контрагента, а анализируем счета-фактуры целой группы контрагентов, которые находятся в группе "Покупатели".

У задачи существует несколько способов реализации. Рассмотрим наиболее эффективный. Открываем журнал "Документы покупателей", указываем в элементе отбора "Вид документа" документ "Счет-фактура выданный". После этого в элементе отбора "Контрагент" указываем вид сравнения "В группе". Выбираем тип значения "Контрагенты" и открываем форму выбора контрагентов. В ней выбираем группу "Покупатели" (рис. 12).

Рис. 12

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

А теперь усложним задачу: просмотрим в журнале документов "Документы покупателей" только документы "Счет-фактура", но при этом нужно просмотреть документы и для покупателей, и для поставщиков. Решаем ее аналогично предыдущей, за исключением одного накладываемого критерия отбора.

Человеческим языком задача формулируется так: "отобразить все нужные документы по всем контрагентам, находящимся в группах справочника Покупатели, Поставщики, Поставщики на реализацию". Реализуется это просто - в условии отбора "Контрагент" выбираем "В группе из списка" (рис. 13). После этого становится доступным механизм заполнения списка, в который можно добавить нужные группы (или элементы) справочника. Причем список можно заполнить вручную. По аналогии с решением предыдущей задачи, найти нужную группу и выбрать ее, повторив это для каждого нового элемента списка. Однако целесообразнее воспользоваться удобным механизмом подбора, который автоматически реализуется программой. С помощью подбора намного проще и быстрее заполнить список нужными составляющими. После того, как список заполнен, нажимаем "ОК" и активируем настроенные критерии отбора. Задача решена.

Рис. 13

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

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

И, наконец, отобразим в документе "Реализация товаров и услуг" с номером ТДН00002 в табличной части только номенклатуру, содержащую в наименованиях слово "СТИНОЛ". Эта задача, позволит увидеть универсальность самого механизма отбора, а также насколько разнообразно может быть его использование. Задача основана на реальных ситуациях, когда, например, в табличной части накладной несколько сотен (а то и тысяч) строк и надо быстро проанализировать ее состав. В нашей демобазе есть документ "Реализация товаров и услуг" с номером ТДН00002, у которого в табличной части есть несколько строк. Несмотря на то что в документе кнопок использования отборов не наблюдается, вызов отбора доступен через контекстное меню (правая кнопка мыши).

Далее накладываем критерии отбора в разрезе Номенклатуры. Тут же возникает другой вопрос - как отобрать "СТИНОЛ", если условия выбора номенклатуры довольно сильно ограничены (доступно "Равно", "Не равно", "В списке" и "Не в списке"). Решить задачу можно и при таких условиях. Выбираем условие "В списке", открываем уже знакомое окно заполнения списка, используем подбор номенклатуры (рис. 14, 1). В списке номенклатуры может быть большое количество элементов, поэтому не будем искать глазами нужные позиции. Воспользуемся отбором в списке номенклатуры, указав условие отбора "Содержит" для наименования номенклатуры (рис. 14, 2).

Рис. 14

После этого остается только добавить отобранные позиции в список отбора для документа и применить критерии отбора.

Полезные функции механизма отбора

Рассмотрим еще несколько моментов, связанных так или иначе с отборами в системе "1С:Предприятие 8.1".

В списках объектов конфигурации, где используется привязка к датам (например, списки документов), и в журналах документов можно использовать быстрый отбор по диапазону дат. Для этого достаточно нажать соответствующую кнопку "Настройка периода" на панели действий (или выбрать в контекстном меню) (рис. 15). Таким способом можно в каждом списке индивидуально регулировать критерий отображения элементов по датам.

Рис. 15

Быстро установить отбор по значению в текущей ячейке списка можно, нажав на кнопку "Отбор по значению в текущей колонке" (рис. 16). При нажатии на эту кнопку будет установлен отбор по текущему значению в колонке. Эта функция работает только для тех колонок, по реквизитам которых можно устанавливать отборы. Если в списке уже используется какой-либо отбор, новый будет присоединен к нему. Причем кнопка становится активной для данной колонки. Отменить такой отбор можно аналогично - "отжав" кнопку в соответствующей колонке.

Рис. 16

Еще одно полезное свойство механизма отборов - ведение истории отборов (рис. 17). Программа запоминает, какие отборы были установлены, поэтому можно быстро вернуться к какому-либо из них, просто выбрав его из выпадающего списка. К слову, в окне "Отбор и сортировка" обратите внимание на кнопку "Отборы" (рис. 6). Нажав на эту кнопку, вы попадете в интерфейс, в котором можно сохранять и восстанавливать настройки отборов, чтобы в последствие можно было к ним вернуться (рис. 18).

Рис. 17

Рис. 18

И последняя функция - это отмена всех отборов (рис. 19). Нажатием кнопки "Отключить отбор" отключаются все отборы, установленные в списке. Аналогичного действия можно добиться, открыв окно "Отбор и сортировка" и сняв галочки напротив всех активных элементов.

Рис. 19

В программе также есть возможность быстрого поиска по номеру документа в списках документов или в журналах. Вызывается эта возможность кнопкой "Поиск по номеру" (рис. 20) и позволяет найти нужный документ, гибко настроив параметры поиска. Найденные документы по указанным критериям отображаются в нижней части окна этого сервиса, и можно перейти к нужному документу.

Сравнительно с предыдущей публикацией текста много, но по-другому совсем никак.

1.Полная форма использования оператора В.

Помимо формы, указанной в предыдущей публикации:

Поле В (&СписокЗначений),

Также в запросах языка 1С допустимы следующие формы использования этого оператора:

1.Поле В (&Массив)

2.Поле В (&Значение1,....&ЗначениеN),

3.Поле В (Выбрать …..) или для нескольких полей:

(Поле1, Поле2) В (Выбрать Т.Поле5, Т.Поле6 Из Таблица Т) , где Т - таблица (физическая, виртуальная или временная)

4.Поле В (&ТаблицаЗначений) или для нескольких полей:

(Поле1, Поле2) В (&ТаблицаЗначений)

Вариант записи №3 называют подзапросом.

У варианта №4 есть особенность: количество полей в Таблице значений должно точно совпадать с количеством полей, по которым производится проверка. Кроме того следует учесть что при сравнении по нескольким полям условие будет принимать значение Истина только при совпадении по всем полям одновременно.

2.Оператор В Иерархии.

Этот оператор может быть использован только для иерархических справочников (и других иерархических объектов, например План Счетов, План Видов Характеристик). По сути этот оператор очень схож с оператором В, но имеет совсем другой смысл: оператор производит проверку, что элемент справочника принадлежит указанной группе (или группам вложенным в указанную группу).

Пример использования: отбираем в запросе все элементы справочника номенклатура, которые находятся в группе товаров «Мебель» (для простоты элемент справочника «Номенклатура» Мебель - предопределённый).

Запрос.Текст = "ВЫБРАТЬ Номенклатура.Ссылка ИЗ Справочник.Номенклатура КАК Номенклатура

Запрос. УстановитьПараметр(" Группа1", Справочники. Номенклатура. Мебель);

Примечание1: если в качестве аргумента оператора В Иерархии указать пустой элемент - будут отобраны все элементы справочника (т.е. оператор в Иерархии будет возвращать значение Истина для любого элемента справочника, т.к. у элементов и групп самого верхнего уровня значение реквизита Родитель пустое), например: Запрос. УстановитьПараметр(" Группа1", Справочники. Номенклатура. ПустаяСсылка());

Примечание2: оператор В Иерархии очень мощный и позволяет проверить принадлежность группе для элементов справочника неограниченного уровня вложенности в рамках одного запроса (что невозможно сделать другими способами), но скорость работы этого оператора не сильно велика, что особенно заметно на больших справочниках.

3.Использование конструктора запроса.

В среде программистов 1С не редко возникают споры о использовании конструктора запросов или отказе от использования конструктора и написании запроса вручную. Тем не менее, по мнению большинства программистов, пользоваться конструктором нужно, но иногда после этого полученный запрос «допиливают руками». Для вызова конструктора запросов в любом модуле нужно кликнут по правой кнопке манипулятора мышь и из выпавшего меню выбрать или «Конструктор запроса» или «Конструктор запроса с обработкой результата».

Основные преимущества использования конструктора запросов:

1.Видимость всех доступных объектов конфигурации для построения запроса (а также всех временных таблиц запроса и т.п.).

2.Точное указание имён полей и реквизитов (т.к. они не набираются вручную а выбираются из списка).

3.Упрощенное отображение взаимосвязей между объектами запроса и условий.

4.Относительно изолированная работа над каждой частью запроса (каждым запросом в пакетном запросе или отдельном запросе при объединении запросов).

5.Абсолютно достоверные данные по «существующим» в данной конфигурации Виртуальным таблицам.

4.Работа с датами в запросах (дата, момент времени, граница)

В средствах разработки 1С, начиная с версии 8.0, тип данных Дата стал составным из Даты и Времени . И всё-бы было хорошо, но и тут есть свои особенности.

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

Док

Док

Док = Документы. Приход. СоздатьДокумент(); Док. Дата = ТекущаяДата(); Док.Записать();

Док = Документы. Расход. СоздатьДокумент(); Док. Дата = ТекущаяДата(); Док.Записать();

А потом выполнить следующий запрос:

ОБЪЕДИНИТЬ ВСЕ

УПОРЯДОЧИТЬ ПО Дата

То получим странный результат:

Документы не упорядочены даже по порядку их создания! Если заменим реквизит документа Дата на реквизит МоментВремени в запросе получим уже более лучший результат:

В пределах 1 секунды идут сначала документы «Приход» этой секунды, а далее документы «Расход» этой секунды, причём номера документов идут строго в порядке возрастания (в нашем случае в виду автонумерации документов это означает что в порядке создания). Осталось решить небольшую проблему - упорядочить внутри секунды документы в реальном порядке их создания а не только для каждого вида документа - если заблаговременно не было задачи решения этой проблемы - она не разрешима в принципе.

Примечание: МоментВремени содержит дату, время и ссылку на объект базы данных. А т.к. ссылка содержит код типа объекта и уникальный номер объекта - то сортировка в пределах секунды по МоментуВремени в качестве результата выдаст группы разнотипных объектов внутри групп упорядоченных, но между собой не «перемешанных».

Как решить эту задачу:

1вариант: если номера самих документов не принципиальны - можно создать нумератор документов и тогда номер документа будет ответствовать его порядковому номеру при создании. Это решение очень плохо в виду отказа от сквозной нумерации документов.

2 вариант: ввести дополнительное идентификационное поле и перед сохранением документа с незаполненным значением этого поля получать значение этого поля для этого документа из любого сеансанезависимого источника, которым может быть и специальная запись непериодического Регистра Сведений и значение записное во внешний текстовый или другой файл или специально для этого написанный Com-сервис и т.п. и писать полученное значение в это поле, а сохраненное значение увеличить на единичку.

2 Проблема . Выбор времени для выполнения запроса получения остатков. При выполнении многих запросов нужно указывать конец периода выборки (т.е. момент на который получаются остатки). Казалось-бы вполне правильным было так:

Запрос . УстановитьПараметр(" КонецПериода " , КонецМесяца(ТекущаяДата()));

Но на самом деле запрос получения остатков будет выполнен по состоянию на начало указанной даты(которая есть дата+время). Если учесть, что КонецМесяца(Дата(2012, 10, 29)) = 31.10.0012 23:59:59

То получается, что у нас выпадают обороты формируемые движениями (документами) за последнюю секунду периода и мы получим остатки за секунду до конца месяца а не по состоянию на конец месяца! Особенно часто эта особенность приводит к ошибке получения остатков при импорте нечальных остатков (когда в последную секунду может поместиться огромное количество документов) и в организациях работающих в режиме 7*24.

Как решить эту проблему:

1 вариант: прибавить к концу периода 1 секунду:

Запрос . УстановитьПараметр(" КонецПериода " , КонецМесяца(ТекущаяДата())+1);

2 вариант: воспользоваться специально созданным для этого объектом Граница:

ГраницаПериода = Новый Граница(КонецМесяца(ТекущаяДата())+ 1, ВидГраницы. Исключая);

Запрос. УстановитьПараметр("КонецПериода" , ГраницаПериода);

Примечание : если в запросе необходимо производить выборку по положению какого-то документа на временной оси, то второй вариант нагляднее, например:

ГраницаПериода = Новый Граница(Документ. МоментВремени, ВидГраницы. Исключая);

или если движения и этого документа должны попасть:

ГраницаПериода = Новый Граница(Документ. МоментВремени, ВидГраницы. Включая);

Примечание 2: Как справедливо заметили в комментариях ещё 1 плюс работы с типом данных Граница - не надо задумываться что выбираешь остатки или обороты и нет необходимости передавать в сложный запрос в котором выбираются и остатки и обороты 2 параметра описывающих момент на который проиводится выборка (один для оборотов, второй для остатков).

5.Выборка по группировкам, итоги.

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

Инструменты

Напильник

То обычная выборка запроса вида:

Выборка = Запрос. Выполнить(). Выбрать();

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

Запрос = Новый Запрос;

Запрос. Текст = "ВЫБРАТЬ Номенклатура.Ссылка КАК Номенклатура ИЗ Справочник.Номенклатура КАК Номенклатура

ИТОГИ ПО Номенклатура ИЕРАРХИЯ";

Выборка = Запрос.Выполнить(). Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Номенклатура" );

Сообщить("Элемент=" + ВыборкаДетали. Номенклатура);

КонецЦикла;

КонецЦикла;

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

Запрос = Новый Запрос;

Запрос. Текст = "ВЫБРАТЬ Номенклатура.Ссылка КАК Номенклатура, Номенклатура.Продано КАК Продано

ИЗ Справочник.Номенклатура КАК Номенклатура

ИТОГИ СУММА(Продано)

ПО Номенклатура ИЕРАРХИЯ";

Выборка = Запрос. Выполнить(). Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Номенклатура" );

Пока Выборка. Следующий() Цикл

Сообщить("Группа=" + Выборка. Номенклатура+ " Продано=" + Выборка. Продано);

ВыборкаДетали = Выборка.Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Номенклатура" );

Пока ВыборкаДетали. Следующий() Цикл

Сообщить("Элемент=" + ВыборкаДетали. Номенклатура+ " Продано=" + ВыборкаДетали. Продано);

КонецЦикла;

КонецЦикла;

Примечание1: есть ещё один вариант обход «ПоГруппировкам», отличается от иерархического обхода тем, что элементы выборки с иерархическими итогами будут в нем как детальные записи а не узловые.

Примечание2: для обхода справочника с более сложной структурой (количеством уровней>2) можно воспользоваться рекурсией, например вот так:

……………………..

Выборка = Запрос.Выполнить(). Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией);
ВыбратьРекурсивно(Выборка);

………….
КонецПроцедуры

Процедура ВыбратьРекурсивно(Выборка)

Пока Выборка.Следующий() Цикл

Сообщить(Выборка. Номенклатура+ " колво=" + Выборка. Продано);

// Попытка получить дочерние записи

ВыбратьРекурсивно(Выборка. Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией);
КонецЦикла;
КонецПроцедуры

Примечание3: ещё одно применение иерархической выборки - выгрузка результатов запроса в объект типа Дерево Значений, например так:

ЗначениеВРеквизитФормы(Результат. Выгрузить(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Дерево" );

Дерево = Результат. Выгрузить(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией);

6.Временные таблицы, пакетные запросы .

Ещё одной очень мощной возможностью языка запросов 1С является работа с временными таблицами. По сути, мы результат запроса помещаем во временную таблицу, с которой далее можем работать как с обычной таблицей. Сам запрос становится составным из нескольких запросов, которые выполняются строго последовательно, один (последний) запрос пакета выполняет выборку данных - такой составной запрос называют пакетным запросом. Каждая временная таблица имеет своё имя и т.о. в пакетном запросе может создаваться произвольное количество таблиц. Время жизни временной таблицы ограниченно временем выполнения запроса, как только запрос был выполнен - все временные таблицы уничтожаются, а память занятая хранением данных временных таблиц высвобождается.

Для того чтобы выполнить помещение данных во временную таблицу используется оператор ПОМЕСТИТЬ , который пишется в запросе между операторами ВЫБРАТЬ и ИЗ . Запросы внутри пакетного запроса отделяются друг от друга строками:

////////////////////////////////////////////////////////////

Пример небольшого пакетного запроса выбирающего последний документ продажи «Реализация» (у документа есть табличная часть «Товары», в которой перечислены реализованные товары) для каждой номенклатуры.

Схема пакетного запроса:

в 1 запросе получаем полный перечень продаваемой номенклатуры и максимальную дату продажи для каждой из номенклатур,

во 2 запросе отбираем для каждой номенклатуры из первого запроса документ реализации с датой равной для этой номенклатуры максимальной

ВЫБРАТЬ РелизацияТовары.Номенклатура, МАКСИМУМ(РеализацияТоваровТовары.Ссылка.Дата) КАК Дата

ПОМЕСТИТЬ Даты

ИЗ Документ.Реализация.Товары КАК РеализацияТовары

СГРУППИРОВАТЬ ПО РеализацияТовары.Номенклатура

////////////////////////////////////////////////////////////

ВЫБРАТЬ Даты.Номенклатура, Даты.Дата, МАКСИМУМ(Реализация.Ссылка) КАК Ссылка

ИЗ Даты КАК Даты

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.Реализация КАК Реализация

ПО Даты.Дата = Реализация.Дата

СГРУППИРОВАТЬ ПО Реализация.Ссылка

Что даёт использование пакетных запросов: даёт возможность написания более сложных запросов и при этом более читабельных запросов, оптимизирует скорость выполнения запроса, часто это единственный способ избежать выполнения запроса в цикле. Если посмотреть в исходники типовых конфигураций - все сложные запросы пишутся исключительно как пакетные.

7.Последовательность чисел, дат.

Задача: генерация числовой последовательности от 0 до 959 в запросе. При использовании пакетного запроса задача решается легко:

ВЫБРАТЬ Цифры.Поле1 КАК Цифра

ПОМЕСТИТЬ Цифры

ИЗ (ВЫБРАТЬ 1 КАК Поле1

ОБЪЕДИНИТЬ ВЫБРАТЬ 2

ОБЪЕДИНИТЬ ВЫБРАТЬ 3

ОБЪЕДИНИТЬ ВЫБРАТЬ 4

ОБЪЕДИНИТЬ ВЫБРАТЬ 5

ОБЪЕДИНИТЬ ВЫБРАТЬ 6

ОБЪЕДИНИТЬ ВЫБРАТЬ 7

ОБЪЕДИНИТЬ ВЫБРАТЬ 8

ОБЪЕДИНИТЬ ВЫБРАТЬ 9

ОБЪЕДИНИТЬ ВЫБРАТЬ 10) КАК Цифры

ВЫБРАТЬ (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100 КАК Число

ГДЕ (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100 <= 959

УПОРЯДОЧИТЬ ПО Число

Задача : генерация последовательности дат от Дата1 до Дата2 . Решается аналогично, можно как выполнить в 3 шага (первый и второй как в приведённом примере, но результат не выбрать а поместить во временную таблицу) или в 2 шага изменив второй запрос пакета на вот такой:

ВЫБРАТЬ ДОБАВИТЬКДАТЕ (&Дата1 , ДЕНЬ , (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100) КАК Дата

ИЗ Цифры КАК Цифры, Цифры КАК Цифры1, Цифры КАК Цифры2

ГДЕ ДОБАВИТЬКДАТЕ (&Дата1 , ДЕНЬ , (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100)

УПОРЯДОЧИТЬ ПО Дата

Примечание: естественно этот запрос будет правильно работать только если между датами Дата1 и Дата2 не более 999 дней.

8.Использование данных из таблицы значений в запросе.

Если в первом разделе (оператор В ) мы производим сравнение набора полей с данными из Таблицы значений, то иногда этого мало. Например, из стороннего источника передаются наборы данных, например такие: штрих-код и количество единиц проданной продукции. Можно конечно в запросе обойти переданный набор значений выполняя на каждой итерации цикла запрос, но это наихудший вариант решения этой задачи. Правильнее сделать так:

1.Создать типизированную Таблицу значений (т.е. у которой указан тип для каждого поля).

2.Заполнить Таблицу значений полученными данными о продажах.

3.Произвести поиск номенклатуры в запросе.

Пример кода для 1 и 3 этапа:

Создание типизированной Таблицы значений:

// Создание описателей типов для таблицы значений

КЧК = Новый КвалификаторыЧисла(14, 3);

КЧШК = Новый КвалификаторыЧисла(13, 0);

Массив = Новый Массив;

Массив. Добавить(Тип("Число" ));

ОписаниеТиповЧК = Новый ОписаниеТипов(Массив, КЧК);

Массив. Очистить();

Массив. Добавить(Тип(" Число"));

ОписаниеТиповЧШ = Новый ОписаниеТипов(Массив, КЧШК);

// Создание таблицы значений

ТаблицаЗначений = Новый ТаблицаЗначений;

// добавим в таблицу значений две колонки

ТаблицаЗначений. Колонки.Добавить("ШтрихКод" , ОписаниеТиповЧШ, "ШтрихКод" , 13); ТаблицаЗначений. Колонки. Добавить("Продано" , ОписаниеТиповЧК, "Продано" , 14);

Поиск Номенклатуры в запросе:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ТЗ.ШтрихКод, ТЗ.Количество

ПОМЕСТИТЬ ТЗ

ИЗ &ТЗ КАК ТЗ

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ ТЗ.Количество КАК ОбъемПродаж, Номенклатура.Ссылка КАК Ссылка

ИЗ ТЗ КАК ТЗ

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура

ПО ТЗ.ШтрихКод = Номенклатура.ШтрихКод";

Запрос. УстановитьПараметр("ТЗ" , ТаблицаЗначений);

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