Примеры запросов в 1С 8
Доброго времени суток, коллеги! Много раз на нашем сайте обсуждалась тема запросов в 1С, например, как получить всех родителей элемента справочника одним запросом. В этой статье вы увидите еще много разных примеров запросов, которые помогут вам решать повседневные задачи. Вот, посмотрите.
Содержание
- Как в запросе 1с8 установить условие проверки периода на конец дня?
- Как правильно обрабатывать значения NULL в запросе 1С8?
- Как вывести результат запроса в табличный документ?
- Как посчитать возраст по дате рождения в запросе 1С8?
- Почему в результате запроса 1С8 появляется ошибка «Ошибка чтения значения» при отладке?
- Как запросом получить все подчиненные документы?
- Как выглядит недокументированный синтаксис оператора ВЫБОР?
- Как составить запрос к табличной части документа?
- Как запросом для документа найти все подчинённые ему документы?
- Как сравнить строки в запросе?
- Как в запросе проверить поле на пустую ссылку?
- Как в запросе убрать фильтр на значение параметра?
Как в запросе 1с8 установить условие проверки периода на конец дня?
В запросе воспользуемся функцией КОНЕЦПЕРИОДА(&ДатаКонец, ДЕНЬ), она приведет дату к виду «23:59:59».
Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | СчетНаОплатуПокупателю.Дата |ИЗ | Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю |ГДЕ | СчетНаОплатуПокупателю.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&ДатаНачала, ДЕНЬ) | И КОНЕЦПЕРИОДА(&ДатаКонец, ДЕНЬ)"; Запрос.УстановитьПараметр("ДатаКонец", ДатаКонец); Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); РезультатЗапроса = Запрос.Выполнить();
Как правильно обрабатывать значения NULL в запросе 1С8?
В запросе значения типа NULL образуются в результате соединений (ЛЕВОЕ, ПРАВОЕ), когда элементу из одной таблицы по условию не находится соответствующего элемента из другой. Значение типа NULL имею специфические особенности:
-
- Cравнение значения NULL с любым другим аргументом всегда возвращает ложь. Например, если в запросе поле «Количество» возвращает NULL, то если использовать операции сравнения «<», «>», или «=» с числом 1000, то результатом всегда будет «Ложь». Даже, если сравнить с самим значением NULL, то все равно результатом будет «Ложь»:
ГДЕ ГТД.Количество = NULL
-
- Применение арифметических операций к значению типа NULL всегда возвращает NULL. Например, если в запросе к полю «Количество», которое возвращает NULL, прибавить числовое значение или отнять от него числовое значение, то будет возвращено значение NULL:
ГТД.Количество+300 КАК Поле1
-
- Для определения значения NULL используется функция конструкция «IS NULL». Чтобы получить записи со значением NULL воспользуемся следующей конструкцией:
ГДЕ ГТД.Регистратор.Организация IS NULL
если нужно получить записи без NULL, тогда:
ГДЕ НЕ ГТД.Регистратор.Организация IS NULL
- Для преобразования типа NULL используется функция «isNULL» или «ЕСТЬNULL». Теперь можно сравнивать с полученным значением или применять к нему арифметические операции, не боясь за конечный результат:
- Для определения значения NULL используется функция конструкция «IS NULL». Чтобы получить записи со значением NULL воспользуемся следующей конструкцией:
ЕСТЬNULL(ГТД.Количество, 0)+300 КАК Поле1
-
- Для того, чтобы в результате запроса отсечь записи, содержащие значения NULL применяются следующие конструкции: «IS NOT NULL», «NOT <поле> is NULL»:
ГДЕ ГТД.Регистратор.Организация IS NOT NULL
или
ГДЕ NOT ГТД.Регистратор.Организация IS NULL
Как вывести результат запроса в табличный документ?
Для этого можно использовать объект ПостроительОтчета:
ТабДок = Новый ТабличныйДокумент; Результат = РезультатЗапроса.Выгрузить(); Построитель = Новый ПостроительОтчета; Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Результат); Построитель.Вывести(ТабДок); ТабДок.Записать("D:\mxl\Таблица.mxl");
Как посчитать возраст по дате рождения в запросе 1С8?
Использовать функцию языка запроса РАЗНОСТЬДАТ:
ВЫБРАТЬ Сотрудники.Сотрудник, Сотрудники.Пол, РАЗНОСТЬДАТ(Сотрудники.ДатаРождения, &ТекДата, ГОД) КАК Возраст ИЗ Сотрудники КАК Сотрудники ПОЛНОЕ СОЕДИНЕНИЕ ПриемНаРаботу КАК ПриемНаРаботу ПО Сотрудники.Сотрудник = ПриемНаРаботу.Сотрудник ПОЛНОЕ СОЕДИНЕНИЕ Пенсия КАК Пенсия ПО Сотрудники.Сотрудник = Пенсия.Сотрудник
Почему в результате запроса 1С8 появляется ошибка «Ошибка чтения значения» при отладке?
Бывает, что в консоли запрос отрабатывается нормально, но в рабочем режиме падает с ошибкой «Значение не является значением объектного типа (Сумма)». При этом отладчик показывает, что в коллекции «ВыборкаИзРезультатаЗапроса» находиться сумма со значением «Ошибка чтения значения». При отладке выдается «Ошибка чтения значения», если в функции написать так:
Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Возврат Выборка;
Ошибка чтения значений результата запроса, возникает из-за того, что в выборке еще не осуществлена установка на первый элемент выборки. Для этого существует метод «Следующий()» коллекции «ВыборкаИзРезультатаЗапроса». Поэтому надо писать так:
Если Выборка.Следующий() Тогда ДоговорКонтрагента = Выборка.Наименование; КонецЕсли;
Как запросом получить все подчиненные документы?
С помощью Функции «ПолучитьСписокВводимыхДокументовНаОсновании» получим список документов, которые вводятся на основании заданного документа:
// Параметры: ДокументПоиска: Тип - Метаданные объекта Функция ПолучитьСписокВводимыхДокументовНаОсновании(ДокументПоиска) Экспорт СписокДокументов = Новый СписокЗначений; Для Каждого Документ Из Метаданные.Документы Цикл Если Документ.ВводитсяНаОсновании.Содержит(ДокументПоиска) Тогда СписокДокументов.Добавить(Документ.Имя, Документ.Синоним); КонецЕсли; КонецЦикла; Возврат СписокДокументов; КонецФункции
Теперь, на основании списка документов найдем все подчинённые заданному документу:
Функция ПолучитьПодчиненныеДокументы() СписокЗаполнения = ПолучитьСписокВводимыхДокументовНаОсновании(СсылкаНаОбъект.Метаданные()); ТекстЗапросаПоСтатусу = ""; Для Каждого ЭлементСписка Из СписокЗаполнения Цикл Если НЕ ПустаяСтрока(ТекстЗапросаПоСтатусу) Тогда ТекстЗапросаПоСтатусу = ТекстЗапросаПоСтатусу + " |ОБЪЕДИНИТЬ ВСЕ |"; КонецЕсли; ТекстЗапросаПоСтатусу = ТекстЗапросаПоСтатусу + " |ВЫБРАТЬ " + ?(ПустаяСтрока(ТекстЗапросаПоСтатусу), "РАЗРЕШЕННЫЕ", "") + " | Док.Ссылка КАК ПодчиненныйДокумент |ИЗ | Документ." + ЭлементСписка.Значение + " КАК Док |ГДЕ | Док.ДокументОснование = &парамОснование | И Док.Проведен |"; КонецЦикла; Запрос = Новый Запрос; Запрос.УстановитьПараметр("парамОснование", СсылкаНаОбъект); Запрос.Текст = ТекстЗапросаПоСтатусу; Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ПодчиненныйДокумент"); КонецФункции // ПолучитьПодчиненныеДокументы()
Выведем полученные документы:
Процедура ВывестиПодчиненныеДокументы() Массив = ПолучитьПодчиненныеДокументы(); Для каждого Эл Из Массив Цикл Сообщить(Эл); КонецЦикла; КонецПроцедуры
Как выглядит недокументированный синтаксис оператора ВЫБОР?
Вот нестандартный вариант синтаксиса оператора ВЫБОР:
ВЫБРАТЬ ВЫБОР ДЕНЬНЕДЕЛИ(ДАТАВРЕМЯ(2015, 4, 1)) КОГДА 1 ТОГДА "Понедельник" КОГДА 2 ТОГДА "Вторник" КОГДА 3 ТОГДА "Среда" КОГДА 4 ТОГДА "Четверг" КОГДА 5 ТОГДА "Пятница" КОГДА 6 ТОГДА "Суббота" ИНАЧЕ "Воскресенье" КОНЕЦ КАК ДеньНедели
В этом примере показано, как с помощью опрератора ВЫБОР выводить текстовое представление дня недели.
Как составить запрос к табличной части документа?
Пример запроса:
Построитель.Текст = "ВЫБРАТЬ | Товары.Ответственный, | Товары.Ссылка КАК Документ, | Товары.Номенклатура, | СУММА(Товары.Сумма) КАК Сумма |ИЗ | Документ.ЧекККМ.Товары КАК Товары |ГДЕ | Товары.Ссылка.Дата Между &ДатаНач и &ДатаКон |СГРУППИРОВАТЬ ПО | Товары.Ссылка, | Товары.Ответственный, | Товары.Номенклатура";
Особенность этого запроса в том, что мы обращаемся к табличной части «Товары». Поэтому к реквизитам документа «ЧекККМ» мы обращаемся через свойство «Ссылка». Только в этом случае мы сможем получить строки табличной части документа. Если не указать свойство «Ссылка», то появится ошибка, примерно такого вида:
{(7, 5)}: Поле не найдено «Документ.ЧекККМ.Дата»
Как запросом для документа найти все подчинённые ему документы?
Воспользуемся следующим запросом:
Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | СчетФактураВыданный.Ссылка |ИЗ | Документ.СчетФактураВыданный КАК СчетФактураВыданный |ГДЕ | СчетФактураВыданный.ДокументОснование = &ДокументОснование"; Запрос.УстановитьПараметр("ДокументОснование", Накладная); РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); Пока Выборка.Следующий() Цикл СФ = Выборка.Ссылка.ПолучитьОбъект(); СФ.ДокументОснование = ""; СФ.Записать(РежимЗаписиДокумента.Запись); КонецЦикла;
Как сравнить строки в запросе?
| ГДЕ (Номер ПОДОБНО &НомерНакладной) Запрос.УстановитьПараметр("НомерНакладной", "%"+НомерНакладной+"%");
Как в запросе проверить поле на пустую ссылку?
ВЫБРАТЬ Начисление.Ссылка, Увольнение.Ссылка КАК Ссылка1, Начисление.ДокументОснование, Увольнение.ДокументОснование КАК ДокументОснование1 ИЗ Документ.НачислениеЗарплатыРаботникамОрганизаций КАК Начисление СОЕДИНЕНИЕ Документ.УвольнениеИзОрганизаций КАК Увольнение ПО Начисление.ДокументОснование = Увольнение.ДокументОснование ГДЕ (Начисление.ДокументОснование<> ЗНАЧЕНИЕ(Документ.ТабельУчетаРабочегоВремениОрганизации.ПустаяСсылка))
Заметим, что в параметре пишем «Документ», а не «Документы» и «ПустаяСсылка» без скобок.
Как в запросе убрать фильтр на значение параметра?
Например, нам нужно вывести данные о продажах, отфильтровав их по значению в поле формы «Товар», если в этом поле выбран нужный нам товар. И если товар не выбран, то вывести данные по всем товарам. Пример запроса такой:
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ПродажиОбороты.Номенклатура, | ПродажиОбороты.СуммаОборот КАК Сумма |ИЗ | РегистрНакопления.Продажи.Обороты(&ДатаНачала, | &ДатаОкончания, , | &Товар) КАК ПродажиОбороты"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Запрос.УстановитьПараметр("Товар", Товар);
Рассмотрим четыре способа, как избавится от фильтра в запросе.
- Изменим параметр запроса с помощью функции «СтрЗаменить»:
Если Товар.Пустая() Тогда Запрос.Текст = СтрЗаменить(Запрос.Текст, "&Товар", ""); Иначе Запрос.Текст = СтрЗаменить(Запрос.Текст, "&Товар", "Номенклатура = &Товар"); КонецЕсли;
- В параметре виртуальной таблицы вместо значения «&Товар» запишем следующее выражение:
|&Товар = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) | ИЛИ Номенклатура = &Товар
Если параметр товар не заполнен, то первое выражение примет значение ИСТИНА, тогда значение всего выражения примет значение ИСТИНА. В этом случае как-будто и нет никакого фильтра. Но если товар заполнен, то первое выражение принимает значение ЛОЖЬ. Тогда сработает второе выражение и произойдет фильтрация по товару.
- Еще один способ возможен благодаря новому объекту платформы «СхемаЗапроса (QuerySchema)», который появился в версии 1С 8.3.5:
СхемаЗапроса = Новый СхемаЗапроса; СхемаЗапроса.УстановитьТекстЗапроса(Запрос.Текст); Если ЗначениеЗаполнено(Товар) Тогда СхемаЗапроса.ПакетЗапросов[0].Операторы[0].Источники[0].Источник.Параметры[3].Выражение = Новый ВыражениеСхемыЗапроса("Номенклатура = &Товар"); КонецЕсли; Запрос.Текст = СхемаЗапроса.ПолучитьТекстЗапроса();
- Последний способ очень громоздкий, но его тоже можно использовать:
Если Товар.Пустая() Тогда Запрос.Текст = "ВЫБРАТЬ | ПродажиОбороты.Номенклатура, | ПродажиОбороты.СуммаОборот КАК Сумма |ИЗ | РегистрНакопления.Продажи.Обороты(&ДатаНачала, | &ДатаОкончания, , ) КАК ПродажиОбороты" Иначе Запрос.Текст = "ВЫБРАТЬ | ПродажиОбороты.Номенклатура, | ПродажиОбороты.СуммаОборот КАК Сумма |ИЗ | РегистрНакопления.Продажи.Обороты(&ДатаНачала, | &ДатаОкончания, , Номенклатура = &Товар) КАК ПродажиОбороты"; КонецЕсли;
Как видите, в запросе изменилось только значение условия виртуальной таблицы.