Excel VBA оптимизирует скорость при переходе через фильтр отчетов

Окончательное решение Редактировать:

Во-первых, я извиняюсь, что это заняло так много времени. Вскоре после написания этого я вышел из города, а затем снял этот проект, пока не смог найти время для работы над ним в последнее время.

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

Код для тех из вас, которые могут найти его полезным – помните, что он включает в себя гораздо больше:

Sub Filter_PivotField_by_Dates(TargetPvtFld As PivotField, dtFrom As Date, dtTo As Date, _ Optional dtFrom2 As Date, Optional dtTo2 As Date) ' Filter the dates on all related pivoted tables via a grouping method. ' Variables ----- Dim bMultiRng As Boolean Dim iPvtTblRowCnt As Integer, iPvtTblColCnt As Integer, i As Integer, j As Integer, iGrpTrack As Integer, iSlcRowCnt As Integer Dim sarrPvtInfo() As String, sarrSlcInfo() As String Dim xCell As Range, rngGroup As Range, LastRw As Range, LastCol As Range Dim PvtFld As PivotField Dim Pvt As PivotTable Dim SlcItm As SlicerItem Dim SlcCache As SlicerCache Dim WS As Worksheet ' --------------- ' Disable application updating for speed. With Application .EnableEvents = False .Calculation = xlCalculationManual .ScreenUpdating = False End With ' First validate and determine whether or not it will be necessary to create a secondary comparison group. ' Ensure that something valid is entered for the pivot field value. If TargetPvtFld Is Nothing Then Msgbox "Invalid pivot field supplied to filter by date macro." Exit Sub Else On Error Resume Next Debug.Print "Target Pvt Field Name: " & TargetPvtFld.Name If Err.Number > 0 Then Debug.Print "Invalid pivot field supplied as target pivot field." Debug.Print " ----------------------------------" Err.Clear Exit Sub End If On Error GoTo 0 End If If dtFrom <= 0 Or dtTo <= 0 Then Debug.Print "Invalid dates fed to Filter Pivot by Date macro." Exit Sub ElseIf dtFrom > dtTo Then MsgBox "Please ensure that the starting date of comparison range 1 comes prior or equal to the ending date." Exit Sub End If If dtFrom2 <= 0 Or dtTo2 <= 0 Then bMultiRng = False Else bMultiRng = True ' If there is a comparison date range fed, then validate. If bMultiRng Then If dtFrom2 > dtTo2 Then MsgBox "Please ensure that the starting date of comparison range 2 comes prior or equal to the ending date." Exit Sub ElseIf (dtFrom2 >= dtFrom And dtFrom2 <= dtTo) Or (dtTo2 >= dtFrom And dtFrom2 <= dtTo) Then MsgBox "Please ensure that the two comparison dates are not overlapping before continuing." Exit Sub End If End If ' Determine how many pivot tables are related to the target for tracking original row field variables. ' Define the first dimension on the multidimensional tracking array. Hate looping twice, figure out a better way later! For Each WS In ActiveWorkbook.Worksheets For Each Pvt In WS.PivotTables If Pvt.CacheIndex = TargetPvtFld.Parent.CacheIndex Then ' Record the number of pivot tables. iPvtTblRowCnt = iPvtTblRowCnt + 1 i = 0 ' Loop through and determine the number of maximum fields. For Each PvtFld In Pvt.PivotFields If PvtFld.Orientation = xlRowField Then i = i + 1 If i > iPvtTblColCnt Then iPvtTblColCnt = i End If Next PvtFld End If Next Pvt Next WS ' Dimension full size of multidimensional array to store info about current state of linked pivot tables. ' The first field will contain each pivot tables name. The second field will contain the name of each pivot table field that ' is currently a row field for restoration after the event date filtering. ReDim sarrPvtInfo(0 To iPvtTblRowCnt, 0 To iPvtTblColCnt) ' Reset increment counters. i = 0 j = 0 ' Loop one more time through each pivot cache and record each related pivot table's name and it's respective ' pivot field names in the array for future use. For Each WS In ActiveWorkbook.Worksheets For Each Pvt In WS.PivotTables If Pvt.CacheIndex = TargetPvtFld.Parent.CacheIndex Then sarrPvtInfo(i, 0) = Pvt.Name j = 1 For Each PvtFld In Pvt.PivotFields If PvtFld.Parent.Name = TargetPvtFld.Parent.Name Then If PvtFld.Orientation = xlRowField Then sarrPvtInfo(i, j) = PvtFld.Name j = j + 1 ' Now remove the field after storing it. It will be returned after the date change. PvtFld.Orientation = xlHidden Else If PvtFld.Name <> "Values" Then End If End If End If ' Remove all column labels (except values) to ensure proper ungrouping. If PvtFld.Orientation = xlColumnField And PvtFld.Name <> "Values" Then PvtFld.Orientation = xlHidden End If Next PvtFld i = i + 1 End If Next Pvt Next WS ' In order to filter, there cannot be any filters on the data from the slicers. ' First identify the target pivot field's slicer caches. i = 0 iSlcRowCnt = 0 For Each SlcCache In ActiveWorkbook.SlicerCaches For Each Pvt In SlcCache.PivotTables If Pvt = TargetPvtFld.Parent And Not SlcCache.Name Like "*event_date*" Then Debug.Print " -----" & vbNewLine & SlcCache.Name & vbNewLine & " ----- " Debug.Print Pvt.Name If i > iSlcRowCnt Then iSlcRowCnt = i i = i + 1 End If Next Pvt Next SlcCache ' Size the array based off of our values. ReDim sarrSlcInfo(0 To iSlcRowCnt, 0 To 0) ' Reset the increment counters - again. i = 0 j = 0 ' Now loop through all the slicer caches and find which cache has slicers related to the pivot table. If ' those slicers have disabled items, record them and, after all are recorded, remove the filter to prevent ' issues during the date grouping process. For Each SlcCache In ActiveWorkbook.SlicerCaches For Each Pvt In SlcCache.PivotTables If Pvt = TargetPvtFld.Parent And Not SlcCache.Name Like "*event_date*" Then sarrSlcInfo(i, 0) = SlcCache.Name j = 1 For Each SlcItm In SlcCache.SlicerItems If Not SlcItm.Selected Then ReDim Preserve sarrSlcInfo(0 To UBound(sarrSlcInfo, 1), j) sarrSlcInfo(i, j) = SlcItm.Name j = j + 1 End If Next SlcItm SlcCache.ClearManualFilter i = i + 1 End If Next Pvt Next SlcCache ' Now begin to actually filter the dates. With TargetPvtFld .Orientation = xlRowField .ClearAllFilters ' This dynamically removes all grouped Event_Date fields prior to the grouping to come. ' This only needs to be performed on a single pivot, other related pivots will have the grouped ' fields removed as well via the cache. For Each PvtFld In .Parent.PivotFields If PvtFld.Name Like .Name & "?" Then PvtFld.Orientation = xlRowField PvtFld.Position = 1 PvtFld.ClearAllFilters iGrpTrack = iGrpTrack + 1 End If Next PvtFld i = 0 Do Until i >= iGrpTrack If iGrpTrack = 0 Then Exit Do .DataRange.Cells.Ungroup i = i + 1 Loop End With ' Now create the two groups as necessary with a third "Other" group to exclude. ' Comparison Group #1 *----- ' Loop through all cells in the date's data range and add all those that match the first criteria to a range for grouping. For Each xCell In TargetPvtFld.DataRange.Cells If xCell.Value >= dtFrom And xCell.Value <= dtTo Then 'If this is the first encountered occurrence of a match, add it. If rngGroup Is Nothing Then Set rngGroup = xCell Else ' Otherwise, union it with the existing range. Set rngGroup = Union(rngGroup, xCell) End If End If Next xCell ' Finally, group the range. By default the range will inherit the the name Group1. rngGroup.Group ' Comparison Group #2 *------ If bMultiRng Then Set rngGroup = Nothing For Each xCell In TargetPvtFld.DataRange.Cells If xCell.Value >= dtFrom2 And xCell.Value <= dtTo2 Then If rngGroup Is Nothing Then Set rngGroup = xCell Else Set rngGroup = Union(rngGroup, xCell) End If End If Next xCell rngGroup.Group End If ' Excluded events group *------ Set rngGroup = Nothing For Each xCell In TargetPvtFld.DataRange.Cells If bMultiRng Then If Not (xCell.Value >= dtFrom And xCell.Value <= dtTo) _ And Not (xCell.Value >= dtFrom2 And xCell.Value <= dtTo2) _ And Not xCell.Value Like "*-*" _ And Not xCell.Value Like "Group*" Then If rngGroup Is Nothing Then Set rngGroup = xCell Else Set rngGroup = Union(rngGroup, xCell) End If End If Else If Not (xCell.Value >= dtFrom And xCell.Value <= dtTo) _ And Not xCell.Value Like "*-*" _ And Not xCell.Value Like "Group*" Then If rngGroup Is Nothing Then Set rngGroup = xCell Else Set rngGroup = Union(rngGroup, xCell) End If End If End If Next xCell rngGroup.Group ' Now that the grouping is complete, remove the target pivot field from the rows. TargetPvtFld.Orientation = xlHidden ' Perform the final steps to restore the pivot tables. ' Loop through each pivot table and rename each grouped field. Doing this by targeting the group name in the field rather than searching ' a range prevents the need to move the pivot fields around currently. For Each WS In ActiveWorkbook.Worksheets For Each Pvt In WS.PivotTables If Pvt.CacheIndex = TargetPvtFld.Parent.CacheIndex Then Pvt.PivotFields(TargetPvtFld.Name & "2").PivotItems("Group1").Value = dtFrom & " - " & dtTo ' Optionally rename comparison group 2 in each pivot table. After which rename the remaining fields to group "Other." If bMultiRng Then Pvt.PivotFields(TargetPvtFld.Name & "2").PivotItems("Group2").Value = dtFrom2 & " - " & dtTo2 Pvt.PivotFields(TargetPvtFld.Name & "2").PivotItems("Group3").Value = "Other" Else Pvt.PivotFields(TargetPvtFld.Name & "2").PivotItems("Group2").Value = "Other" End If ' Now filter out the "Other" group of event dates so they don't appear. Pvt.PivotFields(TargetPvtFld.Name & "2").PivotItems("Other").Visible = False ' Now, its time to place the modified event date column as our headers and ensure proper sorting. With Pvt.PivotFields(TargetPvtFld.Name & "2") .Orientation = xlColumnField .Position = 1 .PivotItems(dtFrom & " - " & dtTo).Position = 1 End With End If Next Pvt Next WS ' Finally, we're ready to restore the original row fields back to each pivot table. ' Reset again. i = 0 j = 0 ' Restore the target pivot field's row field segments. For i = 0 To UBound(sarrPvtInfo, 1) If sarrPvtInfo(i, 0) = TargetPvtFld.Parent.Name Then For j = 1 To UBound(sarrPvtInfo, 2) If sarrPvtInfo(i, j) <> "" Then TargetPvtFld.Parent.PivotFields(sarrPvtInfo(i, j)).Orientation = xlRowField End If Next j End If Next i ' Now restore the target pivot field's slicer filters. ' First, disable updating on the pivot table until completed. TargetPvtFld.Parent.ManualUpdate = True For i = 0 To UBound(sarrSlcInfo, 1) For j = 1 To UBound(sarrSlcInfo, 2) If sarrSlcInfo(i, j) <> "" Then ActiveWorkbook.SlicerCaches(sarrSlcInfo(i, 0)).SlicerItems(sarrSlcInfo(i, j)).Selected = False End If Next j Next i ' Finally, we'll reset the print area. For Each WS In ActiveWorkbook.Worksheets For Each Pvt In WS.PivotTables If Pvt.CacheIndex = TargetPvtFld.Parent.CacheIndex Then With WS .PageSetup.PrintArea = "" LastRow = .Cells.Find(What:="*", searchorder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row LastCol = .Cells.Find(What:="% Sold", searchorder:=xlColumns, SearchDirection:=xlPrevious, LookIn:=xlValues).Column .PageSetup.PrintArea = .Range(.Cells(1, 1), .Cells(LastRow, LastCol)).Address End With End If Next Pvt Next WS ' Once more reenable automatic updating. TargetPvtFld.Parent.ManualUpdate = False ' Reeanble application updating. With Application .EnableEvents = True .Calculation = xlCalculationAutomatic .ScreenUpdating = True End With 

End Sub


Я целыми днями размахивал мозгами, пытаясь понять это, так что НИКАКОЙ помощи ДАЛЕЕ высоко ценится!

Моя проблема:

У меня сводная таблица, в которой фильтр отчетов даты объявлен, что я прохожу через заданный некоторый ввод соты, чтобы динамически фильтровать данные. У меня есть цикл, который работает правильно и фильтрует данные, однако для каждого элемента может потребоваться огромное количество времени (через 3,5 минуты при переходе от полного списка элементов к меньшему подмножеству). Я ищу способы оптимизировать это после долгой работы в Интернете (серьезно, я потратил не менее 6 часов на поиск). Очевидно, что Pivotitems.visible свойство, которое занимает так много времени (до секунды за элемент), я не могу понять, как его ускорить.

Что я пробовал:

В моем коде (ниже) я попытался / сделал следующее:

  • Установите для параметров приложения значение false

     With Application .ScreenUpdating = False .EnableEvents = False .DisplayAlerts = False .CalculationMethod = xlManual End with 
  • Установите поле обновления вручную на элемент поворота.

     With Pivottable("somepivottable").Pivotfields("thatonefield") .ManaulUpdate = True End with 
    • На самом деле это не работает, так как даже если настройки приложения установлены на false и ручное обновление установлено на true, я все же могу четко видеть, что приложение приостанавливается при установке элемента на видимый (примерно 0,5 на полную секунду на элемент, который с измененным видимым состоянием)
  • Попробовал установить фильтр в виде столбца на другой сводной таблице (подключен через slicer в том же кеше) и установить фильтр метки. Не думал, что это сработает.

  • Протестировано для макросъемки фактический процесс выбора фильтра на стержне (что почти мгновенно). Из того, что я получил от этого, я попытался явно объявить каждый элемент поворота как истинный или ложный, но у этого был тот же период времени, что и мой стандартный код.

И я здесь. У меня нет других идей. Моя сводная таблица фактически создана из набора данных SAS (плоский файл, а не OLAP-куб), поэтому данные не являются физически в рабочей книге, что я предпочитаю, так как данные приближаются к 800k строк и будут продолжать расти, возможно, вдвое больше , Поскольку SAS addin извлекает данные непосредственно в сводный кеш, я могу избежать ограничений данных.

Мой код до сих пор:

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

 Public Function Filter_PivotField_by_Date_Range(pvtField As PivotField, _ dtFrom As Date, dtTo As Date, Optional ByVal dtFrom2 As Date, Optional ByVal dtTo2 As Date) ' Got the original (very useful) function from: ' http://www.mrexcel.com/forum/excel-questions/669688-select-date-range-pivot-table-using-visual-basic-applications.html ' Modified to use two non-continguous date ranges for YoY analysis. ' Ex: 1/1/2014 - 1/30/2014 AND 1/2/2013 - 2/1/2013 ' Variables ----- Dim blSingleRange As Boolean, blFormLoaded As Boolean Dim bTemp As Boolean, bTemp2 As Boolean, i As Long, iFirst As Long Dim dtTemp As Date, sItem1 As String Dim PT As PivotTable Dim Sheet As Worksheet ' --------------- On Error Resume Next If dtFrom2 <= 0 Or dtTo2 <= 0 Then blSingleRange = True End If With pvtField For i = 1 To .PivotItems.Count dtTemp = .PivotItems(i) bTemp = (dtTemp >= dtFrom) And (dtTemp <= dtTo) If Not blSingleRange Then bTemp2 = (dtTemp >= dtFrom2) And (dtTemp <= dtTo2) End If If bTemp Or bTemp2 Then sItem1 = .PivotItems(i) Exit For End If Next i If sItem1 = "" Then MsgBox "No items are within the specified dates." Exit Function End If Application.ScreenUpdating = False Application.EnableEvents = False Application.Calculation = xlCalculationManual For Each Sheet In ActiveWorkbook.Sheets For Each PT In Sheet.PivotTables If PT.CacheIndex = .Parent.CacheIndex Then PT.ManualUpdate = True End If Next PT Next Sheet If .Orientation = xlPageField Then .EnableMultiplePageItems = True blFormLoaded = UserformFunctions.IsUserFormLoaded("DateProgressForm") For i = 1 To .PivotItems.Count dtTemp = .PivotItems(i) If blSingleRange Then If .PivotItems(i).Visible <> ((dtTemp >= dtFrom) And (dtTemp <= dtTo)) Then .PivotItems(i).Visible = Not .PivotItems(i).Visible End If Else If (((dtTemp >= dtFrom) And (dtTemp <= dtTo)) _ Or ((dtTemp >= dtFrom2) And (dtTemp <= dtTo2))) Then If .PivotItems(i).Visible = False Then .PivotItems(i).Visible = True Else If .PivotItems(i).Visible = True Then .PivotItems(i).Visible = False End If End If ' Update the progress userform. siPrctComp = Round((i / .PivotItems.Count) * 100, 2) If blFormLoaded Then UserformFunctions.Form_Progress (siPrctComp) DoEvents End If Next i ' Reset the manual update property of each connected pivot table. For Each Sheet In ActiveWorkbook.Sheets For Each PT In Sheet.PivotTables If PT.CacheIndex = .Parent.CacheIndex And PT.ManualUpdate = True Then PT.ManualUpdate = False End If Next PT Next Sheet End With Application.ScreenUpdating = True Application.EnableEvents = True Application.Calculation = xlCalculationAutomatic End Function 

Я не заметил никакого удара для обновления пользовательской формы прогресса (просто индикатор выполнения, так как он занимает так много времени, позволяет пользователю узнать, что он действительно работает). Если я могу заставить его работать быстрее, удалив его, я до сих пор, даже с вызовом DoEvents, занимает столько же времени. Я также попытался настроить все сводные таблицы в книге на manualupdate = true и только на текущий, без изменений.

Одна вещь, которую я заметил, это то, что когда код разбивается (или я вставляю точку останова / шаг), свойство manualupdate возвращается к false. Я не уверен, что это по дизайну или если что-то особенно плохое в моей рабочей книге / сводной таблице.

Я также попытался найти способ использовать массив для пакетного применения свойства видимости, но это не представляется возможным.

Спасибо за любую помощь, которую вы могли бы предложить, ее БОЛЬШО оценили, и если вам что-то нужно, пожалуйста, дайте мне знать.

Редактирует ответы на некоторые комментарии (спасибо, что ответили всем!)

  • Во-первых, и я приношу свои извинения за то, что забыл упомянуть об этом, но я использую 32-разрядный Excel 2010.

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

 Sub Macro1() ' ' Macro1 Macro ' ActiveSheet.PivotTables("SASApp:CORPTICK.HISTORICAL_SALES").PivotFields( _ "event_date").CurrentPage = "(All)" With ActiveSheet.PivotTables("SASApp:CORPTICK.HISTORICAL_SALES").PivotFields( _ "event_date") .PivotItems("07/01/2014").Visible = True .PivotItems("07/02/2014").Visible = True .PivotItems("07/04/2013").Visible = True .PivotItems("07/05/2013").Visible = True End With ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.0").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.1").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.2").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.3").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.4").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.5").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.6").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702").Delete ActiveWorkbook.Names.Add Name:="_AMO_ContentDefinition_105016702.0", _ RefersToR1C1:= _ "=""'<ContentDefinition name=""""SASApp:CORPTICK.HISTORICAL_SALES"""" rsid=""""105016702"""" type=""""PivotTable"""" format=""""ReportXml"""" imgfmt=""""ActiveX"""" created=""""07/01/2014 11:56:37"""" modifed=""""07/16/2014 15:31:46"""" user=""""xxx"""" apply=""""False"""" css='""" ' And if I adjust a slicer - I've removed a lot of the code for the sake of length but it was mostly just all .Selected=False for all the non-selected code. With ActiveWorkbook.SlicerCaches("Slicer_event_date") .SlicerItems("07/03/2013").Selected = True .SlicerItems("07/04/2013").Selected = True .SlicerItems("07/05/2013").Selected = True .SlicerItems("07/06/2013").Selected = True End With ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.0").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.1").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.2").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.3").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.4").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.5").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702.6").Delete ActiveWorkbook.Names("_AMO_ContentDefinition_105016702").Delete ActiveWorkbook.Names.Add Name:="_AMO_ContentDefinition_105016702.0", _ RefersToR1C1:= _ "=""'<ContentDefinition name=""""SASApp:CORPTICK.HISTORICAL_SALES"""" rsid=""""105016702"""" type=""""PivotTable"""" format=""""ReportXml"""" imgfmt=""""ActiveX"""" created=""""07/01/2014 11:56:37"""" modifed=""""07/16/2014 15:31:46"""" user=""""xxx"""" apply=""""False"""" css='""" End Sub 

Другим подходом было бы группировать элементы Rowfield по диапазонам дат, а затем фильтровать эти группы.

Вы не можете группировать элементы, когда поле является областью фильтров отчетов сводной таблицы; однако вы можете временно перенести это поле в область Ярлыки строк> Группировать по датам> переместить поле в область Фильтры отчетов, а затем скрыть элементы Группы, которые находятся за пределами желаемых диапазонов дат.

Для одного фильтра «между датами» это не слишком сложно. Что-то вроде этого, где «A10» является первым PivotItem вашего поля (фактический код должен будет найти эту ячейку) …

 Public Function Filter_PivotField_by_Date_Range(pvtField As PivotField, _ dtFrom As Date, dtTo As Date, Optional ByVal dtFrom2 As Date, Optional ByVal dtTo2 As Date) With pvtField '--make a rowfield if not already If .Orientation <> xlRowField Then .Orientation = xlRowField .ClearAllFilters '--add code to find a pivotitem Range("A10").Group Start:=CLng(dtFrom), End:=CLng(dtTo), _ Periods:=Array(False, False, _ False, False, False, False, True) '--move to report filters area .Orientation = xlPageField .Position = 1 End With End Function 

Для двух диапазонов «между датами» это все равно можно сделать, но вам, вероятно, нужно будет сделать все видимые предметы> сортировать по дате>, затем использовать Match или Find, чтобы найти начало и конец каждого диапазона дат для создания групп.

Считаете ли вы, что вы просто столкнулись с ограничениями EXCEL (на сегодняшнем оборудовании) для обработки сводных таблиц:

And that's where I'm at. I have no other ideas. My pivot table is actually created from a SAS dataset (flat file, not OLAP cube) so the data isn't physically in the workbook which is what I prefer since the data is nearing 800k rows and will continue to grow to possibly double the size. Since the SAS addin pulls the data directly into the pivot cache I can avoid data restraints

Вы говорите о 800K строках данных, возможно, в скором времени удваиваете до 1600K строк, а EXCEL только недавно взломал предел 65K.

Как изменить ваш запрос набора данных SAS только для возврата записей в указанный диапазон дат?

Если вы используете Excel 2007 или выше, вы можете добавить PivotFilter в свой PivotField и использовать тип xlDateBetween для фильтрации в вашем диапазоне дат (это будет охватывать случай blSingleRange = True :

 pvtField.PivotFilters.Add Type:=xlDateBetween, Value1:=CLng(dtFrom), Value2:=CLng(dtTo) 
  • Создание динамического диапазона в сводной таблице
  • Код Vba для создания сводной таблицы, а затем фильтра по значению top 10
  • Interesting Posts

    Удалить весь столбец с определенным контентом в python с помощью pandas

    Excel VBA запускает макросы на Foreach Loop без коммутационных листов

    Можете ли вы иметь макрос Excel для автоматического сохранения копии в формате CSV

    MS Query Excel iif синтаксическая ошибка выражения

    Графики точек доступа из списка

    Как суммировать все ячейки, содержащие только время в excel?

    Проблема отладки VBA

    используйте кнопку на userform, чтобы получить переменную и продолжить с помощью sub

    Получить индекс ячейки из значения ячейки, Apache POI

    SQL-запрос между датами в VBA

    Применение Формирование на нескольких листах

    Проверка флажков с помощью VBA

    Можете ли вы объявить зубчатые массивы в excel VBA напрямую?

    ActiveWorkbook.Styles возвращает ничего из-за того, что «вызванный объект отключился от своих клиентов»

    Форматирование ячейки Excel в качестве доллара с POI Apache, где машинная валюта не является долларом

    Давайте будем гением компьютера.