AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.07.2021, 11:40   #1  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Поле "XXX" (= -0,000) может содержать только положительные числа
dax2012 R3

Поле имеет свойство AllowNegative = No. Т.е. запрет отрицательных значений

X++:
ttsbegin;

qty = (  );    // здесь расчет значения
qty = decRound(qty, 3);
myTab.MyField = qty;

if (myTab.MyField < 0)
   throw error('Отрицательное значение');

if (myTab.validateWrite())
{
    myTab.update();
}

ttscommit;

Иногда! При выполнении этого кода в пакете получаю указанную в названии темы ошибку


Цитата:
Поле "XXX" (= -0,000) может содержать только положительные числа

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

Пока обошел проблему вот так

X++:
ttsbegin;

qty = (  );    // здесь расчет значения
qty = decRound(qty, 3);

// Если в результате расчет ноль, то явно указать ноль
if (qty == 0)
{
     qty = 0;
}

myTab.MyField = qty;

if (myTab.MyField < 0)
   throw error('Отрицательное значение');

if (myTab.validateWrite())
{
    myTab.update();
}

ttscommit;
Никто не сталкивался с такой проблемой?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 02.07.2021, 12:21   #2  
online
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Я не сталкивался, но есть догадка почему так получилось.
В X++ все real переменные - это BCD (binary coded decimals) поэтому там такой проблемы не возникает.
А при выполнении в пакете работает CIL
Там скорее всего используется какой-нибудь System.Double который годится для научных расчетов, но не очень для финансовых как раз из-за проблемы с округлениями.

Можно для Excel построить простой пример когда в одном столбце попеременно вводится порядка 30 положительных и отрицательных целых чисел так что их сумма 0. Excel в итоге покажет сумму 1.0+e15 или -1.0+e15
Это та же проблема.

Попробуйте просто в пакете своем поставить округление через X++ функции round или decRound
Или если речь о деньгах, то по феншую заюзать Currency::Amount() или Currency::Price()

Последний раз редактировалось Logger; 02.07.2021 в 12:24.
За это сообщение автора поблагодарили: S.Kuskov (2).
Старый 02.07.2021, 12:26   #3  
online
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
пример
https://www.excel-vba.ru/chto-umeet-...itaet-pochemu/

Цитата:
Спасибо автору за разъяснения. Обнаружил ошибку при сравнении разности с числом, довел ситуацию до абсурда и выяснил, что в Excel 2013 ошибка возникает при действии с числами начиная с четвертого знака после запятой в 17-м знаке, хотя номер знака при сравнении разности с нулем не имеет значения
A B C A-B-C
1,3000000000 1,1000000000 0,2000000000 0,00000000000000000000
1,0300000000 1,0100000000 0,0200000000 0,00000000000000000000
1,0030000000 1,0010000000 0,0020000000 0,00000000000000000000
1,0003000000 1,0001000000 0,0002000000 -0,00000000000000002204
1,0000300000 1,0000100000 0,0000200000 -0,00000000000000009102
1,0000030000 1,0000010000 0,0000020000 0,00000000000000005751
от себя добавлю такой пример
Цитата:
1000003 1000001 2 0,000000000116415321826935000000
ошибка в 10-м знаке получилась.

Последний раз редактировалось Logger; 02.07.2021 в 12:42.
Старый 02.07.2021, 12:51   #4  
online
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
https://docs.microsoft.com/en-us/dyn...eveloper/reals
Старый 02.07.2021, 13:59   #5  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Несколько мест в DAX2012 видел где real прямо приводится к net double и в некоторых комментарии про ошибки округления в CIL.
Вот, навскидку пример: метод price2Amount класса PriceDisc
X++:
// As the precision are different between data type "Real" in X++ and "Decimal" in IL, it may result in rounding defference when
        // running X++ and IL. To resolve this issue, we convert "Decimal" to "Double" here if the code was running in IL, thus there is
        // a precision down, and the precission will extremely like data type "Real" in X++.
        if (xSession::isCLRSession())
        {
            returnAmount = System.Convert::ToDouble(returnAmount);
        }
За это сообщение автора поблагодарили: Владимир Максимов (5), S.Kuskov (2).
Теги
dax2012

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Поле "Ценовые соглашения" в коммерческих соглашениях (PriceDiscTable.Agreement) как используется? glibs DAX: Функционал 1 05.08.2009 21:44
Поле "величина расхода". kkk DAX: Функционал 3 21.04.2008 11:54
Поле "Стандартная себестоимость" AlexeyBP DAX: Функционал 24 03.08.2006 11:09
Поле " Старший смены отгружающего склада" должно быть заполнено. IT-specialist DAX: Программирование 14 25.10.2005 19:37
Право доступа к таблице "Только чтение" gudzon DAX: Программирование 1 24.08.2004 16:14

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:21.