Discussione chiusa
Visualizzazione dei risultati da 1 a 5 su 5

stampare 3 DataGridView

  1. #1
    minomic non è in linea Scolaretto
    Ciao a tutti,
    in un form del mio programma ci sono tre tabelle (che rappresentano classifiche) e diverse label (che rappresentano titoli). Ho la necessità di stampare tutto questo e devo ovviamente gestire i casi in cui una tabella superi i margini del foglio e debba quindi terminare nella pagina successiva.
    Il codice viene da un (fantastico) articolo scritto da Gandalfrank qui su MasterDrive, io l'ho solo modificato leggermente per gestire la stampa di 3 grid. In particolare ho aggiunto parecchi booleani per controllare lo stato della stampa, ma ci sono ancora problemi, soprattutto quando è la seconda tabella che supera i margini del foglio. Posto il codice (parecchio lungo) sperando che qualcuno voglia darci un'occhiata perchè io a forza di studiarci su non vedo più gli errori
    Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
            Static finito_prima As Boolean = False
            Static finito_seconda As Boolean = False
            Static stampare_prima = True
            Static stampare_seconda = False
            Static stampare_NC = False
            Static prima_volta = True
    
            Dim posX As Integer
            Dim posY As Integer
            Dim rettangolo As Rectangle
            Dim altezza As Integer = RisultatiPrimaDataGridView.RowTemplate.Height   'l'altezza delle righe è uguale nelle tre tabelle
            Dim normalFont As Font = New Font("", 11)
            Dim boldfont As Font = New Font("", 10, FontStyle.Bold)
            Static righeStampate As Integer = 0
            Static pagineStampate As Integer = 0
            Static righe_occupate = 0
            Dim righeTotali As Integer
            Dim righePerPagina As Integer = (e.MarginBounds.Height - 100) / altezza   'e nella seconda pagina?
            Dim nPagine As Integer
            Dim testo As String
    
            If prima_volta = True And stampare_prima = True Then
                'stampo le due righe con denominazione e data della gara
                e.Graphics.DrawString(LabelGara.Text, LabelGara.Font, Brushes.Black, PrintDocument1.DefaultPageSettings.PaperSize.Width / 2 - LabelGara.Width / 2, 35)
                e.Graphics.DrawString(LabelData.Text, LabelData.Font, Brushes.Black, PrintDocument1.DefaultPageSettings.PaperSize.Width / 2 - LabelData.Width / 2, 90)
                'stampo la stringa "classifica 1° categoria"
                e.Graphics.DrawString(categ1.Text, categ1.Font, Brushes.Black, PrintDocument1.DefaultPageSettings.PaperSize.Width / 2 - categ1.Width / 2, 150)
                'prima_volta = False
            End If
    
            If stampare_prima = True Then
                'stampo la prima DataGridView
                If prima_volta = True Then
                    posY = e.MarginBounds.Top + 100
                    'prima_volta = False
                Else
                    posY = e.MarginBounds.Top
                End If
    
                righeTotali = RisultatiPrimaDataGridView.Rows.Count
                If righeTotali Mod righePerPagina > 0 Then
                    nPagine = (righeTotali / righePerPagina) + 1
                Else
                    nPagine = righeTotali / righePerPagina
                End If
    
                posX = (e.MarginBounds.Width - RisultatiPrimaDataGridView.Width) / 2 + e.MarginBounds.Left + 50
    
                For Each colonna As DataGridViewColumn In RisultatiPrimaDataGridView.Columns
                    rettangolo = New Rectangle(posX, posY, colonna.Width, altezza)
                    e.Graphics.DrawRectangle(Pens.Black, rettangolo)
                    e.Graphics.DrawString(colonna.HeaderText, boldfont, Brushes.Black, posX, posY + 2)
                    posX += colonna.Width
                Next
                posY += altezza
    
                For i As Integer = righeStampate To righeStampate + righePerPagina - 2
                    posX = (e.MarginBounds.Width - RisultatiPrimaDataGridView.Width) / 2 + e.MarginBounds.Left + 50
                    If i = righeTotali Then
                        e.HasMorePages = False
                        Exit For
                    End If
    
                    For Each colonna As DataGridViewColumn In RisultatiPrimaDataGridView.Columns
                        'stampo la posizione in classifica:
                        e.Graphics.DrawString(righeStampate + 1, normalFont, Brushes.Black, 50, posY + 2)
    
                        testo = RisultatiPrimaDataGridView.Rows(i).Cells(colonna.Name).Value.ToString
                        rettangolo = New Rectangle(posX, posY, colonna.Width, altezza)
                        e.Graphics.DrawRectangle(Pens.Black, rettangolo)
                        e.Graphics.DrawString(testo, normalFont, Brushes.Black, posX, posY + 2)
                        posX += colonna.Width
                    Next
                    righeStampate += 1
                    righe_occupate += 1
                    posY += altezza
                Next
    
                pagineStampate += 1
    
                If pagineStampate < nPagine Then
                    e.HasMorePages = True
                    prima_volta = False
                    posY = e.MarginBounds.Top
                    righe_occupate = 0
                Else
                    e.HasMorePages = False
                    righeStampate = 0
                    pagineStampate = 0          'giusto?
                    finito_prima = True
                    stampare_prima = False
                    stampare_seconda = True
                    prima_volta = True          'così stampa l'intestazione della seconda categoria
                End If
            End If
    
            If finito_prima = True And stampare_seconda = True Then
                If prima_volta = True Then
                    'stampo "2° categoria"
                    e.Graphics.DrawString(categ2.Text, categ2.Font, Brushes.Black, (PrintDocument1.DefaultPageSettings.PaperSize.Width - categ2.Width) / 2, posY + 50)
                    prima_volta = False
                    'lascio un po' di spazio:
                    posY += 90
                End If
    
                'stampo la seconda grid
                righeStampate = 0
                altezza = RisultatiSecondaDataGridView.RowTemplate.Height
                righeTotali = RisultatiSecondaDataGridView.Rows.Count
                'modifica
                If righeTotali + righe_occupate Mod righePerPagina > 0 Then
                    nPagine = (righeTotali + righe_occupate) / righePerPagina + 1
                Else
                    nPagine = (righeTotali + righe_occupate) / righePerPagina
                End If
    
                posX = (e.MarginBounds.Width - RisultatiSecondaDataGridView.Width) / 2 + e.MarginBounds.Left + 50
    
                For Each colonna As DataGridViewColumn In RisultatiSecondaDataGridView.Columns
                    rettangolo = New Rectangle(posX, posY, colonna.Width, altezza)
                    e.Graphics.DrawRectangle(Pens.Black, rettangolo)
                    e.Graphics.DrawString(colonna.HeaderText, boldfont, Brushes.Black, posX, posY + 2)
                    posX += colonna.Width
                Next
                posY += altezza
    
    
                For i As Integer = righeStampate To righeStampate + righePerPagina - 2 - righe_occupate
                    posX = (e.MarginBounds.Width - RisultatiSecondaDataGridView.Width) / 2 + e.MarginBounds.Left + 50
                    If i = righeTotali Then
                        e.HasMorePages = False
                        Exit For
                    End If
    
                    For Each colonna As DataGridViewColumn In RisultatiSecondaDataGridView.Columns
                        'stampo la posizione in classifica:
                        e.Graphics.DrawString(righeStampate + 1, normalFont, Brushes.Black, 50, posY + 2)
    
                        testo = RisultatiSecondaDataGridView.Rows(i).Cells(colonna.Name).Value.ToString
                        rettangolo = New Rectangle(posX, posY, colonna.Width, altezza)
                        e.Graphics.DrawRectangle(Pens.Black, rettangolo)
                        e.Graphics.DrawString(testo, normalFont, Brushes.Black, posX, posY + 2)
                        posX += colonna.Width
                    Next
                    righeStampate += 1
                    posY += altezza
                Next
    
                pagineStampate += 1
    
                If pagineStampate < nPagine Then
                    e.HasMorePages = True
                    posY = e.MarginBounds.Top
                    righe_occupate = 0          'dovrebbe essere giusto...
                Else
                    e.HasMorePages = False
                    righeStampate = 0
                    pagineStampate = 0
                    finito_seconda = True
                    stampare_seconda = False
                    stampare_NC = True
                    prima_volta = True
                End If
    
            End If
    
            If finito_prima = True And finito_seconda = True And stampare_NC = True And prima_volta = True Then
    
                'stampo "categoria NC"
                e.Graphics.DrawString(categ3.Text, categ3.Font, Brushes.Black, (PrintDocument1.DefaultPageSettings.PaperSize.Width - categ3.Width) / 2, posY + 50)
                prima_volta = False
                'lascio un po' di spazio:
                posY += 90
    
                'stampo la terza grid
                righeStampate = 0
                altezza = RisultatiNCDataGridView.RowTemplate.Height
                righeTotali = RisultatiNCDataGridView.Rows.Count
                posX = (e.MarginBounds.Width - RisultatiNCDataGridView.Width) / 2 + e.MarginBounds.Left + 50
    
                For Each colonna As DataGridViewColumn In RisultatiNCDataGridView.Columns
                    rettangolo = New Rectangle(posX, posY, colonna.Width, altezza)
                    e.Graphics.DrawRectangle(Pens.Black, rettangolo)
                    e.Graphics.DrawString(colonna.HeaderText, boldfont, Brushes.Black, posX, posY + 2)
                    posX += colonna.Width
                Next
                posY += altezza
    
    
                For i As Integer = righeStampate To righeStampate + righePerPagina - 2
                    posX = (e.MarginBounds.Width - RisultatiNCDataGridView.Width) / 2 + e.MarginBounds.Left + 50
                    If i = righeTotali Then
                        e.HasMorePages = False
                        Exit For
                    End If
    
                    For Each colonna As DataGridViewColumn In RisultatiNCDataGridView.Columns
                        'stampo la posizione in classifica:
                        e.Graphics.DrawString(righeStampate + 1, normalFont, Brushes.Black, 50, posY + 2)
    
                        testo = RisultatiNCDataGridView.Rows(i).Cells(colonna.Name).Value.ToString
                        rettangolo = New Rectangle(posX, posY, colonna.Width, altezza)
                        e.Graphics.DrawRectangle(Pens.Black, rettangolo)
                        e.Graphics.DrawString(testo, normalFont, Brushes.Black, posX, posY + 2)
                        posX += colonna.Width
                    Next
                    righeStampate += 1
                    posY += altezza
                Next
    
                pagineStampate += 1
    
                If pagineStampate < nPagine Then
                    e.HasMorePages = True
                    posY = e.MarginBounds.Top
                Else
                    e.HasMorePages = False
                    righeStampate = 0
                    pagineStampate = 0
                End If
    
            End If
    
        End Sub
    

  2. #2
    L'avatar di sistemista
    sistemista non è in linea Topo di biblioteca
    Di quali errori parli?non hai dato indicazioni di sorta per il tipo di errore.
    ℹ️ Leggi di più su sistemista ...

  3. #3
    minomic non è in linea Scolaretto
    Quote Originariamente inviato da sistemista Visualizza il messaggio
    Di quali errori parli?non hai dato indicazioni di sorta per il tipo di errore.
    sì in effetti non ho spiegato bene: i problemi succedono quando la seconda tabella supera i margini del foglio. A questo punto la prima pagina (con la prima tabella e l'inizio della seconda) viene stampata correttamente, nella seconda pagina viene ristampata dall'inizio la seconda tabella, nella terza pagina viene ristampata nuovamente dall'inizio la seconda tabella e poi la terza. Per finire, l'ultima pagina viene stampata vuota. Evidentemente c'è un problema con il conteggio delle pagine da stampare... Ho provato a correggere da solo il codice ma forse l'ho studiato troppo e non riesco più a capire dove sono gli errori. Spero in un paio di occhi freschi
    Grazie!

  4. #4
    minomic non è in linea Scolaretto
    Ciao,
    vorrei dire che penso di avere risolto i miei problemi. Erano come previsto legati a un'errata gestione dei salti di pagina. Appena ho un po' di tempo cerco di ripulire il codice per renderlo più leggibile e poi se interessa a qualcuno lo posto.
    Ringrazio comunque tutti, soprattutto Gandalfrank che ha scritto l'articolo dal quale ho poi preso la base del codice.
    Mi permetto di dare un suggerimento (non sono un esperto quindi prendetelo per quello che vale): nell'articolo originale il controllo sui salti di pagina viene fatto calcolando all'inizio quante pagine occuperà la nostra tabella e poi incrementando un contatore di pagine che viene confrontato con il numero totale di pagine da stampare. Se si tratta di una sola tabella non ci sono problemi, ma se le tabelle sono più di una credo che possa diventare scomodo anche perchè magari la seconda tabella inizia da metà pagina e quindi risulta un po' più difficile prevedere quante pagine occuperà. Ho risolto così: alla fine di ogni pagina confrontavo righe_stampate con righe_totali e se c'erano ancora righe da stampare allora e.HasMorePages = true, e si ricomincia. Credo che un ulteriore miglioramento potrebbe essere quello di ragionare su posY, cioè l'ordinata alla quale si stampa, in questo modo si evitano i possibili problemi introdotti da eventuali titoli, che "ruberebbero" spazio ad alcune righe della DataGridView ma dei quali sarebbe difficile tenere conto in fase di conteggio delle pagine da stampare.
    Grazie ancora a tutti!

  5. #5
    alip ... forse non hai capito bene ... ti abbiamo detto che NON devi scrivere in thread così vecchi (9 anni fa!), fra l'altro rivolgendoti a utenti che non frequentano il forum da anni.

    Anche questo thread viene chiuso. Se vìoli nuovamente il regolamento potresti incorrere in un ban.
    ℹ️ Leggi di più su AntonioG ...

Discussione chiusa

Potrebbero interessarti anche ...

  1. stampare più DataGridView
    Da minomic nel forum Visual Basic .Net
    Risposte: 2
    Ultimo Post: 05-04-2013, 19:08
  2. Risolto: Stampare una DataGridView
    Da Boolean nel forum Visual Basic .Net
    Risposte: 4
    Ultimo Post: 16-07-2010, 23:10
  3. Stampare un Datagridview
    Da Maury63 nel forum Visual Basic .Net
    Risposte: 3
    Ultimo Post: 19-04-2010, 18:40
  4. Stampare DataGridView su più Pagine
    Da Gandalfrank nel forum Visual Basic .Net
    Risposte: 8
    Ultimo Post: 23-09-2008, 21:14
  5. Stampare un datagridview
    Da alex__ice nel forum Visual Basic .Net
    Risposte: 2
    Ultimo Post: 30-06-2008, 21:07