Lektionen/Werkzeugkasten

Zahlen formatieren & runden

Einsteiger9 Min. Lesezeit

Zahlen wollen selten so aussehen, wie sie im Speicher liegen. Beträge brauchen zwei Nachkommastellen und ein Tausender-Trennzeichen, Prozentwerte ein %, Zwischensummen eine saubere Rundung. VBA bringt dafür Format, Round, die Int/Fix-Funktionen und die Konvertierungsfunktionen mit. In dieser Lektion lernst du, wann du welche nimmst – und warum Round nicht so rundet, wie du es in der Schule gelernt hast.

Format: aus Zahl wird Text

Format wandelt einen Zahlenwert in eine Textdarstellung um. Das Ergebnis ist ein String, kein Zahlentyp mehr – gut für Anzeige und Ausgabe, nicht zum Weiterrechnen. VBA kennt eingebaute Namen für die häufigsten Fälle:

Debug.Print Format(1234.5, "Standard")        ' "1.234,50"
Debug.Print Format(1234.5, "Currency")        ' "1.234,50 €"
Debug.Print Format(0.075, "Percent")          ' "7,50%"
Debug.Print Format(1234.5, "Fixed")           ' "1234,50"  – ohne Tausenderpunkt
Debug.Print Format(1234, "#,##0")             ' "1.234"

Hinweis: Trennzeichen und Währungssymbol richten sich nach den Windows-Regionaleinstellungen. Auf einem deutschen System ist der Dezimaltrenner das Komma und der Tausendertrenner der Punkt – auf einem englischen System genau umgekehrt. Verlass dich für Dateiausgaben nie darauf.

Benutzerdefinierte Formate

Mit eigenen Formatzeichenfolgen steuerst du die Darstellung genau. Die wichtigsten Platzhalter:

ZeichenBedeutung
0Ziffer, führende/anhängende Null wird angezeigt
#Ziffer, nicht signifikante Null wird weggelassen
.Dezimaltrennzeichen (regional)
,Tausendertrennzeichen (regional)
%Wert mal 100 und Prozentzeichen
Debug.Print Format(1234.5, "#,##0.00")     ' "1.234,50"
Debug.Print Format(7, "0000")              ' "0007"  – auf 4 Stellen auffüllen
Debug.Print Format(0.1234, "0.0%")         ' "12,3%"
Debug.Print Format(-50, "#,##0.00;(#,##0.00)")  ' "(50,00)"  – negativ in Klammern

Der Abschnitt hinter dem Semikolon gilt für negative Zahlen. Mit einem dritten Abschnitt legst du zusätzlich die Darstellung der Null fest: "#,##0.00;-#,##0.00;\-".

Round: Runden mit Tücke

Round rundet auf eine gewünschte Zahl von Nachkommastellen:

Debug.Print Round(3.14159, 2)   ' 3,14
Debug.Print Round(2.71828, 0)   ' 3

So weit, so erwartbar. Jetzt kommt die Falle:

Debug.Print Round(2.5, 0)   ' 2  – nicht 3!
Debug.Print Round(3.5, 0)   ' 4
Debug.Print Round(0.5, 0)   ' 0
Debug.Print Round(1.5, 0)   ' 2

VBA benutzt kaufmännisches Runden zur nächsten geraden Zahl – das sogenannte Banker's Rounding. Bei genau ,5 wird zur nächsten geraden Ziffer gerundet, nicht immer auf. Das ist statistisch fair (Rundungsfehler heben sich auf), widerspricht aber dem, was die meisten unter „kaufmännischem Runden" verstehen (,5 immer auf).

Achtung: In Rechnungen und Summen kann Banker's Rounding zu Cent-Abweichungen gegenüber Excel-Zellen oder Buchhaltungssoftware führen. Wenn du „normales" Aufrunden bei ,5 brauchst, nimm nicht Round.

Eine eigene kaufmännische Round-Funktion

Für echtes kaufmännisches Runden (,5 immer auf) baust du dir eine kleine Funktion. Der Trick: einen halben „Schritt" addieren und dann abschneiden.

Public Function KaufmRunden(ByVal wert As Double, _
                            Optional ByVal stellen As Integer = 2) As Double
    Dim faktor As Double
    faktor = 10 ^ stellen
    ' Sgn behandelt negative Werte symmetrisch
    KaufmRunden = Sgn(wert) * Int(Abs(wert) * faktor + 0.5) / faktor
End Function
Debug.Print KaufmRunden(2.5, 0)     ' 3
Debug.Print KaufmRunden(2.675, 2)   ' 2,68
Debug.Print KaufmRunden(-1.5, 0)    ' -2

Int schneidet nach unten ab, das Addieren von 0.5 vor dem Abschneiden erzeugt das gewünschte Aufrunden ab der Hälfte. Sgn und Abs sorgen dafür, dass negative Beträge in dieselbe Richtung gerundet werden.

Int und Fix: die Nachkommastellen weg

Beide entfernen den Nachkommateil, unterscheiden sich aber bei negativen Zahlen:

Debug.Print Int(4.7)     ' 4
Debug.Print Fix(4.7)     ' 4
Debug.Print Int(-4.7)    ' -5  – rundet Richtung minus unendlich
Debug.Print Fix(-4.7)    ' -4  – schneidet einfach ab

Fix schneidet den Nachkommateil schlicht ab (Richtung Null). Int rundet immer zur nächstkleineren ganzen Zahl ab, bei negativen Werten also weiter „nach unten". Für Ganzzahl-Anteile positiver Zahlen sind beide gleich.

Konvertieren: CCur, CDbl, CLng

Diese Funktionen wandeln einen Wert gezielt in einen bestimmten Zahlentyp um – nützlich beim Einlesen von Text oder um Datentypen sauber festzulegen:

FunktionZieltypZweck
CLngLongganze Zahl, rundet (Banker's Rounding)
CDblDoubleFließkomma mit voller Genauigkeit
CCurCurrencyFestkomma, 4 Nachkommastellen, kein Rundungsdrift
Debug.Print CLng("42")         ' 42
Debug.Print CLng(4.6)          ' 5   – CLng rundet, schneidet nicht ab
Debug.Print CDbl("3,14")       ' 3,14  – Komma je nach Regionaleinstellung
Debug.Print CCur("19,99")      ' 19,99

Tipp: Für Geldbeträge ist der Typ Currency (und damit CCur) oft die bessere Wahl als Double. Currency speichert Festkomma mit vier Nachkommastellen und vermeidet die typischen Fließkomma-Ungenauigkeiten wie 0.1 + 0.2 <> 0.3.

Achte darauf, dass die Konvertierungsfunktionen bei ungültigem Text (CDbl("abc")) einen Laufzeitfehler auslösen. Prüfe im Zweifel vorher mit IsNumeric.

Nz: Null abfangen

Kommt ein Wert aus einer Tabelle oder einem Recordset, kann er Null sein – etwa bei einem leeren Feld. Rechnest du damit, kracht es. Nz ersetzt Null durch einen Ersatzwert:

Dim betrag As Double
betrag = Nz(rs!Rabatt, 0)                 ' 0 statt Null
Debug.Print Format(Nz(rs!Umsatz, 0), "Currency")

' Auch für Text nützlich:
Debug.Print Nz(rs!Bemerkung, "(keine)")   ' Ersatztext bei Null

Nz ist eine Access-Funktion (kein reines VBA) und im Access-Kontext immer verfügbar. Ohne zweiten Parameter liefert Nz(Null) einen leeren String bzw. 0. Setz Nz konsequent überall dort ein, wo ein Feldwert Null sein könnte, bevor du formatierst oder rechnest.

Praxis: Betrag für einen Beleg aufbereiten

Public Function BelegBetrag(ByVal netto As Variant, _
                            ByVal satz As Double) As String
    Dim n As Currency, brutto As Currency
    n = CCur(Nz(netto, 0))                 ' Null abfangen, sauber typisieren
    brutto = KaufmRunden(n * (1 + satz), 2)
    BelegBetrag = Format(brutto, "#,##0.00 €")
End Function
Debug.Print BelegBetrag(100, 0.19)   ' "119,00 €"
Debug.Print BelegBetrag(Null, 0.19)  ' "0,00 €"

Das Muster – Null abfangen, typisieren, runden, formatieren – deckt fast jede Betragsberechnung ab.

Zusammengefasst

  • Format macht aus einer Zahl einen formatierten String; benutze "#,##0.00" & Co. für eigene Darstellungen. Trennzeichen folgen den Regionaleinstellungen.
  • Round nutzt Banker's Rounding: 2,5 wird zu 2, nicht zu 3. Für echtes kaufmännisches Runden schreibst du dir eine eigene Funktion mit Int(x + 0.5).
  • Int rundet nach unten (auch bei Negativen), Fix schneidet nur ab.
  • CCur, CDbl, CLng konvertieren gezielt; für Geld ist Currency der sicherste Typ gegen Fließkomma-Fehler.
  • Nz ersetzt Null durch einen Ersatzwert – immer vor Rechnung und Format einsetzen.
Nächste Lektion
MsgBox & InputBox richtig nutzen