segunda-feira, 27 de maio de 2019
DVD
ConteÚdo
DOWNLOADS
Interação
dicas aleatórias
Artigos

Compartilhe seus relatórios usando arquivos PDF

Quem desenvolve em Access certamente já se deparou com um problema bastante comum: exportar relatórios para enviar por e-mail ou mesmo para salvar em disquete. Como fazer isso de modo prático e eficiente?

Por: Andréa de Carvalho Tikhomiroff (andrea@ativoaccess.com.br)
Publicado: 26/04/2006  Visitas: 9532
Dificuldade: Avançado

Indicação de Artigo  Imprimir

Introdução

Quem desenvolve em Access certamente já se deparou com um problema bastante comum: exportar relatórios para enviar por e-mail ou mesmo para salvar em disquete. Como fazer isso de modo prático e eficiente?

A exportação do Access para o Word, que é o caminho naturalmente buscado por todos, não é de todo funcional. E por que não? Porque ao exportar para o Word, os relatórios perdem boa parte de sua formatação. As imagens (como logotipos, por exemplo) também não são exportadas.

O Access possui um formato de exportação que atende a esses requisitos, o SNP. Esse formato deve ser aberto com o Snapshot Viewer, programa que normalmente é instalado junto com o Office e que pode ser baixado gratuitamente da Web por quem não o possui. No entanto, por não ser um formato muito utilizado, quem não o possui não se interessa também em baixá-lo.

O que fazer então? De que maneira podemos exportar os relatórios do Access, sem perder a formatação, e de forma que todos possam ver, sem exigir que instalem um novo aplicativo? A resposta é simples: exportar para PDF. É aberto pelo Acrobat Reader, que também é um aplicativo gratuito, facilmente baixado da Web. Mas com uma grande vantagem sobre o Snapshot: o PDF é um tipo de arquivo muito popular, difundido principalmente pela Internet. Certamente todos já tiveram contato com algum desses arquivos, não é?


Antes de começar

Antes de começarmos a preparar um banco de dados para exportar relatórios para PDF, é necessário baixar da Internet um aplicativo que permite essa ação. Nesse exemplo, irei utilizar o PDF995, software shareware cuja única limitação é a exibição de propagandas, que podem ser retiradas ao registrar o produto. Acessando a página http://www.pdf995.com/download.html você encontrará quatro softwares disponíveis:

- Pdf995 Printer Driver
- Free Converter
- pdfEdit995
- Signature995

Os dois primeiros são fundamentais para gerar o pdf, portanto deverão ser baixados e instalados em seu computador. Deverão, também, fazer parte do seu pacote de instalação se for distribuir seu aplicativo. Os outros dois não há necessidade de baixar neste momento, apenas se quiser manipular os arquivos pdf depois de gerados.


O banco de dados de exemplo

Para implementar o PDF você pode usar qualquer banco de dados que tenha em seu computador. O que criei tem apenas uma tabela (tblCliente) com os campos IDCliente e NomeCliente e um relatório (rptCliente) criado com base nela. Criei o exemplo usando Access 2000 por um motivo bastante simples: na página do PDF995 existe uma observação informando não ser possível criar o PDF diretamente de um relatório do Access 2000, a menos que ele esteja aberto em modo estrutura, fazendo a mudança da impressora padrão, salvando e abrindo o relatório novamente. Nada funcional, não é? E, realmente, para mim, não adiantaria de nada. Tenho um sistema na empresa em que trabalho, funcionando em rede. Como poderia pedir para os usuários fazerem essa operação em um mde? Sem chance...

Mas, como não desisto facilmente, continuei buscando uma solução. E encontrei, entre os inúmeros exemplos que vivo baixando para estudar. Adaptei um ao outro e tudo funcionou redondinho!


Os módulos

Existem alguns módulos que deverão fazer parte do seu sistema, para que ele funcione corretamente.
basGlobal: contém as variáveis globais necessárias para o funcionamento do sistema como um todo.


Option Compare Database
Option Explicit

Global strCaminhoSalvar As String
Global strNomeReport As String
Global strNomeImpressora As String
Global strDriverImpressora As String
Global strPortaImpressora As String
Global strCriterio As String


basGeraPDF: código fornecido pelo fabricante do PDF995. Existem linhas que devem ser comentadas para o uso no Access 2000 ou anterior, como poderão verificar.


Option Compare Database
Option Explicit

'Read INI settings
Declare Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, ByVal lpDefault As String, _
ByVal lpReturnedString As String, ByVal nSize As Long, _
ByVal lpFileName As String) As Long

'Write settings
Declare Function WritePrivateProfileString Lib "kernel32" Alias _
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, ByVal lpString As Any, _
ByVal lpFileName As String) As Long

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub pdfwrite(reportname As String, destpath As String, Optional strcriteria As String)

' Runs an Access report to PDF995 to create a pdf file from the report.
' Input parameters are the name of the report within the current database,
' the path for the output file, and an optional criteria for the report

' Be sure to check that the "Generating PDF CS" setting in pdfsync.ini is set to 0
' when pdf995 is idle. This codes uses that as a completion flag as it seems to be
' the most reliable indication that PDF995 is done writing the pdf file.

' Note: The application.printer object is not valid in Access 2000
' and earlier. In that case, set the printer in the report to pdf995
' and comment out the references herein to the application.printer

Dim syncfile As String, maxwaittime As Long
Dim iniFileName As String ', tmpPrinter As Printer
Dim outputfile As String, x As Long
Dim tmpoutputfile As String, tmpAutoLaunch As String

' set the location of the PDF995.ini and the pdfsync files
iniFileName = "c:\pdf995\res\pdf995.ini"
syncfile = "c:\pdf995\res\pdfsync.ini"

' build the output file name from the path parameter and the report name

'ALTERADO

'If Mid(destpath, Len(destpath), 1) <> "\" Then destpath = destpath & "\"
'outputfile = destpath & reportname & ".pdf"
outputfile = destpath

' PDF995 operates asynchronously. We need to determine when it is done so we can
' continue. This is done by creating a file and having PDF995 delete it using the
' ProcessPDF parameter in its ini file which runs a command when it is complete.

' save current settings from the PDF995.ini file
tmpoutputfile = ReadINIfile("PARAMETERS", "Output File", iniFileName)
tmpAutoLaunch = ReadINIfile("PARAMETERS", "Autolaunch", iniFileName)

' remove previous pdf if it exists
On Error Resume Next
Kill outputfile
On Error GoTo Cleanup

' setup new values in PDF995.ini
x = WritePrivateProfileString("PARAMETERS", "Output File", outputfile, iniFileName)
x = WritePrivateProfileString("PARAMETERS", "AutoLaunch", "0", iniFileName)

' change the default printer to PDF995
' if running on Access 2000 or earlier, comment out the next two lines
'Set tmpPrinter = Application.Printer
'Application.Printer = Application.Printers("PDF995")

'print the report
DoCmd.OpenReport reportname, acViewNormal, , strcriteria

' cleanup delay to allow PDF995 to finish up. When flagfile is nolonger present, PDF995 is done.
Sleep (10000)
maxwaittime = 300000 'If pdf995 isn't done in 5 min, quit anyway
Do While ReadINIfile("PARAMETERS", "Generating PDF CS", syncfile) = "1" And maxwaittime > 0
Sleep (10000)
maxwaittime = maxwaittime - 10000
Loop

' restore the original default printer and the PDF995.ini settings
Cleanup:
Sleep (10000)

x = WritePrivateProfileString("PARAMETERS", "Output File", tmpoutputfile, iniFileName)
x = WritePrivateProfileString("PARAMETERS", "AutoLaunch", tmpAutoLaunch, iniFileName)
x = WritePrivateProfileString("PARAMETERS", "Launch", "", iniFileName)

On Error Resume Next

' if running on Access 2000 or earlier, comment out the next line
'Application.Printer = tmpPrinter

End Sub

Function ReadINIfile(sSection As String, sEntry As String, sFilename As String) As String
Dim x As Long
Dim sDefault As String
Dim sRetBuf As String, iLenBuf As Integer
Dim sValue As String

'Six arguments
'Explanation of arguments:
'sSection: ini file section (always between brackets)
'sEntry : word on left side of "=" sign
'sDefault$: value returned if function is unsuccessful
'sRetBuf$ : the value you're looking for will be copied to this buffer string
'iLenBuf% : Length in characters of the buffer string
'sFileName: Path to the ini file

sDefault$ = ""
sRetBuf$ = String$(256, 0) '256 null characters
iLenBuf% = Len(sRetBuf$)
x = GetPrivateProfileString(sSection, sEntry, _
sDefault$, sRetBuf$, iLenBuf%, sFilename)
ReadINIfile = Left$(sRetBuf$, x)

End Function


basArquivoINI: esse e os próximos módulos foram criados por Ken Getz e Paul Litwin, e permitem a manipulação da impressora padrão do Windows no Access 2000 ou anterior.


Option Compare Database
Option Explicit

' Code from:
' Microsoft Access 95 How-To
' (c) 1998 Ken Getz and Paul Litwin
' All rights reserved.

' You may only use this code as part of an application
' that requires its use. You must including this
' notice intact. You may not distribute the code
' as your own work, nor can you distribute the
' code on its own.

' Module to be used for reading and writing from/to INI files.
' Most of this should be superceded by reading/writing
' from/to the registry under Win95 and Windows NT.

Const MAX_SIZE = 255
Const MAX_SECTION = 2048

' These functions have interfaces defined in this module.
Declare Function aht_apiGetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileInt" (ByVal strAppName As String, ByVal strKeyName As String, ByVal intDefault As Integer, ByVal strFileName As String) As Integer

Declare Function aht_apiGetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal strAppName As String, ByVal strKeyName As String, ByVal strDefault As String, ByVal strReturned As String, ByVal lngSize As Long, ByVal strFileName As String) As Long

Declare Function aht_apiGetProfileString Lib "kernel32" Alias "GetProfileStringA" (ByVal strAppName As String, ByVal strKeyName As String, ByVal strDefault As String, ByVal strReturned As String, ByVal lngSize As Long) As Long

Declare Function aht_apiGetProfileInt Lib "kernel32" Alias "GetProfileInt" (ByVal strAppName As String, ByVal strKeyName As String, ByVal intDefault As Integer) As Integer

Declare Function aht_apiGetProfileSection Lib "kernel32" Alias "GetProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long) As Long

Declare Function aht_apiGetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

' Call these functions directly, since they're so simple.
' They return 0 on failure, and a non-zero value on success.

Declare Function aht_apiWritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal strAppName As String, ByVal strKeyName As String, ByVal strValue As String, ByVal strFileName As String) As Integer

Declare Function aht_apiWriteProfileString Lib "kernel32" Alias "WriteProfileStringA" (ByVal strAppName As String, ByVal strKeyName As String, ByVal strValue As String) As Integer

Function ahtGetINIInt(ByVal strGroup As String, ByVal strItem As String) As Variant

' Get an integer value from WIN.INI.
' Return either the integer value, or -1 if there's no match.
' (Therefore, this function won't help if you need to find a value that
' might be -1!)
'
'
' ? ahtGetINIInt("Windows", "CursorBlinkRate")
' 530

ahtGetINIInt = aht_apiGetProfileInt(strGroup, strItem, -1)
End Function

Function ahtGetINIString(ByVal strGroup As String, ByVal strItem As String) As Variant
' Get a string value from the WIN.INI file. For example,
' the following, in the Immediate Window:
' ? ahtGetINIString("Windows", "Device")
'
' might display:
'
' HP LaserJet 4,HPPCL5E,LPT1:
'
Dim intChars As Integer
Dim strBuffer As String

strBuffer = String(MAX_SIZE, 0)
intChars = aht_apiGetProfileString(strGroup, strItem, "", strBuffer, MAX_SIZE)
ahtGetINIString = Left(strBuffer, intChars)
End Function

Function ahtGetPrivateINIInt(ByVal strGroup As String, ByVal strItem As String, ByVal strFile As String) As Variant
' Get an integer value from and Windows INI file.
' Return either the integer value, or -1 if there's no match.
' (Therefore, this function won't help if you need to find a value that
' might be -1!)
'
'
' ? ahtGetPrivateINIInt("ISAM", "MaxBufferSize", "MSACC20.INI")
' 530

ahtGetPrivateINIInt = aht_apiGetPrivateProfileInt(strGroup, strItem, -1, strFile)
End Function

Function ahtGetPrivateIniString(ByVal strGroup As String, ByVal strItem As String, ByVal strFile As String) As Variant
' Get a string value from any Windows INI file. For example,
' the following, in the Immediate Window:
' ? ahtGetPrivateINIString("Options", "SystemDB", "MSACC20.INI")
'
' might display:
'
' D:\ACCESS2\SYSTEM.MDA
'
Dim intChars As Integer
Dim strBuffer As String

strBuffer = String(MAX_SIZE, 0)
intChars = aht_apiGetPrivateProfileString(strGroup, strItem, "", strBuffer, MAX_SIZE, strFile)
ahtGetPrivateIniString = Left(strBuffer, intChars)
End Function

Function ahtGetProfileSection(ByVal strGroup As String) As Variant
' Get a whole section from Win.INI. For example:
' ? ahtGetProfileSection("Devices")
'
' will retrieve a list of all the devices in Win.INI,
' delimited with Null characters.
'

Dim strBuffer As String
Dim intCount As Integer

strBuffer = Space(MAX_SECTION)
intCount = aht_apiGetProfileSection(strGroup, strBuffer, MAX_SECTION)
ahtGetProfileSection = Left(strBuffer, intCount)
End Function

Function ahtGetPrivateProfileSection(ByVal strGroup As String, ByVal strFile As String) As Variant
' Get a whole section from any .INI file. For example:
' ? ahtGetPrivateProfileSection("Devices", "Win.INI")
'
' will retrieve a list of all the devices in Win.INI,
' delimited with Null characters.
'
Dim strBuffer As String
Dim intCount As Integer

strBuffer = Space(MAX_SECTION)
intCount = aht_apiGetPrivateProfileSection(strGroup, strBuffer, MAX_SECTION, strFile)
ahtGetPrivateProfileSection = Left(strBuffer, intCount)
End Function



basImpressoraPadrao


Option Compare Database 'Use database order for string comparisons
Option Explicit

' Code from:
' Microsoft Access 95 How-To
' (c) 1998 Ken Getz and Paul Litwin
' All rights reserved.

' You may only use this code as part of an application
' that requires its use. You must including this
' notice intact. You may not distribute the code
' as your own work, nor can you distribute the
' code on its own.

Function ahtGetDefaultPrinter(dr As aht_tagDeviceRec) As Boolean
' Retrieve the default printer information. Though
' the function dutifully returns True if the
' values were available, and False otherwise, Windows
' really isn't happy without a default printer, and
' this situation rarely comes up.

' In:
' dr: a aht_tagDeviceRec structure to fill in
' Out:
' Return Value: True if info available, False otherwise.
' dr: filled in with default printer information,
' if it was available (check the function's return
' value).
'
' Comments:
' Requires the ahtGetToken() function from basGetToken
' Requires the ahtGetINIString() function from basINIFile
' Requires type definitions from basPrintTypes

Dim strBuffer As String

strBuffer = ahtGetINIString("Windows", "Device")

If Len(strBuffer) > 0 Then
With dr
.drDeviceName = ahtGetToken(strBuffer, ",", 1)
.drDriverName = ahtGetToken(strBuffer, ",", 2)
.drPort = ahtGetToken(strBuffer, ",", 3)
End With
ahtGetDefaultPrinter = True
Else
ahtGetDefaultPrinter = False
End If
End Function

Function ahtSetDefaultPrinter(dr As aht_tagDeviceRec) As Boolean
' Set the default printer device in Win.INI
' In:
' dr: a aht_tagDeviceRec structure to use as
' the source of information.
' Out:
' Return Value: True if set correctly, False otherwise.
' If successful, writes a string in the form:
' device=HP LaserJet 4,HPPCL5E,LPT1:
' to your Win.INI file.
'
' Comments:
' Requires the aht_apiWriteProfileString() declaration from basINIFile
' Requires type definitions from basPrintTypes

Dim strBuffer As String
' Build up the appropriate string.
strBuffer = dr.drDeviceName & ","
strBuffer = strBuffer & dr.drDriverName & ","
strBuffer = strBuffer & dr.drPort

' Now write that string out to WIN.INI.
ahtSetDefaultPrinter = (aht_apiWriteProfileString("Windows", _
"Device", strBuffer) <> 0)
End Function

Private Sub TestDefaultPrinter()
' Test the ahtDefaultPrinter() function.
' Fill in a DeviceRec structure with
' the pieces of the default printer info,
' and then print them out.

Dim dr As aht_tagDeviceRec
If ahtGetDefaultPrinter(dr) Then
Debug.Print "Device: "; dr.drDeviceName
Debug.Print "Driver: "; dr.drDriverName
Debug.Print "Port : "; dr.drPort
End If
End Sub



basPrintTypes


Option Compare Database 'Use database order for string comparisons
Option Explicit

' Code from:
' Microsoft Access 95 How-To
' (c) 1998 Ken Getz and Paul Litwin
' All rights reserved.

' You may only use this code as part of an application
' that requires its use. You must including this
' notice intact. You may not distribute the code
' as your own work, nor can you distribute the
' code on its own.

' Structure for device information
' This structure, unlike the aht_tagDEVMODE
' and aht_tagDEVNAMES, doesn't have a counterpart
' in the Windows SDK. It's just a convenience

' for Access programmers.

Type aht_tagDeviceRec
drDeviceName As String
drDriverName As String
drPort As String
End Type

' Structure to hold DEVMODE information.
Type aht_tagDEVMODE
dmDeviceName(1 To 32) As Byte
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName(1 To 32) As Byte
dmLogPixels As Integer
dmBitsPerPixel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
dmICMMethod As Long
dmICMIntent As Long
dmMediaType As Long
dmDitherType As Long
dmICCManufacturer As Long
dmICCModel As Long
dmDriverExtraBytes(1 To 1024) As Byte
End Type

' You'll need a user-defined type in order
' to use LSet to copy the values from a DEVMODE
' structure into a string, and vice-versa.

Type aht_tagDEVMODEStr
DMStr As String * 1024
End Type

' Structure to hold DEVNAME information
Type aht_tagDEVNAMES
dnDriverOffset As Integer
dnDeviceOffset As Integer
dnOutputOffset As Integer
dnDefault As Integer
End Type

' You 'll need a user-defined type in order
' to use LSet to copy the values from a DEVNAMES
' structure into a string, and vice-versa.

Type aht_tagDEVNAMEStr
DNStr As String * 4
End Type

' Structure to hold prtMIP information.
Type aht_tagMIP
xLeftMargin As Long
yTopMargin As Long
xRightMargin As Long
yBotMargin As Long
fDataOnly As Long
xFormSize As Long
yFormSize As Long
fDefaultSize As Long
cxColumns As Long
xFormSpacing As Long
yFormSpacing As Long
radItemOrder As Long
fFastPrinting As Long
fDataSheet As Long
End Type

Type aht_tagMIPSTR
MIPStr As String * 28
End Type


basToken


Option Compare Database 'Use database order for string comparisons
Option Explicit

' Code from:
' Microsoft Access 95 How-To
' (c) 1998 Ken Getz and Paul Litwin
' All rights reserved.

' You may only use this code as part of an application
' that requires its use. You must including this
' notice intact. You may not distribute the code
' as your own work, nor can you distribute the
' code on its own.

Function ahtGetToken(ByVal strValue As String, ByVal strDelimiter As String, ByVal intPiece As Integer) As Variant
Dim intPos As Integer
Dim intLastPos As Integer
Dim intNewPos As Integer

On Error GoTo ahtGetTokenExit

' Make sure the delimiter is just one character.
strDelimiter = Left(strDelimiter, 1)

' If the delimiter doesn't occur at all, or if
' the user's asked for a negative item, just return the item
' they passed in.

If (InStr(strValue, strDelimiter) = 0) Or (intPiece <= 0) Then
ahtGetToken = strValue
Else
intPos = 0
intLastPos = 0

Do While intPiece > 0
intLastPos = intPos
intNewPos = InStr(intPos + 1, strValue, strDelimiter)
If intNewPos > 0 Then
intPos = intNewPos
intPiece = intPiece - 1
Else
' Catch the last piece, where there's no
' trailing token.
intPos = Len(strValue) + 1
Exit Do
End If

Loop
If intPiece > 1 Then
ahtGetToken = Null
Else
ahtGetToken = Mid$(strValue, intLastPos + 1, intPos - intLastPos - 1)
End If
End If

ahtGetTokenExit:
Exit Function

ahtGetTokenErr:
MsgBox "Error in ahtGetToken: " & Error & " (" & Err & ")"
Resume ahtGetTokenExit
End Function


Código pronto, compile-o selecionando, no menu Depurar, Compilar PDF.


Fig. 1 – Compilação do Código

Feche o módulo e, no menu Ferramentas, selecione Utilitários de Banco de Dados e, em seguida, Compactar e corrigir banco de dados.


Fig. 2 – Compactar e corrigir banco de dados

Esses passos são necessários sempre que fizer alterações no seu banco de dados, para evitar que haja qualquer tipo de corrompimento.

Determinando o caminho do PDF

Para determinar o caminho do PDF, de forma que o arquivo seja sempre salvo na pasta correta, abra o seu relatório em modo estrutura.

No evento AoAbrir, coloque o seguinte código:


Private Sub Report_Open(Cancel As Integer)
strNomeReport = "rptCliente"

strCaminhoSalvar = "c:\AndreaT\PDF\Relatório de Clientes.pdf"

End Sub



Dessa maneira, ao ser aberto, o nome do relatório no banco de dados será passado para a variável strNomeReport e o caminho padrão do relatório será passado para a variável strCaminhoSalvar. No caso do banco de dados estar em rede, e o relatório precisar ser salvo sempre no servidor (ou em outro computador), será necessário capturar o nome do computador e usar um loop If.



Criando um formulário para gerar o PDF

Com o caminho já determinado, chegou a hora de gerar efetivamente o seu arquivo PDF. Para isso, vamos criar um formulário no modo estrutura. Nesse formulário, inclua uma caixa de texto (txtCaminho) e dois botões de comando (cmdPDF e cmdCancelar), sem usar o assistente. Abra o código do formulário e insira:


Option Compare Database

Option Explicit

' Code from:
' Microsoft Access 95 How-To
' (c) 1998 Ken Getz and Paul Litwin
' All rights reserved.

' You may only use this code as part of an application
' that requires its use. You must including this
' notice intact. You may not distribute the code
' as your own work, nor can you distribute the
' code on its own.
'
' código editado por Andrea Tikhomiroff

Private Sub Form_Open(Cancel As Integer)
Dim dr As aht_tagDeviceRec

' When you open the form, set the default
' printer to be the chosen item in the
' combo box. Because the first column
' (the one displaying "printer name on port name")
' is the bound column, build up an expression of
' that sort. This function calls
' the BuildName() function, just like the combo
' box itself does, so the strings will be
' formatted alike.

If ahtGetDefaultPrinter(dr) Then
strNomeImpressora = dr.drDeviceName
strDriverImpressora = dr.drDriverName
strPortaImpressora = dr.drPort
End If

Me.txtCaminho = strCaminhoSalvar

' prevê casos em que o relatório deva necessariamente ser exportado
' para o Word. Nesses casos, a mensagem entre aspas deve estar no
' lugar do caminho no relatório

If Me.txtCaminho = "Favor enviar esse relatório para o Word." Then
Me.cmdPDF.Enabled = False
Else
Me.cmdPDF.Enabled = True
End If
End Sub



No evento ApósAtualizar da txtCaminho coloque:



Private Sub txtCaminho_AfterUpdate()
strCaminhoSalvar = Me.txtCaminho
End Sub


No evento AoClicar do cmdPDF, coloque:


Private Sub cmdPDF_Click()
' After you make a selection, go write
' the string out to WIN.INI.

Dim dr As aht_tagDeviceRec
Dim intRetval As Integer

' Retrieve the pieces needed by dr from
' the combo box.
With dr
.drDeviceName = "PDF995"
.drDriverName = "Pscript"
.drPort = "PDF995PORT"
End With

intRetval = ahtSetDefaultPrinter(dr)

pdfwrite strNomeReport, strCaminhoSalvar, strCriterio

With dr
.drDeviceName = strNomeImpressora
.drDriverName = strDriverImpressora
.drPort = strPortaImpressora
End With

intRetval = ahtSetDefaultPrinter(dr)

DoCmd.Close acForm, "frmGeraPDF"
End Sub



Altere a propriedade Padrão deste botão para SIM. Assim, ao pressionar Enter, o PDF será gerado.

Por fim, no evento AoClicar do cmdCancelar, coloque:


Private Sub cmdCancelar_Click()
Dim dr As aht_tagDeviceRec
Dim intRetval As Integer

With dr
.drDeviceName = strNomeImpressora
.drDriverName = strDriverImpressora
.drPort = strPortaImpressora
End With

intRetval = ahtSetDefaultPrinter(dr)

DoCmd.Close

End Sub


Altere a propriedade Cancelar deste botão para SIM. Assim, ao pressionar ESC, o formulário será fechado.
Acerte as seguintes propriedades do formulário:


Fig. 3 – Propriedades do frmGeraPDF


Feche o formulário salvando-o como frmGeraPDF.


Criando uma barra de ferramentas


O próximo passo é criar uma barra de ferramentas para os relatórios que chame o frmGeraPDF. Para isso, no menu Exibir, Barra de Ferramentas, escolha Personalizar.


Clique na guia Barras de Ferramentas e, em seguida, em Nova. Digite o nome da nova barra (rptPDF) e clique em OK.


Fig. 4 – criando uma nova barra de ferramentas


Ainda na guia Barras de Ferramentas, marque a barra Visualizar Impressão para que ela fique visível.

Com a tecla Ctrl pressionada, arraste os botões da impressora, do zoom e o Fechar para a sua nova barra.


Fig. 5 – copiando botões

Clique com o botão direito no botão da lupa e escolha Iniciar um grupo. Repita a operação com o botão Fechar. Na caixa Personalizar, desmarque a barra de ferramentas Vizualizar impressão.

Clique na guia Comandos e selecione, em Categorias, Todos os formulários. Arraste o frmGeraPDF para a sua barra de ferramentas, após a caixa de zoom. Clique sobre o ícone criado com o botão direito e altere o nome para &Gerar PDF. Altere também o estilo para Somente texto (sempre) e Iniciar um grupo. A barra deverá ficar assim:


Fig. 6 – barra de ferramentas rptPDF

Feche a barra de ferramentas usando o X da barra de título e a caixa Personalizar clicando em Fechar.


Acoplando a barra de ferramentas ao relatório

Criada a barra de ferramentas, é necessário ligá-la ao seu relatório. Para isso, abra-o em modo estrutura e altere a propriedade Barra de Ferramentas para rptPDF.


Fig. 7 – acoplando a barra de ferramentas ao relatório


Feche o relatório salvando-o.


Testando

Tudo pronto? Hora do teste então! Visualize seu relatório e clique no botão Gerar PDF da barra de ferramentas que criou. Não esqueça de compilar seu código, reparar e compactar o banco de dados, para que tudo funcione corretamente.


Fig. 8 – testando o funcionamento da barra de ferramentas

Clicando em Gerar PDF, abrirá uma caixa informando que o arquivo está sendo salvo na impressora virtual.


Fig. 9 – gerando o pdf

Após isso, será exibida uma caixa com a propaganda do PDF995. Basta esperar a caixa fechar sozinha.



Para encerrar...

Para verificar se o PDF foi gerado corretamente, abra no Windows Explorer, a pasta c:\AndreaT\PDF e verifique se o arquivo Relatório de Clientes.pdf está lá. Clique duas vezes abri-lo.


Fig. 10 – verificando o arquivo PDF gerado pelo Access


Como pôde ver, essa ferramenta poderá ser bastante útil se souber usá-la. Explore-a à vontade!

Até a próxima!

Links relacionados:

Artigos relacionados:
  Nenhum artigo relacionado



 

   Copyright © Ativo Access 2003 - 2019- Todos os direitos reservados   Política de Privacidade | Fale conosco