Как я могу сделать этот код менее сложным? - PullRequest
1 голос
/ 18 апреля 2019

Я довольно новичок в 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

Ответы [ 2 ]

2 голосов
/ 18 апреля 2019
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 голос
/ 19 апреля 2019
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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...