Jump to content

Locale Questions


Recommended Posts

A small example in Autoit: :)

$Input = InputBox("Title","Enter your magical number:")

$Output = ""

If $Input < 20 Then
    
    $Output = $DutchLow[$Input]

ElseIf $Input >= 20 and $Input < 100 Then
    
    $First = StringLeft($Input,1)
    $Second = StringRight($Input,1)
    
    If $Second = "0" Then
        
        $Output = $DutchMid[$First]
        
    Else
        
        $Output = $DutchLow[$Second] & "en" & $DutchMid[$First]; Not first the high number and than the low one, like english.
        
    EndIf
    
EndIf

MsgBox(0,"Another nice title",$Input& " in Dutch would be: "& $Output)
Link to comment
Share on other sites

  • Replies 54
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

@Kip.

Thanks again. That's the nice thing about the AutoIt Forums, people WILL go out of their way to be helpfull.

I'm getting much more than I asked for and it's very valuable to me.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • 11 months later...

Maybe you could have one table with all the LCID values which you'd match against the Locale registry key. It could contain the denomination names like Dollar, Cents, Peso, Centavo, and an additonal field could point to an element in a translation table where you'd convert one to uno to ein, etc. There are a lot of entries in that LCID! Looks like a lot of work.

.NET's mscorlib.dll has some sort of built-in Convert..::.ToString Method (Decimal) conversion routine, but I'm not sure if you could make use of that.

Edit: Hmm, maybe that .NET function just changes the data type, and doesn't output the sort of "string representation" we're interested in...

Edit2: Ahem, pretend I never mentioned anything about .NET :)

Edit3: Off topic, but... I wonder if the GetCurrencyFormat call might make a better replacement for the _StringAddThousandsSep() Bug Trac (#442) that's out there now? It is surely more than twice as fast, it will accept a quoted or unquoted parameter (unlike the existing function), and maybe some tinkering with the CURRENCYFMT structure values could suppress the Dollar sign, or it could be (optionally?) stripped after the dll call?

Edited by Spiff59
Link to comment
Share on other sites

The problem with GetCurrencyFormat is that it only allows for 2 decimal places and you CAN NOT send it a pre-formatted string, which you can do with _StringAddThousandsSep(). I've finished a re-write of _StringAddThousandsSep() and submitted it. As far as I know it will be in the next release but on the other hand you never can tell.

310,654.15 or 310654.157 will fail on GetCurrencyFormat, it would have to be 310654.15 or 310654.16

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I hadn't considered that, the 2-decimal limitation of GetCurrencyFormat would change the functionality of _StringAddThousandsSep().

Out of curiousity...

What's the new _StringAddThousandsSep() look like?

(I'd sent a new faster version to Gary about 5-6 weeks ago based on a nifty StringSplit and SRER that handled leading zeros and contained an error trap for inputs containing alpha chars)

The current version turns the first non-numeric (including a comma) into a decimal point and truncates everything after the second non-numeric character. It probably ought to set @eroor as invalid input instead.

Of course a single SRER could strip any commas out of the input string, then let the rest of the fucntion replace them appropriately.

Edited by Spiff59
Link to comment
Share on other sites

I hadn't considered that, the 2-decimal limitation of GetCurrencyFormat would change the functionality of _StringAddThousandsSep().

Out of curiousity...

What's the new _StringAddThousandsSep() look like?

(I'd sent a new faster version to Gary about 5-6 weeks ago based on a nifty StringSplit and SRER that handled leading zeros and contained an error trap for inputs containing alpha chars)

The current version turns the first non-numeric (including a comma) into a decimal point and truncates everything after the second non-numeric character. It probably ought to set @eroor as invalid input instead.

Of course a single SRER could strip any commas out of the input string, then let the rest of the fucntion replace them appropriately.

It's a total rewrite with no loops at all. Uses primarily RegEx. It is also Locale based and handles leading negatives. I still don't know for sure if it's been accepted or not. As far as I know nobody has broken the latest version yet, but I can't be positive. It could be that they just aren't telling me.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • Moderators

GEOSoft,

Here is a French version. Sorry it is so long, but they have a very peculiar counting system and are also very fussy about hyphenation and pluralisation! See below if you are interested:

; Converts a number to French text
; Author: Melba23
; Example:

#Include <string.au3>

$money = "273398400219.02"

If Number($money) > 999999999999.99 Then Exit

If StringInStr($money, ".") Then
    $split = StringSplit($money, ".")
    $msg = ""
    
    If $split[1] = "1" Then
        $msg &= "un euro"
    Else
        $msg &= _FrenchNumber($split[1]) & "euros"
    EndIf
    
    If $split[2] = "00" Then
    ; Do nothing
    ElseIf $split[2] = "01" Then
        $msg &= " et un centime"
    Else
        $msg &= " et " & _FrenchNumber($split[2]) & "centimes"
    EndIf   
Else
    $msg = ""
    $euro = _FrenchNumber($money)
    If $money = "1" Then
        $msg &= "un euro"
    Else
        $msg &= _FrenchNumber($money) & "euros"
    EndIf
EndIf

MsgBox(0, "French output:", _StringAddThousandsSep($money, ".", ",") & @CRLF & @CRLF & $msg)

Exit

Func _FrenchNumber($string)
    
    Local $answer, $divisions, $centaines, $restant, $section[1]
    Local $fre_low[10] = ["", "un ", "deux ", "trois ", "quatre ", "cinq ", "six ", "sept ", "huit ", "neuf "]
    Local $big[4] = ["", "mille", "million", "milliard"]
    
    If StringLen($string) = 1 Then
        $answer = $fre_low[$string]
    ElseIf StringLen($string) = 2 Then
        $answer = _UpTo100($string, $fre_low)
    Else
        $answer = ""
        $divisions = Int(StringLen($string) / 3)
        Dim $section[$divisions + 1]
        For $i = 0 to $divisions
            $section[$i] = StringRight($string, 3)
            $string = "00" & StringTrimRight($string, 3)
        Next
        
        $answer = ""
        For $i = $divisions To 0 Step -1
            If $section[$i] <> "" Then
                If Number($section[$i]) > 1 Then
                    $centaines = StringLeft($section[$i], 1)
                    $restant = StringRight($section[$i], 2)
                    If $centaines = 1 Then
                        $answer &= "cent "
                    ElseIf $centaines > 1 Then
                        If $restant = "00" Then
                            $answer &= $fre_low[$centaines] & "cents "
                        Else
                            $answer &= $fre_low[$centaines] & "cent "
                        EndIf
                    EndIf
                    $answer &= _UpTo100($restant, $fre_low)
                    If $i = 1 Then
                        $answer &= $big[$i] & " "
                    ElseIf $i > 1 Then
                        $answer &= $big[$i] & "s "
                    EndIf
                ElseIf Number($section[$i]) = 1 Then
                    If $i > 1 Then $answer &= "un "
                    $answer &= $big[$i] & " "
                EndIf
            EndIf
        Next        
        
    EndIf
    
    Return $answer

EndFunc

Func _UpTo100($string, $fre_low)
    
    Local $fre_high[10] = ["dix ", "onze ", "douze ", "treize ", "quatorze ", "quinze ", "seize ", "dix-sept ", "dix-huit ", "dix-neuf "]
    Local $tens[10] = ["", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"]
    
    Local $answer = ""
    Local $dixaines = Number(StringLeft($string, 1))
    Local $unites = Number(StringRight($string, 1))
    Switch $dixaines
        Case 0
            $answer = $fre_low[$unites]
        Case 1
            $answer = $fre_high[$unites]
        Case 2 to 6
            If $unites = 0 Then
                $answer = $tens[$dixaines]
            ElseIf $unites = 1 Then
                $answer = $tens[$dixaines] & " et " & $fre_low[$unites]
            Else
                $answer = $tens[$dixaines] & "-" & $fre_low[$unites]
            EndIf
        Case 7
            If $unites = 0 Then
                $answer = $tens[$dixaines - 1]
            ElseIf $unites = 1 Then
                $answer = $tens[$dixaines - 1] & " et " & $fre_high[$unites]
            Else
                $answer = $tens[$dixaines - 1] & "-" & $fre_high[$unites]
            EndIf
        Case 8
            If $unites = 0 Then
                $answer = $tens[$dixaines] & "s"
            Else
                $answer = $tens[$dixaines] & "-" & $fre_low[$unites]
            EndIf
        Case 9
            $answer = $tens[$dixaines - 1] & "-" & $fre_high[$unites]
    EndSwitch
    
    Return $answer
    
EndFunc

M23

Some examples of French numbering:

70-79 is written as Sixty-Ten to Sixty-Nineteen

80 is written as Four-Twenties

90-99 is writen as Four-Twenty-Ten to Four-Twenty-Nineteen

Hundreds take a plural if there are no tens or units - Thousands are always singular - Millions and Billions take a plural

The French-speaking Belgians and Swiss are rather more sensible with numbers between 70 and 99, but they have their own peculiarities..........

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Time is no problem in getting the language parts done. I have the english version working which works for most people. Thanks for this one. It worked great on a quick test run. The only line that I can't figure out is this one

Local $tens[10] = ["", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"]

"quatre-vingt" twice.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • Moderators

GEOSoft,

If you look closely it has "soixante" twice as well! You need it because of the "SIXTY-TEN" OR "FOUR-TWENTY-FIFTEEN" way the French count.

This way you get the same base for "60" & "70" and "80" & "90" when using the 'tens' figure as the index. The Switch $dixaines section in _UpTo100() then adds either "1 to 9" or "10 to 19" to make the full number.

I well remember when we went to live in France and my children (then going to primary school) and I were learning the French numbering system. One of the periods of our family life which has not dimmed at all with the passage of time - the memory of it still makes us wince collectively. :-)

M23

Edit: speeling

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

@GEOSoft,

I have written a couple of number to text for english...I don't recall which one works exactly, but hopefully they might be useful to you. I did this for a blind friend of mine that need to convert numbers to text so it could be read to him more easily.

I believe this is the final working one.

MsgBox(0, "Test", _N2T(987654321))

Func _N2T($iNum)
    Dim $lenNum, $arrNum, $chgNum, $numTxt
    Dim $boolTeens
    
    If Not(IsInt($iNum)) Then
        SetError(1)
        Return
    EndIf
    
    $lenNum = StringLen($iNum)
    $arrNum = StringSplit($iNum, "")
    
    If $lenNum = 1 Then
        If $arrNum[1] = 0 Then Return "Zero"
        If $arrNum[1] = 1 Then Return "One"
        If $arrNum[1] = 2 Then Return "Two"
        If $arrNum[1] = 3 Then Return "Three"
        If $arrNum[1] = 4 Then Return "Four"
        If $arrNum[1] = 5 Then Return "Five"
        If $arrNum[1] = 6 Then Return "Six"
        If $arrNum[1] = 7 Then Return "Seven"
        If $arrNum[1] = 8 Then Return "Eight"
        If $arrNum[1] = 9 Then Return "Nine"
    EndIf
    
    ;Assign $chgNum the length so the it can be changed.
    $chgNum = $lenNum
    
    For $i = 1 To $lenNum Step 1
        If Mod($chgNum, 3) = 0 Then ;Divisible by 3
            $numTxt &= _Ones($arrNum[$i])
            If $chgNum >= 3 AND Not($arrNum[$i] = 0) Then $numTxt &= "Hundred "
            $chgNum -= 1
        ElseIf Mod($chgNum, 3) = 2 Then
            If $arrNum[$i] = 1 Then
                If $arrNum[$i+1] = 0 Then $numTxt &= "Ten "
                If $arrNum[$i+1] = 1 Then $numTxt &= "Eleven "
                If $arrNum[$i+1] = 2 Then $numTxt &= "Twelve "
                If $arrNum[$i+1] = 3 Then $numTxt &= "Thirteen "
                If $arrNum[$i+1] = 4 Then $numTxt &= "Fourteen "
                If $arrNum[$i+1] = 5 Then $numTxt &= "Fifteen "
                If $arrNum[$i+1] = 6 Then $numTxt &= "Sixteen "
                If $arrNum[$i+1] = 7 Then $numTxt &= "Seventeen "
                If $arrNum[$i+1] = 8 Then $numTxt &= "Eighteen "
                If $arrNum[$i+1] = 9 Then $numTxt &= "Nineteen "
                $chgNum -= 1
                $boolTeens = 1
            Else
                $numTxt &= _Tens($arrNum[$i])
                $chgNum -= 1
            EndIf
        ElseIf Mod($chgNum, 3) = 1 Then
            If Not($boolTeens) Then $numTxt &= _Ones($arrNum[$i])
            $chgNum -= 1
            $boolTeens = 0
        EndIf
        
        If $lenNum = 9 AND $i = 3 Then $numTxt &= "Million "
        If $lenNum = 8 AND $i = 2 Then $numTxt &= "Million "
        If $lenNum = 7 AND $i = 1 Then $numTxt &= "Million "
        If Not($arrNum[$i] = 0) AND $lenNum = 9 AND $i = 6 Then $numTxt &= "Thousand "
        If Not($arrNum[$i] = 0) AND $lenNum = 8 AND $i = 5 Then $numTxt &= "Thousand "
        If Not($arrNum[$i] = 0) AND $lenNum = 7 AND $i = 4 Then $numTxt &= "Thousand "
        If $lenNum = 6 AND $i = 3 Then $numTxt &= "Thousand "
        If $lenNum = 5 AND $i = 2 Then $numTxt &= "Thousand "
        If $lenNum = 4 AND $i = 1 Then $numTxt &= "Thousand "
        
    Next
    
    Return $numTxt
EndFunc

Func _Ones($oNum)
    Select
        Case $oNum = 0
            Return ""
        Case $oNum = 1
            Return "One "
        Case $oNum = 2
            Return "Two "
        Case $oNum = 3
            Return "Three "
        Case $oNum = 4
            Return "Four "
        Case $oNum = 5
            Return "Five "
        Case $oNum = 6
            Return "Six "
        Case $oNum = 7
            Return "Seven "
        Case $oNum = 8
            Return "Eight "
        Case $oNum = 9
            Return "Nine "
    EndSelect
EndFunc

Func _Tens($tNum)
    Select
        Case $tNum = 0
            Return ""
        Case $tNum = 1
            Return "Ten "
        Case $tNum = 2
            Return "Twenty "
        Case $tNum = 3
            Return "Thirty "
        Case $tNum = 4
            Return "Fourty "
        Case $tNum = 5
            Return "Fifty "
        Case $tNum = 6
            Return "Sixty "
        Case $tNum = 7
            Return "Seventy "
        Case $tNum = 8
            Return "Eighty "
        Case $tNum = 9
            Return "Ninety "
    EndSelect
EndFuncoÝ÷ Ù8b²+-çâ®Ë]­§í!·¥ëÞjëh×6MsgBox(0, "Test", _Num2Txt(987654321))

Func _Num2Txt($iNum)
    Dim $lenNum, $arrNum, $i, $j, $retNum, $txtNum, $strText
    
    If Not(IsInt($iNum)) Then
        SetError(1)
        Return
    EndIf
    
    $lenNum = StringLen($iNum)
    $arrNum = StringSplit($iNum, "")
    
    If $lenNum = 1 Then
        Select
            Case $arrNum[1] = 0
                Return "Zero"
            Case $arrNum[1] = 1
                Return "One"
            Case $arrNum[1] = 2
                Return "Two"
            Case $arrNum[1] = 3
                Return "Three"
            Case $arrNum[1] = 4
                Return "Four"
            Case $arrNum[1] = 5
                Return "Five"
            Case $arrNum[1] = 6
                Return "Six"
            Case $arrNum[1] = 7
                Return "Seven"
            Case $arrNum[1] = 8
                Return "Eight"
            Case $arrNum[1] = 9
                Return "Nine"
        EndSelect
    EndIf
        For $i = 1 to $arrNum[0]
            ;If $arrNum[$i] = 0 Then ContinueLoop
            If $arrNum[0] >= 3 Then
                $strText &= _NumOnes($arrNum[$i])
                If Not($arrNum[$i] = 0) Then $strText &= " "
                If $lenNum >= 3 Then $strText &= "Hundred "
                $i += 1
            EndIf
            If $arrNum[$i] = 1 Then
                $i += 1
                If $arrNum[$i] = 0 Then
                    $i -= 1
                    $strText &= _NumTens($arrNum[$i])
                    If Not($arrNum[$i] = 0) Then $strText &= " "
                    $i += 1
                EndIf
                If $arrNum[$i] = 0 Then $strText &= ""
                If $arrNum[$i] = 1 Then $strText &= "Eleven "
                If $arrNum[$i] = 2 Then $strText &= "Twelve "
                If $arrNum[$i] = 3 Then $strText &= "Thirteen "
                If $arrNum[$i] = 4 Then $strText &= "Fourteen "
                If $arrNum[$i] = 5 Then $strText &= "Fifteen "
                If $arrNum[$i] = 6 Then $strText &= "Sixteen "
                If $arrNum[$i] = 7 Then $strText &= "Seventeen "
                If $arrNum[$i] = 8 Then $strText &= "Eighteen "
                If $arrNum[$i] = 9 Then $strText &= "Nineteen "
                If $lenNum <= 3 Then ExitLoop
                $i -= 1
            Else
                $strText &= _NumTens($arrNum[$i])
                If Not($arrNum[$i] = 0) Then $strText &= " "
            EndIf
            $i += 1
            $strText &= _NumOnes($arrNum[$i])
            If Not($arrNum[$i] = 0) Then $strText &= " "
            
            If $lenNum = 9 Then
                $strText &= "Million "
                $lenNum -= 3
            ElseIf $lenNum = 6 Then
                $strText &= "Thousand "
                $lenNum -= 3
            EndIf
        Next
    
    Return $strText
EndFunc ;=> Num2Txt()

Func _NumOnes($tNum)
    Select
        Case $tNum = 0
            Return ""
        Case $tNum = 1
            Return "One"
        Case $tNum = 2
            Return "Two"
        Case $tNum = 3
            Return "Three"
        Case $tNum = 4
            Return "Four"
        Case $tNum = 5
            Return "Five"
        Case $tNum = 6
            Return "Six"
        Case $tNum = 7
            Return "Seven"
        Case $tNum = 8
            Return "Eight"
        Case $tNum = 9
            Return "Nine"
    EndSelect
EndFunc

Func _NumTens($tNum)
    Select
        Case $tNum = 0
            Return ""
        Case $tNum = 1
            Return "Ten"
        Case $tNum = 2
            Return "Twenty"
        Case $tNum = 3
            Return "Thirty"
        Case $tNum = 4
            Return "Fourty"
        Case $tNum = 5
            Return "Fifty"
        Case $tNum = 6
            Return "Sixty"
        Case $tNum = 7
            Return "Seventy"
        Case $tNum = 8
            Return "Eighty"
        Case $tNum = 9
            Return "Ninety"
    EndSelect
EndFunc

I hope the above helps in some way for you, or someone else looking to help you. Doing regular expressions would probably be much better, but I wasn't into those at the time of writing these scripts.

Regards,

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

When first reading this thread, I was thinking one could just write a routine and swap out hardcoded strings to get different languages. It's amazing how different the actual usage is, structurally, with different languages.

MsgBox(1,"",_N2T(123416780))

Func _N2T($Amt)
    Local $Ones[10]  = ["", "One ", "Two ", "Three ", "Four ", "Five ", "Six ", "Seven ", "Eight ", "Nine "]
    Local $Teens[10] = ["Ten ", "Eleven ", "Twelve ", "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Seventeen ", "Eighteen ", "Nineteen "]
    Local $Tens[10]  = ["", "Ten ", "Twenty ", "Thirty ", "Forty ", "Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "]
    Local $Groups[5] = ["", "Thousand", "Million", "Billion", "Megakazillion"]
    Local $String = ""
    $aAmt = StringSplit($Amt, "")
    For $x = 1 to $aAmt[0]
        $i = Mod($aAmt[0] - $x + 1, 3)
        If $aAmt[$x] > "0" Then
            $suffix = 1
            If $i = 2 Then
                If $aAmt[$x] = "1" Then
                    $x += 1
                    $String &= $Teens[$aAmt[$x]]
                    $i = 1
                Else
                    $String &= $Tens[$aAmt[$x]]
                EndIf
            Else
                $String &= $Ones[$aAmt[$x]]         
                If $i = 0 Then $String &= "Hundred "            
            EndIf
        EndIf
        If $suffix And $i = 1 Then 
            $i = ($aAmt[0] - $x) / 3
            $String &= $Groups[$i]
            If $i Then $String &= ", "
            $suffix = 0
        EndIf   
    Next
    Return $String
EndFunc
Edited by Spiff59
Link to comment
Share on other sites

When first reading this thread, I was thinking one could just write a routine and swap out hardcoded strings to get different languages. It's amazing how different the actual usage is, structurally, with different languages.

Yes, it would be impossible. I know the counting mechanism in at least 4 languages and they are all different.

Worst of them being danish, truly the language god forgot.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

It's a total rewrite with no loops at all. Uses primarily RegEx. It is also Locale based and handles leading negatives. I still don't know for sure if it's been accepted or not. As far as I know nobody has broken the latest version yet, but I can't be positive. It could be that they just aren't telling me.

Since this thread has quieted down, I'll pursue a tangent regarding _StringAddThousandsSep() that I brought up a page back...

I'd sent the second example below to one of the Dev's about 7 weeks ago when I saw that the fix shown in the closed Bug Trac #856 still left room for improvement. I didn't use proper channels though, I just sent the code as a PM, so I don't know what became of it. I did notice that an older Bug Trac, #442 was reopened shortly after that, and remains open. I just thought rather than redo things again in a later release, that the new SATS ought to include all of the existing/proposed features, and additionally, should strip leading zeros, and not return unexpected results when the input contains one or more alpha characters. (PS - I'll probably never have a need for this function!)

#include<string.au3>

$Amt = "-000123456789012345678901.124556789" 
;$Amt = "-0001ax23456789012345678901.124556789"; any alpha chars cause existing routines to return unexpected results (GIGO)

$timer = TimerInit()
For $x = 1 to 1000
    $result = __StringAddThousandsSep($amt)
Next
$timer = TimerDiff($timer)
$result1 = "Using Kernel32      Time: " & StringFormat('%.2f', $timer) & "  Result:  " & $result

$timer = TimerInit()
For $x = 1 to 1000
    $result = ___StringAddThousandsSep($amt)
Next
$timer = TimerDiff($timer)
$result2 = "Proposed Version    Time: " & StringFormat('%.2f', $timer) & "  Result:  " & $result

$timer = TimerInit()
For $x = 1 to 1000
    $result = ____StringAddThousandsSep($amt)
Next
$timer = TimerDiff($timer)
$result3 = "Bug Trac 856 Beta  Time: " & StringFormat('%.2f', $timer) & "   Result:  " & $result

$timer = TimerInit()
For $x = 1 to 1000
    $result = _StringAddThousandsSep($amt)
Next
$timer = TimerDiff($timer)
$result4 = "Production version  Time: " & StringFormat('%.2f', $timer) & "  Result:  " & $result

Msgbox(0,"Results",$result1 & @CRLF & $result2 & @CRLF & $result3 & @CRLF & $result4)

; ==============================================================================
; new function using kernel32
Func __StringAddThousandsSep($amt)
    Local $a1 = Stringsplit($amt, ".")
    Local $GCF = DllCall("kernel32.dll", "int", "GetCurrencyFormat", "int", 0, "int", 0, "str", $a1[1], "int", 0, "str", "", "int", 40)
    Local $a2 = Stringsplit($GCF[5], ".")
    If $a2[0] > 1 Then $a2[1] &= "." & $a1[2]
    $a2[1] = StringRegExpReplace($a2[1], "[^0-9\,.-]", ""); strip currency sign
    Return $a2[1]
EndFunc

; ==============================================================================
; new function without kernel32
Func ___StringAddThousandsSep($sText, $sThousands = ",", $sDecimal = ".")
    If Not (StringIsInt($sText) Or StringIsFloat($sText)) Then Return SetError(1,0,"")
    Local $rKey = "HKCU\Control Panel\International"
    If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
    If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")
    Local $aSplit = StringSplit($sText, "-" & $sDecimal )
    If $aSplit[1] Then 
        Local $iInt = 1; integer portion of source string in first array element
    Else
        $aSplit[1] = "-"; minus sign in first element
        Local $iInt = 2; integer portion in second element
    EndIf
    If $aSplit[0] > $iInt Then; decimal value in second or third element
        $aSplit[$aSplit[0]] = "." & $aSplit[$aSplit[0]]
    EndIf
    $aSplit[$iInt] = StringRegExpReplace($aSplit[$iInt], "(\A0+)", ""); Strip leading zeros 
    Local $iMod = Mod(StringLen($aSplit[$iInt]), 3)
    If Not $iMod Then $iMod = 3;  0 --> 3
    $aSplit[$iInt] = StringRegExpReplace($aSplit[$iInt], "(?<=\d{" & $iMod & "})(\d{3})", $sThousands & "\1")   
    For $i = 2 to $aSplit[0]
        $aSplit[1] &= $aSplit[$i]
    Next
    Return $aSplit[1]
EndFunc

; ==============================================================================
; beta function (Bug Trac #856)
Func ____StringAddThousandsSep($sString, $sThousands = -1, $sDecimal = -1)
    Local $sResult = "", $sNegative = ""; Force string
    Local $rKey = "HKCU\Control Panel\International"
    If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
    If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")
    Local $aNumber = StringRegExp($sString, "(\D?\d+)\D?(\d*)", 1); This one works for negatives.
    If UBound($aNumber) = 2 Then
        Local $sLeft = $aNumber[0]
        If StringLeft($sLeft, 1) = "-" Then
            $sNegative = "-"
            $sLeft = StringTrimLeft($sLeft, 1)
        EndIf
        While StringLen($sLeft)
            $sResult = $sThousands & StringRight($sLeft, 3) & $sResult
            $sLeft = StringTrimRight($sLeft, 3)
        WEnd
        $sResult = $sNegative & StringTrimLeft($sResult, StringLen($sThousands)); Strip leading thousands separator
        If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1]
    EndIf
    Return $sResult
EndFunc;==>_StringAddThousandsSep
Edited by Spiff59
Link to comment
Share on other sites

While we are on a similar subject...

Can you please tell me what you find when running this code:

InputBox ("Thanks!", "Thanks for doing this for me, you're a great help", RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\", "StandardName"))

I am trying to build an insert date/time dialog, and trying to get GMT +- X from this string. I get: GMT Standard Time

Slight detour + possibly a case of script hijacking, but its relevent enough, and saves thread.

MDiesel

Link to comment
Share on other sites

While we are on a similar subject...

Can you please tell me what you find when running this code:

InputBox ("Thanks!", "Thanks for doing this for me, you're a great help", RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\", "StandardName"))

I am trying to build an insert date/time dialog, and trying to get GMT +- X from this string. I get: GMT Standard Time

Slight detour + possibly a case of script hijacking, but its relevent enough, and saves thread.

MDiesel

Do you want the Bias key (negative offset from GMT in minutes)?

InputBox ("Thanks!", "Thanks for doing this for me, you're a great help", _
    RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\", "StandardName") & _
    " (GMT - " & RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\", "Bias") / 60 & ")")

Edit: Looks like you have to test the high-order word for FFFF then XOR the low-order word with FFFF to get the "GMT +" time zones to work. Or something along that line...

$offset = RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\", "Bias")
If $offset > 1023 Then
    $offset = 4294967296 - $offset
    $sign = "+ "
Else
    $sign = "- "
EndIf
$offset /= 60
MsgBox(1,"",$sign & $offset)
Edited by Spiff59
Link to comment
Share on other sites

Ugh, use the API's people. If you're reading the registry for this sort of information you're doing it wrong. Functions exist in the Windows API for working with locales: Use them. GetLocaleInfo() is a good jumping point.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...