Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0249: FlexGrid ausdrucken

 von 

Beschreibung 

Alle Grid´s die von "Videosoft" entwickelt wurden, unterstützen den Ausdruck über Formatrange. Damit kann man auf die Schnelle einen sauberen Ausdruck hinbekommen.Gedruckt wird, was man auf dem Bildschirm sieht (WYSIWYG). Auch Farben und Schriftarten werden automatisch berücksichtigt.Um dieses Beispiel in eigene Programme zu verwenden, muss man die Prozedur PrintGrid und die Deklarationen in einem Modul einfügen. Danach kann man von überall, mit PrintGrid ein FlexGrid drucken.

Schwierigkeitsgrad:

Schwierigkeitsgrad 1

Verwendete API-Aufrufe:

SendMessageA (SendMessage)

Download:

Download des Beispielprojektes [3,15 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Projekt1.vbp -------------
' Die Komponente 'Microsoft FlexGrid Control 6.0 (MSFLXGRD.OCX)' wird benötigt.

'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Schaltfläche "Command1"
' Steuerelement: Flexible Tabelle "MSFlexGrid1"
Option Explicit

Private Declare Function SendMessage Lib "user32" Alias _
        "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As _
        Long, ByVal wParam As Long, ByVal lParam As Long) _
        As Long
        
Const WM_USER = &H400
Const VP_FORMATRANGE = WM_USER + 125
Const VP_YESIDO = 456654

Private Type Rect
  Left    As Long
  Top     As Long
  Right   As Long
  Bottom  As Long
End Type

Private Type TFormatRange
  hdc         As Long
  hdcTarget   As Long
  rc          As Rect
  rcPage      As Rect
End Type

Private Sub Command1_Click()
  Call PrintGrid(MSFlexGrid1, 20, 25, 20, 20, _
                 "ActiveVB - FlexGrid drucken über " & _
                 "VP_FORMATRANGE", "")
End Sub

Private Sub Form_Load()
  Dim Zahl%
  
    'Flex mit irgendwelchen Daten füllen
    With MSFlexGrid1
      .ColWidth(0) = 1000
      .ColWidth(1) = 2000
      .ColWidth(2) = 2600
      .ColAlignment(3) = 0
      .ColWidth(3) = 500
      .ColWidth(4) = 2800
      .TextArray(0) = "Name"
      .TextArray(1) = "E-Mail"
      .TextArray(2) = "HomePage"
      .TextArray(3) = "Nr."
      .TextArray(4) = "Sonstiges"
      
      For Zahl = 1 To 9
        .AddItem "Dirk Lietzow" & vbTab & "dirk@activeVB.de" & _
                 vbTab & "www.activeVB.de" & vbTab & Zahl & vbTab & _
                 "Alle für einen, einer für alle ..."
      Next Zahl
      
      ' 1. leere Zeile löschen
      .RemoveItem 1
      
      ' Formatierungsbeispiele
      .Col = 2
      .Row = 2
      .CellFontName = "Arial"
      .CellFontSize = 11
      .Col = 2
      .Row = 3
      .CellFontName = "Arial"
      .CellFontSize = 12
      .Col = 2
      .Row = 4
      .CellFontName = "Arial"
      .CellFontSize = 14
      .CellFontBold = True
      .RowHeight(.Row) = 500
      .Col = 2
      .Row = 6
      .CellBackColor = &H8000000F
      .Col = 2
      .Row = 8
      .CellFontName = "Courier New"
      .CellFontSize = 12
      .CellFontBold = True
      .CellForeColor = vbWhite
      .CellBackColor = &HC00000
      .RowHeight(.Row) = 500
    End With
End Sub

Sub PrintGrid(Grid As MSFlexGrid, ByVal LeftMargin As Single, _
              ByVal TopMargin As Single, ByVal RightMargin As _
              Single, ByVal BottomMargin As Single, Titel As _
              String, Datum As String, Optional many As Integer)
              
  Dim tRange As TFormatRange
  Dim lReturn As Long
  Dim DName As String
  Dim DSchacht As Integer
  Dim gbeg As Long
  Dim CopyCW() As Long
  Dim GRef As Boolean
  Dim X%
  
    GRef = False
    If many > 0 Then
      ' Anzahl der zu druckenden Colums festlegen
      ' Alles > many wird auf colwidth = 0 gesetzt
      If Grid.Cols > many Then
        gbeg = Grid.Cols - many
        ReDim CopyCW(gbeg)
        Grid.Redraw = False
        For X = many To Grid.Cols - 1
          CopyCW(X - many) = Grid.ColWidth(X)
          Grid.ColWidth(X) = 0
        Next X
        GRef = True
      End If
    End If
    
    'mit wParam <> 0 kann überprüft werden
    'ob das Control OPP unterstützt, wenn ja wird
    '456654 (VP_YESIDO) zurückgeliefert
    lReturn = SendMessage(Grid.hWnd, VP_FORMATRANGE, 1, 0)
    
    If lReturn = VP_YESIDO Then
      
      'Struktur mit Formatierungsinformationen füllen
      Printer.ScaleMode = vbPixels
      
      With tRange
        .hdc = Printer.hdc
        
        'Höhe und Breite einer Seite (in Pixel)
        .rcPage.Right = Printer.ScaleWidth
        .rcPage.Bottom = Printer.ScaleHeight
        
        'Lage und Abmessungen des Bereichs auf den
        'gedruckt werden soll (in Pixel)
        .rc.Left = Printer.ScaleX(LeftMargin, vbMillimeters)
        .rc.Top = Printer.ScaleY(TopMargin, vbMillimeters)
        .rc.Right = .rcPage.Right - Printer.ScaleX(RightMargin, _
                                                   vbMillimeters)
                                                   
        .rc.Bottom = .rcPage.Bottom - Printer.ScaleY(BottomMargin, _
                                                     vbMillimeters)
      End With
  
      'Drucker initialisieren
      Printer.Print vbNullString
      
      'Seite(n) drucken
      Do
        Printer.CurrentX = Printer.ScaleX(LeftMargin, vbMillimeters)
        Printer.CurrentY = Printer.ScaleY(10, vbMillimeters)
        If Titel <> "" Then Printer.Print Titel
  
        Printer.CurrentX = Printer.ScaleX(LeftMargin, vbMillimeters)
        Printer.CurrentY = Printer.ScaleY(16, vbMillimeters)
        
        If Datum <> "" Then
          Printer.Print Datum
        Else
          Printer.Print Format(Date, "DD.MM.YYYY")
        End If
        lReturn = SendMessage(Grid.hWnd, VP_FORMATRANGE, 0, _
                              VarPtr(tRange))
        
        If lReturn < 0 Then
          Exit Do
        Else
          Printer.NewPage
        End If
      Loop
      Printer.EndDoc
  
      'Reset
      lReturn = SendMessage(Grid.hWnd, VP_FORMATRANGE, 0, 0)
    End If
    
    If GRef Then
      'Alle Colums wieder in richtiger Breite darstellen
      For X = many To Grid.Cols - 1
        Grid.ColWidth(X) = CopyCW(X - many)
      Next X
      Grid.Redraw = True
    End If
End Sub

'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Projekt1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 34 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Lemberg am 20.03.2009 um 16:05

Hallo!
Am Anfang möchte ich mich für Tipp-FlexGrid ausdrucken bedanken.
Lief problemlos ca 3 Jahre! Nun habe ich mein kleines Programm auf einem Client PC mit Netzwerkdrucker installiert.
Manchmal bei einem Klick auf cmbPrint kommen tausende Seite und Drucker ist nicht zu stoppen. Selbe Programm auf Client2 undClient3 PC lauft aber problemlos- ein Klick und kommt eine Seite.
Brauche Ihre Hilfe, was könnte die Ursache sein? Vielleicht Druckertreiber?
Im voraus vielen Dank
Lemberg

Kommentar von IppuX am 03.08.2008 um 00:15

Hab mal ne farge bin ganz neu in der Szene!!
Mein problem ist bei mir kommt ein fehler den ich nicht verstehe namens : " Ausdruck erwartet ." Was muss ich tun das der fehler nicht mehr besteht ich benutze
Microsoft Visual Basic 2008 Express Editor

!! sry das ich kein beitrag zum thema habe !!

bitte um schnelle Antwort : per email nilsmirchel@web.de

ThX im vorraus IppuX

Kommentar von Ralf am 11.06.2006 um 15:17

Ein MsFlexgrid mit 5 Cols und einer beliebige Anzahl Rows mit Daten füllen ist kein Problem .Nun möchte ich noch die unterste Zeile auf eine Col ändern und hier einen Mengentext welcher sich dann vorschriftsmäßig umbricht einladen . Soweit bin ich mittlerweile .Dieses Grid ausdrucken bereitet mir Probleme weil sich der MengenText der untersten Zeile zwischen das Gitter druckt .Gibt es hierfür wohl eine Lösung ? Und kann jemand den entsprechenden Code zur Verfügung stellen. Ich bedanke mich für jeden Tipp herzlichst .

Kommentar von Jürgen am 14.12.2005 um 22:21

Druck Button:

Private Sub cmdPrint_Click()

'zunächst aktuell verwendeten Drucker "merken"
Dim stdPrinter As String
stdPrinter = Printer.DeviceName

'Druckerwechsel und Ausdruck starten
If SetPrinter(frmKundeProdukt.cboPrinter.text) Then
Call PrintGrid(flexDetails, 20, 25, 20, 20, "titel", "")
End If

'"alten" Drucker wieder als Standard festlegen
SetPrinter stdPrinter

End Sub


Sonstiges:

Option Explicit

Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hWnd As Long, ByVal wMsg As _
Long, ByVal wParam As Long, ByVal lParam As Long) _
As Long

Const WM_USER = &H400
Const VP_FORMATRANGE = WM_USER + 125
Const VP_YESIDO = 456654

Private Type Rect
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Type TFormatRange
hdc As Long
hdcTarget As Long
rc As Rect
rcPage As Rect
End Type

Public Function GetPrinters(Combo As Control)
'Ermitteln aller verfügbaren Drucker
'und füllen der ComboBox
Dim x As Integer

For x = 0 To Printers.Count - 1
Combo.AddItem Printers(x).DeviceName
Next x

'Standarddrucker voreinstellen
For x = 0 To Combo.ListCount - 1
If Combo.List(x) = Printer.DeviceName Then
Combo.ListIndex = x
Exit For
End If
Next x
End Function


Public Function SetPrinter(ByVal prnName As String) _
As Boolean
'Festlegen des Druckers für den Ausdruck
'Erwartet wird als Parameter die im System verwendete
'Bezeichnung des Druckers
'
'Rückgabewert: True = OK
' False = Drucker nicht gefunden

Dim Result As Boolean
Dim x As Integer

Result = False
If Printers.Count > 0 Then
For x = 0 To Printers.Count - 1
If Printers(x).DeviceName = prnName Then
Set Printer = Printers(x)
Result = True
Exit For
End If
Next x
End If
SetPrinter = Result
End Function


Public Function PrintGrid(Grid As MSFlexGrid, ByVal LeftMargin As Single, _
ByVal TopMargin As Single, ByVal RightMargin As _
Single, ByVal BottomMargin As Single, Titel As _
String, Datum As String, Optional many As Integer)

Dim tRange As TFormatRange
Dim lReturn As Long
Dim DName As String
Dim DSchacht As Integer
Dim gbeg As Long
Dim CopyCW() As Long
Dim GRef As Boolean
Dim x%

GRef = False
If many > 0 Then
' Anzahl der zu druckenden Colums festlegen
' Alles > many wird auf colwidth = 0 gesetzt
If Grid.Cols > many Then
gbeg = Grid.Cols - many
ReDim CopyCW(gbeg)
Grid.Redraw = False
For x = many To Grid.Cols - 1
CopyCW(x - many) = Grid.ColWidth(x)
Grid.ColWidth(x) = 0
Next x
GRef = True
End If
End If

'mit wParam <> 0 kann überprüft werden
'ob das Control OPP unterstützt, wenn ja wird
'456654 (VP_YESIDO) zurückgeliefert
lReturn = SendMessage(Grid.hWnd, VP_FORMATRANGE, 1, 0)

If lReturn = VP_YESIDO Then

'Struktur mit Formatierungsinformationen füllen
Printer.ScaleMode = vbPixels
Printer.Orientation = vbPRORLandscape

With tRange
.hdc = Printer.hdc

'Höhe und Breite einer Seite (in Pixel)
.rcPage.Right = Printer.ScaleWidth
.rcPage.Bottom = Printer.ScaleHeight

'Lage und Abmessungen des Bereichs auf den
'gedruckt werden soll (in Pixel)
.rc.Left = Printer.ScaleX(LeftMargin, vbMillimeters)
.rc.Top = Printer.ScaleY(TopMargin, vbMillimeters)
.rc.Right = .rcPage.Right - Printer.ScaleX(RightMargin, _
vbMillimeters)

.rc.Bottom = .rcPage.Bottom - Printer.ScaleY(BottomMargin, _
vbMillimeters)
End With

'Drucker initialisieren
Printer.Print vbNullString

'Seite(n) drucken
Do
Printer.CurrentX = Printer.ScaleX(LeftMargin, vbMillimeters)
Printer.CurrentY = Printer.ScaleY(10, vbMillimeters)
If Titel <> "" Then Printer.Print Titel

Printer.CurrentX = Printer.ScaleX(LeftMargin, vbMillimeters)
Printer.CurrentY = Printer.ScaleY(16, vbMillimeters)

If Datum <> "" Then
Printer.Print Datum
Else
Printer.Print Format(Date, "DD.MM.YYYY")
End If
lReturn = SendMessage(Grid.hWnd, VP_FORMATRANGE, 0, _
VarPtr(tRange))

If lReturn < 0 Then
Exit Do
Else
Printer.NewPage
End If
Loop
Printer.EndDoc

'Reset
lReturn = SendMessage(Grid.hWnd, VP_FORMATRANGE, 0, 0)
End If

If GRef Then
'Alle Colums wieder in richtiger Breite darstellen
For x = many To Grid.Cols - 1
Grid.ColWidth(x) = CopyCW(x - many)
Next x
Grid.Redraw = True
End If

End Function

Kommentar von Torsten am 14.12.2005 um 17:45

hi
funzt super aber kann man irgendwie auch den drucker auswählen bei mir druckt der immer mit dem standarddrucker...

Kommentar von Marc am 05.10.2005 um 17:51

Hi Jürgen , würde mich auch interessiern, hab das gleiche Problem, benötige ne Skalierung für das ganze Grid auf einem Baltt darzustellen.

Kommentar von Jürgen am 19.07.2005 um 15:52

Hallo, habe das auch eingebaut.Qeurformat über

Printer.Orientation = vbPRORLandscape


funktioniert auch. Wie bekomme ich nur eine Sklaierung so hin, dass alles auf eine Seite gedruckt wird? (Für normalen Querdruck ist mein Grid eine Spalte zu breit)?

Kommentar von Klaus am 26.06.2005 um 16:08

Hallo,
hat denn immer noch niemand eine Möglichkeit gefunden, wie das Problem beim Ausdruck von Flexgrids mit MergeCells behoben werden kann?

Grüße Klaus

Kommentar von Ren am 26.11.2004 um 07:45

hi,
i've been wasting some time looking for codes on how to print the flexgrid data after generating the report in a form, since i don't know how to generate a report with data environment and dataReport for a more complex report. Not to mention that i need to print about at least 77-80 lines, font size abt 6 in the flexgrid with 1 line titles.
Thanks to your codes which i just found, i'm now able to print..& just need a little modification to your codes.
Here, i just want to say "Thank You!"

Kommentar von Ian Pace am 29.09.2004 um 11:01

Sorry, I do not read/write German. Hope you can read/write English.

This print routine is excellent except for two points:

1. The grid line is missing from the left and top edges;
2. When the grid includes merged cells then the margins fail and the grid is printed from the top left corner of the page.

Is there any chance you can look at correcting these two items?

Regards

Ian Pace

Kommentar von Ralf Mayer am 25.08.2004 um 19:02

Gibt es noch andere Nachrichten außer VP_FORMATRANGE, die man an die MSFlexGrid senden kann?
Leider habe ich unter VC++ keine msflexgrid.h gefunden.
Eigentlich suche ich nur nach einer Möglichkeit, eine fremde Flexgrid auszulesen.

Kommentar von RoDiMa am 12.06.2004 um 16:18

Hallo,
auch ich habe das Problem mit dem Ausdruck von MergeCells.
Die 1. beiden Zeilen sind solche.
Der Druck beginnt ganz links oben.
Ist denn keine Lösung gefunden worden?

Kommentar von Alexander T. am 26.05.2004 um 11:43

Hallo, danke für diesen Tipp. Funktioniert im Prinzip prima. Allerdings wird bei mir die erste Zeile (fixedrow) nicht über der Tabelle gedruckt, sondern schräg versetzt dahinter versteckt.
Hat jemand eine Idee, woran das liegen kann?

Kommentar von Thomas Vögl am 31.07.2003 um 23:06

Habe den Fehler gefunden: ich habe dieses tolle Tool in VBA implementiert. Dort wurde das Printer-Objekt, da VBA selber es nicht hat, über acticveX eingebunden. Bei dieser Einbindung ist ein Fehler unterlaufen!

mfg

Thomas Vögl

Kommentar von Thomas Vögl am 31.07.2003 um 21:53

Habe da noch folgende Frage: Wird die komplette Datenliste des FlexGrids gedruckt, oder nur der sichtbare Bildschirmteil. Ich stehe vor dem Problem, daß es zwar wunderbar druckt, nur verschluckt das Ding die letzten Zeilen, wenn es eine neue Seite beginnen soll! Weiß hier jemand Rat ???

Danke für Eure ANtworten

Thomas

Kommentar von Christian Hahn am 12.05.2003 um 12:15

vielen Dank, das klappt prima.
Meine Nachfrage:
Wie kann ich nur selektierte Zeilen aus dem FlexGrid
ausdrucken lassen?
Ich kann in der Routine nicht feststellen, an welcher
Stelle die Zeilenauswahl bzw. d.ZeilenNummern eingestellt
werden, oder werden hier automatisch immer alle Zeilen
gedruckt?
Dank für Rat, Christian.

Kommentar von Thomas am 23.03.2003 um 14:52

Hat jemand eine Lösung zum Drucken,
wenn man MergeCells ( wird immer am oberen rechten Rand gerdruck) gefunden?

Danke im voraus

Kommentar von Christoph am 28.11.2002 um 21:49

Echt Klasse
Vielen Dank

Kommentar von Mario am 24.10.2002 um 13:21

Um im Querformat drucken zu können setzt man einfach folgende Printer-Eigenschaft:

Printer.Orientation = vbPRORLandscape

Kommentar von Gerd am 03.08.2002 um 17:28

Hallo, hier ist ein Lob auszusprechen.
Der Tip ist gut.
Nur mein Grid ist zu breit wie kann ich, im Querformat drucken.
Gruß gerd

Kommentar von Hans-Peter Sauer am 27.04.2002 um 19:56

Zu 4.) und 6.):
Ich habe genau dasselbe Problem, und ich muß leider einige Zellen in den ersten Zeilen meiner Tabelle verbinden.
Und wenn ich MergeCells 0 setze, sann sitz meine Tabelle auch ganz oben auf 0,0.
Gibt es hier inzwischen irgendein Ergebnis?
Gruß,
Hans-Peter

Kommentar von Annette am 18.02.2002 um 18:19

Hallo
Ich muß sagen ich finde diese Seite einfach Super
Kann mir einer sagen wie man ein Hierachical FlexGrid ausdrucken kann ???
Wurde mir sehr weiter Helfen

Kommentar von Slomoman am 06.02.2002 um 14:42

ginge sowas Ähnliches auch mit dem DataGrid?

Kommentar von Mirko am 03.02.2002 um 21:27

Danke! MSFlexGrid drucken ist ein sehr guter Tipp.
Frage: Wie kann ich Papierformat und Schacht anwählen?
Über CommonDialog, reaigiert nicht. In voraus Dank!

Kommentar von René am 29.12.2001 um 13:35

Und wie kann ich FlexGrid im Querformat ausdrucken?

Kommentar von KnutF am 20.12.2001 um 11:20

FlexGrid im Querformat drucken?

Kommentar von Hansi am 11.04.2001 um 13:44

Zu

Kommentar von Unbekannt am 11.04.2001 um 13:42

Dieses problem umgehe ich, indem ich grundsätzlich bei jeder Eingabe ins Grid ein Leerzeichen anhänge.
grid.Addnew Zahl & " "

Kommentar von Hansi am 11.04.2001 um 13:41

Hallo Freunde,
ich drucke Flexgrid mit Tip Nr. 249 aus.
Das klappt prima, nur wenn ich MergeCells einschalte
wird kein oberer Rand mehr gemacht.
Lustig ist, wenn ich MergeCol nur für einzelne
Spalten setze, werden diese vom oberen Blattrand gedruckt,
die anderen Spalten normal.
Weiß jemand eine Lösung für dieses Problem?
Herzlichen Dank für Eure Mühe.

Kommentar von Wast am 01.03.2001 um 15:14

Hi!
Bei mir passiert es , daß die letzte Zahl einer Zelle nicht gedruckt wird. und zwar immer dann, wenn die Länge der Zahl inklusive Komma ungerade ist. Also z.B.
100 wird zu 10
1000 bleibt 1000 100,55 bleibt 100,55
100,5 wird 100,
das Problem taucht bei verschiedenen Rechnern und Druckern auf.
Betriebssystem W98,
Prog. VB 6(Standard)
Kennt jemand die Lösung ??
Ciao Wast

Kommentar von Armin am 31.01.2001 um 08:20

Wenn ich MergeCells mit flexMergeRestrictColumns(3) aktiviert habe und in den ersten beiden Zeilen MergeRow auf True gesetzt habe dann werden diese beiden Zeilen in den oberen linken Blattrand gedruck, und der Rest des Grids an die Stelle die ich mit tRange festgelegt habe. Ich bin ratlos, kann mir jemand helfen? DANKE

Kommentar von Martin am 22.01.2001 um 16:34

Danke erstmal für den Tip Ich habs versucht, wie du es gesagt hast. Leider Drukt er es dann neben dem Grid aus und. Ich möchte eigentlich, daß es ganz zum schluß kommt, d.h. nach dem Grid.
Danke im voraus

Kommentar von Dirk Lietzow am 23.11.2000 um 10:16

Ja !
Man brauch nur vor dem Printer.EndDoc die Druckanweisungen zu geben. Über den Rückgabewert lReturn kann man sogar herausfinden wieviel Platz noch auf der aktuellen Seite vorhanden ist.

Kommentar von martin am 22.11.2000 um 14:32

Sehr guter TIPP, leider weiß ich nicht wie mann nach dem Grid noch etwas Drucken kann. Gibt es da eine Möglichkeit ???