Select Menu



por Alessandro Trovato

» » » » » » » » VBA - Artigo 033 - Gerando arquivos PDF via VBA
«
Proxima
Postagem mais recente
»
Anterior
Postagem mais antiga


Gerando arquivos PDF via VBA

Exportar sua planilha para o formato PDF (Portable Document Format, tipo de arquivo criado pela Adobe) é uma tarefa simples: entre no menu Arquivo, depois Exportar, daí clique em Criar Documento PDF/XPS, escolha o nome e local do arquivo e pronto, o arquivo é gerado. XPS é um tipo de arquivo criado pela Microsoft para concorrer com o PDF, sem muita aceitação pelo mercado.

Quando você só precisa exportar uma vez e a planilha está no formato apropriado para exportar, essa solução funciona basta. Porém, se a planilha for um relatório e que precise de novas versões com uma certa periodicidade, é melhor considerar a automatização dessa tarefa. Em um outro cenário, se você precisar gerar um PDF diferente para várias entidades diferentes em um curto período de tempo, um código para automatizar é essencial.

Antes de mais nada, vamos usar o gravador de macros para ver o código gerado pela exportação para PDF:

Sub ExportarPDF()
'
' ExportarPDF Macro
'

'
    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
        "C:\Temp\Teste.pdf", Quality:=xlQualityStandard, _
        IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
        True
End Sub

Em primeiro lugar, vemos que o objeto que está sendo utilizado é o ActiveSheet e o método é o ExportAsFixedFormat. Isto dá a entender que só podemos exportar a partir de um objeto de planilha (Worksheet). Usando o Pesquisador de Objeto (tecla F2 no editor de VBA), vemos que esse método também existe para os objetos pasta de trabalho (Workbook ), intervalo de células (Range) e gráfico (Chart).

Vemos que no código gerado o método ExportAsFixedFormat contém seis parâmetros. Olhando no pesquisador de objeto vemos que há mais alguns que não foram gerados na gravação. Vejamos a função de cada parâmetro:

- Type: Único parâmetro obrigatório, define o formato do arquivo que será gerado. Deve receber um valor da enumeração XlFixedFormatType, cujos valores são os seguintes: xlTypePDF (exporta como PDF) e xlTypeXPS (exporta como XPS);
- Filename: Como o próprio nome entrega, é o nome do arquivo. Você pode colocar o caminho completo onde o arquivo será gravado ou pode colocar apenas o nome do arquivo. Neste caso ele será gravado na pasta padrão, que normalmente é a pasta Documentos;
- Quality: Pode receber dois valores, xlQualityStandard (valor padrão) e xlQualityMinimum. O primeiro especifica qualidade normal, enquanto o segundo reduz a qualidade;
- IncludeDocProperties: Variável booleana. Quando True indica que irá exportar também as propriedades do documento, enquanto False diz para não exportar essas propriedades com o PDF;
- IgnorePrintAreas: Outra variável booleana. Quando True indica para ignorar as áreas de impressão demarcadas no Excel, enquanto False diz para considerar as áreas de impressão;
- OpenAfterPublish: Mais uma variável booleana. Quando True indica para abrir o arquivo gerado, enquanto False não abre o arquivo;
- From: Indica a partir de que página será exportado. Quando não informado considera a partir do início;
- To: Indica a até que página será exportado. Quando não informado considera até o final.

Após conhecer as funcionalidades, fica fácil perceber que mínimo para exportar um PDF é o seguinte código:

Sub ExportarPDF()
    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF
End Sub

Esse código irá exportar a planilha ativa com o mesmo nome do arquivo do Excel, apenas alterando a extensão para .pdf e irá gravar na pasta Documentos. Vamos fazer uma alteração nesse código:

Sub ExportarPDF()
    ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF
End Sub

Alterando de ActiveSheet para ActiveWorkbook altera o objeto que está sendo exportado. Neste caso irá exportar todas as planilhas da pasta de trabalho ativa para o arquivo PDF. Se alterar o objeto para Range, apenas o intervalo especificado será exportado. Assim vemos diferentes possibilidades para diferentes necessidades.

Em condições normais, você usará também o parâmetro Filename para especificar o caminho e o nome do arquivo onde será gravado, pois nem sempre você quer obrigar o usuário a ir na pasta Documentos e também pode querer alterar o nome do arquivo para algo mais apropriado ao que está sendo gerado.

Pode aparecer uma situação em que você quer exportar mais de uma planilha, mas não quer exportar toda a pasta de trabalho que está aberta. Com o que vimos até aqui só poderíamos exportar cada planilha em um arquivo separado. Mas há um macete: selecionando as planilhas desejadas:

Sub ExportarPDF()
    Sheets(Array("Fornecedores", "Produtos")).Select
    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
        ActiveWorkbook.Path & "\Fornecedores e produtos.pdf", IgnorePrintAreas:=False
End Sub

Ao fazer isso, você perceberá que ambas as planilhas estarão selecionadas. No seu código você deverá deixar apenas uma selecionada antes de continuar o processamento.

Um caso onde é bem interessante ter uma rotina para exportar para PDF é quando você precisa gerar diversos arquivos personalizados. Uma rotina preenchen a planilha usando uma fonte de dados, que pode ser outra planilha na mesma pasta de trabalho, sendo que a cada preenchimento completado deverá gerar o PDF com um nome específico. Vejamos um procedimento bem simples para exemplificar:

Sub GerarRelatorios()
    Dim UltimaLinha As Long
    Dim Linha As Long
    plDados.Select
    UltimaLinha = plDados.Cells.Find("*", LookIn:=xlFormulas, _
        SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    plRelatorio.Select
    For Linha = 2 To UltimaLinha
        plRelatorio.Range("Nome").Value = plDados.Cells(Linha, 1).Value
        plRelatorio.Range("Cargo").Value = plDados.Cells(Linha, 2).Value
        plRelatorio.Range("Meta").Value = plDados.Cells(Linha, 3).Value
        plRelatorio.Range("Alcançado").Value = plDados.Cells(Linha, 4).Value
        plRelatorio.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
            ActiveWorkbook.Path & "\Relatórios\" & _
            plRelatorio.Range("Nome").Value & ".pdf", _
            IgnorePrintAreas:=False
    Next
End Sub

Neste exemplo a planilha com os dados é plDados e a planilha que será usada para gerar PDF é plRelatorio. A estrutura de repetição percorre todas as linhas de plDados e preencher quatro campos em plRelatorio: Nome, Cargo, Meta e Alcançado. Em seguida, exporta para PDF usando o campo Nome como nome do arquivo, guardando em uma pasta Relatórios, que está junto à pasta de trabalho. Quando a necessidade é fazer isso com dois ou três casos, dá pra fazer manualmente, mas quando há dezenas ou centenas de casos, é muito melhor fazer um processo automatizado. O código acima pode gerar mil arquivos em poucos minutos, enquanto um processo manual levaria dias para completar.

Perceba que não temos como alterar os atributos de impressão, isso é um processo à parte. É feito utilizando o objeto PageSetup, que é um sub-objeto de Worksheets, e tem dezenas de propriedades e sub-objetos. Os mais importantes são os seguintes:

- Orientation: Propriedade que define a orientação da página, podendo ser xlPortrait (retrato) ou xlLandscape (paisagem);
- PrintArea: Propriedade que define o intervalo que será impresso;
- PaperSize: Propriedade que define o tamanho da folha;
- PrintGridlines: Propriedade booleana que define se as linhas de grades serão impressas ou não;
- PrintHeadings: Propriedade booleana que define se a barra de linhas e colunas da planilha serão impressas ou não;
- PrintTitleRows: Propriedade que define linhas que serão repetidas no topo de cada página;
 - PrintTitleColumns: Propriedade que define colunas que serão repetidas à esquerda de cada página;
- CenterHorizontally e CenterVertically: Propriedades booleanas, especificam se a planilha será centralizada na horizontal e na vertical, respectivamente;
- FitToPagesTall: Define a quantidade de páginas na altura em que os dados impressos serão escalado;
- FitToPagesWide: Define a quantidade de páginas na largura em que os dados impressos serão escalado;
- Zoom: Propriedade que define a escala em percentual em que a planilha será redefinida para a impressão;
- LeftHeader, CenterHeader e RightHeader: Propriedades que definem a seção esquerda, central e direita do cabeçalho da página;
- LeftHeaderPicture, CenterHeaderPicture e RightHeaderPicture: Objetos semelhantes às propriedades acima, mas usando figura. Estes objetos possuem diversas propriedades para definir os atributos da imagem. Quando este objeto for utilizado, a propriedade equivalente acima deverá ser definida com o valor "&G";
- LeftFooter, CenterFooter e RightFooter: Definem a seção esquerda, central e direita do rodapé da página;
- LeftFooterPicture, CenterFooterPicture e RightFooterPicture: Objetos semelhantes às propriedades acima, mas usando figura. Estes objetos possuem diversas propriedades para definir os atributos da imagem. Quando este objeto for utilizado, a propriedade equivalente acima deverá ser definida com o valor "&G";
 - TopMargin, BottomMargin, LeftMargin e RightMargin: Propriedades que definem a margem superior, inferior, esquerda e direita, respectivamente;
- HeaderMargin: Propriedade que define o espaço entre a margem superior e o cabeçalho;
- FooterMargin: Propriedade que define o espaço entre a margem inferior e o rodapé.

Há muitas outras propriedades, mas as principais são essas listadas acima. Não se pode esquecer que as definições de página devem ser feitas antes de gerar o PDF (ou imprimir um documento), portanto no exemplo anterior o código deve ser colocado antes da estrutura de repetição. Se colocar dentro do laço For... Next vai redefinir várias vezes pelos mesmos valores sem necessidade, reduzindo o desempenho do código.

Suponha que você queira exportar o intervalo A1 até D200, mantendo a linha de cabeçalho da tabela no topo de cada página. A definição das propriedades seria assim:

With plRelatorio.PageSetup
    .Orientation = xlPortrait
    .PrintArea = "$A$1:$D$200"
    .PrintTitleRows = "SA$1:$D$1"
    .Zoom = False
    .FitToPagesTall = False
    .FitToPagesWide = 1
End With

Não se pode esquecer que ao usar o método ExportAsFixedFormat a propriedade IgnorePrintArea deve ser definida como False, caso contrário a área definida para impressão será ignorada e o resultado provavelmente será diferente do esperado.

Espero que este artigo lhe ajude a automatizar seus relatórios, análises, boletins e afins, não importando se será gerado apenas um ou centenas de uma vez.


Para dúvidas sobre o artigo, comentários ou sugestões, utilize os comentários abaixo. Até o próximo artigo!

Pedro Martins

Pós-graduando em Business Intelligence e Big Data pela Faculdade Impacta de Tecnologia. Formado em Tecnologia em Eletrônica Digital com Ênfase em Microprocessadores

Autor Pedro Martins

Esta é uma breve descrição no bloco de autor sobre o autor. Você edita-lo, no html
«
Proxima
Postagem mais recente
»
Anterior
Postagem mais antiga

3 comentários

  1. Boa Tarde Pedro!
    Obrigado por mais esse excelente artigo. Parabéns! O pesquisador de objeto já me salvou várias vezes...
    Lembra do artigo sobre Tabelas (ListObject)?
    Encontrei um no link https://www.thespreadsheetguru.com/blog/2014/6/20/the-vba-guide-to-listobject-excel-tables então enquanto aguardo o seu artigo, vou estudando por aqui...
    Abraço!

    ResponderExcluir
    Respostas
    1. Não esqueci do seu pedido. Esse artigo que você citou é um dos que estou usando como base de estudos para elaboração do meu artigo.

      Excluir
  2. Excelente Artigo! Parabéns e obrigado por compartilhar!

    ResponderExcluir