Crystal Report:如何将数字逐字转换为文本?
Great question! The built-in ToWords() function in Crystal Reports is designed for converting numbers to their standard written English form (like "One Thousand Two Hundred and Fifty Seven" for 1257), which doesn't match your need to spell each digit individually. To get output like ONE TWO FIVE SEVEN for $1257, you'll need to build a custom formula that processes each digit separately.
Step-by-Step Formula Solution
Here's a custom formula that takes a numeric field, strips out currency symbols/commas, and converts each digit to its uppercase word equivalent:
// Target your numeric field here (e.g., {Orders.TotalAmount}) Local NumberVar targetNum := {YourTable.NumericField}; // Convert the number to a string, removing decimals and formatting characters Local StringVar numStr := CStr(Truncate(targetNum), 0); numStr := Replace(numStr, ",", ""); numStr := Replace(numStr, "$", ""); // Map digits to their uppercase word counterparts Local StringVar Array digitMap := ["ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]; Local StringVar finalOutput := ""; Local NumberVar i; // Loop through each character in the cleaned number string For i := 1 To Length(numStr) Do ( Local NumberVar currentDigit := Val(Mid(numStr, i, 1)); finalOutput := finalOutput & digitMap[currentDigit + 1] & " "; ); // Remove the trailing space from the result Trim(finalOutput);
Handling Decimal Places (Optional)
If you need to include decimal digits (e.g., $1257.89 → ONE TWO FIVE SEVEN EIGHT NINE), use this modified formula:
Local NumberVar targetNum := {YourTable.NumericField}; Local StringVar numStr := CStr(Truncate(targetNum), 0); Local StringVar decimalStr := ""; // Extract decimal part if it exists If targetNum <> Truncate(targetNum) Then ( decimalStr := Mid(CStr(targetNum, 20), InStr(CStr(targetNum, 20), ".") + 1); ); // Clean up the main number string numStr := Replace(numStr, ",", ""); numStr := Replace(numStr, "$", ""); Local StringVar Array digitMap := ["ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]; Local StringVar finalOutput := ""; Local NumberVar i; // Process main integer digits For i := 1 To Length(numStr) Do ( finalOutput := finalOutput & digitMap[Val(Mid(numStr, i, 1)) + 1] & " "; ); // Process decimal digits if present If decimalStr <> "" Then ( For i := 1 To Length(decimalStr) Do ( finalOutput := finalOutput & digitMap[Val(Mid(decimalStr, i, 1)) + 1] & " "; ); ); Trim(finalOutput);
Reusing the Solution with a User-Defined Function (UDF)
To avoid rewriting this formula across multiple reports, turn it into a reusable UDF:
- Open the Formula Workshop (Ctrl+F2 in Crystal Reports)
- Expand User-Defined Functions
- Right-click and select New
- Paste the formula code above (adjust the target field to accept a parameter instead of a hardcoded field)
- Save the function (e.g.,
SpellDigits) - Now you can call it anywhere in your reports like this:
SpellDigits({YourTable.NumericField})
内容的提问来源于stack exchange,提问作者Tommy Limanto

