condizione IF per esistenza grafico
Hai un problema con Excel? 
condizione IF per esistenza grafico
di Luca (utente non iscritto) data: 18/11/2013 20:05:58
Salve a tutti, rieccomi :D
Questa volta sto realizzando una macro che verifica se esiste un dato grafico, nel caso esista, lo cancella e lo ricrea con in nuovi dati, altrimenti lo crea e basta.
Posso pure pensare di non farlo cancellare, ma semplicemente cambiare il range di dati che il grafico usa. Il problema, però, è che non riesco a fare una condizione if che mi dice se il grafico esista o meno.
Con il codice postato di sotto mi da il seguente errore--> "Errore di run time 1004 Errore definito dall'applicazione o dall'oggetto", proprio sull'IF.
Da cosa dipende?
Sub prova_grafico_with()
If ActiveSheet.ChartObjects(1).Name = "grafico" Then
ActiveSheet.ChartObjects("grafico").Activate
ActiveChart.Parent.Delete
With ActiveSheet.Shapes.AddChart.Chart
.ChartType = xlLineMarkersStacked
.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
.ClearToMatchStyle
.ChartStyle = 43
.ClearToMatchStyle
.SeriesCollecti0n(1).Name = "=""andamento"""
.SeriesCollecti0n(1).ApplyDataLabels
.Parent.Name = "grafico"
End With
Else
With ActiveSheet.Shapes.AddChart.Chart
.ChartType = xlLineMarkersStacked
.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
.ClearToMatchStyle
.ChartStyle = 43
.ClearToMatchStyle
.SeriesCollecti0n(1).Name = "=""andamento"""
.SeriesCollecti0n(1).ApplyDataLabels
.Parent.Name = "grafico"
End With
End If
End Sub |
di isy data: 18/11/2013 21:06:21
Ciao
Devi prima verificare se ci sono grafici su questo foglio
Sub prova_grafico_with()
If ActiveSheet.ChartObjects.Count = 0 Then
MsgBox "Non ci sono Grafici su questo foglio", vbInformation, "Avviso" |
di Luca (utente non iscritto) data: 18/11/2013 22:07:48
Grazie per l'intervento...purtroppo esistono altri grafici nel foglio e anche in generale nel file... :(
di Grograman (utente non iscritto) data: 19/11/2013 08:53:20
Ciao!
Senza un file di esempio non posso essere più preciso, ma a seguire la traduzione di quello che ti serve:
Option Explicit
Sub prova_grafico_with()
Dim ws As Worksheet
Dim oChar As ChartObject
Dim oShp As Shape
Dim blnEsiste As Boolean
For Each ws In ThisWorkbook.Worksheets
For Each oChar In ws.ChartObjects
With oChar
If .Name = "grafico" Then
blnEsiste = 1
.Parent.Delete
End If
End With
Next oChar
Next ws
If blnEsiste Then
Set oShp = ActiveSheet.Shapes.AddChart
With oShp
.Name = "grafico"
.Parent.Name = "grafico"
With .Chart
.ChartType = xlLineMarkersStacked
.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
.ClearToMatchStyle
.ChartStyle = 43
.ClearToMatchStyle
.SeriesCollection(1).Name = "andamento"
.SeriesCollection(1).ApplyDataLabels
End With
End With
Else
Set oChar = ActiveSheet.ChartObjects("grafico")
With oChar
.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
End With
Set oChar = Nothing
End If
End Sub |
di Grograman (utente non iscritto) data: 19/11/2013 08:57:09
Rettifico, non completamente funzionante, mi manca come aggiornare il range in caso il grafico esista già:
Option Explicit
Sub prova_grafico_with()
Dim ws As Worksheet
Dim oChar As ChartObject
Dim oShp As Shape
Dim blnEsiste As Boolean
For Each ws In ThisWorkbook.Worksheets
For Each oChar In ws.ChartObjects
With oChar
If .Name = "grafico" Then
blnEsiste = 1
End If
End With
Next oChar
Next ws
If Not blnEsiste Then
Set oShp = ActiveSheet.Shapes.AddChart
With oShp
.Name = "grafico"
.Parent.Name = "grafico"
With .Chart
.ChartType = xlLineMarkersStacked
.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
.ClearToMatchStyle
.ChartStyle = 43
.ClearToMatchStyle
.SeriesCollection(1).Name = "andamento"
.SeriesCollection(1).ApplyDataLabels
End With
End With
Else
Set oChar = ActiveSheet.ChartObjects("grafico")
With oChar
'.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
End With
Set oChar = Nothing
End If
End Sub
|
Luca
di Luca (utente non iscritto) data: 20/11/2013 10:16:48
Ciao, grazie mille per la risposta. E' molto utile.
A dir la verità il livello di codice che usi è un po' più avanzato di quello che conosco, e me lo dovrei studiare un po' :D
In effetti, come dici, l'aggiornamento nel caso il grafico esista, da "errore run time 438: Proprietà o metodo non supportati dall'oggetto". Non ho idea di come risolvere....
In teoria si può aggirare il problema facendo in modo che se il grafico già esiste, si cancella e si ricrea se non esiste, si crea e basta. Si dovrebbero fare un po' di prove...
P.S: se serve ancora ho allegato il file..
di Grograman (utente non iscritto) data: 20/11/2013 12:07:27
Forse ci sono!
Caso vuole che in questi giorni mi stanno capitando grafici da tutte le parti
O forse prima ignoravo l'argomento non conoscendolo...
Vedi se questo fa al caso tuo, mancava un "salto" da un insieme di oggetti all'altro:
Option Explicit
Sub grafico_finale()
Dim ws As Worksheet
Dim oChar As ChartObject
Dim oShp As Shape
Dim blnEsiste As Boolean
Dim X As Long
For Each ws In ThisWorkbook.Worksheets
For Each oChar In ws.ChartObjects
With oChar
If .Name = "grafico" Then
blnEsiste = 1
Exit For
End If
End With
Next oChar
Next ws
If Not blnEsiste Then
Set oShp = ActiveSheet.Shapes.AddChart
With oShp
.Name = "grafico"
.Parent.Name = "grafico"
With .Chart
.ChartType = xlLineMarkersStacked
.SetSourceData Source:=Range("A21:B" & 21 + [counta(B22:B55)])
.ClearToMatchStyle
.ChartStyle = 43
.ClearToMatchStyle
.SeriesCollection(1).Name = "andamento"
.SeriesCollection(1).ApplyDataLabels
End With
End With
Else
Set oChar = ActiveSheet.ChartObjects("grafico")
With oChar
X = .Parent.Range("A" & .Parent.Rows.Count).End(xlUp).Row
.Chart.SetSourceData Source:=Range("A21:B" & X)
End With
Set oChar = Nothing
End If
End Sub |
di Luca (utente non iscritto) data: 20/11/2013 14:31:46
Funziona perfettamente!!!
Ora devo solo capire il codice...nel caso posso farti qualche domanda?
di Grograman (utente non iscritto) data: 20/11/2013 14:43:48
Certolo!
Se trovo il tempo magari lo commento come si deve.
di Luca (utente non iscritto) data: 21/11/2013 14:08:43
Avevo scritto, ma mi ha cancellato il post.
Comunque, stavo cercando di confrontare la mia istruzione di if:
If ActiveSheet.ChartObjects(1).Name = "grafico" Then
ActiveSheet.ChartObjects("grafico").Activate
ActiveChart.Parent.Delete
con la tua. Tu ovviamente fai le cose "per bene", dichiarando variabili, mettendo i vari cicli di for etc. Mi chiedevo però quanto era possibile semplificare il tutto.
Ho provato per esempio a togliere il for più esterno, ma mi da errore, sia che lascio ws.ChartObjects nel for successivo, sia che scrivo ChartObjects. Il with invece riesco a toglierlo, ma non ha "impatto su niente", diciamo.
Comunque, c'è un modo di scrivere il codice per esempio senza la definizione delle variabili, e relativamente al solo foglio in esame e non tutto il file? (quindi con un solo ciclo for?)
Lo chiedo, perchè, quello che secondo me manca veramente al mio codice è solo un for che cicla tra gli oggetti, ma magari sto prendendo una cantonata assurda!
Grazie!
di Luca (utente non iscritto) data: 22/11/2013 17:33:15
nessuno? :(
di Luca (utente non iscritto) data: 24/11/2013 13:34:52
Ho notato anche un'altra cosa: la macro rinomina il nome del foglio con "grafico".
Facendo qualche prova, è il comando:
If Not blnEsiste Then
Set oShp = ActiveSheet.Shapes.AddChart
With oShp
.Name = "grafico"
.Parent.Name = "grafico"
Se metto nel .Parent.Name = "nome foglio", il problema si risolve.
Mi chiedo però a questo punto come mai accade questo: l'oggetto shape creato, cosa è? non è lo sheet... :mumble:
di Vecchio Frac data: 24/11/2013 14:14:39
Non capisco la tua perplessità... l'oggetto oShp è di tipo Chart :)
di Luca (utente non iscritto) data: 24/11/2013 14:21:09
La mia perplessità è: perchè la macro va a cambiare il nome del foglio?
di Vecchio Frac data: 24/11/2013 18:11:48
Bè,
With oShp
.Name = "grafico"
.Parent.Name = "grafico"
il "padre" (.Parent) di un oggetto Chart è il foglio dove l'oggetto Chart si trova.
La macro ne cambia, appunto il nome, con la seconda istruzione.
Non lo facesse, mi preoccuperei :)
di Luca (utente non iscritto) data: 25/11/2013 17:16:44
Ottima spiegazione
Googlando un po' ho visto che gli oggetti di tipo shape sono quelli associati a disegni/forme etc. Quindi, se ho capito bene, per creare un grafico l'oggetto di tipo shape serve per creare il "riquadro" in cui viene creato poi successivamente il grafico, tramite un oggetto di tipo chart. E' esatto?
Però, non ho capito, perchè l'oggetto oShp è creato di tipo shape e poi diventa un chart..come si spiega? Chiedo scusa se sto facendo molte domande teoriche, ma per me è importante capite... :(
Grazie in anticipo!
Vuoi Approfondire?