Eventi per grafici chenon esistono



  • Eventi per grafici che...non esistono!
    di zangyef data: 25/03/2013 13:35:00

    Ciao a tutti,
    ho un problema che proprio non riesco a risolvere.
    E' possibile controllare gli eventi di un oggetto Chart SENZA che il codice risieda nel suo modulo?
    In sostanza ho un grafico inserito come oggetto Chart (quindi non embedded) sul quale devo aggiungere una procedura evento "Chart_Mousedwn" (cioè mi fa una particolare azione quando clicco dentro il grafico). Il fatto è che all'apertura del file questo oggetto Chart non esiste e viene creato solo durante l'utilizzo del file.
    Ho provato a guardare in giro ma non trovo nulla. So che le procedure evento vanno inserite nel rispettivo modulo di classe (se l'oggetto si chiama Chart1 metterò il codice evento nel modulo di classe Chart1), ma se l'oggetto non esiste dove metto il codice?



  • di Vecchio Frac data: 25/03/2013 14:29:42

    Giocando un po' sporco, si può fare ^_^
    (magari esistono metodi migliori, forse con un template...)

    La mia idea è quella di farti creare a runtime il grafico, premendo un pulsante di comando, poi sempre via codice inserendo nell'area codice del grafico appena creato le righe di VBA necessarie allo scopo. Non parlare di moduli di classe perchè non è appropriato (a te non servono variabili con eventi ma solo procedure per gestire gli eventi) :)

    Supponi di avere una piccolissima tabella in B3:C7.
    Lanciando la macro che segue (associabile a un pulsante) crei un foglio grafico basato sui dati di quel range, quindi metti in una variabile stringa il codice necessario a intercettare l'evento clic sul grafico. Tale codice è inserito a runtime direttamente nell'area codice del foglio grafico appena creato, ed è operativo: se fai clic sul grafico, quando premi il pulsante del mouse compare il messaggio ("Hello! My name is ").
    Se il codice da incollare è molto lungo puoi inserirlo in un file di testo o addirittura in un modulo e copiarlo da lì (con il metodo AddFromFile o leggendo il contenuto del modulo creato ad hoc).


     
    Private Sub generate_code_for_chart()
    Dim ch As Chart, s As String
    
        [b3:c7].Select
        Set ch = Charts.Add
        
        s = "Private Sub Chart_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)" & vbCrLf & _
            "MsgBox ""Hello! My name is "" & ActiveChart.Name " & vbCrLf & _
            "End Sub"
    
        
        Application.VBE.ActiveVBProject.VBComponents(ch.CodeName).CodeModule.AddFromString s
        
    
    End Sub






  • di zangyef (utente non iscritto) data: 25/03/2013 15:04:11

    Interessante! Grazie del consiglio.
    Eviterei di leggere da file perchè tutto il codice andrà inserito in un componente aggiuntivo .xla e accompagnare questo file con un file di testo non mi piace...però l'idea di creare un modulo ad ho dove andarmi a leggere il codice da copiare mi piace. Non so come si faccia, ma mi piace.
    Se non vado errato dovrebbe funzionare anche per più oggetti Chart, perchè la variabile ch è associata ogni volta al nuovo oggetto creato che avrà un id diverso. E' così?
    Te lo chiedo perchè quello che ho io, appena apro il file, è un foglio con molte colonne. Voglio lasciare all'operatore decidere quale colonna graficare con la possibilità di creare più grafici in sequenza (non contemporaneamente). Quindi devo avere la possibilità di inserire quel codice dentro tanti moduli quanti sono i grafici creati.
    Grazie ancora!



  • di Vecchio Frac data: 25/03/2013 15:17:01

    Certo, ogni grafico è indipendente e non devi nemmeno preoccuparti del suo nome (neanche se l'utente lo cambia nella linguetta di scheda) perchè si fa riferimento al suo Codename.

    Per quanto riguarda leggere il codice da un modulo lo preferirei anch'io rispetto alla soluzione su file, perchè puoi indentare il codice, commentarlo, scriverlo bene e soprattutto modificarlo a piacimento anche in futuro (più facile che non manutenere delle stringhe inline).

    Ottenere questo risultato è semplice. Assumo che il modulo in cui è depositato il codice della procedura MouseDown si trova nel Modulo1.
     
    'codice del foglio1
    Option Explicit
    
    Sub generate_code_for_chart()
    Dim ch As Chart, s As String, code_for_chart As Object
    
        Foglio1.[b3:c7].Select
        Set ch = Charts.Add
        
        Set code_for_chart = Application.VBE.ActiveVBProject.VBComponents("Modulo1").CodeModule
        s = code_for_chart.Lines(1, code_for_chart.CountOfLines)
    
        Application.VBE.ActiveVBProject.VBComponents(ch.CodeName).CodeModule.AddFromString s
    
    End Sub
    
    
    'codice di Modulo1
    Private Sub Chart_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
        
        MsgBox "Hello! My name is " & ActiveChart.Name
    
    End Sub






  • di zangyef (utente non iscritto) data: 26/03/2013 12:04:36

    E' proprio quello che mi serve ma ho provato a far girare il codice e c'è qualcosa che non funziona.
    Durante l'esecuzione della macro mi da un errore con questa voce:
    "L'accesso a livello di programmazione al Progetto Visual Basic non è attendibile".
    Se entro in modalità debug all'inizio della funzione il codice genera l'errore alla riga che riporto.
    Per caso hai già provato il codice?
     
    Set code_for_chart = Application.VBE.ActiveVBProject.VBComponents("Modulo1").CodeModule



  • di Vecchio Frac data: 26/03/2013 12:10:19

    E' un messaggio di protezione del codice Visual Basic.
    Si risolve così:
    Menu Strumenti --> Macro --> Protezione --> linguetta Editori attendibili, quindi spunta le due checkbox (considera attendibili tutti i modelli e considera attendibile il progetto)





  • di zangyef (utente non iscritto) data: 26/03/2013 13:06:46

    Ottimo!
    Sei una macchina da guerra!
    Prima di spuntare su "discussione risolta" voglio inglobare il codice sul mio progetto che prevede altre cose.
    Ma sono sicuro che non avrò problemi.
    Grazie mille



  • di Vecchio Frac data: 26/03/2013 13:49:42

    Ingloba, ingloba... e attento ai riferimenti (Foglio1 dovrebbe restare ma se no è così scrivi il CodeName corretto di quel foglio).





  • di zangyef data: 02/04/2013 12:50:49

    Scusate il ritardo...tutto ok!