User Tools

Site Tools


vba:functions:printf:index

[VBA] sprintf(), vsprintf()

Gibt eine anhand des Formatierungs-Strings format gebildete Zeichenkette zurück.1)

Version 2.7.1 - 13.02.2020

Von PHP bin ich mir die tolle Funktion sprintf() gewohnt. Diese vermisste ich schmerzlich im VBA. Immer alle Strings mit & zusammenzusetzen war einfach hässlich. Auf der Suche nach einer Lösung fand ich eine printf Implementierung auf der Seite PrintF and Related Functions in VB.

Das fand ich am Anfang auch ganz toll. Doch vermisste ich die Reihenfolge-Parameter aus PHP. Auch die Umsetzung ohne Reguläre Ausdrücke hat mich erstaunt. Darum habe ich mir in etwa 3 Stunden Arbeit selber sprintf() und vsprintf() aus PHP implementiert.
Später kahm dann noch die Formatierungsregeln etc. dazu.

Hier nun das Resultat.

Erweiterungen findet ihr unter [VBA] PrintF AddOns

Definitionen

Konstanten

Folgende Fehler-Codes sind definiert

Wert Code Beschreibung
-2147221514 2) ERR_INSUFFICIENT_PARAMS Des Pattern hat mehr Platzhalter als Werte übergeben wurden
-2147221515 3) ERR_NOT_NUMBER Es wird keine Zahl geliefert wo eine erwartet wird
-2147221516 4) ERR_INVALID Das Format ist ungültig

Funktionen

sprintf()

Parst einen Pattern mit Werten 5).

Public Function sPrintF( _
        ByVal iFormatString As String, _
        ParamArray iParams() As Variant _
) As String
  • iFormatString Zu formatierender String
  • Weitere Params die dazugehörigen Werte

vsprintf()

Parse einen String mit den Werten als Array 6).

Public Function vsPrintF( _
        ByVal iFormatString As String, _
        ByRef iParams() As Variant _
) As String
  • iFormatString Zu formatierender String
  • iParams() die dazugehörigen Werte als Array

printF_UserDefinedDateFormat()

Mit dem Property printF_UserDefinedDateFormat können benuzerdefinierte FOrmate hinterlegt werden. Siehe Beispiel benutzerdefinierte_formate

Public Property Get printF_UserDefinedDateFormat(Optional ByVal iNumber As Integer = 0) As String

Patterns

Die Formatierungen sind verscheidene Patterns. Die meiste habe ich aus PHP übernommen, andere aus Java. Der Aufbau ist folgednermasen

 %(Index)(Format)[Typ](Datum/ZeitFormat)
  • Index Die Angabe, um welchen übergebenen Werteparameter es sich handelt. Die Angabe ist Optional. Mögliche Werte: [Zahl]$ Oder <. Bei eihner Zahl gefolgt von einem $ Zeichen ist die Nummer des Paramters gemeint. Beginnend bei 1. Sprich %2$s bedeutet, dass der zweite Parameter ausgegeben wird. Bei < wird derselbe Wert verarbeitet wie beim Pattern davor. %<s nimmt also dieselbe Quelle wie der letzte Pattern vor ihm.
  • Format Bei Zahlen und texten können verschieden Formate mitgegeben werden
  • Typ Mit einem Buchstaben wird definiert, um was für ein Datentyp es sich handelt
  • Datum/ZeitFormat Wennd er Type T oder S ist, wird mit diesem Teil angegeben, was vom Datum angezeigt werden soll
  • Maskierung Wenn vor dem % ein \ steht, dann ist das %maskiert und der Pattern wird nicht geparst. Soll aber das \ als Textelement dienen, so muss dieses maskiert werden: \\%s

Typ

Zahlen


c the argument is treated as an integer, and presented as the character with that ASCII value.
d the argument is treated as an integer, and presented as a (signed) decimal number.
e the argument is treated as scientific notation (e.g. 1.2e+2). The precision specifier stands for the number of digits after the decimal point
E like e but uses uppercase letter (e.g. 1.2E+2).
u the argument is treated as an integer, and presented as an unsigned decimal number.
f the argument is treated as a float, and presented as a floating-point number (locale aware).
g shorter of %e and %f.
G shorter of %E and %f.
o the argument is treated as an integer, and presented as an octal number.

Text


s the argument is treated as and presented as a string.
q the argument is treated as and presented as a string in sql-form: 'string'
x the argument is treated as an integer and presented as a hexadecimal number (with lowercase letters).
X the argument is treated as an integer and presented as a hexadecimal number (with uppercase letters).

Datum/Zeit


T date/time Prefix for date and time conversion characters. See Date/Time Conversions.
t like T
S date/time Prefix for date and time conversion characters for MS Access SQL. See Date/Time Conversions.

Datum/ZeitFormat

Zeit Details


H Hour of the day for the 24-hour clock, formatted as two digits with a leading zero as necessary i.e. 00 - 23.
I Hour for the 12-hour clock, formatted as two digits with a leading zero as necessary, i.e. 01 - 12.
k Hour of the day for the 24-hour clock, i.e. 0 - 23.
l Hour for the 12-hour clock, i.e. 1 - 12.
M Minute within the hour formatted as two digits with a leading zero as necessary, i.e. 00 - 59.
S Seconds within the minute, formatted as two digits with a leading zero as necessary, i.e. 00 - 60 (“60” is a special value required to support leap seconds).

Datum Details


B Locale-specific full month name, e.g. “January”, “February”.
b Locale-specific abbreviated month name, e.g. “Jan”, “Feb”.
A Locale-specific full name of the day of the week, e.g. “Sunday”, “Monday”
a Locale-specific short name of the day of the week, e.g. “Sun”, “Mon”
C Four-digit year divided by 100, formatted as two digits with leading zero as necessary, i.e. 00 - 99
Y Year, formatted as at least four digits with leading zeros as necessary, e.g. 0092 equals 92 CE for the Gregorian calendar.
y Last two digits of the year, formatted with leading zeros as necessary, i.e. 00 - 99.
j Day of year, formatted as three digits with leading zeros as necessary, e.g. 001 - 366 for the Gregorian calendar.
m Month, formatted as two digits with leading zeros as necessary, i.e. 01 - 13.
d Day of month, formatted as two digits with leading zeros as necessary, i.e. 01 - 31
e Day of month, formatted as two digits, i.e. 1 - 31.

Datum/Zeit fixe Formate


R Time formatted for the 24-hour clock as “%tH:%tM”
T Time formatted for the 24-hour clock as “%tH:%tM:%tS”.
r Time formatted for the 12-hour clock as “%tI:%tM:%tS %Tp”. The location of the morning or afternoon marker ('%Tp') may be locale-dependent.
D Date formatted as “%tm/%td/%ty”.
f Datetime formated as “%tY-%t-%td_%H:%M:%S”
F ISO 8601 complete date formatted as “%tY-%tm-%td”.

Anwendungsbeispiele

Um ein wenig klar zu machen was die Funktion alles kann, hier mal einige Beispiele. Den Code zur Funktion befindet sich weiter unten.

Standartanwendung

Debug.Print sPrintF("Hallo %s", "Hans")
Hallo Hans
 
Debug.Print sPrintF("%s wiegt %f Kilo", "Hans", 76.5)
Hans wiegt 76.5 Kilo
 
Debug.Print sPrintF("%s wiegt %d Kilo", "Hans", 76.5)
Hans wiegt 76 Kilo

Beispiel mit Reheinfolge

'Mittels Positionszahl und $ kann angegeben werden, welcher Parameter gemeint ist. Es beginnt bei 1
? sPrintF("%2$s wiegt %1$f Kilo", 76.5, "Hans")
Hans wiegt 76.5 Kilo
 
? sPrintF("%1$s ist %1$s und %2$s ist %2$s", "Heute", "Morgen")
Heute ist Heute und Morgen ist Morgen
 
'Mittels < kann angegeben werden, dass derselbe Parameter wir beim Pattern davor verwendet wird
? sPrintF("%s ist %<s und %s ist %<s", "Heute", "Morgen")
Heute ist Heute und Morgen ist Morgen
 
? sprintf("Wir haben %d, ich wiederhole. Wir haben %<d Tage Zeit %d Millionen zu finden", 10, 20)
Wir haben 10, ich wiederhole. Wir haben 10 Tage Zeit 20 Millionen zu finden
 
'Dasselbe, jetzt jedoch zusätzlich mit Positionsangeben
? sPrintF("%s, %<s, %<s! %3$s, %<s, %<s! %2$s, %<s, %<s! %s!", "Ha", "Ho", "Hi", "Yes")
Ha, Ha, Ha! Hi, Hi, Hi! Ho, Ho, Ho! Yes!

Beispiele für dir Funktion vsprintf()

Dim params(1)    As Variant
 
params(0) = "Heute"
params(1) = "Morgen"
 
Debug.Print vsPrintF("%1$s ist %1$s und %2$s ist %2$s", params)

sprintf() mit Formatierungen

'Strings:
'   [Hochkomma][Zeichen][Länge] = String mit [Zeichen] als Prefix auf [Länge] erweitert
'   [Minus][Hochkomma][Zeichen][Länge] = dito, jedoch wird hinten mit [Zeichen] aufgefüllt
'   [Punkt][Länge] = Der String wird auf [Länge] beschnitten
'   [Minus][Punkt][Länge] = dito, jedoch von hinten
debug.print sprintf("%1$s   %1$'#6s   %1$-'#6s   %1$.3s   %1$-.3s   %1$q", "abcd")
abcd   ##abcd   abcd##   abc   bcd   'abcd'
 
'Nummern:
'Float
'   [Länge] = Vor dem Dezimaltrennzeichen wird mit [Länge] 0 aufgefüllt.
'   [Punkt][Länge] = ANzahl Dezimalzeichen
'   [Minus] = Das Vorzeichen wird mit immer angegeben
debug.print sprintf("%1$f   %1$6f   %1$-.1f   %1$.3f   %1$d   %<-d", 123.45)
123.45   000123.45   +123.5   123.450   123   +123
 
'Integer
debug.print sprintf("%1$f   %1$6f   %1$-.1f   %1$.3f   %1$d", 123)
123   000123   +123.0   123.000   123

sprintf() mit Datum

Der Datumspattern ist Zweiteilig. Zuerst kommt ein Buchstabe um anzugegebe, dass es dsich um ein Datum/Zeit handelt und dann ein Buchstabe für das Format. Da sist nicht meine Erfindung, das übernehme ich so von Java (http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html). Einzig beim Einleitenden Buchstaben habe ich noch das S hinzugefügt, um den Output SQL Konform zu schreiben. Somit haben T oder S als Einleitender Buchstabe, gefolgt vom Format

? sprintf("Heute ist  %TA der %<Te %<TB, %<TY", now)
Heute ist  Freitag der 29 Januar, 2016
 
? sprintf("SELECT * FROM mytable WHERE in_date BETWEEN %2$SD AND %1$SD", now, now-10)
SELECT * FROM mytable WHERE in_date BETWEEN #01/19/2016# AND #01/29/2016#

Benutzerdefinierte Formate

Es können bis zu 10 benutzerdefinierte Formate hinterlegt werden. Dazu kann man die Funktion printF_UserDefinedDateFormat verwenden. Die Formate können dann mittel U und dem Index abgerufenwerden

printF_UserDefinedDateFormat(0) = "HH.NN"
printF_UserDefinedDateFormat(1) = "d. MMMM YYYY"
debug.print sPrintF("%Tu1 um %<Tu0", now)
 
21. Oktober 2016 um 11.34

Text-Formatierungen (Zeilenumbrüche und Tabulator)

'Mit Zeilenumbruch \t und Tabulator \n
debug.print sPrintF("%1$s\tist %1$s,\n%2$s\tist %2$s", "Heute", "Morgen")
Heute   ist Heute,
Morgen  ist Morgen
 
'Tabulator \t etc nicht parsen: den \ von \ mit einem \ markieren -> \\t
debug.print sprintf("[\\t]\t%s", "ist ein Tabulator")
[\t]    ist ein Tabulator
 
'um nur diese Formatierungen umzuschreiben kann man auch ohne Paramter arbeiten
debug.print sprintf("item:\tPunkt1")
item:   Punkt1

Code

2)
vbObjectError - 10
3)
vbObjectError - 11
4)
vbObjectError - 12
vba/functions/printf/index.txt · Last modified: 13.02.2020 08:51:20 by yaslaw