Select Menu
» » » » » » » » 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


#excel #excelvba #vbaexcel #vba #microsoftexcel #msexcel #trovato 

Autor Unknown

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

5 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
  3. Bom Artigo Pedro, necessito de ajuda, como ficaria uma macro que ao gravar em pdf e encontrasse o arquivo com o mesmo nome, avise que o Arquivo já existe e cria a possibilidade de aceitar ou não

    ResponderExcluir
  4. Olá boa noite.

    Preciso muito da ajuda para concluir esse projeto.

    Preciso salvar em pdf algumas planilhas com numeração continua de página de acordo com a ordem:

    TERMO ABERTURA, PLANO DE CONTAS, LIVRO DIÁRIO, DEMONST FINANCEIRO, NOTAS EXPLICATIVAS, BALANÇO PATRIM, INDICES LIQUIDEZ e TERMO ENCERRAMENTO.
    Até ai tudo bem. Porém no Livro Diario existe um filtro, aonde seleciono apenas as celulas com data, excluindo as vazias.

    No momento que aciono a macro, ele salvar em pdf todas as planilhas, porém a planilha Livro Diário ele pega toda a area de impressão e não considera o filtro da coluna A.

    Está ai a macro:

    Sub SalvarPDF()
    Sheets(Array("TERMO ABERTURA", "PLANO DE CONTAS", "LIVRO DIÁRIO", _
    "DEMONST FINANCEIRO", "NOTAS EXPLICATIVAS", "BALANÇO PATRIM", "INDICES LIQUIDEZ", _
    "TERMO ENCERRAMENTO"))SpecialCells(xlCellTypeVisible).Select _
    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
    "C:\Users\TIAGO MARTINELLI\Desktop\LIVRO DIÁRIO.pdf", Quality:= _
    xlQualityMinimum, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
    OpenAfterPublish:=False
    End Sub
    Preciso de ajuda para adequar essa macro ou fazer uma nova para que ele gere pdf de todas as planilhas citadas acima, considerando o filtro da planilha Livro Diário selecionando somente as linhas visiveis da mesma.

    Se puder ser também uma macro o qual seleciona a impressora "cute pdf" para gerar o pdf, não tem problema.

    Grato pela colaboração.

    ResponderExcluir