VBA数据透视过滤器 - 日期范围

问题描述 投票:0回答:3

希望将数据透视表过滤到日期范围内。日期过滤器位于枢轴的顶部,主表有3列。我有一张带有实际例子的图片,但无法在此处上传。

如果我输入2018年2月1日 - 2018年3月1日的日期范围,则过滤器可以正常工作。如果我输入2018年2月1日 - 2018年2月28日的日期范围,过滤器会错过2月3日 - 2月9日,从2月10日的剩余数据再次回升。

不同的日期范围会产生此行为的变体。

从我的在线研究中,这种类型的VBA过滤有一些错误,代码以美国日期格式读取数据,无论Excel设置和数据本身(因此格式化代码,没有它会导致不匹配错误)。我在网上看到过几个解决方法,例如使用CLng,但下面的方法是我得到的最接近的方法。

  • 数据透视表本身位于名为“Pivots”的工作表上。列A-C,单元格B2中的日期,第4行中的主表标题。
  • 日期范围位于名为“Paretos”的工作表上,下面是单元格引用。
  • 我在这里工作的表是PivotTable1

Sub FilterPivotDates()

Application.DisplayAlerts = False
Application.ScreenUpdating = False
Application.EnableEvents = False

Dim ws As Worksheet, ws2 As Worksheet, pt As PivotTable, pf As PivotField, PI As PivotItem
Dim FromDate As Date, ToDate As Date

Set ws = ThisWorkbook.Worksheets("Pivots")
Set ws2 = ThisWorkbook.Worksheets("Paretos")

FromDate = ws2.Range("B1").Value
ToDate = ws2.Range("E1").Value

pivno = 1
MCCol = 25

Set pt = ws.PivotTables("PivotTable" & pivno)
Set pf = pt.PivotFields("Date")

'On Error Resume Next

Do While pivno < 2 '25
    Set pt = ws.PivotTables("PivotTable" & pivno)
    Set pf = pt.PivotFields("Date")
    pt.PivotFields("Date").ClearAllFilters
    With pf
        For Each PI In pf.PivotItems
            If PI.Value >= Format(FromDate, "M/D/YYYY") And PI.Value <= Format(ToDate, "M/D/YYYY") Then PI.Visible = True Else PI.Visible = False
        Next
    End With

pivno = pivno + 1

Loop

Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.EnableEvents = True

End Sub

逐步使用msgbox命令,似乎缺少日期在其中一个日期检查上失败,因此AND函数删除该条目。我无法解决最新情况。

使用Excel 2016

excel vba
3个回答
0
投票

Excel将日期存储为数值,即使您可能将其格式从"mm/dd/yyyy"更改为"dd-mmm-yy"或更改为"mmmm"等月份名称,它实际上不会更改Excel存储值的方式,即数字。

例如,取01-Feb-2018,如果你将>> Paste Special(仅限值)复制到相邻单元格,你将获得43132

在您的情况下,最好的方法是比较日期的数值。

在您的代码中,替换您的行:

If Pi.Value >= Format(FromDate, "M/D/YYYY") And Pi.Value <= Format(ToDate, "M/D/YYYY") Then ...

附:

If Pi.Value >= CDbl(FromDate) And Pi.Value <= CDbl(ToDate) Then ...

你可以稍微优化你的Do While循环:

Do While pivno < 2 '25
    Set pt = ws.PivotTables("PivotTable" & pivno)
    Set pf = pt.PivotFields("Date")

    With pf
        .ClearAllFilters

        For Each pi In .PivotItems
            ' since you already used .ClearAllFilters, you don't need to use Visible = True,
            ' only hide the ones which are not within your desired dates range
            If Not (pi.Value >= CDbl(FromDate) And pi.Value <= CDbl(ToDate)) Then pi.Visible = False
        Next
    End With

    pivno = pivno + 1
Loop

0
投票

好吧,看来我找到了一个解决方法。

用于创建数据透视表的源数据需要是原始Excel数字,43108或其他任何内容而不是日期。

当使用CDbl(FromDate)完成此操作时,这似乎有效。

只是试图澄清,问题源于枢轴项目名称(或标题,或值等),当它是一个日期,无法格式化,设置或处理为美国日期格式以外的任何其他内容。尝试将任何数据与它匹配似乎不起作用,只是如上所述更改原始数据并使用CDbl转换代码中的任何过滤条件似乎让我无处可去。


0
投票

PivotItems.Value属性返回String值。 Format函数还返回String(Variant)值。

因此,当您执行PI.Value与FromDate / ToDate的比较时,您的代码似乎执行TEXT比较,而不是DATE比较。在文本比较中,某些日期正确地“超出范围”。

重现下面图片中的简单表格(确保在输入值之前将所有字段设置为文本格式),您将看到它可以重现与您提到的相同的“错误”行为。

解决方案可能以某种方式将您比较的值转换回日期格式。

Simple test

© www.soinside.com 2019 - 2024. All rights reserved.