【问题标题】:Error while creating Pivot Table automatically自动创建数据透视表时出错
【发布时间】:2017-10-17 17:58:00
【问题描述】:

我创建了一个宏来通过索引匹配和一般计算创建一个包含一些值的表。该表位于范围("AA1:BA"&LastRow) --> 我正在写 LastRow 因为 lastrow 每天都在变化。我想创建一个位于单元格(9,1)中的数据透视表,并将我创建的初始表作为源。我构建了您在下面看到的代码,但它给了我一个错误说数据透视表字段名称在行上无效:

Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange).CreatePivotTable(TableDestination:=PSheet.Cells(2, 2), TableName:="PivotTable")

与数据透视表相关的完整代码如下。

   Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable As PivotTable
Dim PRange As Range
Dim LastRow As Long
Dim LastCol As Long

Application.DisplayAlerts = False
Application.DisplayAlerts = True
Set PSheet = Worksheets("Budget_Report")
Set DSheet = Worksheets("Budget_Report")

LastRow = DSheet.Cells(Rows.Count, 27).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column

Set PRange = DSheet.Cells(1, 27).Resize(LastRow, LastCol)

Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable = PCache.CreatePivotTable(TableDestination:=PSheet.Cells(9, 1), TableName:="PivotTable")

With ActiveSheet.PivotTables("PivotTable").PivotFields("T-Lane")
.Orientation = xlRowField
.Position = 1
.Subtotals(1) = True
.Subtotals(1) = False
End With

With ActiveSheet.PivotTables("PivotTable").PivotFields("Monthly Cost FCST")
.Orientation = xlDataField
.Position = 1
.Function = xlSum
.Name = "Monthly Cost Forecast"
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Monthly Vol FCST")
.Orientation = xlDataField
.Position = 2
.Function = xlSum
.Name = "Monthly Vol Forecast"
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Monthly $/SU FCST")
.Orientation = xlDataField
.Position = 3
.Function = xlSum
.Name = "Monthly $/SU Forecast"
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Monthly Cost Actuals")
.Orientation = xlDataField
.Position = 4
.Function = xlSum
.Name = "Monthly Cost Actual"
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Monthly Vol Actuals")
.Orientation = xlDataField
.Position = 5
.Function = xlSum
.Name = "Monthly Vol Actual"
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Monthly $/SU Actuals")
.Orientation = xlDataField
.Position = 6
.Function = xlSum
.Name = "Monthly $/SU Actual"
End With

下面提供了构建数据透视表的录制宏(它具有特定范围,当然不是 lastrow 和 lastcolumn)

ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:="Budget_Report!R1C27:R279C53", Version:=6).CreatePivotTable TableDestination:="Budget_Report!R9C1", TableName:="PivotTable1", DefaultVersion:=6
Sheets("Budget_Report").Cells(9, 1).Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields("T-Lane")
    .Orientation = xlRowField
    .Position = 1
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables("PivotTable1").PivotFields("Monthly Cost FCST"), "Monthly Cost Forecast", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables("PivotTable1").PivotFields("Monthly Vol FCST"), "Monthly Vol Forecast", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables("PivotTable1").PivotFields("Monthly $/SU FCST"), "Monthly $/SU Forecast", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables("PivotTable1").PivotFields("Monthly Cost Actuals"), "Monthly Cost Actual", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables("PivotTable1").PivotFields("Monthly Vol Actuals"), "Monthly Vol Actual", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables("PivotTable1").PivotFields("Monthly $/SU Actuals"), "Monthly $/SU Actual", xlSum

ActiveWorkbook.ShowPivotTableFieldList = False

【问题讨论】:

  • 如果没有错误,数据透视表的字段名称是什么?
  • hmm 很抱歉 jsotola,但我不太明白这个问题。我对数据透视表不是很有经验,所以我无法真正回答这个问题 :( 我只是在网上看到代码并尝试实现它对于我的宏。
  • 您真的有可以输入数据透视表的数据吗? ...如果你这样做,然后手动创建数据透视表。 excel 应该抱怨字段名称,它可能会指出问题所在。
  • 我刚刚手动创建了数据透视表,没有问题。可能是因为我在设置 PTable 的行中命名了数据透视表吗?
  • 再次创建数据透视表,但这次在创建之前启动宏记录器。然后检查生成的代码

标签: vba excel pivot-table


【解决方案1】:

在设置PRange 时,您可以使用Cells.SpecialCells 方法来设置您的范围,即使您并不总是知道该结束地址是什么,只要您确定下面的某处不会有额外的数据/超出你的目标范围。

看起来像这样:

Set PRange = DSheet.Range(DSheet.Cells(1, 27), DSheet.Cells.SpecialCells(xlCellTypeLastCell))

另外,这是个人风格的问题,但我发现嵌套With 块有时会导致代码更具可读性。例如:

With ActiveSheet.PivotTables("PivotTable1")
    With .PivotFields("Field 1")
        .Caption = "My first field"
        .Function = xlSum
    End With
    With .PivotFields("Field 2")
        .Caption = "My second field"
        .Function = xlMax
    End With
End With

等等

最终产品如下所示:

Dim DSheet As Worksheet  ', PSheet As Worksheet
Dim PCache As PivotCache, PTable As PivotTable, PRange As Range
'Dim LastRow As Long, LastCol As Long

'Application.DisplayAlerts = False   ' This is redundant since you're setting it to true below.
Application.DisplayAlerts = True
'Set PSheet = Worksheets("Budget_Report") '
Set DSheet = Worksheets("Budget_Report") ' These two are Redundant - I am using only DSheet.

'LastRow = DSheet.Cells(Rows.Count, 27).End(xlUp).Row
'LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column

Set PRange = DSheet.Range(Cells(1, 27),Cells.SpecialCells(xlCellTypeLastCell))

Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable = PCache.CreatePivotTable(TableDestination:=DSheet.Cells(9, 1), TableName:="PivotTable")

With ActiveSheet.PivotTables("PivotTable")
 With .PivotFields("T-Lane")
    .Orientation = xlRowField
    .Position = 1
    .Subtotals(1) = True   ' You're resetting this value in the next     line, you can probably remove it.
    .Subtotals(1) = False
 End With

With .PivotFields("Monthly Cost FCST")
.Orientation = xlDataField
.Position = 1
.Function = xlSum
.Caption = "Monthly Cost Forecast" 'You want .Caption here, not .Name
End With

With .PivotFields("Monthly Vol FCST")
.Orientation = xlDataField
.Position = 2
.Function = xlSum
.Caption = "Monthly Vol Forecast"
End With

With .PivotFields("Monthly $/SU FCST")
.Orientation = xlDataField
.Position = 3
.Function = xlSum
.Caption = "Monthly $/SU Forecast"
End With

With .PivotFields("Monthly Cost Actuals")
.Orientation = xlDataField
.Position = 4
.Function = xlSum
.Caption = "Monthly Cost Actual"
End With

With .PivotFields("Monthly Vol Actuals")
.Orientation = xlDataField
.Position = 5
.Function = xlSum
.Caption = "Monthly Vol Actual"
End With

With .PivotFields("Monthly $/SU Actuals")
.Orientation = xlDataField
.Position = 6
.Function = xlSum
.Caption = "Monthly $/SU Actual"
End With

End With

【讨论】:

  • 很高兴听到它对您有用。注意,MSDN 上的 PivotCaches.Create 文章指出 传递 Range 时,建议要么使用字符串指定工作簿、工作表和单元格范围,要么设置命名范围并将名称作为字符串传递.传递 Range 对象可能会意外导致“类型不匹配”错误。 link
  • 很抱歉再次打扰你,伙计。如果我想在同一张表中添加第二个表,具有相同的源数据(但当然显示数据不同),我应该在代码中更改什么?我设置了一个新的 PTable2,我只是将数据透视表的名称更改为 PivotTable2,它说它不能覆盖数据透视表
  • 您还需要指定一个新的位置来放置它 - 您不能将一个枢轴置于另一个之上。 TableDestination:=...
【解决方案2】:

您似乎尝试创建同一个表两次:

Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange).CreatePivotTable(TableDestination:=PSheet.Cells(2, 2), TableName:="PivotTable")
Set PTable = PCache.CreatePivotTable(TableDestination:=PSheet.Cells(9, 1), TableName:="PivotTable")

把它一分为二:

Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable = PCache.CreatePivotTable(TableDestination:=PSheet.Cells(9, 1), TableName:="PivotTable")

【讨论】:

  • @PericlesFaliagas Set PTable... 的行绝对正确。因此,要么您已经有一个具有该名称的数据透视表,要么目的地有问题,或者 PivotCache 没有正确创建。
  • 它实际上是我在这本工作簿上唯一的数据透视表!是不是我在同一张工作表中创建了数据透视表,并将其用作源数据?
  • @PericlesFaliagas 可能是您试图将数据透视表写入占用的范围。在Set PCache 之后进入代码并在即时窗口中输入?PCache.SourceData 并检查缓存是否创建正确
  • 它告诉我需要对象
  • @PericlesFaliagas 那么很可能您的PivotCache 没有正确创建。检查ActiveWorkbook 是否与PRange 中包含您的数据的工作簿相同。
【解决方案3】:

分配给PCache only Cache:

Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)

【讨论】:

  • 它在我设置 PTable 的那一行给出了一个自动化错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多