Zahl (Int, Float) in Tausendergruppierung ausgeben, Währungsformatierung

    • Offizieller Beitrag

    In der SB war die Frage, wie man eine Zahl mit den Tausenderpunkten ausgeben kann.
    Hier mal eine Lösung dazu.
    Eingabe:
    - als nummerischer Wert (Komma als Punkt)
    - als String (Komma als Zeichen)
    Ausgabe:
    - Tausendertrenner "." - Dezimaltrenner "," (Standard)
    - Tausendertrenner "," - Dezimaltrenner "." (zweiten Parameter übergeben <> "DE")
    Limitiert auf 18 Vorkommastellen - sollte aber wohl reichen. Wer mehr braucht: im Pattern weitere Dreierblocks ( "(\d{3})?" ) einfügen.
    Man könnte das Pattern auch dynamisch über die Stringlänge anpassen. Aber ich denke so reicht es auch. ;)

    Spoiler anzeigen
    [autoit]

    $i = '1234567890,97'
    ConsoleWrite('EN: ' & _NumberFormatThousand($i, 'EN') & @CRLF)
    $i = 12345678901234567
    ConsoleWrite('EN: ' & _NumberFormatThousand($i, 'EN') & @CRLF)
    $i = 123456789.1234
    ConsoleWrite('EN: ' & _NumberFormatThousand($i, 'EN') & @CRLF & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    $i = '1234567890,97'
    ConsoleWrite('DE: ' & _NumberFormatThousand($i) & @CRLF)
    $i = 12345678901234567
    ConsoleWrite('DE: ' & _NumberFormatThousand($i) & @CRLF)
    $i = 123456789.1234
    ConsoleWrite('DE: ' & _NumberFormatThousand($i) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _NumberFormatThousand($vNumber, $ret='DE') ; bis 18 Vorkommastellen
    Local $sOut = '', $a = StringRegExp(StringReplace($vNumber, '.', ','), "(-?\d{1,3})(\d{3})?(\d{3})?(\d{3})?(\d{3})?(\d{3})?(?:\Z|(,\d+))", 3)
    For $i = 0 To UBound($a) -1
    If $a[$i] <> '' Then $sOut &= '.' & $a[$i]
    Next
    If $ret <> 'DE' Then Return StringTrimLeft(StringReplace(StringReplace($sOut, '.', ','), ',,', '.'), 1)
    Return StringTrimLeft(StringReplace($sOut, '.,', ','), 1)
    EndFunc

    [/autoit]

    Edit: Vielleicht bekommt jemand das ja auch mit StringFormat() hin. Falls ja - würde mich mal interessieren. Die Funktion liegt mir überhaupt nicht. ;)

    Edit 26.03.2011:
    Ich habe gerade eine Funktion zur Währungsausgabe benötigt. Da diese z.T. auf der vorigen Funktion basiert, hänge ich sie mal hier mit an.
    Währungssymbol, Dezimaltrenner und Gruppenseperator werden aus den Ländereinstellungen des PC übernommen. Ihr könnt ja zum Testen mal ein anderes Länderformat aktivieren.

    _FormatCurrency
    [autoit]

    ; Ausgabe PC-Währung, Standard-Währungseinstellung
    ConsoleWrite(_FormatCurrency(200*12345) & @CRLF) ; ==> 2.469.000,00 € , Länderformat USA: 2,469,000.00 $

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe Dollar, Währungssymbol führend
    ConsoleWrite(_FormatCurrency(-200*12345, -1, -1, '$', -1, 1) & @CRLF) ;==> $ -2.469.000,00 , Länderformat USA: -2,469,000.00 $

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe Dollar, Währungssymbol führend, negativer Wert in Klammern
    ConsoleWrite(_FormatCurrency(-200*12345, -1, -1, '$', -1, 1, 1) & @CRLF) ;==> [$ -2.469.000,00] , Länderformat USA: [$ -2,469,000.00]

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe PC-Währung, mit Vornull
    ConsoleWrite(_FormatCurrency(4/80) & @CRLF) ;==> 0,05 € , Länderformat USA: 0.05 $

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe PC-Währung, ohne Vornull
    ConsoleWrite(_FormatCurrency(4/80, -1, -1, -1, 0) & @CRLF) ;==> ,05 € , Länderformat USA: .05 $

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name...: _FormatCurrency
    ; Description.....: Formatiert einen Ausdruck als Währung
    ; Parameter(s)....: $iExpression der zu formatierende Ausdruck
    ; Requirement(s)..: $iNumDigit Anzahl Nachkommastellen, -1 = Währungseinstellung PC (Standard)
    ; $iGroupDig Anzahl Zeichen für Gruppierung, -1 = 3 Zeichen (Standard)
    ; $sCurr Währungszeichen, -1 = Währungseinstellung PC (Standard)
    ; $iLeadingZero Führende Null anzeigen, -1 = Währungseinstellung PC (Standard), 0 = nein
    ; $fLeadingSign Währungszeichen führend anzeigen, 0 = nein (Standard)
    ; $fNegNumInPara Negative Werte in eckigen Klammern anzeigen, 0 = nein (Standard)
    ; Return Value(s).: Der formatierte Währungsstring
    ; Note............: Die Gruppierung ermöglicht maximal 8 Blöcke
    ; Author(s).......: BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _FormatCurrency($iExpression, $iNumDigit=-1, $iGroupDig=-1, $sCurr=-1, $iLeadingZero=-1, $fLeadingSign=0, $fNegNumInPara=0)
    Local $sRegKey = 'HKCU\Control Panel\International', $sReturn, $aTmp, $sTmp, $sNul = '000000000', $fNeg = 0
    Local $sDec = RegRead($sRegKey, 'sMonDecimalSep'), $sThousand = RegRead($sRegKey, 'sMonThousandSep')
    Local $sNegative = RegRead($sRegKey, 'sNegativeSign')
    If $iGroupDig < 0 Then $iGroupDig = 3
    If $sCurr = -1 Then $sCurr = RegRead($sRegKey, 'sCurrency')
    If $iNumDigit = -1 Then $iNumDigit = RegRead($sRegKey, 'iCurrDigits')
    If $iLeadingZero = -1 Then $iLeadingZero = RegRead($sRegKey, 'iLZero')
    If IsFloat($iExpression) Then
    $iExpression = Round($iExpression, $iNumDigit)
    $sReturn = String($iExpression)
    If $iNumDigit Then
    $aTmp = StringSplit(String($iExpression), '.')
    $sReturn = $aTmp[1] & Chr(29) & StringLeft($aTmp[2] & $sNul, $iNumDigit)
    EndIf
    Else
    $sReturn = String($iExpression)
    If $iNumDigit Then $sReturn = String($iExpression) & Chr(29) & StringLeft($sNul, $iNumDigit)
    EndIf
    If Not $iLeadingZero And StringRegExp($sReturn, '^-?0' & Chr(29) & '\d*') Then $sReturn = StringReplace($sReturn, '0' & Chr(29), Chr(29), 1)
    If $iGroupDig > 0 And StringLen(Abs($sReturn)) >= $iGroupDig Then
    $aTmp = StringRegExp(StringReplace($sReturn, '.', Chr(29)), _
    "(-?\d{1,"&$iGroupDig&"})(\d{"&$iGroupDig&"})?(\d{"&$iGroupDig&"})?(\d{"&$iGroupDig&"})?(\d{"&$iGroupDig&"})?(\d{"&$iGroupDig&"})?(\d{"&$iGroupDig&"})?(\d{"&$iGroupDig&"})?(?:\Z|("&Chr(29)&"\d+))", 3)
    For $i = 0 To UBound($aTmp) -1
    If $aTmp[$i] <> '' Then $sTmp &= $sThousand & $aTmp[$i]
    Next
    $sReturn = StringTrimLeft(StringReplace($sTmp, $sThousand&Chr(29), Chr(29)), 1)
    EndIf
    If StringLeft($sReturn, 1) = '-' Then $fNeg = 1
    $sReturn = StringReplace(StringReplace($sReturn, '-', $sNegative), Chr(29), $sDec)
    If $fLeadingSign Then
    $sReturn = $sCurr & ' ' & $sReturn
    Else
    $sReturn &= ' ' & $sCurr
    EndIf
    If $fNeg And $fNegNumInPara Then $sReturn = '[' & $sReturn & ']'
    Return $sReturn
    EndFunc ;==>_FormatCurrency

    [/autoit]
  • Schöne, brauchbare Funktion (ich hatte mir mal eine mühsam Stelle für Stelle gebastelt, war viel länger und nicht so sicher).
    Allerdings funktioniert sie nicht für negative Zahlen, was irgendwie schade ist...
    Aber sonst ist die richtig gut!

    • Offizieller Beitrag

    Bis vor kurzem war doch diese Funktion noch Bestandteil der UDFs:

    Spoiler anzeigen
    [autoit]


    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _StringAddThousandsSep
    ; Description ...: Returns the original numbered string with the Thousands delimiter inserted.
    ; Syntax.........: _StringAddThousandsSep($sString[, $sThousands = -1[, $sDecimal = -1]])
    ; Parameters ....: $sString - The string to be converted.
    ; $sThousands - Optional: The Thousands delimiter
    ; $sDecimal - Optional: The decimal delimiter
    ; Return values .: Success - The string with Thousands delimiter added.
    ; Author ........: SmOke_N (orignal _StringAddComma
    ; Modified.......: Valik (complete re-write, new function name)
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......; Yes
    ; ===============================================================================================================================
    Func _StringAddThousandsSep($sString, $sThousands = -1, $sDecimal = -1)
    Local $sResult = "" ; 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]
    While StringLen($sLeft)
    $sResult = $sThousands & StringRight($sLeft, 3) & $sResult
    $sLeft = StringTrimRight($sLeft, 3)
    WEnd
    $sResult = StringTrimLeft($sResult, StringLen($sThousands)) ; Strip leading thousands separator
    If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1]
    EndIf
    Return $sResult
    EndFunc ;==>_StringAddThousandsSep

    [/autoit]


    Die hatte ich mir vorsorglich mal archiviert, als ich gelesen habe, dass sie aus den UDFs entfernt wird.

    • Offizieller Beitrag

    sicher).
    Allerdings funktioniert sie nicht für negative Zahlen, was irgendwie schade ist...

    Das hatte ich glatt vergessen, habe die dafür notwendigen 2 Zeichen hinzugefügt. ;)

    Die hatte ich mir vorsorglich mal archiviert, als ich gelesen habe, dass sie aus den UDFs entfernt wird.

    Hatte ich auch irgendwie in Erinnerung, dass es da schon mal was gab. Habs nur nicht mehr gefunden. Da meine Variante deutlich kürzer ist, werde ich diese weiter nutzen. ;)

  • hi,
    kannst du die funktion um ein parameter erweitern, sodass auch bei ergebnissen mit keiner nachkommastelle, dennoch 2 nachkommazahlen mitausgegeben werden?

    Zur Zeit:
    _NumberFormatThousand("300,00")
    =
    300

    Nach Änderung:
    _NumberFormatThousand("300,00")
    =
    300,00

    • Offizieller Beitrag

    kannst du die funktion um ein parameter erweitern, sodass auch bei ergebnissen mit keiner nachkommastelle, dennoch 2 nachkommazahlen mitausgegeben werden?


    Hiermit getan. Mit "-1" (Voreinstellung) für $iDecPlaces wird die tatsächliche Anzahl an Dezimalstellen verwendet. Jede andere Angabe (0, 1, 2, ...) erzwingt diese Anzahl an Nachkommastellen. Wird dabei die Ausgabe gekürzt, wird die letzte Stelle gerundet.

    _NumberFormatThousand
    [autoit]


    Func _NumberFormatThousand($vNumber, $iDecPlaces=-1, $sLang='DE') ; bis 18 Vorkommastellen
    If $iDecPlaces > -1 Then $vNumber = StringFormat('%.' & $iDecPlaces & 'f', StringReplace($vNumber, ',', '.'))
    Local $sOut = '', $a = StringRegExp(StringReplace($vNumber, '.', ','), "(-?\d{1,3})(\d{3})?(\d{3})?(\d{3})?(\d{3})?(\d{3})?(?:\Z|(,\d+))", 3)
    For $i = 0 To UBound($a) -1
    If $a[$i] <> '' Then $sOut &= '.' & $a[$i]
    Next
    If $sLang <> 'DE' Then Return StringTrimLeft(StringReplace(StringReplace($sOut, '.', ','), ',,', '.'), 1)
    Return StringTrimLeft(StringReplace($sOut, '.,', ','), 1)
    EndFunc

    [/autoit]