Dunque, ricapitolando e sperando che questo lavoro possa tornare utile a qualcun altro :-) provo a sintetizzare gli aspetti salienti di questa discussione.
L’obiettivo è quello di rilevare il cambiamento di valore di una cella contenente DDE al fine di sfruttare questo evento per collegarlo ad altri (es. l’esecuzione in automatico di una macro).
Per rilevare il cambiamento di valore in una cella contenente DDE, le macro normalmente utilizzate (che funzionano egregiamente quando i cambiamenti derivano da immissioni manuali di dati)
non sortiscono effetti Parlo soprattutto di questo tipo di routine
- Codice: Seleziona tutto
Sub Worksheet_SelectionChange(ByVal Target As Range)
oppure di
- Codice: Seleziona tutto
Sub Worksheet_Change(ByVal Target As Range)
Di questo problema è al corrente Microsoft, che infatti propone una macro specifica per ovviare ai relativi inconvenienti. Il codice è scaricabile
da quìE la macro si chiama sub Linklist
- Codice: Seleziona tutto
Sub LinkList()
Dim Links As Variant
' Obtain an array for the links to Excel workbooks
' in the active workbook.
Links = ActiveWorkbook.LinkSources(xlOLELinks)
' If the Links array is not empty, then open each
' linked workbook. If the array is empty, then
' display an error message.
If Not IsEmpty(Links) Then
For I = 1 To Ubound(Links)
ActiveWorkbook.SetLinkOnData Links(i), "LinkChange"
Next I
Else
MsgBox "This workbook does not contain any links " & _
"to other workbooks"
End If
End Sub
A questa macro ne viene collegata un’altra
- Codice: Seleziona tutto
Sub LinkChange()
MsgBox "linked"
End Sub
che “parte” tutte le volte che una cella contenente DDE nella cartella di lavoro cambia contenuto.
In pratica, chi vuole far partire una macro al cambiamento di una qualsiasi cella DDE deve semplicemente copiare il codice della prima macro (Linklist) e sostituire il codice
della seconda (Linkchange) inserendo quello che gli serve.
Il funzionamento di queste due routine è perfetto.
Ma può darsi che l’utilizzatore di excel abbia bisogno di far partire la seconda macro non al cambiamento di qualsiasi cella DDE, ma al cambiamento di una specifica cella.
A questo scopo sono utilizzabili diverse strade,
La prima, è rinvenibile Quì e si compone, in realtà di due codici:
- Codice: Seleziona tutto
Private Sub Worksheet_Calculate()
ControlloNotifica 'richiama la macro in questione
'sull'evento Calculate del WorkSheet
End Sub
- Codice: Seleziona tutto
Sub ControlloNotifica()
Set WBook_Attuale = ThisWorkbook
Dim MioTesto As String
MioTesto = "Codice_DDE’*1"
'WBook_Attuale.SetLinkOnData "Formula di riferimento al titolo", "Macro richiamata"
WBook_Attuale.SetLinkOnData MioTesto, "Macro1"
End Sub
In pratica il cambiamento della cella DDE (il cui codice è stato da me generalizzato come esempio nella riga Mio testo = ‘Codice_DDE’ e il cui valore è leggibile semplicemente selezionando la cella in cui è contenuto, in modo che appaia, dopo un segno di = nella barra della formula) determina la partenza della macro “Macro1”.
La seconda strada è quìpermette anche di fermare l’update e il relativo lancio della macro (qui esemplificata da un msgbox, al posto del quale può essere messo qualsiasi altro tipo di routine, all’occorrenza).
Per fare funzionare il tutto occorre inserire “TRUE” nella cella C1 (e par fermare tutto “FALSE”).
- Codice: Seleziona tutto
Dim bRunNow As Boolean
- Codice: Seleziona tutto
Sub Test1()
With ActiveWorkbook
bRunNow = .Worksheets("Foglio1").Range("C1").Value
If bRunNow Then .SetLinkOnData " Codice_DDE’", "Test2" Else .SetLinkOnData " Codice_DDE’", ""
End With
End Sub
- Codice: Seleziona tutto
Sub Test2()
MsgBox "StockUpdated.", vbOKOnly, "Set Link On Data"
End Sub
- Codice: Seleziona tutto
Sub ButtonTest()
Test1
End Sub
(le istruzioni, in inglese, sono sul sito ;-) )
(Anche qui ho esemplificato scrivendo “Codice_DDE’” al posto del codice reale DDE contenuto nella cella).
La terza strada, velocissima, proposta da Anthony prevede una macro che (Anthony) che ne fa attivare un’altra (Macro1) tutte le volte che una cella contenente DDE (immaginiamo sempre, a livello esemplificativo, che la sua formula sia = Codice_DDE’) cambia il suo contenuto.
- Codice: Seleziona tutto
Sub Anthony()
ActiveWorkbook.SetLinkOnData "Codice_DDE’", "Macro1"
End Sub
- Codice: Seleziona tutto
Sub Macro1()
MsgBox "La cella DDE è cambiata", vbOKOnly, "Messaggio"
End Sub
- Codice: Seleziona tutto
Sub auto_open()
Call Anthony
End Sub
Naturalmente, se si vuole attivare una macro che faccia qualcosa di più o di diverso che mostrare un msgbox al variare della cella DDE avente quel particolare codice (nell’esempio ho usato “Codice_DDE’”, ma va messo quello specifico del DDE) , basterà sostituire il contenuto di codice della routine Macro1 con quello che, nel caso specifico, si vuole utilizzare.
Spero che il riepilogo, dopo questa lunga ma utilissima discussione, possa servire a chi incontra gli stessi problemi che ho avuto io con la manipolazione delle celle DDE. Per informazioni ulteriori sulle prime due soluzioni proposte (e anche per attingere direttamente alle relative fonti), consiglio di visitare i siti che ho postato.
Grazie ancora, a dopo