1

I don't have much experience with VBA so it's been difficult to troubleshoot this. When running the code, it outputs Array(i<=i) instead of Array(i)

I've tested the for condition and found Array(0) properly returns the result. However Array(1) will print Array(1) with Array(0) and so on.

The goal of this code is to group worksheets based on their name and print them to pdfs based on grouping, i.e. all sheets starting with I1 to a single pdf.

Sub Test()
    FolderPath = "C:\Example"

    Dim aWS()
    Dim n As Integer
    Dim ws As Worksheet
    Dim DocTypes()

    DocTypes = Array("I1","I2","I3")

    For i = LBound(DocTypes) To UBound(DocTypes)
        For Each ws In Worksheets
            If Left(ws.Name, 2) = DocTypes(i) Then
                n = n + 1
                ReDim Preserve aWS(1 To n) 'Add 1 to to array length
                aWS(n) = ws.Name 'Add worksheet name meeting If condition 
            End If
        Next ws  

        Sheets(aWS).Select
        ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FolderPath & 
            DocTypes(i), _
            openafterpublish:=True, ignoreprintareas:=False
    Next i
End Sub

What I expect is:

i = 0 to 2

First Array(i) = "I1" so output all sheets beginning with "I1" as a pdf

Then move to i = 1

Here Array(i) = "I2" so output all sheets beginning with "I2" as a pdf

However when I step forward it doesn't seem to be following this logic and I don't understand why. I'm thinking it has to do with the selection, it would follow that if i=0 was selected, then i=1 was added to the selection this problem would make sense. I've tried re-selecting a single sheet right before Next i to force past this but it didn't work. This leads me to think I've made a logical mistake in my for loops.

barkare
  • 13
  • 5
  • 1
    You need to `Erase aWS` and `n = 0` on each iteration of the `i` loop. – GSerg Jan 06 '19 at 08:01
  • @VBasic2008 Why? – GSerg Jan 06 '19 at 08:06
  • Oh that makes perfect sense thank you. aWS was persisting so the next i was being added to the previous. Erasing and resetting n to 0 after the print fixed it. – barkare Jan 06 '19 at 08:07
  • @Aida However please do pay attention to https://stackoverflow.com/a/54059685/11683. `ActiveSheet` is indeed just one sheet and you appear to want to export several sheets into one pdf. – GSerg Jan 06 '19 at 08:10
  • As far as I know, Sheets() cannot have an array as a parameter, you can only use 1 sheet e.g. Sheets(1) or Sheets(2). After reading [this](https://learn.microsoft.com/en-us/office/vba/api/excel.workbook.exportasfixedformat), it would appear that you cannot do what you want in this way. A workaround might be to copy the contents of each sheet of a group to one new sheet and export it. – VBasic2008 Jan 06 '19 at 09:34
  • @VBasic2008 `Sheets` [can have an array as a parameter](https://learn.microsoft.com/en-us/office/vba/api/excel.sheets#example). The way to do what the OP wants has been [mentioned](https://stackoverflow.com/a/54059685/11683) by Variatus and involves [selecting the ranges first](https://stackoverflow.com/a/20751096/11683). – GSerg Jan 06 '19 at 10:29
  • @GSerg: Sorry, It obviously isn't my day. You're right about the Sheets parameter. I've tried it by using ClearContents on UsedRanges, and it cleared ranges of the size of Sheet1's UsedRange on all sheets. An important ingredient of the 'success' of the solution, which isn't mentioned at all, is IgnorePrintAreas:=False. I thought about a solution sorting the sheets and then using the IgnorePrintAreas, the From and To arguments, but it seemed too complicated. Maybe that is the way to go. – VBasic2008 Jan 06 '19 at 11:56

2 Answers2

0

Use Selection.ExportAsFixedFormat etc instead of ActiveSheet. The ActiveSheet is always only one sheet while your selection comprises many. Upon further study I find that you may have to include making a selection for each of the worksheets, like Ws.UsedRange.Select. Take a look at this thread.

Variatus
  • 14,293
  • 2
  • 14
  • 30
  • I tested this and had the same issue as others in the thread. Integrating GSerg's advice made the sub function as intended, while Selection for some reason prints blank pdf pages. – barkare Jan 06 '19 at 08:39
  • 1
    @barkare `Selection` always refers to cells, not sheets, and like it is shown in the [linked question](https://stackoverflow.com/questions/20750854/excel-vba-to-export-selected-sheets-to-pdf), you need to select all used ranges on all relevant sheets and then export the selection. If your sub works as is, it means you never have more than one sheet that starts with `I1`, `I2` etc. – GSerg Jan 06 '19 at 08:51
0

You might not be aware but you can use a variant as a control variable in a for each to iterate an array of variants. Your use of redim to extend an array by 1 item suggests that you should be using a scripting dictionary as an intermediate step to your array. The .Items method of a scripting dictionary returns an array of items so it is easy to get your array that you use subsequently. Here is your code revised to use a scripting.dictionary and a variant control variable. In your specific case we are basically using the scripting.dictionary as a list by making the key and the item the same thing.

Option Explicit

Sub Test()

    Const FolderPath                        As String = "C:\Example"

    Dim aWS                                 As Scripting.Dictionary
    Dim ws                                  As excel.Worksheet
    Dim DocTypes()                          As Variant
    Dim DocType                             As Variant

    DocTypes = Array("I1", "I2", "I3")

    For Each DocType In DocTypes

        Set aWS = New Scripting.Dictionary

        For Each ws In Worksheets

            If DocType = left(ws.Name, 2) Then

                aWS.Add Key:=ws.Name, Item:=ws.Name

            End If

        Next ws

        Sheets(aWS.Items).Select
        ActiveSheet.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            FileName:=FolderPath & DocType, _
            openafterpublish:=True, _
            ignoreprintareas:=False
    Next

End Sub
freeflow
  • 4,129
  • 3
  • 10
  • 18
  • Thank you for this, I was not aware of dictionaries. I've been testing this all day and this method both works faster for large sheet ranges and outputs the same results as modifying my array method. – barkare Jan 07 '19 at 05:48