在Crystal Reports中将字符串数字转换为十进制时出错:“字符串为非数字”

时间:2018-12-11 13:51:44

标签: crystal-reports crystal-reports-2013

问题描述

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

  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 :(得分:0)

我解决此问题的想法是将字符串数量分成整数和小数部分,分别将它们转换为数字,然后将两者相加以获得值。

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
;

尽管这个棘手的解决方案很好用,但我的问题仍然有想法和/或建议。

已更新

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

答案 1 :(得分:0)

我发现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 Reports报表解决了我的问题。在Crystal Reports预览中显示的金额值还可以,但是当我将报表上传到SAP B1应用程序时,金额乘以100。所以...

enter image description here

enter image description here

似乎转换错误或Crystal Report的SAP B1解释崩溃了...

U!真是一团糟...

因此,我回到了以前的解决方案,其中分别转换了整数和小数部分,它们在Crystal Reports预览和SAP B1应用程序上均产生正确的金额。