Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Silvex M

Como imprimir em 2 ou mais páginas?

Mensagens Recomendadas

Silvex M

Boas, estou bloqueado aqui numa situação que não consigo resolver por não querer mudar o código......isto é,

consigo imprimir (para ecrã) tudo direitinho mas apenas numa página, mas.......as linhas vão acumulando e não passam para a segunda página, analisando o código a seguir, pergunto se existe hipótese de aproveitar o meu código para imprimir em mais páginas conforme o número de linhas?

Private Sub RelatorioInfo()
Dim printIt As New PrintDocument
Dim printPreview As New PrintPreviewDialog
printPreview.Document = printIt
AddHandler printIt.PrintPage, AddressOf printIt_PrintPage
printPreview.ShowDialog()
End Sub
Private Sub printIt_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
Dim i, x As Integer
Dim item As ListViewItem
x = 0
Dim rect As New Rectangle(25, 235, 775, 880)
Dim rectcab As New Rectangle(25, 40, 775, 85)
e.Graphics.DrawRectangle(Pens.Gray, rectcab)
e.Graphics.DrawRectangle(Pens.Gray, rect)
e.Graphics.DrawString("Nome ", New Font("Verdana", 12, FontStyle.Bold), Brushes.Black, 35, 200)
e.Graphics.DrawString("Movimento ", New Font("Verdana", 12, FontStyle.Bold), Brushes.Black, 130, 200)
e.Graphics.DrawString("Destino ", New Font("Verdana", 12, FontStyle.Bold), Brushes.Black, 280, 200)
e.Graphics.DrawString("Credito ", New Font("Verdana", 12, FontStyle.Bold), Brushes.Black, 420, 200)
e.Graphics.DrawString("Debito ", New Font("Verdana", 12, FontStyle.Bold), Brushes.Black, 560, 200)
e.Graphics.DrawString("Data ", New Font("Verdana", 12, FontStyle.Bold), Brushes.Black, 710, 200)
e.Graphics.DrawString("GESTÃO FINANCEIRA", New Font("Verdana", 17, FontStyle.Bold), Brushes.Black, 205, 70)
For i = 0 To LV1.Items.Count - 1
item = LV1.Items(i)
If Not String.IsNullOrEmpty(item.SubItems(1).Text) Then
e.Graphics.DrawString(item.SubItems(1).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 35, 250 + (x * 20))
e.Graphics.DrawString(item.SubItems(2).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 130, 250 + (x * 20))
e.Graphics.DrawString(item.SubItems(3).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 280, 250 + (x * 20))
e.Graphics.DrawString(item.SubItems(4).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 460, 250 + (x * 20))
e.Graphics.DrawString(item.SubItems(5).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 600, 250 + (x * 20))
e.Graphics.DrawString(item.SubItems(6).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 710, 250 + (x * 20))
x = x + 1
End If
Next
Dim User As System.Security.Principal.WindowsIdentity
User = System.Security.Principal.WindowsIdentity.GetCurrent()
e.Graphics.DrawString(Date.Now, New Font("Verdana", 10, FontStyle.Regular), Brushes.Black, 642, 130)
e.Graphics.DrawString("Financiado: " & lblDebito.Text, New Font("Verdana", 10, FontStyle.Regular), Brushes.Black, 30, 130)
e.Graphics.DrawString("Amortizado: " & lblCredito.Text, New Font("Verdana", 10, FontStyle.Regular), Brushes.Black, 30, 150)

End Sub

Private Sub btnImprimir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImprimir.Click
RelatorioInfo()
End Sub

Alguma ajuda por favor?

Cumps

Silva

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Silvex M

Cerzedelo, entendi mais ou menos o assunto...mas como o código está diferente do meu agora baralhei-me todo..... :(

A minha dúvida é, se imprimo através da listview porque tenho de abrir ligação à BD para imprimir mais do que uma página? a conecção é para fazer a contagem de linhas a imprimir?

basicamente vou ter de alterar o meu código certo? ...desculpa pelas dúvidas mas já tenho os meus fusíveis a ferver!!

Pensei que fosse algo mais fácil tipo:

dim linhasPorPagina As Single = 30

If linhasPorPagina > 30 then

e.HasMorePages = True

end if

mas estou ciente que vais ser muito mais trabalhoso, ou então terei de alterar todo o meu código para conseguir isto!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cerzedelo

Mas o vb não adivinha quantas linhas já imprimiu, para isso tem de possuir um contador. No exemplo que lhe dei repare no ciclo while e na condiçao if seguinte.

No exemplo que apresentou já possuiu um contador a variavel item e o número total de linhas o lv.items.count . O que tera de fazer e que quando a variavel for maior ao número de linhas que pretende por pagina (30), o vb faz o HasMorePage.

Editado por Cerzedelo
  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Silvex M

Tenho esta solução que faz a contagem de linhas do ListView mas quando o executo o número de páginas a imprimir não pára.....o que está errado aqui?

Dim Nlinhas As String = LV1.Items.Count

Dim LinhasPorPagina As String = 30

MsgBox("Número de linhas do ListView: " & Nlinhas, vbInformation)


If (Nlinhas > LinhasPorPagina) Then

e.HasMorePages = True

Else

e.HasMorePages = False

End If

Help....Cerzedelo! :)

Editado por apocsantos
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
FreiNando

Não é dessa forma...

O procedimento PrintPage imprime uma página de cada vez que é chamado, e caso seja marcada a propriedade HasMorePages, será chamado a executar mais uma vez.

Tens de verificar a posição que fica cada linha até chegar ao fundo da página ou ao fim da lista.

Se o espaço de cada linha é fixo, então tens um número fixo de linhas por página, no teu exemplo 30.

Por isso tens de guardar numa variável (externa ao procedimento) a linha do LV1 que estás a imprimir e em outra variável guardar o número da linha na página actual.

No inicio do procedimento a variável com o número de linha da página é zerada (=0), mas a variavel que indica a linha de LV1 a ser impressa continua o valor anterior.

O procedimento deve conter um ciclo para imprimir as 30 linhas por página.

Antes do ciclo é impresso o cabeçalho, e depois do ciclo o rodapé. São opcionais...

Dentro cesse ciclo, é impressa uma linha e as duas variáveis são incrementadas e verificados os limites: quando for atingida a ultima linha de LV1, o procedimento sai com HasMorePages=False, e se o número de linha da página chegar a 30, o procedimento termina com HasMorePages=True para que possa reiniciar.

Opcionalmente pode ter uma terceira variável para guardar o número de página....


O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cerzedelo

A resposta do FreiNando está correcta. Repare no exemplo que dei, a linha actual assume inicialmente o valor 0 e depois no ciclo While e incrementada em 1, por cada vez que o ciclo e efetuado e e acrescentada uma linha. E já fora do ciclo e feita a comparação entre o número de linhas imprimidas e o número de linhas por pagina e activada ou não a propriedade HasMorePages.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Silvex M

Bom dia amigos,

Antes de tudo agradeço imenso a explicação dada por vós, mais clara é impossível e lido parece mais fácil do que feito......eu quero implementar essa lógica mas utilizando o meu código (usando contagem de linhas do listview) mas para isso tenho que definir a posição da primeira linha sendo esta:

e.Graphics.DrawString(item.SubItems(1).Text, New Font("Verdana", 9, FontStyle.Regular), Brushes.Black, 35, 250+(x *20))

Estando a primeira linha na posição 250 a última seria na posição 950, como crio as variáveis?

Editado por Silvex M

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
jmsmoreira

'Verifica se a linha actual vai caber dentro da página
	 If CellTopPos + DataGridView1.Rows(Row).Cells(0).Size.Height + 10 > 800 Then
		 imp_fila = Row
		 e.HasMorePages = True
		 Return
	 Else
		 e.HasMorePages = False
	 End If

Eu uso este código para imprimir as filas de uma datagridview... Podes adaptar ao teu e colocar antes de começares com os comandos drawstring...

Editado por apocsantos
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Silvex M

Agradeço desde já as dicas jmsmoreira, Cerzedelo e FreiNando.....estou a tentar entender, então aqui vai:

Dim PosPrimeiraLinha As Integer = (como colocar aqui a posição da linha sabendo que é 250?)

If PosPrimeiraLinha + LV1.Items.count.Size.height + 10 > 950 Then (+ 10 é relativo a quê?)

....imprime comandos drawstring

e.HasMorePages = True

Return

Else

e.HasMorePages = False

End If

Eu esforço-me bastante para entender, não tenho qualquer formação/ curso de programação já fiz algumas aplicações mas nunca me surgiu ter de imprimir, isto está-me a passar completamente ao lado, e fico fustrado porque vejo que me tentam ajudar e eu não consigo seguir.... os exemplos que colocam são diferentes do meu código e faltam-me as bases do vb.net para entender.

Consigo entender o que o FreiNando disse perfeitamente e está bem claro, mas conseguir fazê-lo!!!!

Agradeço qualquer ajuda (mas tb críticas),

Saudações,

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
FreiNando

Deixo um exemplo para impressão de uma lista de registos de uma base de dados. É só adaptar ...

   '============================================================
   'Impressão da lista de registos
   '============================================================
   Private PR() As Integer = {} 'Lista de Ids dos registos a imprimir
   Private Sub ImprimirLista()
    'SELECIONAR PRINTER
    Dim PRT = New PrintPreviewDialog
    Dim docPRT As New PrintDocument
    PRT.Document = docPRT
    docPRT.DocumentName = "Lista de Obras"
    docPRT.DefaultPageSettings.Landscape = True
    With docPRT.DefaultPageSettings.Margins
	    .Left = 40 '1.0cm
	    .Top = 60 '1.5cm
	    .Bottom = 40 ' 1.0cm
	    .Right = 40 '1.0cm
    End With
    AddHandler docPRT.PrintPage, AddressOf Me.docPRT_PrintPage
    'Criar a lista
    PreparaPrintLista()
    PRT.ShowDialog()
    'Limpar a lista ao fechar o formulário de impressão
    PR = Nothing
   End Sub

   Private Sub docPRT_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs)
    Static Dim P As Integer = 1 ' Número da Página
    Static Dim K As Integer = 0 ' Numero do Item da Lista
    'Medidas da Folha
    Dim mL As Integer, mR As Integer, mT As Integer, mB As Integer
    mL = e.PageSettings.Margins.Left
    mR = e.PageSettings.Margins.Right
    mT = e.PageSettings.Margins.Top
    mB = e.PageSettings.Margins.Bottom
    Dim W As Long = e.PageSettings.PaperSize.Height
    Dim H As Long = e.PageSettings.PaperSize.Width
    Dim tPos As Integer = mT, tPos1 As Integer
    Dim Z() As String, I As Integer = 0, D As Date

    Dim Pb As Pen = New Pen(Color.Black, 0.1) 'para usar nas linhas
    Dim B As New SolidBrush(Color.Black)
    Dim G As New SolidBrush(Color.Gray)
    Dim fSmall As Font = New Font("Tahoma", 8)
    Dim fSmB As Font = New Font("Tahoma", 8, FontStyle.Bold)
    Dim fText As Font = New Font("Tahoma", 9)
    Dim fHead As Font = New Font("Tahoma", 10)
    Dim sSize As New SizeF
    Dim S As String = ""
    If P = 1 Then
	    'Cabeçalho da primeira página
	    S = "LISTA DE ...."
	    sSize = e.Graphics.MeasureString(S, fHead)
	    e.Graphics.DrawString(S, fHead, B, (W - sSize.Width) / 2, tPos)
	    tPos = tPos + 30
	    S = "Data: " & Now.ToString("dd-MM-yyyy HH:mm")
	    e.Graphics.DrawString(S, fText, B, mL, tPos)
	    S = "Página " & P.ToString("0")
	    sSize = e.Graphics.MeasureString(S, fSmall)
	    e.Graphics.DrawString(S, fSmall, B, W - sSize.Width - mR, tPos)
	    'adicionar outras imformações no cabeçalho da primeira página
	    tPos = tPos + 15
    Else
	    'cabeçalho das páginas seguintes
	    'Titulo
	    S = "LISTA DE ...."
	    sSize = e.Graphics.MeasureString(S, fText)
	    e.Graphics.DrawString(S, fText, B, (W - sSize.Width) / 2, tPos)
	    S = "Página " & P.ToString("0")
	    sSize = e.Graphics.MeasureString(S, fSmall)
	    e.Graphics.DrawString(S, fSmall, B, W - sSize.Width - mR, tPos)
	    tPos = tPos + 25
    End If

    'Cabeçalho da listagem
    e.Graphics.DrawString("Nr.", fSmB, B, mL + 3, tPos)
    e.Graphics.DrawString("Data", fSmB, B, mL + 50, tPos)
    e.Graphics.DrawString("Descrição", fSmB, B, mL + 130, tPos)
    ' e etc....
    tPos = tPos + 15
    'Imprimir Linhas da lista
    Do Until tPos > (H - mB - 15) Or K > PR.GetUpperBound(0) '15 é o espaço do rodapé.
	    'linha horizontal da lista. OPCIONAL
	    e.Graphics.DrawLine(Pb, mL, tPos, W - mR, tPos)
	    tPos = tPos + 3
	    S = PR(K).ToString("#") ' ID ou outra informação
	    e.Graphics.DrawString(S, fText, B, mL + 3, tPos)
	    D = DataRegisto(PR(K)) 'Obter a data deste registo
	    e.Graphics.DrawString(D.ToString("dd-MM-yyyy"), fText, B, mL + 50, tPos)
	    S = DescricaoRegisto(PR(K)) 'Obter a descrição deste registo
	    e.Graphics.DrawString(S, fText, B, mL + 50, tPos)
	    'etc
	    'Linha seguinte
	    tPos = tPos1 + 3
	    K = K + 1
    Loop
    'Linha final
    e.Graphics.DrawLine(Pb, mL, tPos, W - mR, tPos)
    tPos = tPos1 + 15
    ' e rodapé  ....
    'fim da lista
    If K < PR.Length Then
	    P = P + 1
	    e.HasMorePages = True
    Else
	    e.HasMorePages = False
	    K = 0
	    P = 1
    End If
   End Sub

   Private Sub PreparaPrintLista()
    'Lista
    Dim C As Integer = 0
    Dim K As Integer = 0
    Dim S As String =  ' FiltroListagem()
    '  dbCon é uma coneção à base de dados já aberta!
    Dim cmd As New OleDbCommand("SELECT COUNT(*) FROM TABELA WHERE " & S, dbCon)
    Dim drt As OleDbDataReader = cmd.ExecuteReader
    If drt.HasRows Then
	    drt.Read()
	    C = Val(drt(0).ToString)
    Else
	    C = 0
    End If
    drt.Close()
    ReDim PR(C - 1)
    If C > 0 Then
	    cmd.CommandText = "SELECT * FROM TABELA WHERE " & S & " ORDER BY Data"
	    drt = cmd.ExecuteReader
	    While drt.Read()
		    PR(K) = Val(drt("ID").ToString)
		    K = K + 1
	    End While
	    drt.Close()
    End If
   End Sub

Editado por FreiNando

O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cefeu

Bom dia.

Sou também novo em tentar programar e sigo atentamente a descrição para imprimir.

Adaptei a informação do FreiNando. Funciona até ao printPreview...mostrando as folhas a imprimir, mas quando se pretende imprimir só faz o cabeçalho e última linha (drawline.).

Aonde poderá estar o erro?

Obrigado pela ajuda, será sempre benvinda

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.