VB.Net Drucken der Werte aus DGV

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 76 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    VB.Net Drucken der Werte aus DGV

    Hallo,

    ich habe folgendes Problem.
    Ich habe eine Access-Datenbank. Diese wird gefiltert in einem DataGridView angezeigt. Nun möchte ich diese gefilterten Werte ausdrucken, um eine Art Übersichtsdokument zu erstellen.

    Für diesen Druck verwende ich eine Schleife, welches die gefilterten Werte auf das Papier bringt. Jedoch möchte ich es darauf begrenzen, dass ab 20 Datensätzen eine neue Seite angebrochen wird.

    VB.NET-Quellcode

    1. Try
    2. Dim mRow As Integer = 0
    3. Dim newpage As Boolean = True
    4. With Form4.DataDataGridView
    5. Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
    6. fmt.LineAlignment = StringAlignment.Center
    7. fmt.Trimming = StringTrimming.EllipsisCharacter
    8. Dim y As Single = e.MarginBounds.Top + 70
    9. Do While mRow < .RowCount
    10. Dim row As DataGridViewRow = .Rows(mRow)
    11. Dim x As Single = 25
    12. Dim h As Single = 0
    13. For Each cell As DataGridViewCell In row.Cells
    14. Dim rc As RectangleF = New RectangleF(x, y, 75, cell.Size.Height)
    15. e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
    16. If (newpage) Then
    17. e.Graphics.DrawString(Form4.DataDataGridView.Columns(cell.ColumnIndex).HeaderText, fon, Brushes.Black, rc, fmt)
    18. Else
    19. e.Graphics.DrawString(Form4.DataDataGridView.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), fon, Brushes.Black, rc, fmt)
    20. End If
    21. x += rc.Width
    22. h = Math.Max(h, rc.Height)
    23. Next
    24. If newpage Then
    25. newpage = False
    26. Else
    27. mRow += 1
    28. End If
    29. y += h
    30. If y + h > e.MarginBounds.Bottom Then
    31. e.HasMorePages = True
    32. mRow -= 1
    33. newpage = True
    34. Exit Sub
    35. End If
    36. Loop
    37. mRow = 0
    38. End With
    39. Catch ex As Exception
    40. MsgBox(ex.Message)
    41. End Try


    Wie definiere ich, dass eine neue Seite nach exakt 20 Datensätzen angebrochen wird?
    Ich habe dazu im Forum einige Beiträge gefunden, die mir leider nicht weiter geholfen haben.
    Ich weiß nicht was e ist oder was fon ist, aber das ist wohl auch egal. Nur kann man deinen Code so nicht mal nachstellen.
    Was ich sehe ist, dass du die Variable mRow benötigst um aus dem DGV die entsprechende Zeile zu greifen und an DataGridViewRow zu übergeben.
    Daher kannst du mRow nicht an anderen Stellen einfach mal eben auf 0 setzen oder den Zähler zurücksetzen, das gibt ja ein schönes KuddelMuddel.
    Nimm als Zeilenmerker einfach eine neue Variable und zähle die im Do While ... Loop hoch. Wenn du 20 Zeilen ausgegeben hast machst du den Seitenumbruch und setzt diesen Zähler auf 0 zurück.
    mRow muss hochgezählt werden und darf sonst nicht weiter verändert werden. Ob newpage überhaupt benötigt wird weiß ich nicht, ich zweifle es an.

    Nachtrag:
    Was hat dein Post mit Datenbankprogrammierung zu tun? Richtig: gar nichts. Das ist ganz typisch Sonstige Problemstellungen.
    Warum musst du die Werte überhaupt aus dem DGV herausgrabbeln?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Dksksm“ ()

    @Dksksm WHAT :?:
    @uNbRaKe Mache Dich zunächst mit dem Konzept des mehrseitigen Drucks vertraut: Drucken mehrseitiger Dokumente
    Im BeginPrint-Event wird der Zeilenzähler und der Seitenzähler genullt.
    im PrintPage druckst Du alle Zeilen von Zeilenzähler bis Math.Min(Zeilenzähler + 20, Zeilenanzahl).
    Sind alle Zeilen gedruckt, setzt Du e.HasMorePages = False und feddich.
    ELSE
    Sind nicht alle Zeilen gedruckt, setzt Du e.HasMorePages = True und erhöhst Zeilenzähler um 20 und Seitenzähler um 1.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dksksm schrieb:

    So eine Antwort kannst du dir sparen.
    Meine Antwort geht unter dieser zitierten Zeile noch weiter.
    Auch wenn sie nicht explizit an Dich gerichtet ist, bitte ich höflichst, sie trotzdem zu lesen, denn sie hilft Dir, Dich selbst zu verbessern.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @uNbRaKe Es gibt keine Schleife :!: :thumbsup:
    Das passiert alles im PrintPage-Event.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @uNbRaKe Steht doch alles in Post #3.
    Du meinst diese Schleife:
    im PrintPage druckst Du alle Zeilen von Zeilenzähler bis Math.Min(Zeilenzähler + 20, Zeilenanzahl).
    Poste mal die BeginPrint- und die PrintPage-Prozedur.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. ​Dim x1 As Integer = 170
    2. Dim y1 As Integer = 100
    3. Dim xwidth As Integer = 80
    4. Dim yheight As Integer = 20
    5. Dim cellwidth As Integer = 300
    6. Dim cellheight As Integer = 370
    7. Dim fon As New Font(FontFamily.GenericSerif, 8, FontStyle.Regular)
    8. Dim fonHeaderName As New Font("arial", 12, FontStyle.Regular)
    9. Dim fonHeaderNameU As New Font("arial", 12, FontStyle.Underline)
    10. Dim fonHeader As New Font("arial", 10, FontStyle.Regular)
    11. Dim fonHeaderU As New Font("arial", 10, FontStyle.Underline)
    12. e.Graphics.DrawString("Mitarbeiter:", fonHeaderName, Brushes.Black, New Point(30, 30))
    13. e.Graphics.DrawString(Form1.TextBox3.Text, fonHeaderNameU, Brushes.Black, New Point(30, 50))
    14. e.Graphics.DrawString("von:", fonHeader, Brushes.Black, New Point(550, 30))
    15. e.Graphics.DrawString(Form4.TextBox1.Text, fonHeaderU, Brushes.Black, New Point(590, 30))
    16. e.Graphics.DrawString("bis:", fonHeader, Brushes.Black, New Point(670, 30))
    17. e.Graphics.DrawString(Form4.TextBox2.Text, fonHeaderU, Brushes.Black, New Point(700, 30))
    18. e.Graphics.DrawString("Mitarbeiternummer:", fonHeader, Brushes.Black, New Point(30, 100))
    19. e.Graphics.DrawString(Form1.TextBox2.Text, fonHeaderU, Brushes.Black, New Point(30, 120))
    20. e.Graphics.DrawString("Abteilung:", fonHeader, Brushes.Black, New Point(180, 100))
    21. e.Graphics.DrawString(Form1.TextBox4.Text, fonHeaderU, Brushes.Black, New Point(180, 120))
    22. e.Graphics.DrawString("Position:", fonHeader, Brushes.Black, New Point(300, 100))
    23. e.Graphics.DrawString(Form1.TextBox5.Text, fonHeaderU, Brushes.Black, New Point(300, 120))
    24. Try
    25. Dim mRow As Integer = 0
    26. Dim newpage As Boolean = True
    27. With Form4.DataDataGridView
    28. Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
    29. fmt.LineAlignment = StringAlignment.Center
    30. fmt.Trimming = StringTrimming.EllipsisCharacter
    31. Dim y As Single = e.MarginBounds.Top + 70
    32. Do While mRow < .RowCount
    33. Dim row As DataGridViewRow = .Rows(mRow)
    34. Dim x As Single = 25
    35. Dim h As Single = 0
    36. For Each cell As DataGridViewCell In row.Cells
    37. Dim rc As RectangleF = New RectangleF(x, y, 75, cell.Size.Height)
    38. e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
    39. If (newpage) Then
    40. e.Graphics.DrawString(Form4.DataDataGridView.Columns(cell.ColumnIndex).HeaderText, fon, Brushes.Black, rc, fmt)
    41. Else
    42. e.Graphics.DrawString(Form4.DataDataGridView.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), fon, Brushes.Black, rc, fmt)
    43. End If
    44. x += rc.Width
    45. h = Math.Max(h, rc.Height)
    46. Next
    47. If newpage Then
    48. newpage = False
    49. Else
    50. mRow += 1
    51. End If
    52. y += h
    53. If y + h > e.MarginBounds.Bottom Then
    54. e.HasMorePages = True
    55. mRow -= 1
    56. newpage = True
    57. Exit Sub
    58. End If
    59. Loop
    60. mRow = 0
    61. End With
    62. Catch ex As Exception
    63. MsgBox(ex.Message)
    64. End Try


    das ist meine printpage -prozedur. Ich habe einen "Header" und dann die Ausgabe der Datensätze.
    @uNbRaKe Was genau ist der Unterschied zwischen Deinem Code aus Post #1 und Deinem Code aus Post #10?
    Hats Du Dir diesen Link angesehen? Drucken mehrseitiger Dokumente
    Ich denke nicht.
    Hast Du verstanden, wie der in Post #3 beschriebene Ablauf aussieht?
    Ich denke nicht.
    Ich schlage vor, Du erstellst ein neues Testprojekt, in dem Du das, was ich geschrieben habe, umsetzt.
    Das geht ohne DataGridView, es genügt eine InputBox zur Vorgabe der Anzahl der zu druckenden Zeilen und ein String-Array mit den Zeilen-Überschriften.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Da waren aber 2 Prozeduren in Post9 erfragt, und zwar immer mit Prozedurkopf, also Private Sub …
    Do While mRow < .RowCount: nein, das geht eben nicht, weil mRow lokal deklariert ist. Du musst Dir klassenweit merken, bis zu welcher Row schon gedruckt wurde. Aber Moment, ich will bei RfGs Erklärungsversuchen nicht allzu sehr reingrätschen.

    nur vielleicht hier noch
    Form4.DataDataGridView 8|
    MsgBox 8|
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @uNbRaKe Sieh Dir mal diesen Code basierend auf Deinem an:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private LineCount As Integer
    3. Private ActLine As Integer
    4. Private ActPage As Integer
    5. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    6. Me.LineCount = CInt(InputBox("Anzahl der zu druckenden Zeilen eingeben", "Zeilen", "50"))
    7. Using dlg As New PrintPreviewDialog
    8. dlg.Document = Me.PrintDocument1
    9. dlg.ShowDialog()
    10. End Using
    11. End Sub
    12. Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    13. Dim x1 As Integer = 170
    14. Dim y1 As Integer = 100
    15. Dim xwidth As Integer = 80
    16. Dim yheight As Integer = 20
    17. Dim cellwidth As Integer = 300
    18. Dim cellheight As Integer = 370
    19. Dim fon As New Font(FontFamily.GenericSerif, 8, FontStyle.Regular)
    20. Dim fonHeaderName As New Font("arial", 12, FontStyle.Regular)
    21. Dim fonHeaderNameU As New Font("arial", 12, FontStyle.Underline)
    22. Dim fonHeader As New Font("arial", 10, FontStyle.Regular)
    23. Dim fonHeaderU As New Font("arial", 10, FontStyle.Underline)
    24. Me.ActPage += 1
    25. e.Graphics.DrawString(String.Format("Seite {0}", Me.ActPage), fonHeaderName, Brushes.Black, New Point(30, 10))
    26. e.Graphics.DrawString("Mitarbeiter:", fonHeaderName, Brushes.Black, New Point(30, 30))
    27. e.Graphics.DrawString(Me.TextBox3.Text, fonHeaderNameU, Brushes.Black, New Point(30, 50))
    28. e.Graphics.DrawString("von:", fonHeader, Brushes.Black, New Point(550, 30))
    29. e.Graphics.DrawString(Me.TextBox1.Text, fonHeaderU, Brushes.Black, New Point(590, 30))
    30. e.Graphics.DrawString("bis:", fonHeader, Brushes.Black, New Point(670, 30))
    31. e.Graphics.DrawString(Me.TextBox2.Text, fonHeaderU, Brushes.Black, New Point(700, 30))
    32. e.Graphics.DrawString("Mitarbeiternummer:", fonHeader, Brushes.Black, New Point(30, 100))
    33. e.Graphics.DrawString(Me.TextBox2.Text, fonHeaderU, Brushes.Black, New Point(30, 120))
    34. e.Graphics.DrawString("Abteilung:", fonHeader, Brushes.Black, New Point(180, 100))
    35. e.Graphics.DrawString(Me.TextBox4.Text, fonHeaderU, Brushes.Black, New Point(180, 120))
    36. e.Graphics.DrawString("Position:", fonHeader, Brushes.Black, New Point(300, 100))
    37. e.Graphics.DrawString(Me.TextBox5.Text, fonHeaderU, Brushes.Black, New Point(300, 120))
    38. Dim HeaderText() = {"Spalte 1", "Spalte 2", "Spalte 3", "Spalte 4"}
    39. Dim mRow As Integer = 0
    40. Dim newpage As Boolean = True
    41. Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
    42. fmt.LineAlignment = StringAlignment.Center
    43. fmt.Trimming = StringTrimming.EllipsisCharacter
    44. Dim y As Single = e.MarginBounds.Top + 70
    45. Dim cell1 = New Rectangle(0, 0, 60, 30)
    46. Dim x As Single = 25
    47. Dim rc As RectangleF
    48. Dim row As DataGridViewRow = Me.DataDataGridView.Rows(0)
    49. For Each cell As DataGridViewCell In row.Cells
    50. rc = New RectangleF(x, y, 75, cell.Size.Height)
    51. e.Graphics.DrawString(Me.DataDataGridView.Columns(cell.ColumnIndex).HeaderText, fon, Brushes.Black, rc, fmt)
    52. e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
    53. x += rc.Width
    54. Next
    55. Dim h As Single = rc.Height
    56. y += h
    57. For mRow = Me.ActLine To Math.Min(Me.ActLine + 19, Me.LineCount - 1)
    58. 'Dim row As DataGridViewRow = Me.DataDataGridView.Rows(0)
    59. x = 25
    60. For Each cell As DataGridViewCell In row.Cells
    61. rc = New RectangleF(x, y, 75, cell.Size.Height)
    62. e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
    63. 'e.Graphics.DrawString(Me.DataDataGridView.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), fon, Brushes.Black, rc, fmt)
    64. e.Graphics.DrawString((mRow + 1).ToString(), fon, Brushes.Black, rc, fmt)
    65. x += rc.Width
    66. h = Math.Max(h, rc.Height)
    67. Next
    68. y += h
    69. If y + h > e.MarginBounds.Bottom Then
    70. ' Seite voll
    71. e.HasMorePages = True
    72. Exit For
    73. End If
    74. 'e.HasMorePages = False
    75. Next
    76. If mRow < Me.LineCount - 1 Then
    77. e.HasMorePages = True
    78. End If
    79. Me.ActLine = mRow
    80. End Sub
    81. Private Sub PrintDocument1_BeginPrint(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
    82. Me.ActLine = 0
    83. Me.ActPage = 0
    84. End Sub
    85. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Meine Antwort geht unter dieser zitierten Zeile noch weiter.
    Auch wenn sie nicht explizit an Dich gerichtet ist, bitte ich höflichst, sie trotzdem zu lesen, denn sie hilft Dir, Dich selbst zu verbessern.


    Da irrst Du aber, denn ich sehe nicht was an meinen Ausführungen falsch ist und was nicht.
    Mag ja sein, dass es daran liegt, dass ich mich mit dem Drucken an sich noch nie beschäftigt habe. Ich bin nur auf den missbrauchten Zähler nRow eingegangen.
    Trotzdem hilft mir deine blaffende und nichtssagende Antwort nicht weiter, aber kannst dir jetzt auch sparen, denn deine Posts, egal wie gut sie manchmal auch sind, werde ich nicht mehr lesen.
    @RodFromGermany Der code funktioniert super. Danke dafür, jedoch hab ich die Frage, wie ich festlege, dass der die Zeilen automatisch zählt und dementsprechend den Druck anpasst. Bisher ist es ja so, dass man per Eingabe festlegen kann, wie viele Zeilen gedruckt werden.

    Ich habe auf jeden Fall so grob verstanden wie es funktioniert muss es mir aber noch genau ansehen.
    @uNbRaKe das ist die Anzahl der zu druckenden Zeilen in Deinem DGV.
    Und - Sieh Dir mal an, wie in .NET auf Dialoge zugegriffen wird:
    Dialoge: Instanziierung von Forms und Aufruf von Dialogen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    uNbRaKe schrieb:

    mRow beinhaltet die zu druckenden Zeilen oder?
    Vielleicht meinst Du das Richtige, schreibst aber das Falsche. mRow ist der Index von der aktuellen Zeile, die gedruckt werden soll.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.