Eddie Monster
11th September 2012, 15:59
I see (in other postings) that there is an available function tcmcsdll0006 which will convert numbers (99) to words (ninety-nine).

We have a situation where are going to implement a Baan IVc4 environment in a Spanish-speaking country. The installation is not going to use the Spanish language pack (we do not have it installed), but according to the banks, any checks written out of the Cash Management module need to be in Spanish.

Anybody have ideas on how this could be accomplished (hopefully without installing the language pack)? I didn't see any argument for tcmcsdll0006 for language selection (even if it Spanish was not an available language). I am assuming that the report's language would set a global variable that would be picked up by the function...

I could (and might have to) write my own function...

Just curious if anyone else has run into this and how they addressed it.

Great thanks to anyone with information. Thank you!

shah_bs
11th September 2012, 19:33
I have only the english language installed (and so not much experience with multiple language set ups), so hard to verify what I am writing below. But I am hoping it will lead you to some sort of solution.

In any case, the check routines are in a FUNCTION file called tfcmg0005 (Decode Amounts). (I could not find tcmcsdll0006 in my installation - maybe it is not available in BAAN IV c3 A&D). From what I can see, this function script has decodes which rely on messages, which of course are by language. For example, the following gets the word 'hundred':


decode.hundred = form.text$("tfcmgs0186")


Similar code exists for decoding the numbers: 1 to 'one' and so on, using form.text$() command.

SO, if it is possible for you to test this somehow, you could get away with just copying the required messages from english to spanish and translating the words in Maintain Messages. Not sure how you can 'force' the check report to pick the language you need, though. Also, not sure how exactly the number in words will look like in the other language, because the 'assembly' of the words is basically in english. Will need lot of testing, if the concept works.

shah_bs
24th September 2012, 18:47
Hello again.

Just curious about how you decide to solve the issue for converting numbers to words.

Eddie Monster
25th September 2012, 14:40
I was able to find some VB code which converts a number to text (in Spanish). I am in the process of converting the VB code to Baan's SQL dialect. I'm about 95% there. I will post the code once I finish and test it out.

Eddie Monster
30th October 2012, 20:58
I (finally) completed the code and will pass it to our Controller in Costa Rica for testing. If everything works, I will clean up the code a bit and post it.

Eddie Monster
3rd December 2012, 21:45
Here is the finished code... there is probably some room for optimization, but I don't have the time to optimize it now. The code below is from the test session. The user enters the number and then the written Spanish text is displayed as a message.

This is a Costa Rican dialect of Spanish as defined by our controller at that facility.


|****************************** DECLARATION SECTION ***************************
declaration:

| Selection Criteria

extern domain tfgld.amnt ws.amnt | Amount

| Working Storage

domain tcmcs.long length | Length of string
domain tcmcs.str215 temp.dollars
domain tcmcs.str215 ws.amnt.text | Amount in text (Spanish)
domain tcmcs.str215 ws.cents | Represents text portion of dollars
domain tcmcs.long ws.counter | Represents actions taken on each three-digit group within the number to convert
domain tcmcs.str215 ws.dollars | Represents text portion of dollars


|****************************** PROGRAM SECTION ***************************

|****************************** ZOOM FROM SECTION ***************************

|****************************** FORM SECTION ***************************

form.1:
init.form:
get.screen.defaults()

|****************************** CHOICE SECTION ***************************

choice.cont.process:
on.choice:
| Reset variables if session is run a second time
length = 0
temp.dollars = ""
ws.amnt.text = ""
ws.cents = ""
ws.dollars = ""

ws.amnt.text = convert.number(ws.amnt)
message(ws.amnt.text)

|****************************** FIELD SECTION ***************************

|****************************** MAIN TABLE SECTION ***************************

|****************************** FUNCTION SECTION ***************************
functions:

|******************************************************************************
| This function translates any 'cents' and then sets up a counter to deal with
| each three digit group within the number.
|******************************************************************************
function extern string convert.number(domain tfgld.amnt f.amnt)
{
domain tcmcs.long decimal.position
domain tcmcs.str215 f.amnt.str
domain tcmcs.str215 result
domain tcmcs.long ws.million

| Flag used to determine if number is an 'even' millions of dollars.
ws.million = 0

| Convert ws.amnt to string
f.amnt.str = trim$(str$(ws.amnt))

| Find the position of the decimal point within the string
decimal.position = rpos(f.amnt.str, ".")

if decimal.position = 0 then
| No decimal position exists
ws.cents = "00/100"
else
length = len(f.amnt.str)
if length - decimal.position = 1 then
ws.cents = f.amnt.str(decimal.position + 1; 1) & "0/100"
else
ws.cents = f.amnt.str(decimal.position + 1; 2) & "/100"
endif
| Strips the decimal and mantissa (fractional-part)
| from the string, leaving the characteristic (integer-part)
f.amnt.str = f.amnt.str(1;decimal.position-1)
endif

on case f.amnt.str
case("1000000"):
case("2000000"):
case("3000000"):
case("4000000"):
case("5000000"):
case("6000000"):
case("7000000"):
case("8000000"):
case("9000000"):
| Number is an 'even' millions of dollars
ws.million = 1
break
default:
ws.million = 0
break
endcase

ws.counter = 1

while f.amnt.str <> ""
temp.dollars = " "
length = len(f.amnt.str)

if length >= 3 then
temp.dollars = ConvertHundreds(f.amnt.str(length-2;3))
else
if length = 2 then
f.amnt.str = " " & f.amnt.str
temp.dollars = ConvertHundreds(f.amnt.str)
else
if length = 1 then
f.amnt.str = " " & f.amnt.str
temp.dollars = ConvertHundreds(f.amnt.str)
endif
endif
endif

if f.amnt.str(1;2) = " " then
length = 1
else
if f.amnt.str(1;1) = " " then
length = 2
else
length = len(f.amnt.str)
endif
endif

if f.amnt.str(length;2) = " 1" then
on case ws.counter
case(1):
ws.dollars = "un " & ws.dollars
break
case(2):
ws.dollars = "mil " & ws.dollars
break
case(3):
ws.dollars = "un million " & ws.dollars
break
case(4):
ws.dollars = "un billion " & ws.dollars
break
case(5):
ws.dollars = "un trillion " & ws.dollars
break
default:
break
endcase
else
if temp.dollars <> "" then
on case ws.counter
case(2):
if ws.amnt >= 1001 and ws.amnt <= 1999 then
| Do Not use 'un mil' if there is only 1 'thousands'
ws.dollars = " mil " & ws.dollars
else
ws.dollars = temp.dollars & " mil " & ws.dollars
endif
break
case(3):
| Handle plural of 'million' if necessary
if temp.dollars = "un" then
ws.dollars = temp.dollars & " millon " & ws.dollars
else
ws.dollars = temp.dollars & " millones " & ws.dollars
endif
break
case(4):
ws.dollars = temp.dollars & " billones " & ws.dollars
break
case(5):
ws.dollars = temp.dollars & " trillones " & ws.dollars
break
default:
ws.dollars = temp.dollars & ws.dollars
break
endcase
else

endif
endif

length = len(f.amnt.str)

if length > 3 then
f.amnt.str = f.amnt.str(1;length-3)
else
f.amnt.str = ""
endif

length = len(f.amnt.str)

| Reset variable
temp.dollars = " "

ws.counter = ws.counter + 1

endwhile

if ws.dollars = "" then
ws.dollars = "cero"
endif


if ws.million = 1 then
ws.dollars = trim$(ws.dollars) & " de colones con " & ws.cents
else
ws.dollars = trim$(ws.dollars) & " colones con " & ws.cents
endif

result = ws.dollars

return(result)
}


|******************************************************************************
| This function converts the 'hundreds' column.
|******************************************************************************
function extern string ConvertHundreds(domain tcmcs.str3 f.hundreds)
{
domain tcmcs.str215 result
domain tcmcs.str2 digit

result = ""

if val(f.hundreds) = 0 then
return(result)
endif

digit = f.hundreds(1;1)

| Do we have a 'hundreds' place digit to convert?
if digit <> " " then
on case lval(digit)
case(1):
result = "ciento "
break
case(2):
result = " doscientos "
break
case(3):
result = " trescientos "
break
case(4):
result = " cuatrocientos "
break
case(5):
result = " quinientos "
break
case(6):
result = " seiscientos "
break
case(7):
result = " setecientos "
break
case(8):
result = " ochocientos "
break
case(9):
result = " novecientos "
break
default:
break
endcase
endif

digit = f.hundreds(2;1)

| Do we have a 'tens' place digit to convert?
if digit <> " " then
result = result & ConvertTens(f.hundreds(2;2))
else
| If not, then convert the ones place digit
result = result & ConvertOnes(f.hundreds(3;1))
endif

| Is the number exactly 100? If so - overwrite
if f.hundreds = "100" then
result = "cien "
endif

result = trim$(result)

return(result)
}


|******************************************************************************
| This function converts the 'tens' column.
|******************************************************************************
function extern string ConvertTens(domain tcmcs.str2 f.tens)
{
domain tcmcs.str215 result
domain tcmcs.str2 digit

result = ""

digit = f.tens(1;1)

| Is value between 10 and 19?
if digit = "1" or
digit = "2" then
on case lval(f.tens)
case(10):
result = "diez"
break
case(11):
result = "once"
break
case(12):
result = "doce"
break
case(13):
result = "trece"
break
case(14):
result = "catorce"
break
case(15):
result = "quince"
break
case(16):
result = "dieciseis"
break
case(17):
result = "diecisiete"
break
case(18):
result = "dieciocho"
break
case(19):
result = "diecinueve"
break
case(20):
result = "veinte"
break
case(21):
result = "veinteuno"
break
case(22):
result = "veintedos"
break
case(23):
result = "veintetres"
break
case(24):
result = "veintecuatro"
break
case(25):
result = "veintecinco"
break
case(26):
result = "veinteseis"
break
case(27):
result = "veintesiete"
break
case(28):
result = "veinteocho"
break
case(29):
result = "veintenueve"
break
default:
break
endcase
else
| The value is between 20 and 99
on case lval(f.tens(1;1))
case(3):
result = "treinta "
break
case(4):
result = "cuarenta "
break
case(5):
result = "cincuenta "
break
case(6):
result = "sesenta "
break
case(7):
result = "setenta "
break
case(8):
result = "ochenta "
break
case(9):
result = "noventa "
break
default:
break
endcase

| Convert ones place digits
length = len(f.tens)
if ConvertOnes(f.tens(length;1)) = "" then
result = result & ConvertOnes(f.tens(length;1))
else
result = result & ConvertOnes(f.tens(length;1))
endif
endif

return(result)
}


|******************************************************************************
| This function converts the 'ones' column.
|******************************************************************************
function extern string ConvertOnes(domain tcmcs.str1 f.ones)
{
domain tcmcs.str215 result

result = ""

on case lval(f.ones)
case(1):
result = "un"
break
case(2):
result = "dos"
break
case(3):
result = "tres"
break
case(4):
result = "cuatro"
break
case(5):
result = "cinco"
break
case(6):
result = "seis"
break
case(7):
result = "siete"
break
case(8):
result = "ocho"
break
case(9):
result = "nueve"
break
default:
result = ""
break
endcase

return(result)
}


|****************************** END OF SCRIPT ***************************