Ошибка при преобразовании числа строки в десятичное в Crystal Reports: «Строка не является числовой» - PullRequest
0 голосов
/ 11 декабря 2018

Описание проблемы

В моем отчете я получаю суммы в строках.Форматирование довольно необычное:

  1. "" - это нулевая сумма
  2. "(200.00)" - отрицательная сумма
  3. "1,234.56" - это положительная сумма

Я хочу преобразовать эти строки в числовые значения более удобным способом:

  1. 0,00
  2. -200,00
  3. 1234,56

Сначала я выполняю некоторые предварительные форматированияколичество строк:

local stringvar amount := Trim({PLD__ITEMS.F_18});

if amount = ''
    then amount := '0.00'
;

amount := Replace(amount, "(", "-");
amount := Replace(amount, ")", "");
amount := Replace(amount, ",", "");
amount := Replace(amount, " ", "");

Затем я хотел преобразовать строку в число, используя методы ToNumber или CDbl , но оба результата приводят к одной и той же ошибке

// "The string is non-numeric"
//ToNumber(amount)

// "The string is non-numeric"
//CDbl(amount)

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

The string is non-numeric


Вопросы

  1. Как мне исправить количество строк, чтобы ToNumber и CDbl работали нормально?
  2. Как я могу преобразовать количество строк в десятичное число сиспользуя методы ToNumber или CDbl ?

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


Тестирование неожиданных символов в количестве строк

Я подготовил специальный тест, чтобы проверить, есть ли внутри какого-либо значения суммы строк неожиданный символ внутри,но все результаты приведенного ниже сравнения вернули True

// ---- test ----

amount := Replace(amount, "0", "");
amount := Replace(amount, "1", "");
amount := Replace(amount, "2", "");
amount := Replace(amount, "3", "");
amount := Replace(amount, "4", "");
amount := Replace(amount, "5", "");
amount := Replace(amount, "6", "");
amount := Replace(amount, "7", "");
amount := Replace(amount, "8", "");
amount := Replace(amount, "9", "");
amount := Replace(amount, ".", "");
amount := Replace(amount, "-", "");

// has not unexpected characters
amount = ''

// ---- end test ----

Тестирование преобразования

Я протестировал явное преобразование строки с точкой в ​​качестве десятичного разделителя и снова произошла ошибка (что для меня странно)!

enter image description here


Я использую Crystal Reports 2013

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

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

ToNumber('1,00')

Так как теперь решение было простым:

local stringvar amount := Trim({PLD__ITEMS.F_18});

if amount = ''
    then amount := '0.00'
;

amount := Replace(amount, "(", "-");
amount := Replace(amount, ")", "");
amount := Replace(amount, ",", "");
amount := Replace(amount, ".", ",");
amount := Replace(amount, " ", "");

ToNumber(amount)

Выше решает мойпроблема с отчетом Crystal Reports.Значения сумм, отображаемых в Crystal Reports Preview, были в порядке, но когда я загружаю свой отчет в приложение SAP B1, суммы увеличиваются в 100 раз. Итак ...

enter image description here

enter image description here

Похоже, что преобразования неверны или интерпретация SAP B1 Crystal Report нарушена ...

Тьфу!Какой беспорядок ...

Итак, я вернулся к предыдущему решению с раздельно преобразованной целой и дробной частями, которые дают правильные суммы как для предварительного просмотра Crystal Reports, так и для приложения SAP B1.

0 голосов
/ 11 декабря 2018

Моя идея для решения этой проблемы состояла в том, чтобы разделить суммы строк на целые и дробные части, преобразовать их в числа по отдельности, а затем добавить оба, чтобы получить значение.

local stringvar amount := Trim({PLD__ITEMS.F_18});
local stringvar intAmount := '0';
local stringvar decAmount := '0';
local numbervar result;
local numbervar decimal;


if amount = ''
    then amount := '0.00'
;

amount := Replace(amount, "(", "-");
amount := Replace(amount, ")", "");
amount := Replace(amount, ",", "");
amount := Replace(amount, " ", "");

if InStr(amount, '.') > 0
    then (
        intAmount := Left(amount, InStr(amount, '.') - 1);
        decAmount := Right(amount, len(amount) - InStr(amount, '.'));
    )
    else intAmount := amount
;

result := ToNumber(intAmount);
decimal := ToNumber(decAmount) / 100;

if result > 0
    then result := result + decimal
    else result := result - decimal
;

Хотя это сложноРешение работает отлично, мои вопросы все еще открыты для идей и / или советов.

обновлено

Исправлено решение для отрицательных чисел - дробная часть должна быть вычтена из целой части

...