_SepThd() ersetzt _StringAddThousandsSep()

  • Hier ein kleines Script um Zahlen (auch negative) auf tausender mit einem bestimmten Buchstaben oder Symbol zu trennen.
    Sollte eigentlich nur ein ersatz für die rausgenommene '_StringAddThousandsSep' Funktion sein..

    [autoit]


    ;===============================================================================
    ;
    ; Function Name: _SepThd()
    ; Description: Returns a by thouthands seperated number
    ; Parameter(s): $iNum any number to seperate
    ; $sSep any char to seperate the number
    ; Requirement(s): None
    ; Return Value(s): On Success - Returns the number seperated with $sSep
    ; On Failure - Returns a blank string and sets @error = 1
    ; Author(s): Phil-IT
    ;
    ;===============================================================================
    Func _SepThd($iNum, $sSep = ".")
    If IsNumber($iNum) Then
    For $i = StringLen($iNum) To 1 Step -1
    If Mod($i, 3) = 0 Then
    $iNum = StringTrimRight($iNum, $i) & $sSep & StringRight($iNum, $i)
    EndIf
    Next
    If StringLeft($iNum, 2) = "-" & $sSep Then $iNum = "-" & StringTrimLeft($iNum, 2)
    If StringLeft($iNum, 1) = $sSep Then $iNum = StringTrimLeft($iNum, 1)
    Return $iNum
    Else
    SetError(1)
    Return ""
    EndIf
    EndFunc

    [/autoit]
  • Tschuldigung :D

    [autoit]

    $l = -69523783.12345678
    ConsoleWrite("-> " & ThSp($l) & @LF)

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

    Func ThSp($l,$s='.')
    Dim $b=Abs(Int($l)),$m=Mod(StringLen($b),3),$t=StringLeft("-",($l<0))&StringLeft($b,$m)&StringLeft($s,$m)&StringTrimRight(StringRegExpReplace(StringTrimLeft($b,$m),'(\b.{1,3}\b|.{0,3})','\0'&$s),1)
    If StringInStr($l, ".") Then Return $t & StringMid($l, StringInStr($l, ".")+1)
    Return StringTrimRight($t, 1)
    EndFunc

    [/autoit]
  • Zitat

    If it looks stupid, but works. It isn't stupid

    Hier mal in lesbarer Form (immernoch nur 5 Zeilen):

    [autoit]

    Func ThSp($l,$s='.')
    Local $b = Abs(Int($l)), $m = Mod(StringLen($b),3)
    $t = StringLeft("-",($l<0)) & StringLeft($b,$m) & StringLeft($s,$m)
    $t &= StringTrimRight(StringRegExpReplace(StringTrimLeft($b,$m),'(\b.{1,3}\b|.{0,3})','\0'&$s),1)
    If StringInStr($l, ".") Then Return $t & StringMid($l, StringInStr($l, ".")+1)
    Return StringTrimRight($t, 1)
    EndFunc

    [/autoit]
  • minx, also manchmal bin ich echt enttäuscht :D
    Phil schießt mit nem Panzer auf Spatzen, und minx mit Atombomben.
    Wofür werden denn hier hunderte von wertvollen Bytes, Regexen, Vorzeichenabfragen, usw... verbraten ?

    [autoit]

    Func ThSp($n, $s = '.')
    Return StringLen($n) <= 3 ? $n : ThSp(StringTrimRight($n, 3), $s) & ((StringLen($n) = 4 And $n < 0) ? '' : $s) & StringRight($n, 3)
    EndFunc

    [/autoit]

    Man nennt mich auch den Bytewolf !

    • Offizieller Beitrag

    Eure Versuche Bytes einzusparen in allen Ehren, aber was ist mit Kommazahlen?
    Der Dezimalpunkt bzw. im deutschen das Komma wird bei euren Versuchen nicht berücksichtigt.
    Ich habe damals die Funktion "_StringAddThousandsSep" archiviert. Ich denke, es ist nach wie vor die beste Variante:

    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]
  • Kommazahlen funktionieren bei mir tadellos (siehe Code, Zeile 1), wie alle anderen Zahlen auch (außer Potenzen schätze ich). Der Unterschied ist der Input als echte Zahl und nicht als String.

  • Kommazahlen funktionieren bei mir tadellos (siehe Code, Zeile 1), wie alle anderen Zahlen auch (außer Potenzen schätze ich). Der Unterschied ist der Input als echte Zahl und nicht als String.

    Oscar meinte wohl eher die Unterscheidung von Tausendertrennzeichen und Dezimaltrennzeichen.
    In euren Beispielen wird sowohl für Tausendertrennzeichen als auch Dezimaltrennzeichen das jeweils gleiche verwendet.

    Typografisch korrekt wäre allerdings das Komma als Dezimaltrennzeichen mit dem Punkt als Tausendertrennzeichen für die deutsche Notation und dem Punkt als Dezimaltrennzeichen mit dem Komma als Tausendertrennzeichen für die englische Notation. (Siehe: >>Klickmich<<)

    Einmal editiert, zuletzt von AspirinJunkie (15. September 2014 um 09:57)

    • Offizieller Beitrag

    "kaesereibe" hat den richtigen Tip gegeben. :)
    In der neuen AutoIt-Version gibt es die Funktion "_WinAPI_GetNumberFormat" und zusammen mit "_WinAPI_CreateNumberFormatInfo" kann man jedes beliebige Format erstellen.
    Wenn v3.3.12.0 installiert ist, reicht:

    [autoit]


    #include <WinAPILocale.au3>

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

    Global $sNumber = -123456789.1234
    ConsoleWrite(_WinAPI_GetNumberFormat(0, $sNumber, _WinAPI_CreateNumberFormatInfo(3, 1, 3, ',', '.', 1)) & @CRLF)

    [/autoit]

    und für alle mit älteren AutoIt-Versionen:

    Spoiler anzeigen
    [autoit]


    Global Const $tagNUMBERFMT = 'uint NumDigits;uint LeadingZero;uint Grouping;ptr DecimalSep;ptr ThousandSep;uint NegativeOrder' ; & ';wchar DecimalSepChars[n];wchar ThousandSepChars[n]'

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

    Global $sNumber = -123456789.1234
    ConsoleWrite(_WinAPI_GetNumberFormat(0, $sNumber, _WinAPI_CreateNumberFormatInfo(3, 1, 3, ',', '.', 1)) & @CRLF)

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

    ; #FUNCTION# ====================================================================================================================
    ; Author.........: Yashied
    ; Modified.......: Jpm
    ; ===============================================================================================================================
    Func _WinAPI_GetNumberFormat($iLCID, $sNumber, $tNUMBERFMT = 0)
    If Not $iLCID Then $iLCID = 0x0400 ; LOCALE_USER_DEFAULT

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

    Local $aRet = DllCall('kernel32.dll', 'int', 'GetNumberFormatW', 'dword', $iLCID, 'dword', 0, 'wstr', $sNumber, _
    'struct*', $tNUMBERFMT, 'wstr', '', 'int', 2048)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, '')
    ; If Not $aRet[0] Then Return SetError(1000, 0,'')

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

    Return $aRet[5]
    EndFunc ;==>_WinAPI_GetNumberFormat

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

    ; #FUNCTION# ====================================================================================================================
    ; Author.........: Yashied
    ; Modified.......:
    ; ===============================================================================================================================
    Func _WinAPI_CreateNumberFormatInfo($iNumDigits, $iLeadingZero, $iGrouping, $sDecimalSep, $sThousandSep, $iNegativeOrder)
    Local $tFMT = DllStructCreate($tagNUMBERFMT & ';wchar[' & (StringLen($sDecimalSep) + 1) & '];wchar[' & (StringLen($sThousandSep) + 1) & ']')
    DllStructSetData($tFMT, 1, $iNumDigits)
    DllStructSetData($tFMT, 2, $iLeadingZero)
    DllStructSetData($tFMT, 3, $iGrouping)
    DllStructSetData($tFMT, 4, DllStructGetPtr($tFMT, 7))
    DllStructSetData($tFMT, 5, DllStructGetPtr($tFMT, 8))
    DllStructSetData($tFMT, 6, $iNegativeOrder)
    DllStructSetData($tFMT, 7, $sDecimalSep)
    DllStructSetData($tFMT, 8, $sThousandSep)
    Return $tFMT
    EndFunc ;==>_WinAPI_CreateNumberFormatInfo

    [/autoit]