ВсёПросто

Проверка на пустую ссылку, дату или строку в запросе 1С

Содержание

Примеры запросов в 1С 8

В запросе воспользуемся функцией КОНЕЦПЕРИОДА(&ДатаКонец, ДЕНЬ), она приведет дату к виду «23:59:59».

Запрос = Новый Запрос;
Запрос.Текст = «
|ВЫБРАТЬ
| СчетНаОплатуПокупателю.Дата
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
|ГДЕ
| СчетНаОплатуПокупателю.

Дата МЕЖДУ НАЧАЛОПЕРИОДА(&ДатаНачала, ДЕНЬ)
| И КОНЕЦПЕРИОДА(&ДатаКонец, ДЕНЬ)»;
Запрос.УстановитьПараметр(«ДатаКонец», ДатаКонец);
Запрос.

УстановитьПараметр(«ДатаНачала», ДатаНачала);
РезультатЗапроса = Запрос.Выполнить();

Как правильно обрабатывать значения NULL в запросе 1С8?

В запросе значения типа NULL образуются в результате соединений (ЛЕВОЕ, ПРАВОЕ), когда элементу из одной таблицы по условию не находится соответствующего элемента из другой. Значение типа NULL имею специфические особенности:

Как вывести результат запроса в табличный документ?

Для этого можно использовать объект ПостроительОтчета:

ТабДок = Новый ТабличныйДокумент;
Результат = РезультатЗапроса.Выгрузить();

Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Результат);
Построитель.Вывести(ТабДок);
ТабДок.Записать(«D:mxlТаблица.mxl»);

Как посчитать возраст по дате рождения в запросе 1С8?

Использовать функцию языка запроса РАЗНОСТЬДАТ:

ВЫБРАТЬ
Сотрудники.Сотрудник,
Сотрудники.Пол,
РАЗНОСТЬДАТ(Сотрудники.ДатаРождения, &ТекДата, ГОД) КАК Возраст
ИЗ Сотрудники КАК Сотрудники ПОЛНОЕ СОЕДИНЕНИЕ ПриемНаРаботу КАК ПриемНаРаботу

ПО Сотрудники.Сотрудник = ПриемНаРаботу.Сотрудник

ПОЛНОЕ СОЕДИНЕНИЕ Пенсия КАК Пенсия

ПО Сотрудники.Сотрудник = Пенсия.Сотрудник

Почему в результате запроса 1С8 появляется ошибка «Ошибка чтения значения» при отладке?

Бывает, что в консоли запрос отрабатывается нормально, но в рабочем режиме падает с ошибкой «Значение не является значением объектного типа (Сумма)». При этом отладчик показывает, что в коллекции «ВыборкаИзРезультатаЗапроса» находиться сумма со значением «Ошибка чтения значения». При отладке выдается «Ошибка чтения значения», если в функции написать так:

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

Ошибка чтения значений результата запроса, возникает из-за того, что в выборке еще не осуществлена установка на первый элемент выборки. Для этого существует метод «Следующий()» коллекции «ВыборкаИзРезультатаЗапроса». Поэтому надо писать так:

Если Выборка.Следующий() Тогда
ДоговорКонтрагента = Выборка.Наименование;
КонецЕсли;

Как запросом получить все подчиненные документы?

С помощью Функции «ПолучитьСписокВводимыхДокументовНаОсновании» получим список документов, которые вводятся на основании заданного документа:

// Параметры: ДокументПоиска: Тип — Метаданные объекта
Функция ПолучитьСписокВводимыхДокументовНаОсновании(ДокументПоиска) Экспорт

СписокДокументов = Новый СписокЗначений;
Для Каждого Документ Из Метаданные.Документы Цикл
Если Документ.ВводитсяНаОсновании.Содержит(ДокументПоиска) Тогда
СписокДокументов.Добавить(Документ.Имя, Документ.Синоним);
КонецЕсли;
КонецЦикла;
Возврат СписокДокументов;

КонецФункции

Теперь, на основании списка документов найдем все подчинненные заданному документу:

Функция ПолучитьПодчиненныеДокументы()

СписокЗаполнения = ПолучитьСписокВводимыхДокументовНаОсновании(СсылкаНаОбъект.Метаданные());
ТекстЗапросаПоСтатусу = «»;
Для Каждого ЭлементСписка Из СписокЗаполнения Цикл
Если НЕ ПустаяСтрока(ТекстЗапросаПоСтатусу) Тогда
ТекстЗапросаПоСтатусу = ТекстЗапросаПоСтатусу + «
|ОБЪЕДИНИТЬ ВСЕ
|»;
КонецЕсли;

ТекстЗапросаПоСтатусу = ТекстЗапросаПоСтатусу + «
|ВЫБРАТЬ « + ?(ПустаяСтрока(ТекстЗапросаПоСтатусу), «РАЗРЕШЕННЫЕ», «») + «
| Док.Ссылка КАК ПодчиненныйДокумент
|ИЗ
| Документ.» + ЭлементСписка.Значение + » КАК Док
|ГДЕ
| Док.ДокументОснование = &парамОснование
| И Док.Проведен
|»;
КонецЦикла;

Запрос = Новый Запрос;
Запрос.УстановитьПараметр(«парамОснование», СсылкаНаОбъект);
Запрос.Текст = ТекстЗапросаПоСтатусу;
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(«ПодчиненныйДокумент»);

КонецФункции // ПолучитьПодчиненныеДокументы()

Выведем полученные документы:

Процедура ВывестиПодчиненныеДокументы()
Массив = ПолучитьПодчиненныеДокументы();
Для каждого Эл Из Массив Цикл
Сообщить(Эл);
КонецЦикла;
КонецПроцедуры

Как выглядит недокументированный синтаксис оператора ВЫБОР?

Вот нестандартный вариант синтаксиса оператора ВЫБОР:

ВЫБРАТЬ ВЫБОР ДЕНЬНЕДЕЛИ(ДАТАВРЕМЯ(2015, 4, 1)) КОГДА 1 ТОГДА «Понедельник» КОГДА 2 ТОГДА «Вторник» КОГДА 3 ТОГДА «Среда» КОГДА 4 ТОГДА «Четверг» КОГДА 5 ТОГДА «Пятница» КОГДА 6 ТОГДА «Суббота» ИНАЧЕ «Воскресенье» КОНЕЦ КАК ДеньНедели

В этом примере показано, как с помощью опрератора ВЫБОР выводить текстовое представление дня недели.

Как составить запрос к табличной части документа?

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

Построитель.Текст = «ВЫБРАТЬ
| Товары.Ответственный,
| Товары.Ссылка КАК Документ,
| Товары.Номенклатура,
| СУММА(Товары.Сумма) КАК Сумма
|ИЗ
| Документ.ЧекККМ.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Дата Между &ДатаНач и &ДатаКон
|СГРУППИРОВАТЬ ПО
| Товары.Ссылка,
| Товары.Ответственный,
| Товары.Номенклатура»;

Особенность этого запроса в том, что мы обращаемся к табличной части «Товары».Поэтому к реквизитам документа «ЧекККМ» мы обращаемся через свойство «Ссылка».Только в этом случае мы сможем получить строки табличной части документа.

Если не указать свойство «Ссылка», то появится ошибка, примерно такого вида:

Понятие пустой даты и ее использование в запросах 1С

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

Именно на эти вопросы мы и постараемся ответить в нашей статье.

Что такое дата и как ее определить

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

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

Существующие в мире форматы даты имеют существенное различие:

  1. В России мы привыкли на первое место ставить день, затем идет месяц события, в конце – год;
  2. Жители США начинают дату с месяца;
  3. Чехи, поляки и словенцы записывают период в формате «Год – Месяц – День».

Именно последний формат и использует платформа 1С.

Преобразование к дате

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

Рис. 1

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

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

Отсчет времени в программе идет от начала дня 1 января 0001 года. Для приведенного выше кода это значение можно определить одним из двух способов (Рис. 2).

Рис. 2

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

Особенности использования даты в запросах 1С

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

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

Рис. 3

Получив пустую дату, мы можем указать ее в качестве параметра к нашему запросу, то есть использовать конструкцию (Рис. 4)

Рис. 4

Однако, существуют моменты, когда проверку лучше проводить внутри текста запроса, не передавая пустую дату в качестве параметра. Для этого в коде запроса можно ввести соответствующее условие (Рис. 5) и использовать функцию запроса ДатаВремя().

Рис. 5

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

Дата и граница времени

Еще один интересный факт, касающийся соотношения запросов и даты – это использование понятия «момент времени» при обращении к различным таблицам базы данных.

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

Для того чтобы понять, как и почему это происходит, рассмотрим простой пример:

  1. До проведения в 12 часов 31 минуту 36 секунд документа реализации остатки по номенклатуре Сахар составляли 30 кг;
  2. Документом в указанное время было списано 10 кг;
  3. Отчет, формируемый на дату документа на 12 часов 31 минуту 36 секунд по таблице Остатки, покажет остаток 30кг;
  4. Тот же самый отчет по таблице ОстаткиИОбороты на то же самое время покажет остаток в 20 кг.

В чем же причина подобного поведения и как этого избежать?

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

Выходов из этой ситуации несколько:

  1. При использовании таблицы Остатки, указывать момент времени на 1 секунду больший, чем заданный;
  2. Использовать только таблицу ОстаткиИОбороты (не самый оптимальный с точки зрения производительности вариант);
  3. Использовать понятие Граница.

Последний вариант можно представить кодом, указанном на Рис. 6.

Рис. 6

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

Запросы 1С:Предприятие 8. Прочие функции

В языке запросов 1С существует большое количество различных функций и операторов, облегчающих построение запроса. Часть из них мы рассмотрели в статьях Функции работы с датами, Группировки в запросах 1С, остальные рассмотрим сейчас.

Функции работы со строками в запросах 1С

Функций и операторов для работы со строковыми данными в запросах 1С немного.

Во-первых, строки в запросах можно складывать. Для этого используется оператор «+»:

Запрос.Текст=»ВЫБРАТЬ
«»Строка: «» + Источник.Наименование
Из Справочник.Источник КАК Источник»;

Во-вторых, можно выделить часть строки. Для этого используется функция ПОДСТРОКА. Функция аналогична функции СРЕД () встроенного языка 1С. У нее три параметра:

  1. Строка-источник.
  2. Номер символа, с которого должна начинаться выделяемая строка.
  3. Количество символов.

Запрос.Текст=»ВЫБРАТЬ
ПОДСТРОКА(«»Строка: «», 4, 3) КАК Результат»; // Результат: ока

И, наконец, существует оператор, которые позволяет сравнить строку с неким шаблоном. Это оператор ПОДОБНО. О его использовании читайте в нашей статье о парамертах и операторах сравнения в запросах 1С.

Функция ЕСТЬNULL

NULL — особый тип данных на платформе 1С:Предприятие. Он же является единственным возможным значением этого типа.

NULL может возникать в запросах в нескольких случаях: при соединениях источников запроса, если не было найдено соответствующего значения в одной из таблиц; при обращении к реквизитам несуществующего объекта; если NULL был указан в списке полей запроса (например при объединении результатов выборки из нескольких таблиц) и т.д.

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

Она имеет два параметра:

  1. Проверяемое значение.
  2. Значение, на которое нужно заменить первый параметр, если он оказался равен NULL.

Запрос.Текст=»ВЫБРАТЬ
ЕСТЬNULL(Источник.Остаток, 0) КАК Остаток»; // Если в результате запроса поле остаток=NULL,
// то оно заменится на 0, и с ним можно будет выполнять математические действия

Функции ПРЕДСТАВЛЕНИЕ и ПРЕДСТАВЛЕНИЕССЫЛКИ

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

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

ПРЕДСТАВЛЕНИЕ(ДАТАВРЕМЯ(2016,10,07)) КАК Дата»

;
// Булево = «Да», Число = «4», Ссылка = «Документ Расходный кассовый ордер №… от…»
// Дата=»07.10.2016 0:00:00″

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

ПРЕДСТАВЛЕНИЕССЫЛКИ (ДАТАВРЕМЯ(2016,10,07)) КАК Дата»

;
// Булево = ИСТИНА, Число = 4, Ссылка = «Документ Расходный кассовый ордер №… от…»
// Дата=07.10.2016 0:00:00

Функции ТИП и ТИПЗНАЧЕНИЯ

Функция ТИП возвращает тип данных платформы 1С:Предприятие.

Запрос.Текст=»ВЫБРАТЬТИП (Число) ,ТИП (Строка),

ТИП (Документ.РасходныйКассовыйОрдер)»

;

Функция ТИПЗНАЧЕНИЯ возвращает тип переданного в нее значения.

Запрос.Текст=»ВЫБРАТЬТИПЗНАЧЕНИЯ (5) КАК Число,

ТИП («

«Строчка»») КАК Строка,ТИП (Источник.Ссылка) КАК Справочник

Из Справочник.Источник КАК Источник»

;
//Число=Число, Строка=Строка, Справочник = СправочникСсылка.Источник

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

Запрос.Текст=»ВЫБРАТЬКонтактнаяИнформация.ПредставлениеИЗРегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформацияГДЕ

ТИПЗНАЧЕНИЯ(КонтактнаяИнформация.Объект) = ТИП(Справочник.Контрагенты)»

;

Функция ЗНАЧЕНИЕ

Функция Значение позволяет использовать в запросе объекты конфигурации 1С напрямую, без применения параметров запроса.

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

Запрос.Текст=»ВЫБРАТЬКонтактнаяИнформация.ПредставлениеИЗРегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформацияГДЕТИПЗНАЧЕНИЯ(КонтактнаяИнформация.Объект) = ТИП(Справочник.Контрагенты)
И КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон)»

;

Следует отметить, что эту функцию можно использовать только с предопределенными значениями, т.е. со значениями, к которым можно обратиться напрямую из конфигуратора. То есть функция ЗНАЧЕНИЕ не можно использоваться с элементами справочников, созданными пользователями, но может работать с перечислениями, с предопределенными элементами справочников, со значениями ПустаяСсылка.

Оператор ССЫЛКА

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

Например, задачу выбора контактной информации контрагентов можно было решить и так:

Запрос.Текст=»ВЫБРАТЬКонтактнаяИнформация.ПредставлениеИЗРегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформацияГДЕ

КонтактнаяИнформация.Объект ССЫЛКА Справочник.Контрагенты»

;

Оператор ВЫРАЗИТЬ

Оператор ВЫРАЗИТЬ используется в запросах 1С в двух случаях:

К примитивным типам данных относятся: число, строка, дата, булево. Некоторые из этих типов данных имеют дополнительные характеристики. Тип Число имеет длину и точность, тип Строка — длину или неограниченность.

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