condizione IF per esistenza grafico



  • 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!