Я встроил код в Excel, чтобы брать данные из сводной таблицы и вставлять их в диаграмму, сводная диаграмма, напрямую связанная с таблицей, не даст мне той маневренности, которую я ищу. Причина, по которой я прошел через трудности создания такого «замысловатого» кода, заключается в том, что для каждой комбинации Plant и Test Info мне нужно, чтобы это была отдельная запись в диаграмме.
Итак, основная цель этого кода — пройти по каждой комбинации Plant и Test info (вложенные команды for), а затем вставить данные в диаграмму. Мой пользователь не будет менять расположение столбцов для x и y, поэтому смещения работают нормально.
Моя проблема в том, что если комбинация информации о заводе/тесте не существует, она все равно вносит ее в диаграмму. Когда я пытаюсь использовать команду goto и отправить ее в Next PI2 с помощью дескриптора ошибки, это не работает (возможно, из-за вложенных команд if). Я искал команду, которая могла бы отправить мой код в определенную строку в коде (то есть сразу после команд графика), но мне не повезло...
Кто-нибудь знает, как перейти к определенной строке в случае ошибки?
Я добавил набор команд для возобновления на следующем PI2, где я говорю при возникновении ошибки перейти к errhandler, а затем из errhandler перейти к следующей итерации, но когда я запускаю код и получаю ошибку, он не проходит по этому маршруту, а вместо этого останавливается на строке «пересечения».
Sub CreatePivotChart()
Dim PF1 As PivotField
Dim PI1 As PivotItem
Dim PI2 As PivotItem
Dim PF2 As PivotField
Dim chartcount As Integer
Dim pt As PivotTable
Set pt = Worksheets("Pivot Table").PivotTables("PivotTable")
'set up pivot field locations 1 - plant and unit , 2 - test conditions
Set PF1 = Worksheets("PivotTable").PivotTables("PivotTable").PivotFields("Plant")
Set PF2 = Worksheets("Pivot Table").PivotTables("PivotTable").PivotFields("Test Info")
'clear the chart from previous run
chartcount = 0
Sheets("Pivot Table Graph").ChartObjects("Chart 1").Chart.ChartArea.ClearContents
On Error GoTo ErrHandler
'find each visible unit
For Each PI1 In PF1.PivotItems
If PI1.Visible = True Then
Unit = PI1.Name
For Each PI2 In PF2.PivotItems
'for each unit and test condition find the information at their intersection
If PI2.Visible = True Then
TC = PI2.Name
'find the information that corresponds to each unit/test condition combination
Intersect(pt.PivotFields("Plant").PivotItems(Unit).DataRange.EntireRow, pt.PivotFields("Test Info").PivotItems(TC).DataRange).Select
Selection.Offset(-1, 0).Select
ForXRanges = "='Pivot Table'!" & Selection.Address
Selection.Offset(0, 1).Select
ForYRanges = "='Pivot Table'!" & Selection.Address
ForRangesName = Unit & "_" & TC
'for each combination create a new series on the chart
chartcount = chartcount + 1
Sheets("Pivot Table Graph").ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.SeriesCollection(chartcount).Name = ForRangesName
ActiveChart.SeriesCollection(chartcount).XValues = ForXRanges
ActiveChart.SeriesCollection(chartcount).Values = ForYRanges
End If
NextIteration:
Next PI2
End If
Next PI1
Exit Sub
ErrHandler:
Resume NextIteration:
End Sub
решение1
Лучшим подходом было бы проверить ваши данные с помощью оператора if, чтобы убедиться, что ваши данные действительны. Если нет, не продолжайте работу с блоком кода, который может сгенерировать ошибку.
В вашем примере это может сработать... измените это:
'find the information that corresponds to each unit/test condition combination
Intersect(pt.PivotFields("Plant").PivotItems(Unit).DataRange.EntireRow, pt.PivotFields("Test Info").PivotItems(TC).DataRange).Select
Selection.Offset(-1, 0).Select
ForXRanges = "='Pivot Table'!" & Selection.Address
Selection.Offset(0, 1).Select
ForYRanges = "='Pivot Table'!" & Selection.Address
ForRangesName = Unit & "_" & TC
'for each combination create a new series on the chart
chartcount = chartcount + 1
Sheets("Pivot Table Graph").ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.SeriesCollection(chartcount).Name = ForRangesName
ActiveChart.SeriesCollection(chartcount).XValues = ForXRanges
ActiveChart.SeriesCollection(chartcount).Values = ForYRanges
К этому:
'find the information that corresponds to each unit/test condition combination
Set isect = Application.Intersect(pt.PivotFields("Plant").PivotItems(Unit).DataRange.EntireRow, pt.PivotFields("Test Info").PivotItems(TC).DataRange)
If isect Is Nothing Then
'Msgbox "Ranges do not intersect"
Else
isect.Select
Selection.Offset(-1, 0).Select
ForXRanges = "='Pivot Table'!" & Selection.Address
Selection.Offset(0, 1).Select
ForYRanges = "='Pivot Table'!" & Selection.Address
ForRangesName = Unit & "_" & TC
'for each combination create a new series on the chart
chartcount = chartcount + 1
Sheets("Pivot Table Graph").ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.SeriesCollection(chartcount).Name = ForRangesName
ActiveChart.SeriesCollection(chartcount).XValues = ForXRanges
ActiveChart.SeriesCollection(chartcount).Values = ForYRanges
End If
Я не могу это проверить, так как у меня нет вашей рабочей тетради, но если это не сработает, то это должно продемонстрировать подход.
решение2
goto
Обрабатывать ошибки без VBA можно следующим образом:
Sub ErrorHandling()
Dim A, d
On Error Resume Next
REM Line that throws an error
A = A / 0
REM Store details about your error before it gets cleared
d = Err.Description
On Error GoTo 0
REM You see and can handle your error message here
MsgBox d
End Sub
On Error Resume Next
Отключает выдачу ошибок
On Error GoTo 0
Включает выдачу ошибок и очищает Err
объект
решение3
В итоге я сам ответил на свои вопросы, продолжая просматривать старые посты и т. д., и обнаружил,http://www.cpearson.com/excel/errorhandling.htmбыть чрезвычайно полезным.
Оказалось, что я пытался использовать две команды goto, сначала goto обработчик ошибок, а затем goto следующая итерация. Мне нужно было изменить вторую goto, чтобы возобновить.
Спасибо всем за помощь, ребята, код выше работает отлично!