在 Crystal 报告中将字符串数字转换为十进制时出错:"The string is non-numeric"

Error when converting string number to decimal in Crystal Reports: "The string is non-numeric"

问题描述

在我的报告中,我得到了字符串形式的金额。格式很不寻常:

  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, " ", "");

然后我想使用 ToNumberCDbl 方法将字符串转换为数字,但结果都是相同的错误

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

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

我不知道什么可能导致这个错误。
我在格式化的金额中找不到任何损坏的字符串...


问题

  1. 我怎样才能修复我的字符串数量,使 ToNumberCDbl 工作正常吗?
  2. 如何在不使用 ToNumberCDbl 方法的情况下将字符串金额转换为十进制数?

如果只有显示问题,我可以使用现有的字符串,但我需要对这些金额进行一些计算,因此我必须在那里使用数值。


正在测试字符串数量中的意外字符

我准备了特定的测试来查看是否有任何字符串数量值在内部包含意外字符,但以下比较的所有结果都返回 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 ----

测试转化

我测试了以点作为小数分隔符的字符串的显式转换,但再次出现错误(这对我来说很奇怪)!


我正在使用 Crystal 2013 年报告

我解决这个问题的想法是将字符串金额拆分为整数和小数部分,将它们分别转换为数字,然后将两者相加得到值。

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
;

虽然这个棘手的解决方案工作正常,但我的问题仍然开放以寻求想法 and/or 建议。

已更新

修复负数的解决方案 - 整数部分应减去小数部分

我发现 Crystal 使用逗号作为小数点分隔符。 (这对我来说是出乎意料的部分!)
下面的代码对我来说很好用:

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 报告解决了我的问题。 Crystal Reports Preview 中显示的金额值正常,但是当我将报告上传到 SAP B1 应用程序时,金额乘以 100。所以...

看起来转换有误或 SAP B1 解释 Crystal 报告崩溃...

呃!真是一团糟...

所以我回到以前的解决方案,分别转换整数和小数部分,它在 Crystal 报表预览和 SAP B1 应用程序上产生正确的金额。