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:

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.

Links