我对VBA还是很陌生,我想知道如何简化此代码? 该代码基本上将字段添加到数据透视表中的值。
Dim pt As PivotTable
Dim pf As PivotField
Dim SField As String
'Set Variable
Set pt = ActiveSheet.PivotTables(1)
SField = ActiveSheet.Shapes(Application.Caller).TextFrame.Characters.Text
'Remove Existing Fields
For Each pf In pt.DataFields
If pf.Name <> "Values" Then
pf.Orientation = xlHidden
End If
Next pf
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2016"), "Sum of 2016", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2017"), "Sum of 2017", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2018"), "Sum of 2018", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2019"), "Sum of 2019", xlSum
End Sub
答案 0 :(得分:2)
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2016"), "Sum of 2016", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2017"), "Sum of 2017", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2018"), "Sum of 2018", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("2019"), "Sum of 2019", xlSum
U可以创建一个函数
Public Sub PvSumByYear(year As String)
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields(year), "Sum of " & year, xlSum
End Sub
现在使用
for i = 6 to 9
call PvSumByYear(Vba.cstr(2010+ i))
next i
答案 1 :(得分:1)
Dim pt As PivotTable Dim pf As PivotField Dim SField As String
首先从不在程序顶部的单块声明变量开始,而是在尽可能接近其首次使用/赋值的位置声明变量。并使用清楚表达的,可读的标识符传达语义含义,而不仅仅是它们的数据类型。
Dim target As PivotTable
Set target = ActiveSheet.PivotTables(1)
RemoveExistingFields target
通知SField
已消失-已分配,但从未在任何地方引用。注释“在XYZ之下执行代码”几乎总是错失更好抽象的机会:
Private Sub RemoveExistingFields(ByVal target As PivotTable)
Dim currentField As PivotField
For Each currentField In target.DataFields
If currentField.Name <> "Values" Then currentField.Orientation = xlHidden
Next
End Sub
单手提取此过程就无需在原始范围内声明pf
/ currentField
,从而大大减少了认知负担。
与第二个块相同-因此最终的重构过程可能如下所示:
Public Sub ResetPivotDataFields()
Dim target As PivotTable
Set target = ActiveSheet.PivotTables(1)
RemoveExistingFields target
Dim currentYear As Long
currentYear = GetCurrentYear
AddYearDataFields target, currentYear - 3, currentYear
End Sub
GetCurrentYear
可能像这样简单:
Private Function GetCurrentYear() As Long
'TODO confirm year logic correctness (currently assumes regular calendar years)
GetCurrentYear = Year(Date)
End Function
AddYearDataFields
可能看起来像这样:
Private Sub AddYearDataFields(ByVal target As PivotTable, ByVal fromYear As Long, ByVal toYear As Long)
If fromYear > toYear Then Err.Raise 5, , "FromYear must be less than or equal to ToYear."
Dim currentYear As Long
For currentYear = fromYear To toYear
target.AddDataField target.PivotFields(fieldName), "Sum of " & fieldName, xlSum
Next
End Sub
将过程保持小而专业,给它们起好名字,并且毫不犹豫地将过程的依赖项作为参数传递;您的代码将很快变得清晰和简单。始终验证您的输入,过时的关键字和构造(例如Call
语句)始终使用显式且适当的访问修饰符(如果不需要,请不要创建过程Public
;隐式默认为Public
),并传递参数ByVal
(默认值为ByRef
)。