• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Create a macro to print reports to Adobe PDF using entries in a data validation list

courtconn

New Member
Hi,

I'm new to this forum and VBA and hoping I could get some help....

I created a report in Excel that uses a data validation list that includes 900+ unique IDs. By selecting an ID, the contents of the report update with the relevant data. I would like to create a macro that does the following:

1. Choose the first ID in the data validation list which then populates the report with the unique data.
2. Print the report to its own PDF file that will be saved in a folder I designate, using the unique ID as the file name.
3. Repeat steps 1 & 2 for every unique ID in the data validation list.

I would also like to create a similar macro that prints a report for each of the unique IDs to my networked office printer.

Thanks for your help!
 
For posterity, and to make clear, just a question on point number 2

Are you saying you want to update an existing PDF that corresponds to each unique ID? Or do you mean you want to save the unique data in the sheet to a new PDF that corresponds to each unique ID?
 
First time around no PDF will exist for the unique IDs so initially I want to do the latter - save the unique data in the report to a new PDF that corresponds to each unique ID. However, I will be updating these reports periodically over time at which point I'll need to save new PDF files for the same set of IDs. Given this second consideration, perhaps I should add a 2nd reference to the file name, which indicates the report timeframe - e.g. a file name for this current set of reports may be 1008009-Sep 2013. Then when I rerun the reports in October the new file name becomes 1008009-Oct 2013.
 
I don't want to overwrite because the "outdated" PDFs will reflect data from historical periods. Such PDF files will be distributed to individuals with the corresponding IDs so I will need to retain for reference purposes.
 
Fair enough. And this unique ID list, I am assuming it's there somewhere on the same workbook (since you are using it for the data validation).
 
By the way, why do you say Choose the first ID in the data validation list?

What about the remaining 899+ IDs?

EDIT: Oops. My bad. You already clarified that in point 3 above.
 
Yes. The worksheet I want to print is called "Summary Report". This is also where the data validation drop down list is. The source for the data validation list is on a second sheet in the workbook called List, starting in cell A4.
 
My first step is to choose the first ID in the list. You'll note in step 3 I said repeat steps 1 & 2 for each unique ID.
 
Crystal. And I hope it's safe to assume that the unique IDs do not have any special characters that does not allow it to be used as a file name? Once you clarify that, I guess I've got all the information I need to create a macro.

You have to excuse me as it's late here. Other developers who are at better timezones can help you. If you don't get a solution by tomorrow evening (which is highly unlikely), I'll create a macro for you tomorrow [a bit too late for bed here].
 
No special characters that cannot be used in the file name. All unique IDs are #s only.

Thanks so much for your help!
 
Hi, courtconn!

Give a look at this file:
https://dl.dropboxusercontent.com/u/60558749/Create a macro to print reports to Adobe PDF using entries in a data validation list (for courtconn at chandoo.org).xlsm

It uses these named ranges:
a) ValueCell: cell with data validation list
b) DataValList: data validation list (dynamic)
c) Print area of output sheet

Replace constant ksFolder value for any output path different from that of workbook.

This is the code:
Code:
Option Explicit
 
Sub MarvelAgentsOfShield()
    ' constants
    Const ksWSSource = "Hoja1"
    Const ksWSTarget = "Hoja1"
    Const ksValue = "ValueCell"
    Const ksDataVal = "DataValList"
    Const ksFolder = ""
    ' declarations
    Dim rngV As Range, rngDV As Range
    Dim sPath As String
    Dim I As Long, A As String
    ' start
    '  ranges
    Set rngV = Worksheets(ksWSSource).Range(ksValue)
    Set rngDV = Worksheets(ksWSSource).Range(ksDataVal)
    '  path
    If ksFolder = "" Then
        sPath = ActiveWorkbook.Path
    Else
        sPath = ksFolder
    End If
    sPath = sPath & Application.PathSeparator
    ' process
    With rngDV
        For I = 1 To .Rows.Count
            A = .Cells(I, 1).Value
            rngV.Value = A
            Worksheets(ksWSTarget).ExportAsFixedFormat xlTypePDF, sPath & A
        Next I
    End With
    ' end
    '  ranges
    Set rngDV = Nothing
    Set rngV = Nothing
    '  ring
    Beep
End Sub

Just advise if any issue.

Regards!
 
Wow! This is great. I made changes to the references to apply to my file as needed and it works - thank you!! I have a few follow up questions if you don't mind...
  • I didn't see DataValList as a named reference in your sample file. I named the entire list in my file, but not sure if it was needed. How does it know where to pull the list from if it's not a named reference? Or maybe I just missed it?
  • How can I alter the code to print to a network printer?
  • If I wanted to print just a segment of the reports (e.g. reports 200-250 in the list of Unique ID values) to allow for testing of only a sample of the 900+ reports, how would I change the code?
  • How can I add default text to the end of the Unique ID file name - e.g. [Unique ID] - 09.15.13, with the " - 09.15.13" being the added default text?
Also, would you happen to have any recommendations as to how I (a newbie) can begin to get up to speed on writing VBA code? I'm a power Excel user in the sense of using advanced formulas and logic in Excel to manipulate and analyze data and build financial models, but I have no experience with VBA. I ordered the book Excel Power Programming with VBA that should arrive tomorrow, but I'm completely new to this and wondering if you can recommend any additional resources.

Thanks so much for your help - it really is going to save me so much time! And it's piqued my interest in and desire to learn VBA programming.
 
Hi, courtconn!

You can check DataValList and the ValueCell dynamic names from the Formula tab, Names or Defined Names group (I don't remember exactly how it is in the English version), Name Manager icon. You should, you must find them... if not, we're in serious trouble.

The code isn't printing anything, that's to say, it doesn't output to a printer device either local or network. It just that I missed your 2nd. point in your original requirement.

Download again the file from same previous link.

Worksheet changes:
1) Addition of column B to mark with "X" selectable reports to be printed
2) New named ranges:
a) PrintCell: cell with data validation list with entries select All/Selected
b) PrintList: print list associated to DataValList (dynamic)
3) cell D1: total of reports to be printed
=SI(PrintCell="All";FILAS(DataValList);CONTAR.SI(B:B;"X")) -----> in english: =IF(PrintCell="All",ROWS(DataValList),COUNTIF(B:B,"X"))

Code updated:
Code:
Option Explicit
 
Sub MarvelAgentsOfShield()
    '
    ' constants
    '  ranges
    Const ksWSSource = "Hoja1"
    Const ksWSTarget = "Hoja1"
    Const ksValue = "ValueCell"
    Const ksDataVal = "DataValList"
    Const ksPrint = "PrintCell"
    '  print
    Const ksPrintAll = "All"
    Const ksPrintSelected = "Selected"
    Const ksX = "X"
    '  path
    Const ksFolder = ""
    '  format
    Const ksSeparator = " - "
    Const ksAddedText = ""
    '
    ' declarations
    Dim rngV As Range, rngDV As Range, rngP As Range
    Dim sPath As String, bOk As Boolean, sActivePrinter As String
    Dim I As Long, A As String
    '
    ' start
    '  ranges
    Set rngV = Worksheets(ksWSSource).Range(ksValue)
    Set rngDV = Worksheets(ksWSSource).Range(ksDataVal)
    Set rngP = Worksheets(ksWSSource).Range(ksPrint)
    '  path
    If ksFolder = "" Then
        sPath = ActiveWorkbook.Path
    Else
        sPath = ksFolder
    End If
    sPath = sPath & Application.PathSeparator
    '  print
    sActivePrinter = Application.ActivePrinter
    Application.Dialogs(xlDialogPrinterSetup).Show
    '
    ' process
    With rngDV
        For I = 1 To .Rows.Count
            ' id
            A = .Cells(I, 1).Value
            rngV.Value = A
            ' added text
            If ksAddedText <> "" Then
                A = A & ksSeparator & ksAddedText
            Else
                A = A & ksSeparator & Format(Now(), "mm.dd.yy")
            End If
            ' pdf
            Worksheets(ksWSTarget).ExportAsFixedFormat xlTypePDF, sPath & A
            ' print
            Select Case rngP.Value
                Case ksPrintSelected
                    If UCase(.Cells(I, 2).Value) = ksX Then
                        bOk = True
                    Else
                        bOk = False
                    End If
                Case ksPrintAll
                    bOk = True
                Case Else
                    bOk = False
            End Select
            If bOk Then
                ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True, _
                    IgnorePrintAreas:=False
            End If
        Next I
    End With
    '
    ' end
    '  print
    Application.ActivePrinter = sActivePrinter
    '  ranges
    Set rngP = Nothing
    Set rngDV = Nothing
    Set rngV = Nothing
    '  ring
    Beep
    '
End Sub

Hope I didn't miss anything now.

Regarding printing on a network device instead of on a local one, you can do it in 2 ways:
- the easy and lazy (and I'd choose it so I work less; me, not you!)
- the hard but smarter (this will cost you extra)

Excel prints by default to your defined or -worth repeating- default printer, so:
- the 1st, is setting your printer to the network device desired and after doing the job setting it again to the previous one... and I shouldn't have worked any more
- the 2nd, ... do you still want to make me work more? it's cruel... was adding these lines (yet done) at the end of th start section of the code:
Code:
    '  print
    sActivePrinter = Application.ActivePrinter
    Application.Dialogs(xlDialogPrinterSetup).Show
and these at the start of the end section of the code:
Code:
    '  print
    Application.ActivePrinter = sActivePrinter

Regards!
 
Hi, courtconn!

About "begin to get up to speed on writing VBA code" there you have a problem: if want to learn VBA (or anything) it's better to begin slowly but continued, speed will arrive (if you succeed) with time and practice; if you focus on getting speedy you'd probably miss steps that surely will cost you more tomorrow.

John Walkenbach's book is a good reference. There're courses at this site too -http://chandoo.org/wp/excel-school/, http://chandoo.org/wp/financial-modeling/- (hey, Chandoo, remember my 15%, I'm still waiting for the accumulated points with the black AmEx and my golden iPad).

You can check this link too: http://chandoo.org/wp/excel-vba/books/

But I recommend you to begin recording your own macros as well, using the built-in macro recorder (little worksheet button at bottom left of the Excel screen just at the right of the "Ready" label, or Programmer tab, Code group, Record Macro icon). Then go to the VBA editor with Alt-F11 and read and study the generated code, which I advise you that sometimes it's not very elegant, for example, it abuses of the Select method and then uses the Selection object, thing that's absolutely slow and almost always unnecessary.

Anyhow, welcome back whenever needed or wanted.

Regards!
 
Thank you for all of this info! I'm excited to make the changes you provided to enhance my project and continue to learn. I'll let you know how it goes once I've had a chance to work them through.

:)
 
Hi SirJB7,

This is very helpful but I am still very lost. May be because I am totally new in VB. My situation is if I have a pivot table like this and I want to print values of each Broker and save as pdf how do I mirror your code?

Broker Number (All)
Values Col1 Col2 Grand Total
Volume 15.00 22.00 37.00
Numeric Rating 1.00 0.91 0.95
Premier Service % 100.00% 90.91% 94.59%
 
Back
Top