Excel: Dezimalzahlen in Userforms
Gepostet am: Feb 18, 2011 11:25:47 AM
Da ich ehrlich gesagt immer wieder Probleme mit Dezimalzahlen in Userforms habe, möchte ich mich heute damit mal intensiv beschäftigen.
Grundlagen
Grundsätzlich verwendet Excel die Einstellungen der Systemsteuerung, um Dezimalzahlen zu formatieren. Um zu überprüfen, ob diese Einstellungen auf die aktuelle Excel Arbeitsmappe greifen, kann man folgenden Befehl verwenden:
> Debug.Print Application.UseSystemSeparators
wenn dieser True/Wahr zurückgibt, dann werden die Systemeinstellungen verwendet
Diese gelten primär, werden also von folgenden Befehlen nicht verändert:
> Application.DecimalSeparator = "."
> Application..ThousandsSeparator = ","
In diesem Fall bei werden trotz dieser beiden Einstellungen die Zahlen mit Dezimal-Komma angezeigt, das die Systemeinstellungen primär greifen. Wenn man also die Einstellung für eine Excel-Datei ändern möchte, muss man den Zugriff auf die Systemsteuerungseinstellungen unterdrücken.
Änderungen der Einstellungen von Dezimal-Komma auf Dezimal-Punkt
With Application .UseSystemSeparators = False .DecimalSeparator = "." .ThousandsSeparator = ","End With
Wenn man die Einstellungen für eine Excel-Datei vom Dezimal-Komma auf Dezimal-Punkt umstellen möchte, empfiehlt sich folgender Code:
Excel-Arbeitsmappe
Private Sub Workbook_Activate()With Application .DecimalSeparator = "." .ThousandsSeparator = "," .UseSystemSeparators = FalseEnd WithEnd SubPrivate Sub Workbook_Deactivate()With Application .DecimalSeparator = "," .ThousandsSeparator = "." .UseSystemSeparators = trueEnd WithEnd Sub
aktuelle Ländereinstellungen bezüglich Dezimalzahlen ermitteln
Das Problem hierbei ist jedoch, dass man nicht weiß, wie die Systemsteuerungs-Einstellungen für Dezimalzahlen überhaupt eingestellt sind, und ob somit überhaupt die Änderung nötig ist. Daher stellt sich die Frage, wie man am besten die aktuellen Einstellungen bezüglich Ländereinstellungen ermittelt. Dafür gibt es 2 Methoden:
Auslesen der Systemeinstellungen
ACHTUNG: nur für wirklich versierte Benutzer
Ländereinstellungen auslesen
Option ExplicitConst LOCALE_SCURRENCY = &H14Const LOCALE_SINTLSYMBOL = &H15Const LOCALE_SMONDECIMALSEP = &H16Const LOCALE_SMONTHOUSANDSEP = &H17Const LOCALE_SMONGROUPING = &H18Const LOCALE_ICURRDIGITS = &H19#If VBA7 Then Declare PtrSafe Function GetThreadLocale Lib "kernel32" () As Long Declare PtrSafe Function GetSystemDefaultLCID Lib "kernel32" () As Long Declare PtrSafe Function GetLocaleInfo Lib "kernel32" _ Alias "GetLocaleInfoA" ( _ ByVal Locale As Long, _ ByVal LCType As Long, _ ByVal lpLCData As String, _ ByVal cchData As Long) As Long#Else Declare Function GetThreadLocale Lib "kernel32" () As Long Declare Function GetSystemDefaultLCID Lib "kernel32" () As Long Declare Function GetLocaleInfo Lib "kernel32" _ Alias "GetLocaleInfoA" ( _ ByVal Locale As Long, _ ByVal LCType As Long, _ ByVal lpLCData As String, _ ByVal cchData As Long) As Long#End If Private Function GetUserLocaleInfo(ByVal dwLocaleID As Long, _ ByVal dwLCType As Long) As String Dim sReturn As String Dim Result As Long Result = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, _ Len(sReturn)) If Result Then sReturn = Space$(Result) Result = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, _ Len(sReturn)) If Result Then GetUserLocaleInfo = Left$(sReturn, Result - 1) End If End IfEnd FunctionPublic Function getTausendertrennzeichen() As StringDim LCID As Long LCID = GetSystemDefaultLCID() getTausendertrennzeichen = GetUserLocaleInfo(LCID, LOCALE_SMONTHOUSANDSEP)End FunctionPublic Function getDezimaltrennzeichen() As StringDim LCID As Long LCID = GetSystemDefaultLCID() getDezimaltrennzeichen = GetUserLocaleInfo(LCID, LOCALE_SMONDECIMALSEP)End FunctionPublic Sub aktuelleSystemeinstellungen()MsgBox "Tausendertrennzeichen: " & getTausendertrennzeichen & vbNewLine & _ "Dezimaltrennzeichen: " & getDezimaltrennzeichen, vbInformation + vbOKOnly End Sub
Mit der Funktion aktuelleSystemeinstellungen(), auf die man mittels Makros zugreifen kann, können die Systeminformationen ermittelt werden.
Quick & Dirty
Zwar technisch nicht ganz so schön, aber wesentlich kürzer ist folgende Lösung
1.000 & 1,00
' Dezimalzeichen ermittelnPublic Function GetDecimalChar() As String GetDecimalChar = Mid$(CStr(1.5), 2, 1)End Function' Tausender-Trennzeichen ermittelnPublic Function GetThousandGroupDigit() As String Dim sTemp As String sTemp = Mid$(FormatNumber(1000, 0, , , vbTrue), 2, 1) If sTemp = "0" Then sTemp = "" GetThousandGroupDigit = sTemp End FunctionPublic Sub aktuelleSystemeinstellungen2()MsgBox "Tausendertrennzeichen: " & GetThousandGroupDigit & vbNewLine & _ "Dezimaltrennzeichen: " & GetDecimalChar, vbInformation + vbOKOnly End Sub
Die Funktion aktuelleSystemeinstellungen2() führt zum selben Ergebnis:
Dezimalzahlen in Userforms
Nun aber zum eigentlichen Problem, wie Userforms mit Dezimalzahlen umgehen:
gegeben ist ein Userform mit einem Textfeld (Me.txt_Dezimalzahl)
Ergebnisse:
Die Methode [Range("D8").Value = CDbl(Replace(Me.txt_Dezimalzahl.Value, ".", ","))] funktioniert ungeachtet der Einstellungen, sofern die Systemeinstellungen auf Komma gesetzt sind, sowohl die Eingabe als Dezimalzahl mit Komma als auch mit Dezimalpunkt. Dies ist die von mir bevorzugte Variante.