Имя: Пароль:
1C
1С v8
Округление в запросе при помощи ВЫРАЗИТЬ()
,
0 CepeLLlka
 
30.11.19
20:52
Добрый день, хочу округлять в запросе до нужной мне разрядности. Разрядность варьируется по условию. Пытаюсь сделать через ВЫРАЗИТЬ(), не получается, пишет ошибку - "Ожидается константа"


ВЫРАЗИТЬ(МояТаблица.МоёЧисло КАК ЧИСЛО(22 &ДлинаДробнойЧасти)) КАК МоёПоле

Текст запроса: Строка кода 2: {(2,44)}: Ожидается константа
ВЫРАЗИТЬ(МояТаблица.МоёЧисло КАК ЧИСЛО(22, <<?>>&ДлинаДробнойЧасти)) КАК МоёПоле


Как я понял, мне нужно указывать константы, переменные тут не подходят.
Понимаю что можно сделать через ВЫБОР КОГДА ТОГДА, но в таком случае получится очень громоздко и некрасиво, поэтому прошу помощи у вас.
Уважаемые знатоки, подскажите пожалуйста ещё какие-нибудь варианты округления в запросе..
1 acht
 
30.11.19
20:55
СтрЗаменить
2 Бертыш
 
30.11.19
21:09
Во первых должно быть указано число знаков дробной части явно, а во вторых вообще выразить скажем остаток от деления точна на мой взгляд и по моему опыту не совсем тривиальная задача если я ничего за давностью не путаю.
Во всяком случае я всегда раньше во избежания потерь точности производил умножения с тем что получалось в результате выразить на остаток от деления и потом определял в какую сторону округлять дробь. Вот только сейчас уже не помню за давностью то ли я крутил это всё для точного получения остатка от деления или же ради эмуляции в языке запросов конструкции ЦЕЛ
Вы уж сами там для подстраховки проверьте математику
3 CepeLLlka
 
30.11.19
21:13
(1)Не хотелось бы конечно, но, в любом случае спасибо, буду иметь ввиду..

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

(2)Ну я математику не проверял конечно.. в статьях в интернете пишут что округляет, верю на слово, но всё равно спасибо
4 Сияющий в темноте
 
30.11.19
23:27
для корректного получения умножаем на число знаков в дробной(десять в этой степени),добавляем 0.5 и берем целую часть.
потом делим на то,на что умножали,если надо.
5 hhhh
 
01.12.19
09:44
(4) а в запросе есть степень?
6 Консультант Баранов
 
01.12.19
10:47
ВЫБРАТЬ
    вз2.Номенклатура,
    ВЫБОР
        КОГДА &Разряд = 1
            ТОГДА вз2.Разряд1
        КОГДА &Разряд = 2
            ТОГДА вз2.Разряд2
        КОГДА &Разряд = 3
            ТОГДА вз2.Разряд3
        КОГДА &Разряд = 4
            ТОГДА вз2.Разряд4
        КОГДА &Разряд = 5
            ТОГДА вз2.Разряд5
        ИНАЧЕ вз2.Разряд6
    КОНЕЦ КАК Цена
ИЗ
    (ВЫБРАТЬ
        вз1.Номенклатура КАК Номенклатура,
        ВЫРАЗИТЬ(вз1.Сумма / вз1.Количество КАК ЧИСЛО(15, 1)) КАК Разряд1,
        ВЫРАЗИТЬ(вз1.Сумма / вз1.Количество КАК ЧИСЛО(15, 2)) КАК Разряд2,
        ВЫРАЗИТЬ(вз1.Сумма / вз1.Количество КАК ЧИСЛО(15, 3)) КАК Разряд3,
        ВЫРАЗИТЬ(вз1.Сумма / вз1.Количество КАК ЧИСЛО(15, 4)) КАК Разряд4,
        ВЫРАЗИТЬ(вз1.Сумма / вз1.Количество КАК ЧИСЛО(15, 5)) КАК Разряд5,
        ВЫРАЗИТЬ(вз1.Сумма / вз1.Количество КАК ЧИСЛО(15, 6)) КАК Разряд6
    ИЗ
        (ВЫБРАТЬ
            АвансовыйОтчетТовары.Номенклатура КАК Номенклатура,
            СУММА(АвансовыйОтчетТовары.Количество) КАК Количество,
            СУММА(АвансовыйОтчетТовары.Сумма) КАК Сумма
        ИЗ
            Документ.АвансовыйОтчет.Товары КАК АвансовыйОтчетТовары
        
        СГРУППИРОВАТЬ ПО
            АвансовыйОтчетТовары.Номенклатура) КАК вз1) КАК вз2
7 acht
 
01.12.19
10:57
(3) Если у тебя параметр, от которого зависит округление, находится в той же строке текущего запроса, то в (4) тебе отличный рецепт дали. Вместо числа знаков после запятой хранишь 10 в нужной степени и вычисляшь примерно так:

ВЫРАЗИТЬ(МояТаблица.МоёЧисло * ВТПараметрыРасчета.СтепеньОкругления + 0.5 КАК ЧИСЛО(22, 0)) / ВТПараметрыРасчета.СтепеньОкругления

где в ВТПараметрыРасчета.СтепеньОкругления у тебя будет, например, 1000 для 3х знаков после запятой
8 RomanYS
 
01.12.19
11:31
(7)(4) ВЫРАЗИТЬ уже округляет по правилам арифметики. Добавляя 0.5 вы 1.0 округлите до 2.
Если нужно округление строго вверх (в (0) это вроде не требуется), то добавлять нужно 0.499..9
9 Cthulhu
 
01.12.19
11:32
иногда решение "в лоб" бывает продуктивным...
"ВЫРАЗИТЬ(МояТаблица.МоёЧисло КАК ЧИСЛО(22,"+ДлинаДробнойЧасти+")) КАК МоёПоле ........
10 CepeLLlka
 
01.12.19
11:34
(9)Это решение из (1) и оно не походит, по каким причинам, я написал в (3)
11 CepeLLlka
 
01.12.19
11:36
(7)Да, это я понял, спасибо, буду иметь ввиду. У меня получится тоже самое, просто хранить параметры дробной части нужно будет сразу в 10 степени и всё..
12 RomanYS
 
01.12.19
11:36
(10) тогда (7) вполне подойдет. Без 0.5 конечно.
13 CepeLLlka
 
01.12.19
11:42
(12)Нужно только добавлять 0.49 как я понял, а не 0.5

Огромное всем вам спасибо за подсказки, вы очень помогли! СПАСИБО!
14 RomanYS
 
01.12.19
11:49
(13) если тебе нужно округление по арифметическим правилам (0.4... до 0, а 0.5 до 1), то добавлять не нужно НИЧЕГО.
Если нужно 0.01 округлять до 1, то добавляй 0.49999. Количество "9" подобрать из максимальной точности входных данных
15 CepeLLlka
 
01.12.19
11:54
(14)Понятно, тогда ещё легче.. Мне нужно округлять по арифметическим правилам :)
16 CepeLLlka
 
01.12.19
13:14
Ничё не получилось кароче :)

Получаю ошибку:
Ошибка при выполнении операции над данными:
Ошибка SQL: Переполнение поля

Нормально отрабатывает до длинны - 7 знаков после запятой (10000000 - 10 в седьмой степени).. Притом очень странно..

Если вот так, то идёт ошибка..
ВЫРАЗИТЬ(МояТаблица.МоёЧисло * ВТПараметрыРасчета.СтепеньОкругления КАК ЧИСЛО(22, 0)) / ВТПараметрыРасчета.СтепеньОкругления

А если вот так, то ошибки нет..
ВЫРАЗИТЬ(МояТаблица.МоёЧисло * 100000000 КАК ЧИСЛО(22, 0)) / 100000000

Проверял значение поля - "ВТПараметрыРасчета.СтепеньОкругления" 100 раз уже, оно равно числу - 100000000, но если не явно указываешь число, а умножаешь на поле, то ошибка, а если явно указываешь число, то нет..

Пока писал это сообщение пришла мысль сделать вот так:
ВЫРАЗИТЬ(МояТаблица.МоёЧисло * ВЫРАЗИТЬ(ВТПараметрыРасчета.СтепеньОкругления КАК ЧИСЛО(10,0)) КАК ЧИСЛО(22, 0)) / ВТПараметрыРасчета.СтепеньОкругления

И о чудо, всё заработало.. решаю проверить себя.. и пишу следующее поле в запросе
ВТПараметрыРасчета.СтепеньОкругления = ВЫРАЗИТЬ(ВТПараметрыРасчета.СтепеньОкругления КАК ЧИСЛО(10,0)) КАК ЛОЛ

Выполняю запрос, смотрю, значение поля - "ЛОЛ" = ИСТИНА

То есть они равны..
Что за бред происходит? Не надо работать по выходным, да? :)
17 RomanYS
 
01.12.19
13:18
(16) может проще вместо 22 взять, например, 44
18 CepeLLlka
 
01.12.19
13:22
(17) Пробовал это, максимум можно указать 38, на 39 уже ошибка:

Неверные параметры "ЧИСЛО"
ВЫРАЗИТЬ(МояТаблица.МоёЧисло * ВТПараметрыРасчета.СтепеньОкругления КАК <<?>>ЧИСЛО(39, 0)) / ВТПараметрыРасчета.СтепеньОкругления
19 RomanYS
 
01.12.19
13:28
(18) Ну пусть 38. Тебе должно хватить. (16) то это исправило?
20 CepeLLlka
 
01.12.19
13:35
(19)Да, если делать вот так:

ВЫРАЗИТЬ(МояТаблица.МоёЧисло * ВЫРАЗИТЬ(ВТПараметрыРасчета.СтепеньОкругления КАК ЧИСЛО(10,0)) КАК ЧИСЛО(22, 0)) / ВТПараметрыРасчета.СтепеньОкругления

то всё норм.. Просто это очень странно :)

Спасибо за поддержку в любом случае :)
21 RomanYS
 
01.12.19
13:43
(20) Не надо два ВЫРАЗИТЬ. Проверь с одним, но 38 вместо 22
22 CepeLLlka
 
01.12.19
13:52
(21)Не работает если ставить 38, вместо 22, я это сразу проверил как нагуглил, что может нехватать чисел.. но это не помогает..

Помогает два ВЫРАЗИТЬ
23 CepeLLlka
 
01.12.19
14:06
(21)Смоделировал ситуацию..

ВЫБРАТЬ
    5.7287013 КАК МоёЧисло,
    100000000 КАК СтепеньОкругления
Поместить ВТПараметры
;

//////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВЫРАЗИТЬ(ВТПараметры.МоёЧисло * ВТПараметры.СтепеньОкругления КАК ЧИСЛО(38,0)) / ВТПараметры.СтепеньОкругления КАК МоёСуперЧисло
ИЗ
    ВТПараметры КАК ВТПараметры

Всё работает как часы, хоть 1000000000000 ставь

Полагаю как-то из регистра сведений криво выбираются данные что-ли.. хз

Либо потом в операциях объединения как-то неверное число получается..
Хотя я уже больше думаю о типах числа.. возможно тут я сразу явно задаю какой-нибудь Decimal, а если выбираю из регистра получаю какой-нибудь Integer или что-то вроде того..
24 CepeLLlka
 
01.12.19
14:07
(21)Я думаю при выборе "СтепеньОкругления" в ВТПараметрыРасчета, буду сразу его выражать как число 10,0 и всё.. так красивее будет и лучше
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn