Rubrik: Drucker | VB-Versionen: VB4, VB5, VB6 | 25.01.02 |
DataGrid / Recordset ausdrucken Mit einfachen Mitteln und ohne zusätzliche kommerzielle Tools den Inhalt eines DataGrid/Recordsets ausdrucken. | ||
Autor: Dieter Otter | Bewertung: | Views: 67.678 |
www.tools4vb.de | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
In unserem letzten Tipp haben wir Ihnen gezeigt, wie man mit VB-Boardmitteln eine komfortable Druckroutine zum formatierten Ausdrucken des MSFlexGrid-Controls realisieren kann.
Nun kommt es aber mit Sicherheit genauso häufig vor, dass man Daten aus einer Datenbank tabellarisch am Bildschirm anzeigt, und diese Tabelle dann gerne auch ausgedruckt haben möchte - jedoch ohne den Einsatz zusätzlicher Reporting-Tools, wie CrystalReport, List & Label, ActiveTable o.ä.
Für die Bildschirmdarstellung werden viele von Ihnen sicherlich das Microsoft DataGird Control verwenden, da es im Installationsumfang von VB enthalten ist und somit kein zusätzliches Geld kostet. Die Daten werden häufig über einData-Control aus der Datenbank gefiltert. Damit die Daten dann im DataGrid-Control angezeigt werden, weisst man einfach der DataSource-Eigenschaft das Data-Control zu. Seit Einführung von ADO kann man der DataSource-Eigenschaft aber auch direkt ein Recordset-Objekt zuweisen. Somit spart man sich das DataControl und ist in vielen Bereichen flexibler.
Und genau, das machen auch wir. Wir öffnen die Datenbank, erstellen ein Recordset, weissen dem DataGrid das Recordset zu und feilen dann noch ein wenig am Tabellen-Layout - und schon werden die Daten aus der Datenbank-Tabelle schön formatiert am Bildschirm angezeigt.
Als Beispiel nehmen wir eine kleine Literatur-Datenbank, welche folgenden Aufbau hat:
Tabellenname: Buecher
Felder:
Die Testdatenbank können Sie sich hier downloaden: Literatur.zip (7 KB)
' Globale Variablen ' Datenbank-Connection + Recordset Objekt Public Conn As ADODB.Connection Public Rs As ADODB.Recordset
Im Form_Load-Ereignis öffnen wir also die Datenbank, erstellen das Recordset und nehmen die Spalten-Formatierungen vor:
Private Sub Form_Load() ' Datenbank öffnen Set Conn = New ADODB.Connection Conn.CursorLocation = adUseClient Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & App.Path & "\Literatur.mdb;" & _ "Persist Security Info=False" ' Recordset erstellen und öffnen Set Rs = New ADODB.Recordset Rs.Open "SELECT * FROM Buecher", Conn, _ adOpenStatic, adLockOptimistic ' DataGrid mit dem Inhalt des Recordsets füllen With DataGrid1 ' Titel der Tabelle .Caption = "BÜCHER" ' Datenanbindung Set .DataSource = Rs ' Spaltenbreiten .Columns(0).Width = 2000 .Columns(1).Width = 2000 .Columns(2).Width = 600 .Columns(3).Width = 1350 .Columns(4).Width = 650 .Columns(5).Width = 3000 ' Spaltenausrichtung .Columns(2).Alignment = dbgCenter .Columns(4).Alignment = dbgRight ' Spaltenformat .Columns(4).NumberFormat = "0.00" End With End Sub
Nun werden alle Daten der Tabelle Buecher sauber und schön formatiert im DataGrid dargestellt - das Erscheinungsjahr wird hierbei zentriert und der Buchpreis rechtsbündig angezeigt.
Ausdrucken des DataGrid/Recordsets
Per Knopfdruck möchten wir, dass die am Bildschirm im DataGrid angezeigten Daten auch ausgedruckt werden können - natürlich ebenfalls alle Spalten schön sauber untereinander und entsprechend formatiert (rechts/links/zentriert).
Hierzu bedienen wir uns (viele werden es schon ahnen) logischerweise wieder "unserer" zwei universellen Druckfunktionen aus dem gestrigen Tipp. Für alle die es nicht wissen: es handelt sich hierbei um die Prozeduren PrintRow und PrintCheckLength. Alle wichtigen Details und Beschreibungen lesen Sie bitte hier nach:
MSFlexGrid ausdrucken
DataGrid/Recordset drucken
Folgende Anforderungen:
a) Tabellenbeschriftung anhand der Spaltenbezeichner ermitteln
Die Tabellenebschriftung ermitteln wir, indem wir die Spalten des Grids durchlaufen und die Spaltenbeschriftungen der Columns-Objekte (Caption-Eigenschaft) in einem String zusammenfassen - jedoch nur für sichtbare Spalten.
With DataGrid1 For I = 0 To .Columns.Count - 1 If .Columns(I).Visible Then _ sHeader = sHeader + .Columns(I).Caption Next I End With
b) aktuell eingestellten Spaltenbreiten prozentual zum Papierformat berücksichtigen
c) Spaltenformat berücksichtigen (links-/rechtsbündig und zentriert)
Zunächst berechnen wir die Gesamtbreite aller Spalten im Grid. Hierzu werden die Spaltenbreiten der einzelnen Spalten aufaddiert.
With DataGrid1 For I = 0 To .Columns.Count - 1 If .Columns(I).Visible Then _ GridWidth = GridWidth + .Columns(I).Width Next I End With
Jetzt berechnen wir für jede einzelne Spalte die benötigte Spaltenbreite in Prozent der Gesamtbreite. Wenn wir dann die auf dem Ausdruck verfügbare maximale Druckbreite durch 100 dividieren und mit der berechneten Spaltenprozentzahl multiplzieren, erhalten wir die Spaltenbreite, die uns für den Ausdruck zur Verfügung steht.
With DataGrid1 For I = 0 To .Columns.Count - 1 With .Columns(I) If .Visible Then ' Ausrichtung berücksichtigen Select Case .Alignment Case dbgCenter ' zentriert fmt = fmt + "^" Case dbgRight ' rechtsbündig fmt = fmt + ">" End Select intProz = (.Width / GridWidth * 100 + 0.5) ColWidth = (PageWidth / 100 * intProz + 0.5) fmt = fmt + Format$(ColWidth, "0") + "|" End If End With Next I End With
d) alle Spalten schön sauber untereinander ausdrucken
Um alle Datensätze auszudrucken durchlaufen wir das gesamte Recordset-Objekt, indem wir mit dem ersten Datensatz beginnen (MoveFirst) und solange "weiterblättern" (MoveNext), bis wir am Recordset-Ende (EOF) angelangt sind. Die entsprechenden Feldinhalte holen wir uns also aus dem Recordset, wobei folgendes zusätzlich zu beachten ist:
- Prüfen, ob ein Feld einen Inhalt hat, da wir sonst einen Laufzeitfehler erhalten (Unzulässige Verwendung von Null)
- Den Feldinhalt brauchen wir als Text, also müssen Integer, Long oder sonstige "Zahlenfelder" in Text umgewandelt werden
- Anzeigeformate, die über NumberFormat (Columns-Objekt des DataGrid-Controls) festgelegt wurden, sollen für den Ausdruck ebenfalls berücksichtigt werden
Rs.MoveFirst While Not Rs.EOF sRow = "" With DataGrid1 For I = 0 To .Columns.Count - 1 If .Columns(I).Visible Then ' NumberFormat berücksichtigen If .Columns(I).NumberFormat <> "" Then sRow = sRow + Format$(FeldInhalt(Rs.Fields(I)), _ .Columns(I).NumberFormat) + "|" Else ' normaler Text / sonstige Datentypen sRow = sRow + CStr(FeldInhalt(Rs.Fields(I))) + "|" End If End If Next I PrintRow xPos, fmt, sRow End With ' nächster Datensatz Rs.MoveNext Wend
Zusammenfassung
Im nachfolgenden finden Sie ein vollständiges und funktionierendes Beispiel für den Ausdruck des DataGrid/Recordsets einschliesslich der Hilfsfunktion FeldInhalt.
Private Sub cmdPrint_Click() Dim fmt As String Dim sRow As String Dim xPos As Long Dim I As Long Dim intProz As Integer Dim GridWidth As Long Dim ColWidth As Long Dim PageWidth As Long Dim sHeader As String Screen.MousePointer = 11 With Printer .ScaleMode = 6 ' Maßeinheit "mm" xPos = 20 ' 20mm Rand link .Font.Name = "Arial" .Font.Size = 12 ' Listenbezeichnung .CurrentY = 10 .CurrentX = xPos .Font.Bold = True Printer.Print DataGrid1.Caption + vbCrLf .Font.Bold = False ' Format (Spaltenbreiten) + Tabellenkopf ' anhand Bildschirm-Spaltenbreite ermitteln PageWidth = .ScaleWidth - (xPos * 2) With DataGrid1 ' Gesamtbreite For I = 0 To .Columns.Count - 1 If .Columns(I).Visible Then GridWidth = GridWidth + .Columns(I).Width End If Next I ' Prozentuale Verteilung auf die Spalten ' plus Tabellenkopf For I = 0 To .Columns.Count - 1 With .Columns(I) ' zunächst Spaltenausrichtung berücksichtigen Select Case .Alignment Case dbgCenter ' zentriert fmt = fmt + "^" Case dbgRight ' rechtsbündig fmt = fmt + ">" End Select ' jetzt Spaltenbreite berechnen intProz = (.Width / GridWidth * 100 + 0.5) ColWidth = (PageWidth / 100 * intProz + 0.5) fmt = fmt + Format$(ColWidth, "0") ' Tabellenkopf sHeader = sHeader + .Caption End With fmt = fmt + "|" sHeader = sHeader + "|" Next I ' abschliessendes "|" entfernen fmt = Left$(fmt, Len(fmt) - 1) sHeader = Left$(sHeader, Len(sHeader) - 1) End With ' Tabellenkopf drucken .Font.Bold = True .Font.Size = 9 PrintRow xPos, fmt, sHeader .Font.Bold = False ' Jetzt Recordset "satzweise" ausdrucken .Font.Size = 8 .CurrentY = .CurrentY + 5 Rs.MoveFirst While Not Rs.EOF sRow = "" With DataGrid1 For I = 0 To .Columns.Count - 1 If .Columns(I).Visible Then ' NumberFormat berücksichtigen If .Columns(I).NumberFormat <> "" Then sRow = sRow + Format$(FeldInhalt(Rs.Fields(I)), _ .Columns(I).NumberFormat) + "|" Else ' normaler Text / sonstige Datentypen sRow = sRow + CStr(FeldInhalt(Rs.Fields(I))) + "|" End If End If Next I PrintRow xPos, fmt, sRow End With ' nächster Datensatz Rs.MoveNext Wend ' Druckauftrag beenden .EndDoc End With Screen.MousePointer = 0 MsgBox "Grid wurde ausgedruckt!", 64, "Drucken..." End Sub
' Nullfeld abfragen Public Function FeldInhalt(Feld As Field) As Variant If IsNull(Feld.Value) Then Select Case Feld.Type Case adInteger, adSmallInt FeldInhalt = 0 Case adBoolean FeldInhalt = False Case Else FeldInhalt = "" End Select Else FeldInhalt = Feld.Value End If End Function