Eu construí um código no Excel para pegar os dados de uma tabela dinâmica e inseri-los em um gráfico, um gráfico dinâmico vinculado diretamente à tabela não me dará a capacidade de manobra que procuro. A razão pela qual tive o trabalho de criar um código tão 'complexo' é que, para cada combinação de informações de planta e teste, preciso que seja uma entrada separada no gráfico.
Portanto, o ponto principal deste código é passar por cada combinação de informações de planta e teste (os comandos for aninhados) e inserir os dados no gráfico. Meu usuário não alterará a localização da coluna para x e y, portanto os deslocamentos funcionam bem.
Meu problema é que, se a combinação de informações de planta/teste não existir, ela será inserida no gráfico de qualquer maneira. Quando tento usar o comando goto e enviá-lo para o Next PI2 usando um errorhandle, ele não funciona (talvez por causa dos comandos if aninhados). Eu estava procurando um comando que pudesse enviar meu código para uma linha específica do código (ou seja, logo após os comandos do gráfico), mas não tive sorte ...
Alguém sabe como pular para uma linha específica em caso de erro?
Eu adicionei o conjunto de comandos para retomar no próximo PI2, onde digo em caso de erro, vá para errhandler, depois de errhandler vá para a próxima iteração, mas quando executo o código e recebo um erro, ele não está passando por essa rota, é em vez disso, parando na linha de 'interseção'.
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
Responder1
Uma abordagem melhor seria testar seus dados com uma instrução if para garantir que seus dados sejam válidos. Caso contrário, não prossiga com o bloco de código que pode gerar um erro.
No seu exemplo, isso pode funcionar... mude isso:
'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
Para isso:
'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
Não posso testar isso porque não tenho sua apostila, mas se não funcionar, devo demonstrar a abordagem.
Responder2
Você pode lidar com erros sem goto
VBA assim:
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
Desativa erros de lançamento
On Error GoTo 0
Permite lançar erros e limpa o Err
objeto
Responder3
Acabei respondendo minhas próprias perguntas, continuando a folhear postagens antigas etc., descobrihttp://www.cpearson.com/excel/errorhandling.htmpara ser extremamente útil.
Acontece que eu estava tentando usar dois comandos goto, primeiro para ir para o manipulador de erros e depois para a próxima iteração. O que eu precisava fazer era mudar o segundo goto, para retomar.
Obrigado por toda a ajuda pessoal, o código acima funciona perfeitamente!