Skip to main content

Одноуровневые запросы

Хранение данных в 1С.

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

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

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

Состав и описание таблиц в синтаксис-помощнике в разделе Работа с запросами - Таблицы запросов.

Запросы

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

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

Запрос состоит из следующих секций:

  • описание запроса,
  • объединение запросов,
  • упорядочивание результатов,
  • автоупорядочивание,
  • описание итогов.

Для реальных полей поддерживается * для выбора всех полей. Виртуальные поля нужно задавать явно.

ВЫБРАТЬ 
  Справочник.Клиенты.* 

Полный текст с получением столбцов в запросе: 

&НаСервереБезКонтекста
Процедура ПолучитьВсюТаблицуНаСервере()
	Запрос = Новый Запрос;
	Запрос.Текст ="ВЫБРАТЬ
		|	Справочник.Филиалы.*";
	Результат = Запрос.Выполнить();
	Если не Результат.Пустой() Тогда         
		ВыборкаДетальныеЗаписи = Результат.Выбрать();
		РезультатЗапроса = ВыборкаДетальныеЗаписи.Владелец();
		ПолнаяСтрокаОтвета = "";
		Для Каждого Кол ИЗ РезультатЗапроса.Колонки Цикл
			ПолнаяСтрокаОтвета = ПолнаяСтрокаОтвета + Кол.Имя + "     ";
		КонецЦикла;
		Сообщить(ПолнаяСтрокаОтвета);
		Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
			ПолнаяСтрокаОтвета = "";
			Для Каждого Кол ИЗ РезультатЗапроса.Колонки Цикл
    			ПолнаяСтрокаОтвета = ПолнаяСтрокаОтвета + ВыборкаДетальныеЗаписи[Кол.Имя] + "     ";
			КонецЦикла;
			Сообщить(ПолнаяСтрокаОтвета);
		КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Условия и преобразования в ВЫБРАТЬ

Операция выбора (ВЫБОР (КОГДА ТОГДА) ИНАЧЕ КОНЕЦ). После ключевого слова КОГДА записывается условие выбора, после ключевого слова ТОГДА значение поля выборки в  случае, если условие истинно. В  общем  случае  в  операции  выбора  может указываться  неограниченное количество альтернативных одиночных  выборов  КОГДА  …  ТОГДА.  Значение выражения, указанного после слова ИНАЧЕ, используется в  качестве результата операции выбора в  том случае, если ни одно из ранее указанных условий выбора не было выполнено.

ВЫБРАТЬ
  Товары.Наименование КАК Наименование,
  ВЫБОР    
    КОГДА (Товары.Производитель) ЕСТЬ NULL ТОГДА "NULL"
    ИНАЧЕ Товары.Производитель
  КОНЕЦ КАК Производитель
ИЗ
  Справочник.Товары КАК Товары

Также в ВЫБРАТЬ могут содержаться следующие элементы:

  • Литералы  типов:  число,  строка  (в  кавычках),  булево  (значения Истина и  Ложь),  Null,  Неопределено.  Чтобы  указать  литерал  типа  Дата,  можно воспользоваться ключевым словом языка запросов ДАТАВРЕМЯ или пере-
    дать дату через параметр запроса.
  • Арифметические  операции  (+,  -,  /,  *).  Операция  получения  остатка  % в  языке запросов не поддерживается.
  • Операцию  конкатенации  строк  (+).  Операцию  конкатенации  нельзя использовать для виртуальных полей.
  • Встроенные функции языка запросов (ДЕНЬ, МЕСЯЦ, ГОД и т. д.).
  • Агрегатные  функции  (СУММА,  МИНИМУМ,  МАКСИМУМ,  СРЕДНЕЕ, КОЛИЧЕСТВО).
  • Операцию  выбора ВЫБОР –  позволяет  получить  одно  из  возможных значений в  соответствии с указанными условиями.
  • Операцию  приведения  типов ВЫРАЗИТЬ  –  позволяет  привести  значение составного типа к одному из составляющих это значение типов. А также функцию  ВЫРАЗИТЬ()  используют  для  получения  результатов  нужной 
    длины и точности.
ВЫБРАТЬ
  Товары.Наименование + "   (" + Товары.Код + ")" КАК Товар,
  ВЫБОР 
    КОГДА Товары.ЭтоГруппа = ИСТИНА ТОГДА "Это группа"
    ИНАЧЕ "Это элемент"
  КОНЕЦ КАК ПризнакГруппы
ИЗ
  Справочник.Товары КАК Товары

ВЫБРАТЬ
  НАЧАЛОПЕРИОДА(ОстаткиТоваров.Период, НЕДЕЛЯ) КАК Период,
  ВЫБОР
    КОГДА (ОстаткиТоваров.Регистратор ССЫЛКА Документ.ПриходнаяНакладная) 
    ТОГДА ВЫРАЗИТЬ (ОстаткиТоваров.Регистратор КАК
                    Документ.ПриходнаяНакладная).Поставщик
    КОГДА (ОстаткиТоваров.Регистратор ССЫЛКА Документ.РасходнаяНакладная) 
    ТОГДА ВЫРАЗИТЬ (ОстаткиТоваров.Регистратор КАК
                  Документ.РасходнаяНакладная).Покупатель
  КОНЕЦ КАК Контрагент
ИЗ
  РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров
ГДЕ
  ОстаткиТоваров.Период МЕЖДУ &ДатаНачала И &ДатаОкончания

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

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

ВЫБРАТЬ 
  Цены.Товар КАК Товар,
  Цены.Цена КАК Цена
ИЗ
  РегистрСведений.Цены КАК Цены
УПОРЯДОЧИТЬ ПО 
  Цены.Период УБЫВ, 
  Цена 

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

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

Текстовое представление ссылочного поля

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

Каждая объектная таблица в информационной базе имеет виртуальное поле Представление. Это текстовое представление объекта. При получении данного поля запрос получает несколько полей, которые соответствуют прикладной сущности 
объекта, а при получении значения поля из результата запроса преобразовывает полученные значения в  строку. Варианты ПРЕДСТАВЛЕНИЕ(Товар) аналогично Товар.Представление, но лучше первый. 

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

Но результат функции ПРЕДСТАВЛЕНИЕ() не может быть использован в  выражении языка запросов, в  условиях  сравнения 
в предложении ГДЕ, в любых операциях.

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

ВЫБРАТЬ ПЕРВЫЕ 3

Непересекающаяся выборка

ВЫБРАТЬ РАЗЛИЧНЫЕ 
  ЗаказТовара.Клиент,
  ЗаказТовара.Дата
ИЗ
  Документ.ЗаказТовара КАК ЗаказТовара

Если в запросе указано ключевое слово РАЗЛИЧНЫЕ и в предложении УПОРЯДОЧИТЬ ПО указано поле, отсутствующее в списке выборки, то при выполнении такого запроса будет выдана ошибка. 

Получение данных табличной части

ВЫБРАТЬ
  СоставЗаказа.Товар,
  СоставЗаказа.Количество,
  СоставЗаказа.Сумма
ИЗ
  Документ.ЗаказТовара.Состав КАК СоставЗаказа

Этот запрос выведет все табличные части всех документов Заказ товара. Для получения также информации о реквизитах документа используется ссылка. Можно также установить условие.

ВЫБРАТЬ
  СоставЗаказа.Ссылка.Номер,
  СоставЗаказа.Ссылка.Клиент,
  СоставЗаказа.Товар,
  СоставЗаказа.Количество,
  СоставЗаказа.Сумма
ИЗ
  Документ.ЗаказТовара.Состав КАК СоставЗаказа
ГДЕ
  СоставЗаказа.Ссылка = &Документ

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

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

Запрос с одной и двумя вложенными таблицами: 

// Первый вариант – одна вложенная таблица
ВЫБРАТЬ
  ЗаказТовара.Номер,
  ЗаказТовара.Клиент,
  ЗаказТовара.СуммаЗаказа,
  ЗаказТовара.Состав.(
    Товар,
    Количество,
    Сумма
 )
ИЗ
  Документ.ЗаказТовара КАК ЗаказТовара
// Второй вариант – две вложенные таблицы
ВЫБРАТЬ
  ЗаказТовара.Номер,
  ЗаказТовара.Клиент,
  ЗаказТовара.СуммаЗаказа,
  ЗаказТовара.Состав.Товар,
  ЗаказТовара.Состав.Сумма
ИЗ
  Документ.ЗаказТовара КАК ЗаказТовара

Получение иерархической структуры

Ключевое слово ИЕРАРХИЯ после поля, по которому происходит сортировка, позволяет сортировать в соответствии с настроенными группами. 

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

Получение групп 

// Условие без параметров
ВЫБРАТЬ
  Товары.*
ИЗ
  Справочник.Товары КАК Товары
ГДЕ
  Товары.ЭтоГруппа = ИСТИНА

Получение товаров определенной группы 

ВЫБРАТЬ
  Товары.*
ИЗ
  Справочник.Товары КАК Товары
ГДЕ
  Товары.ЭтоГруппа = &ЭтоГруппа
  И Товары.Родитель = &Родитель

Получение корневых записей 

ВЫБРАТЬ
  Товары.*
ИЗ
  Справочник.Товары КАК Товары
ГДЕ
  Товары.Родитель = ЗНАЧЕНИЕ(Справочник.Товары.ПустаяСсылка

Получение записей принадлежащих группе  

ВЫБРАТЬ
  Товары.*
ИЗ
  Справочник.Товары КАК Товары
ГДЕ
  Товары.Ссылка В ИЕРАРХИИ (&ГруппаТоваров)
УПОРЯДОЧИТЬ ПО
  Наименование ИЕРАРХИЯ

Ограничения на выборку 

ВЫБРАТЬ
  Накладная.Дата КАК Дата,
  Накладная.Номер КАК Номер,
  Накладная.Поставщик
ИЗ
  Документ.ПриходнаяНакладная КАК Накладная
ГДЕ
  Дата >= ДАТАВРЕМЯ(2012, 11, 01)

ВЫБРАТЬ
  Клиенты.Наименование КАК Наименование,
  Клиенты.Адрес,
  Клиенты.Телефон
ИЗ
  Справочник.Клиенты КАК Клиенты
ГДЕ 
  Наименование ПОДОБНО "%Иван%"

В функции ПОДОБНО % - любое кол-во символов, _ - один символ, 

Агрегатные функции и группировка

Агрегатные функции обычно вызываются вместе с группировкой. При отсутствии СГРУППИРОВАТЬ ПО все записи исходной таблицы будут сгруппированы в одну строку.

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

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

В случае группировки по значению нескольких полей нужно после ключевого слова СГРУППИРОВАТЬ ПО перечислить через запятую список полей группировки. 

СГРУППИРОВАТЬ ПО
  НакладнаяСостав.Ссылка.Покупатель,
  НакладнаяСостав.Товар

ИМЕЮЩИЕ добавляет условие на значения агрегатных функций, применяемых  к исходным записям с одинаковым значением поля группировки.  Оно  накладывает условие на записи, получившиеся в  результате группировки. 

ВЫБРАТЬ
  НакладнаяСостав.Ссылка.Покупатель КАК Покупатель,
  НакладнаяСостав.Товар КАК Товар,
  СУММА(НакладнаяСостав.Количество) КАК Количество,
  СУММА(НакладнаяСостав.Сумма) КАК Сумма
ИЗ
  Документ.РасходнаяНакладная.Состав КАК НакладнаяСостав
СГРУППИРОВАТЬ ПО
  НакладнаяСостав.Ссылка.Покупатель,
  НакладнаяСостав.Товар
ИМЕЮЩИЕ 
  СУММА(НакладнаяСостав.Сумма) > 50000

Итоги

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

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

За счет ключевых слов ИЕРАРХИЯ и ТОЛЬКО ИЕРАРХИЯ можно считать итоги по иерархии (или только) 

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

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

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