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

1с выразить как число в запросе

  • автор:

Округление результатов арифметических операций в запросах

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

Методическая рекомендация (полезный совет)

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

0.02 / 28346 * 9287492

0.02 * 9287492 / 28346

2. При выполнении арифметических операций в запросах к базе данных платформа 1С:Предприятия поддерживает точность вычислений до 8 разрядов дробной части. Однако, из-за особенностей работы различных СУБД в некоторых ситуациях точность результатов может отличаться от 8. Более подробно о вычислении разрядности результатов можно почитать в статье ИТС Разрядность результатов выражений и агрегатных функций в языке запросов.

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

  • арифметические операции деления,
  • агрегатные функции СРЕДНЕЕ ,
  • арифметические операции умножения, если каждый из множителей может иметь дробную часть,

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

ВЫРАЗИТЬ(. КАК Число(m, n))

Оператор ВЫРАЗИТЬ следует применять к операндам, если на какой-нибудь СУБД точность получаемого результата недостаточна. Например, требуется 10 разрядов после запятой, а получается 6.

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

Важно иметь в виду, что на разных СУБД имеются различные ограничения на максимальную разрядность десятичных чисел. Самое жесткое ограничение — это 31 разряд в целой и дробной частях. Чем меньшее значение разрядности будет указано для операндов, тем выше сможет быть точность результата. Например, если в результате требуется не менее 10 разрядов дробной части, первый операнд заведомо помещается в 15 разрядов целой части, а второй операнд заведомо помещается в 5 знаков целой части, то выражение может быть записано так:

ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10)) / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Результат
ИЗ Таблица КАК Таблица

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

ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель / Таблица.Знаменатель КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица

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

ВЫБРАТЬ
ВЫРАЗИТЬ(ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10)) / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица

1с выразить как число в запросе

8(495)005-62-29

skype: live:di-sem

@programmist_1C

Отправить заявку

1С Строку в число в запросе. Число в строку в запросе.

МАКСИМУМ(выразить(Номенклатура.Код как число(6,2))) — к сожалению вот так преобразовать строку в число не получится!

На помощь придут вот такие функции. Нашел их тут.

Функция ТекстЗапросаИзЧислаВСтроку(пИмяПоля, пДлинаЦел, пДлинаДробь, пЛидирующийСимвол="") лЗапрос=Новый Запрос("ВЫБРАТЬ ВЫРАЗИТЬ(0.5 КАК ЧИСЛО (15, 0)) КАК Проверка"); лВыборка=лЗапрос.Выполнить().Выбрать(); лВыборка.Следующий(); лЗапросОкругляетПоАрифметическимПравилам=лВыборка.Проверка=1; лТекст="ВЫБОР КОГДА "+пИмяПоля+""-"" ИНАЧЕ """" КОНЕЦ "+Символы.ПС; лИмяПоляАбс=" ВЫБОР КОГДА "+пИмяПоля+"+пИмяПоля+" ИНАЧЕ "+пИмяПоля+" КОНЕЦ "; лПараметр=Pow(10, пДлинаЦел-1); Для лИнд=1 По пДлинаЦел+пДлинаДробь цикл лТекст=лТекст+?(лИнд=пДлинаЦел+1, "+"".""+", "+"); лТекст=лТекст+" ВЫБОР "+Символы.ПС+ ?(лИндпДлинаЦел, " КОГДА "+лИмяПоляАбс+" < "+Формат(лПараметр, "ЧРД=.; ЧГ k">)+" ТОГДА """+пЛидирующийСимвол+""" "+Символы.ПС, ""); Для лЦифра=0 По 9 Цикл лТекст=лТекст+" КОГДА "+лИмяПоляАбс+"-"+Формат(лПараметр*10, "ЧРД=.; ЧГ k">)+"*ВЫРАЗИТЬ(("+лИмяПоляАбс+?(лЗапросОкругляетПоАрифметическимПравилам, "-"+Формат(лПараметр*5, "ЧРД=.; ЧГ k">), "")+")/"+Формат(лПараметр*10, "ЧРД=.; ЧГ k">)+" КАК ЧИСЛО(15, 0))"+" > k">+Формат((9-лЦифра)*лПараметр, "ЧН=0; ЧРД=.; ЧГ k">)+" ТОГДА """+Формат(9-лЦифра, "ЧН=0; ЧРД=.; ЧГ k">)+""" "+Символы.ПС; КонецЦикла; лТекст=лТекст+" ИНАЧЕ ""0"""+Символы.ПС+" Конец "+Символы.ПС; лПараметр=лПараметр/10; КонецЦикла; Сообщить(лТекст); Возврат лТекст; КонецФункции Функция ТекстЗапросаИзСтрокиВЧисло(пИмяПоля, пДлинаСтроки, пСимволРазделителя=".") лТекст="ВЫБОР "; Для лДлинаЦелойЧасти=0 По пДлинаСтроки Цикл Если лДлинаЦелойЧасти=пДлинаСтроки Тогда лТекст=лТекст+"ИНАЧЕ"+Символы.ПС; Иначе лТекст=лТекст+"КОГДА ПОДСТРОКА("+пИмяПоля+", "+(лДлинаЦелойЧасти+1)+", 1) s">""+пСимволРазделителя+""" ИЛИ ПОДСТРОКА("+пИмяПоля+", "+(лДлинаЦелойЧасти+1)+", 1) s">""" ТОГДА "+Символы.ПС; КонецЕсли; Если лДлинаЦелойЧасти=0 Тогда лТекст=лТекст+" 0"+Символы.ПС; КонецЕсли; Для лИнд=1 По лДлинаЦелойЧасти Цикл лТекст=лТекст+" ВЫБОР "+Символы.ПС; Для лЦифра=0 По 9 Цикл лТекст=лТекст+" КОГДА ПОДСТРОКА("+пИмяПоля+", "+лИнд+", 1) s">""+лЦифра+""" ТОГДА "+лЦифра+Символы.ПС; КонецЦикла; лТекст=лТекст+" ИНАЧЕ 0 КОНЕЦ"+?(лИнд=лДлинаЦелойЧасти, "", "*"+Формат(Pow(10, лДлинаЦелойЧасти-лИнд), "ЧРД=.; ЧГ=0")+"+")+Символы.ПС; КонецЦикла; Для лИнд=лДлинаЦелойЧасти+2 По пДлинаСтроки Цикл лТекст=лТекст+"+ ВЫБОР"; Для лЦифра=0 По 9 Цикл лТекст=лТекст+" КОГДА ПОДСТРОКА("+пИмяПоля+", "+лИнд+", 1) s">""+лЦифра+""" ТОГДА "+лЦифра+Символы.ПС; КонецЦикла; лТекст=лТекст+" ИНАЧЕ 0 КОНЕЦ"+?(лИнд=лДлинаЦелойЧасти, "", "/"+Формат(Pow(10, лИнд-лДлинаЦелойЧасти-1), "ЧРД=.; ЧГ=0"))+Символы.ПС; КонецЦикла; КонецЦикла; лТекст=лТекст+"КОНЕЦ"; Возврат лТекст; КонецФункции 

Использовать их так:

Процедура КнопкаВыполнить1(Кнопка) лЗапрос=Новый Запрос; лЗапрос.Текст="ВЫБРАТЬ ""Полученная строка : ""+"+ТекстЗапросаИзЧислаВСтроку(12, 2, 0)+" КАК Строка"; лТзЗапроса=лЗапрос.Выполнить().Выгрузить(); лТзЗапроса.ВыбратьСтроку(); КонецПроцедуры Процедура КнопкаВыполнить2(Кнопка) лЗапрос=Новый Запрос; лЗапрос.УстановитьПараметр("а", "1333.3"); лЗапрос.Текст="ВЫБРАТЬ "+ТекстЗапросаИзСтрокиВЧисло("&а", 6)+" КАК Число"; Сообщить(лЗапрос.Текст); лТзЗапроса=лЗапрос.Выполнить().Выгрузить(); лТзЗапроса.ВыбратьСтроку(); КонецПроцедуры 

Получаем максимальный числовой код для товара из спр Номенклатура, где код — строка:

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

1с выразить как число в запросе

Здравствуйте! Не появилась ли данная возможность в свежих версиях 1С? Работаю на 8.2. Перейти на 8.3 возможности нет пока, острой необходимости тоже. Спрашиваю, чтоб велосипед не изобретать. В инете готовых решений, чтоб прям запросом из строки в число, не видел пока что.

выбор когда «1» тогда 1
когда «2» тогда 2
.
конец
ВЫРАЗИТЬ (Таблица.Строка КАК Число(15,2))
В явном виде нельзя.
Если только извращаться как в (1)
(2) Размечтался.
Такая возможность была давно, если не всегда.
(5) ловите наркомана
(4)(6) 🙂
(0) не слушай их. Всю жизнь использовал как в (2). Прекрасно работает.
(2) сам то пробовал так делать?
(9) десятки раз.
(1) )) А если справочник с 70 тыс строками и реквизит из строки в число?
(2) Так низя. Не работает.
Пля. Или я туплю, сейчас проверю.
(12) ты тупишь. можешь не проверять.
(10) Ругнется она на разные типы данных

не, ну если тип реквизита «строка» — число — то (2) работает.
а вообще надо сделать так, чтобы в исходных данных было число

(8) Не работает оно как надо. Может у Скуля робит, но не у 1С 🙂

Готовых решений не было не у кого? Я вчера задался идеей победить. Несколько раз в ступор восмёрошными ограничениями (по сравнению со скулем) вставал.

(12) Не тупишь, в результате запроса будет то что в выразить, но в самом запросе будет строка. Преобразование, по сути, происходит после выполнения всего запроса.

(17) сделай так, чтобы в исходных данных было число
(19) Ругается парсер на енто
(0) http://catalog.mista.ru/public/170336/ рвет шаблоны и взрывает мозг, как и все статьи автора
(19) и всё-таки я тупанул 🙂
Пишет «Несовместимые типы»

выбрать ВЫРАЗИТЬ (&парам как число(10, 0))
где парам задан как строка «15»

Текст запроса: Строка 1: : Несовместимые типы «ВЫРАЗИТЬ»
выбрать >ВЫРАЗИТЬ (&парам как число(10, 0))

(22) страшно далек он от реальности

Господа, вы меня пугаете.

(19) ВЫРАЗИТЬ не работает в конце запроса, в конце работает ПРЕДСТАВЛЕНИЕ.

(14) Думаю, что не ругнется, просто в значении типа строка значения типа число не будет обнаружено, а поэтому вернется какая-нить пустая кака, может неопределено.

(26) читай (24) до просветления
(22) Кому рвет? Мне не рвет.

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

(27) Ну значит так. Че ты как ребенок :))
В любом случае главное, что никакого преобразования ни в начале запроса ни в конце не будет.

(29) Думаю, что так, да.

(20) Можно и так, но победить оч захотелось.
(22) )) Хорошая статья, надо проверить как механизм с пробелами борется. По идее должен. Мимолетом на сколько смог код вкурить: там вроде сравнение на вхождение в 0123456789 проверяется, так что пробелы в сад вроде..

Я про то, когда Код в справочнике строковый, то в конце пробелы до длины строки добавляются. Они и костыли в колеса добавляют. А ни ltrim-rtrim ни right 1c не умеет.

когда уже народ будет требовать в запросах операторы ISERT/UPDATE/DELETE?
(33) видимо за последствия боятся
(33) а зачем тогда язык 1с нужен будет?

(22) Все работает. Статья в точку, спасибо огромнищее за ссылку!

А я, не видя (22), вчера вот такой код наваял. Теперь не актуально, но мож на мысли хорошие натолкнет кого.

Запрос.Текст =
«ВЫБРАТЬ
| ВЫБОР
| КОГДА ПОДСТРОКА(Товары.Код, 6, 1) <> «» «»
| ТОГДА Товары.Код
| КОГДА ПОДСТРОКА(Товары.Код, 5, 1) <> «» «»
| ТОГДА «» «» + ПОДСТРОКА(Товары.Код, 1, 5)
| КОГДА ПОДСТРОКА(Товары.Код, 4, 1) <> «» «»
| ТОГДА «» «» + ПОДСТРОКА(Товары.Код, 1, 4)
| КОГДА ПОДСТРОКА(Товары.Код, 3, 1) <> «» «»
| ТОГДА «» «» + ПОДСТРОКА(Товары.Код, 1, 3)
| КОГДА ПОДСТРОКА(Товары.Код, 2, 1) <> «» «»
| ТОГДА «» «» + ПОДСТРОКА(Товары.Код, 1, 2)
| КОГДА ПОДСТРОКА(Товары.Код, 1, 1) <> «» «»
| ТОГДА «» «» + ПОДСТРОКА(Товары.Код, 1, 1)
| ИНАЧЕ «»»»
| КОНЕЦ КАК Код
|ПОМЕСТИТЬ Коды
|ИЗ
| Справочник.Товары КАК Товары
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ 0 КАК n, «»0″» КАК nstr
|ПОМЕСТИТЬ conv
|ОБЪЕДИНИТЬ ВЫБРАТЬ 1, «»1″» ОБЪЕДИНИТЬ ВЫБРАТЬ 2, «»2″» ОБЪЕДИНИТЬ ВЫБРАТЬ 3, «»3″» ОБЪЕДИНИТЬ ВЫБРАТЬ 4, «»4″» ОБЪЕДИНИТЬ ВЫБРАТЬ 5, «»5″»
|ОБЪЕДИНИТЬ ВЫБРАТЬ 6, «»6″» ОБЪЕДИНИТЬ ВЫБРАТЬ 7, «»7″» ОБЪЕДИНИТЬ ВЫБРАТЬ 8, «»8″» ОБЪЕДИНИТЬ ВЫБРАТЬ 9, «»9″»
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ЕСТЬNULL(f.n, 0) * 1 + ЕСТЬNULL(e.n, 0) * 10 + ЕСТЬNULL(d.n, 0) * 100 + ЕСТЬNULL(c.n, 0) * 1000 + ЕСТЬNULL(b.n, 0) * 10000 + ЕСТЬNULL(a.n, 0) * 100000 КАК КодЧисло
|ИЗ
| Коды КАК Коды
| ЛЕВОЕ СОЕДИНЕНИЕ conv КАК a
| ПО (a.nstr = ПОДСТРОКА(Коды.Код, 1, 1))
| ЛЕВОЕ СОЕДИНЕНИЕ conv КАК b
| ПО (b.nstr = ПОДСТРОКА(Коды.Код, 2, 1))
| ЛЕВОЕ СОЕДИНЕНИЕ conv КАК c
| ПО (c.nstr = ПОДСТРОКА(Коды.Код, 3, 1))
| ЛЕВОЕ СОЕДИНЕНИЕ conv КАК d
| ПО (d.nstr = ПОДСТРОКА(Коды.Код, 4, 1))
| ЛЕВОЕ СОЕДИНЕНИЕ conv КАК e
| ПО (e.nstr = ПОДСТРОКА(Коды.Код, 5, 1))
| ЛЕВОЕ СОЕДИНЕНИЕ conv КАК f
| ПО (f.nstr = ПОДСТРОКА(Коды.Код, 6, 1))
|ГДЕ ЕСТЬNULL(f.n, 0) * 1 + ЕСТЬNULL(e.n, 0) * 10 + ЕСТЬNULL(d.n, 0) * 100 + ЕСТЬNULL(c.n, 0) * 1000 + ЕСТЬNULL(b.n, 0) * 10000 + ЕСТЬNULL(a.n, 0) * 100000 МЕЖДУ 65422 И 69287″;

Есть справочник Товары со строковым кодом. Нужно обобрать все коды в числовом интервале (для поиска дырки для нового кода). Длина кода 6 символов.

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

ВЫРАЗИТЬ в запросах 1С 8.3 — применение на примерах

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

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

Рассмотрим на примерах работу такого оператора.

ВЫРАЗИТЬ КАК Строка

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

Синтаксис:

Наша команда предоставляет услуги по консультированию, настройке и внедрению 1С.
Связаться с нами можно по телефону +7 499 350 29 00.
Услуги и цены можно увидеть по ссылке.
Будем рады помочь Вам!

Пример:

ВЫБРАТЬ

ВЫРАЗИТЬ(Номенклатура.Наименование КАК Строка(1)) КАК НаименованиеДлина_1

ИЗ

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

В таком примере выбираем все наименования из справочника «Номенклатура», затем с помощью конструкции «ВЫРАЗИТЬ» совместно с оператором «Строка», ограничиваем размер строки поля выборки до одного символа.

ВЫРАЗИТЬ КАК Число

В полях выборки запроса имеющих числовой тип данных, с помощью оператора «ВЫРАЗИТЬ» возможно, контролировать длину целой и дробной части числа. В случаях, когда в результате такого контроля будет уменьшено количество знаков в числе, произойдёт округление по математическим правилам.

Синтаксис:

Получите понятные самоучители по 1С бесплатно:

  • Самоучитель по 1С Бухгалтерии 8.3;
  • Самоучитель по 1С ЗУП 8.3.

Пример№1:

ВЫБРАТЬ

3.55 КАК НашеЧисло,

ВЫРАЗИТЬ(3.55 КАК Число(15,1)) КАК РезультатОкругления

Результат:

Пример№2:

ВЫБРАТЬ

10/3 КАК Результат,

ВЫРАЗИТЬ(10/3 КАК Число(15,2)) КАК РезультатОкругления

Результат:

Глядя на результаты примеров понятно, что оператор «ВЫРАЗИТЬ» округляет числа по правилу «до ближайшего целого».

«ВЫРАЗИТЬ» для составного типа данных и оптимизация запросов

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

Есть запрос, который выбирает всех покупателей, из существующих в базе документов «ПродажаТоваров». У документов такого вида реквизит «Покупатель» имеет составной тип данных:

Запрос:

ВЫБРАТЬ

ПродажаТоваров.Ссылка КАК СсылкаНаДокументПродажи,

ПродажаТоваров.Покупатель КАК СсылкаНаПокупателя

ИЗ

Документ.ПродажаТоваров КАК ПродажаТоваров

Результат:

Следует понимать, что данные в поле «СсылкаНаПокупателя» формируются путём неявного левого соединения с таблицами «Контрагенты.Ссылка» из справочника «Контраенты» и «Сотрудники.Ссылка» из справочника «Сотрудники». Такие соединения в запросах 1С происходят, когда мы обращаемся к подчинённому полю через точку (разыменовываем поле). В нашем случае мы обращаемся к полю «Покупатель».

Визуальное представление работы такого запроса:

Если бы стояла задача отобрать только те документы, в которых покупателем был сотрудник. То наиболее оптимальным решением с точки зрения скорости выполнения запроса было бы вовсе запретить обращаться к справочнику «Контрагенты» так как данные из этого справочника для нас излишни. С такой задачей легко справится оператор «ВЫРАЗИТЬ» и запрос мог бы выглядеть так:

Запрос:

ВЫБРАТЬ

ПродажаТоваров.Ссылка КАК СсылкаНаДокументПродажи,

ВЫРАЗИТЬ(ПродажаТоваров.Покупатель КАК Справочник.Сотрудники) КАК СсылкаНаПокупателя

ИЗ

Документ.ПродажаТоваров КАК ПродажаТоваров

Результат:

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

Запрос:

ВЫБРАТЬ

ПродажаТоваров.Ссылка КАК СсылкаНаДокументПродажи,

ВЫРАЗИТЬ(ПродажаТоваров.Покупатель КАК Справочник.Сотрудники) КАК СсылкаНаПокупателя

ИЗ

Документ.ПродажаТоваров КАК ПродажаТоваров

Где

ПродажаТоваров.Покупатель ССЫЛКА Справочник.Сотрудники

Результат:

Возможные ошибки

С помощью оператора «ВЫРАЗИТЬ» не представляется возможным преобразование типов данных. Например, строку в число:

ВЫРАЗИТЬ(«123» КАК Число(15,2)) КАК Число

При выполнении такого запроса неизбежно получим следующую ошибку:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *