VBA, чтобы выбрать каждый элемент слайсера, а затем сохранить каждый выбранный элемент слайсера в формате pdf?

Я разработал информационную панель, состоящую из нескольких различных сводных таблиц и сводных диаграмм.

Все эти сводные таблицы/диаграммы контролируются 1 слайсером под названием «Slicer_Store».

В этом слайсере есть около 800 различных магазинов на выбор.

Мне нужно сохранить PDF-файл с приборной панелью КАЖДОГО магазина. Процесс ручного выбора каждого элемента слайсера, а затем сохранения листа в виде файла PDF занимает очень много времени с более чем 800 хранилищами, поэтому я надеялся автоматизировать этот процесс с помощью VBA.

Вот мой код:

Public Sub myMacro()
Dim sI As SlicerItem, sI2 As SlicerItem, sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store")
With sC

    For Each sI In sC.SlicerItems
        sC.ClearManualFilter
        For Each sI2 In sC.SlicerItems
            If sI.Name = sI2.Name Then sI2.Selected = True Else: sI2.Selected = False
        Next

        Debug.Print sI.Name
        'add export to PDF code here
        ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
        "C:\Users\TestUser\Desktop\testfolder" & Range("b1").Text  & ".pdf", Quality:= _
        xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
        OpenAfterPublish:=False
    Next

End With
End Sub

Код обрабатывает все элементы слайсера, но файл не сохраняется в формате pdf. Мне нужно, чтобы каждый файл сохранялся как значение в B2, поэтому это будет Store1.pdf, Store2.pdf, Store3.pdf и т. д.

Любая помощь будет очень признательна. Это большой рабочий проект, и многие люди зависят от этих pdf-файлов.


Отредактированный код:

Это должно работать, но для просмотра всех элементов слайсера (800+) требуется вечность. Кроме того, мне нужно убедиться, что он печатает только первую страницу (область печати), поэтому сам слайсер не будет напечатан.

Public Sub myMacro()
Dim sI As SlicerItem, sI2 As SlicerItem, sC As SlicerCache
Dim ws As Worksheet
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store_Number")
Set ws = Sheet18
With sC

    For Each sI In sC.SlicerItems
        sC.ClearManualFilter
        For Each sI2 In sC.SlicerItems
            If sI.Name = sI2.Name Then sI2.Selected = True Else: sI2.Selected = False
        Next

       Debug.Print sI.Name
        'add export to PDF code here
      ws.PageSetup.PrintArea = ws.Range("A1:N34").Address

       ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
        "C:\Users\testuser\Desktop\testfolder" & Range("M1").Text & ".pdf", Quality:= _
        xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
        OpenAfterPublish:=False
    Next

End With
End Sub

person ranopano    schedule 18.04.2017    source источник
comment
Где вы получаете ошибку? (Где выделено?)   -  person M--    schedule 21.04.2017
comment
Когда я получил ошибку в прошлом, ни одна строка не была выделена. Вот почему я подозревал, что это может быть связано с памятью. Я перезапустил код, и до сих пор он работал около 20 минут, но файлы не сохранялись, и панель инструментов, похоже, не обновлялась с помощью выбора слайсера. Могу ли я отправить вам книгу по электронной почте?   -  person ranopano    schedule 21.04.2017
comment
В настоящее время на работе, но вы можете сделать это, если у вас нет личных данных. До этого я предполагаю, что вы меняете путь (т.е. "C:\Users\testuser\Desktop\testfolder") к каталогу, который существует на вашем компьютере. Я знаю, что это очевидно, но иногда я забываю об этом.   -  person M--    schedule 21.04.2017
comment
Попробуйте запустить Step Into работает. нажав F8.   -  person M--    schedule 21.04.2017
comment
Проверьте мой сайт. И мы здесь для помощи, а не для зарабатывания денег.   -  person M--    schedule 21.04.2017


Ответы (2)


Это на самом деле решает проблему, но подход, который вы получаете к 800+ элементам, займет целую вечность. См. ниже другое решение, которое требует небольшого сотрудничества со стороны пользователя, но оно намного быстрее.

Добавьте эту строку перед печатью в PDF:

 Range("b1") = sI.Name

Это запишет имя магазина в диапазон, чтобы позже вы могли использовать его в качестве имени вашего файла PDF.

Также добавьте косую черту в конце вашего пути:

 ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
          "C:\Users\TestUser\Desktop\testfolder\" & Range("b1").Text  & ".pdf", Quality:= _

ЕСЛИ вы хотите печатать только первую страницу, вы можете установить область печати прямо перед строками выше или использовать это:

ActiveSheet.PrintOut from:=1, To:=1

ОБНОВЛЕНИЕ

В этом решении вам нужно убедиться, что выбран первый элемент слайсера и только он (поэтому вам не следует очищать фильтр вручную). Это закодировано на основе этого. Исходный код каждый раз перебирает все элементы слайсера, выбирает один и отменяет выбор других, что приводит к чрезвычайно высоким вычислительным затратам.

Public Sub myMacro()
Dim sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store_Number")




  'This reminds the user to only select the first slicer item
   If sC.VisibleSlicerItems.Count <> 1 Or sC.SlicerItems(1).Selected = False Then
      MsgBox "Please Only Select Store-Number 1"
      Exit Sub
   End If


For i = 1 To sC.SlicerItems.Count

    'Do not clear ilter as it causes to select all of the items (sC.ClearManualFilter)

    sC.SlicerItems(i).Selected = True
    If i <> 1 Then sC.SlicerItems(i - 1).Selected = False


    'Debug.Print sI.Name
    'add export to PDF code here
    With Sheet18.PageSetup

    .PrintArea = Sheet18.Range("A1:N34" & lastRow).Address

    .FitToPagesWide = 1
    .FitToPagesTall = 1

    End With

    Sheet18.Range("M1") = sC.SlicerItems(i).Name

   'This prints to C directory, change the path as you wish

   Sheet18.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
    "C:\" & Range("M1").Text & ".pdf", Quality:= _
    xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
    OpenAfterPublish:=False
Next

End Sub
person M--    schedule 18.04.2017
comment
Благодарю вас! Если бы я хотел изменить этот код так, чтобы печаталась только первая страница документа, как бы я это сделал? - person ranopano; 20.04.2017
comment
Хорошо, у меня есть панель инструментов на странице 1 и слайсер на странице 2 (поэтому я хотел распечатать только 1-ю страницу). Однако, когда я запускаю код, я получаю сообщение об ошибке 1004 Application-defined или Object-defined error. Я не уверен, что вызывает это... - person ranopano; 21.04.2017
comment
@Darren Просто попробуйте явно определить область печати (где бы она ни была, первая страница или последняя). Читайте здесь: stackoverflow .com/questions/17623445/ - person M--; 21.04.2017
comment
Посмотрите на мой обновленный код выше. Мне кажется, что VBA неверен, так как я все еще получаю сообщение об ошибке. Диапазон области печати, которую мне нужно распечатать, составляет (A1: N34) - person ranopano; 21.04.2017
comment
@Darren Это работает намного быстрее, чем предыдущий код. Проверьте это. - person M--; 22.04.2017
comment
@Darren Теперь он протестирован и отлажен. На моей машине для запуска требуется 13 минут и 25 секунд. Это может варьироваться в зависимости от конфигурации вашей системы. - person M--; 22.04.2017

person    schedule
comment
Привет Уильям, добро пожаловать на сайт. Что делает этот код/как он по-новому решает вопрос? Ответы, содержащие только код, могут быть полезны, но мы настоятельно рекомендуем, чтобы ответы содержали объяснение, чтобы люди не запутались или, что еще хуже, не запустили опасный код. - person TylerH; 07.08.2019
comment
Привет, Уильям, добро пожаловать на сайт (раз два, лол), не забудьте добавить теги к своим сообщениям, чтобы людям было легче понять, о чем ваш вопрос. Например, если бы я задавал вопрос о python о том, как использовать json, я бы, возможно, добавил теги python и json. - person Kyle Bridenstine; 08.08.2019
comment
Привет Кайлер Тайлер, Спасибо, я новичок в VBA. Этот код проходит через слайсер из Power Pivot и печатает каждый слайсер. Я попробовал код MM, но он останавливается на If sC.VisibleSlicerItems.Count ‹› 1 или sC.SlicerItems(1).Selected = False Then. Я не уверен, что это из-за силового шарнира. По крайней мере, мой код работает для меня - person William Xia; 08.08.2019