Lavorare celle DDE rispetto al variare del loro valore

giamoros

New Member
Joined
Jul 14, 2011
Messages
6
Mi sono fato un migliaio di giri su vari siti e sono arrivato alla conclusione che l'unico sistema per intercettare automaticamente se una cella DDE sia cambiata è usare il sistema setlinkondata (per me emerito sconosciuto).
Comunque ho preparato qualcosa per verificare se ciò sia possibile ma ho subito un errore che non riesco a capire.
Nello screenshot14 come si presente la cartella Excel quando la lancio. http://www.mediafire.com/?ipmtprciui954qi
Nello screenshot15 l'errore che ho all'inizio dell'arrivo degli stessi. http://www.mediafire.com/?hlhkzz4ewftgg1z
Nello screenshot16 le istruzioni del foglio2 sezione generale. http://www.mediafire.com/?vm28e13forxxj97
Nello screenshot17 le istruzioni della sezione worksheet. http://www.mediafire.com/?wou8esw44o2ojbl
Qualcuno sa darmi una mano a correggere tale errore?]
 

Excel Facts

Quick Sum
Select a range of cells. The total appears in bottom right of Excel screen. Right-click total to add Max, Min, Count, Average.
Sto preparando un resoconto delle mie esperienze e quando sarà pronto te lo posterò sperando di farti cosa gradita.
In caso contrario farmelo sapere.
Saluti.
 
Upvote 0
Nell’accingermi a raccontare le mie esperienze con il DDE mi sento in dovere prima di tutto di ringraziare coloro che, in egual misura, con il loro costante aiuto, suggerimenti, spiegazioni e sopratutto con la loro infinita pazienza mi hanno permesso di risolvere il mio problema.

Mi riferisco agli utenti:

Antony47 del forum pc-facile.com
Scossa del forum archi.forumup.it
Icecube del forum finanzaonline.com
Paolo1956 del forum finanzaonline.com

Alcune considerazioni sul DDE :

1° so perfettamente che la tecnica del DDE è antiquata ma questa ho e questa devo usare
2° non è adatto a gestire grandi moli di dati specialmente in relazione al real time (millesimo di secondi)
3° non vuole assolutamente sostituirsi agli strumenti professionali delle banche, Sim ecc. ecc
4° pur tuttavia fa onestamente il proprio lavoro.

Come funziona il mio DDE :

1° sul sito della banca viene attivata la funziona DDE
2° sul PC utente viene lanciato un programma generalmente fornito dalla stessa banca
3° i due programmi si sincronizzano e nella barra del PC utente l’icona diventa verde
4° si lancia la cartella Excel utente e nelle celle dove ci sono le formule DDE arrivano i dati.

Cosa sono , come sono fatte e dove vanno messe le formule DDE :

Ogni fornitore di dati usa propri parametri per indicare nelle formule quali dati l’utente vuole ma sostanzialmente alla fine sono moto simili fra di loro.

Nel mio caso la formula è
FDF|Q!'ASR.MI;2'
dove

FDF|Q! è l’identificativo delle mia banca
'FNC.MI; è il codice del titolo usato dalla banca in questo caso sigla di Finmeccanica
2' indica il dato che si vuole in questo caso l’ultimo prezzo

Quindi per ottenere tale dato dovremmo immettere in una cella Excel la formula :
= FDF|Q!'FNC.MI;2'

Per ottenere il Last Time dello stesso titolo la formula da mettere in un’altra cella sarà :
=FDF|Q!'FNC.MI;14'

e così per altri dati quali open, volume, percent change, bid, ask ecc.ecc

Le formule possono essere messe in qualsiasi cella di qualunque foglio della cartella.
Va tenuto presente comunque che per ogni formula e quindi per ogni titolo viene aperto un
canale DDE il che significa che se ci sono 8 formule in un foglio, 12 in un altro e 7 in un terzo anche se ridondanti fra di loro ed i titoli sono 10 si avranno un totale di
8 * 12* 7 * 10 = 6720 canali
quindi è giocoforza diminuire drasticamente il loro numero.
Nel mio caso, cartella con 6 fogli, quello per me primario era formato da 11 righe ,una per titolo che voglio ottenere, così composta :

sigla titolo, denominazione, prezzo, last time ed altre colonne e quindi 4 formule per riga.

Inoltre in ordine diverso le stesse formule per gli stessi dati esistevano anche negli altri 5 fogli.

Allora cosa ho fatto:

1° sostituite le formule della sigla titolo e denominazione con delle costanti
in quanto so perfettamente che se chiedo il prezzo della sigla FNC.MI si tratta del titolo con denominazione FINMECCANICA.

2° le formule rimaste ridondanti degli altri fogli le ho sostituite con la funzione
Excel ” =nomefoglio!J8” dove J8 è la coordinata della cella dove è stata immessa la formula appropriata.

Come senz’altro, ai più noto, per visualizzare il codice VBA cliccando il tasto destro del mouse sul nome delle linguette dei fogli si apre una finestra che fra le altre ha anche la scelta “VISUALIZZA CODICE” evidenziando il quale e cliccando con il destro si ottiene il codice VBA.

A questo punto scegliendo in alto “VISUALIZZA” si apre una finestra e scegliendo la riga riportante “GESTIONE PROGETTI” si ha sulla destra una sezione così composta :

VbaProject (nome della mia cartella)

Microsoft Excel Oggetti
Foglio1 (Formule) fra parentesi il nome che ho dato al foglio1
Foglio2 (Ordinario) fra parentesi il nome che ho dato al foglio2
……
……
fino al Foglio6 (Movimenti azioni) fra parentesi il nome che ho dato al foglio6
ThisWorkbook
Form
Userform1
Userform2
Moduli
Moduli1
Moduli2
..... e così riga per riga fino alla fine
Moduli di classe
Classe1
Classe2
Classe3

Alcune considerazioni su questa struttura :

1° Nei fogli, si consiglia da più parte, di mettere solo gli eventi Excel quali:
Worksheet_SelectionChange(ByVal Target As Range)
Worksheet_Calculate
<code></code><code>........ e cosi via dicendo</code>
<code> </code>
2° Nei moduli, si consiglia da più parti, vanno messe le routine public.

3° Alcuni chiamano i moduli anche con il nome Standard quindi quando vi suggeriscono di mettere delle istruzioni fatevi spiegare esattamente dove e perché.

4° Tenete presente che per visualizzare il codice di un Foglio o ThisWorkbook o di un modulo o form o Classe dovete evidenziare cioè che volete quindi tasto destro e poi visualizza codice.

E finalmente passiamo ad commentare tutti i passi fatti.

1° ho inserito in ThisWorkbook il codice

Code:
Private Sub Workbook_Open()
                 Call LinkList
                 End Sub
All’apertura della cartella queste istruzioni sono eseguite per prime e passano il controllo alla routine, di nome a piacere, LinkList

2° ho inserito nel Modulo1 la routine pubblica Linklist

Code:
Public Sub LinkList()
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'ASR.MI;2'", "Macro1"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'C40.PAR;2'", "Macro2"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'BP.MI;2'", "Macro3"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'BNG.MI;2'", "Macro4"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'CED.MI;2'", "Macro5"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'ENEL.MI;2'", "Macro6"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'EGPW_C.MI;2'", "Macro7"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'ENG.MI;2'", "Macro8"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'FNC.MI;2'", "Macro9"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'IRE.MI;2'", "Macro10"
                 ActiveWorkbook.SetLinkOnData "FDF|Q!'UCG.MI;2'", "Macro11"
                 End Sub
Perché ho scartato l’esempio di seguito esposto fornito dai più Microsoft compresa?

Code:
Public 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 – Il sistema delle 11 macro mi permette di avere immediatamente l’indicazione della riga in cui il prezzo è variato.
Notare che se anche manca il DDE time o di altri dati gli stessi arriveranno nelle celle dei fogli in cui sono immesse le relative formule.
In definitiva non è tanto importante avere tanti SetLinkOnData ma solo uno per titolo; la scelta dipende dall’architettura del vostro progetto.

B - Il sistema dell’unico SetLinkOnData ha lo svantaggio che poi costringe a programmare dei controlli ( loop od on timer) per individuare quale cella è variata anche in considerazione del fatto che gli eventi :

<!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:HyphenationZone>14</w:HyphenationZone> <w:Compatibility> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Tabella normale"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman";} </style> <![endif]--> Worksheet_SelectionChange(ByVal Target As Range)
Worksheet_Calculate
non scattano per effetto del variare di una cella DDE (parola di Microsoft)

<code></code><code></code>3° ho inserito nel Modulo2 le tredici macroN

Code:
Public Sub Macro1()
                 nriga = 8
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro2()
                 nriga = 9
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro3()
                 nriga = 10
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro4()
                 nriga = 11
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro5()
                 nriga = 12
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro6()
                 nriga = 13
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro7()
                 nriga = 14
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro8()
                 nriga = 15
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro9()
                 nriga = 16
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro10()
                 nriga = 17
                 Call LinkChange(nriga)
                 End Sub
                 Public Sub Macro11()
                 nriga = 18
                 Call LinkChange(nriga)
                 End Sub
Qui si capisce perché la scelta è caduta sul metodo A in quanto ogni macro imposta la riga del
proprio titolo e chiama la routine LinkChange (anche essa nome a piacere)

4° ho inserito la routine LinkChange nel Modulo2 ma potrebbe andare in qualunque altro modulo :

Code:
Public Sub LinkChange(priga)
   
                  If IsError(Range("J" & priga).Value) Then GoTo finejob
                  If IsError(Range("N" & priga).Value) Then GoTo finejob
      
                  If Range("J" & priga) > Range("Q" & priga).Value Then
                           Range("J" & priga).Interior.ColorIndex = 4
                           lSuono = 10
      Else
                  If Range("J" & priga) < Range("Q" & priga).Value Then
                           Range("J" & priga).Interior.ColorIndex = 3
                          lSuono = 11
                           End If
      End If
                  Range("J" & priga).Select
                 
                 Range("Q" & priga).Value = Range("J" & priga).Value
                 Range("R" & priga).Value = Range("N" & priga).Value
                 
                 GeneraSuono lSuono
              
  finejob:
  End Sub
Considerazioni e spiegazioni:

1° Quando si passa una variabile ad una routine non è che si passa la variabile ma il suo contenuto quindi la Call LinkChange(nriga) passa il valore della sua variabile nriga.
La Public Sub LinkChange(priga) prende quel valore e lo mette nella sua variabile priga.

2° (Range("J" & priga).Value) significa considerare il valore della cella Jx dove x sarà il numero della riga passato da una delle 11 macro cioè da J8 fino a J18.

3° IsError è necessaria perché se una cella DDE non viene calcolata, se non arriva il relativo dato ad esempio il titolo entra in contrattazione ad orario successivo ad altri titoli oppure è sospeso per l’intera giornata, all’apertura della cartella Excel calcola la formula come errore ma pur tenendone conto lascia la visualizzazione precedente.
Di conseguenza qualsiasi istruzione con quella cella dà l’errore 13 Tipo non corrispondente.
Con tale istruzione quindi si bypassano le celle che darebbero l’errore perché la colonna J contiene i prezzi mentre la colonna N contiene il last time dell’ultimo prezzo.
Infatti da J8 a J18 ci sono le formule DDE per chiedere il prezzo mentre da N8 a N18 ci sono le formule DDE per ottenere il last time.

4° Per capire se l’ultimo prezzo arrivato è maggiore o minore al precedente occorre avere delle aree che i più chiamano “ombra” io direi di salvataggio o d’appoggio.
Tale aree possono stare anche su altri fogli e possono essere dichiarati invisibile ecc. ecc.
Nel mio caso sono state individuate nello stesso foglio rispettivamente nelle colonne Q ed R e nelle stesse righe da 8 a 18 ma potevono stare se celle libere anche nelle colonne J ed N alla righe 1289 ecc. ecc. adattando opportunamente le relative posizioni nelle istruzioni.
Supponendo che la riga in questione sia la 13° il primo if dice se il valore di J13 è maggiore del precedente salvato in Q13 allora colora la cella J13 di verde ed imposta il suono numero 10.
Il secondo if analogamente se minore colora la cella J13 di rosso ed imposta il suono numero 11.

5° Comunque la cella viene evidenziata e si procede a salvare i valori della cella J13 ed N13 rispettivamente in Q13 ed R13 per il controllo del prossimo arrivo.
Quindi si procede alla generazione del suono.

5° ho inserito in testa al Modulo2 queste tre righe perché dichiarazione private

Code:
Private Declare Function sndPlaySound Lib "WINMM.DLL" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
                 Const SND_ASYNC = &H1
6° ho inserito nel Modulo2 la routine GeneraSuono

Code:
Public Sub GeneraSuono(ByVal TipoSuono As Long)
   
                 Dim P As Long, SoundName As String
   
                          Select Case TipoSuono
                                     Case 1
                                     SoundName = "c:\windows\media\Chimes.wav"
                                     Case 2
                                     SoundName = "c:\windows\media\Chord.wav"
                                     Case 3
                                     SoundName = "c:\windows\media\Ding.wav"
                                     Case 4
                                     SoundName = "c:\windows\media\Notify.wav"
                                     Case 5
                                     SoundName = "c:\windows\media\Recycle.wav"
                                     Case 6
                                     SoundName = "c:\windows\media\Ringing.wav"
                                     Case 7
                                     SoundName = "c:\windows\media\Ringout.wav"
                                     Case 8
                                     SoundName = "c:\windows\media\Start.wav"
                                     Case 9
                                     SoundName = "c:\windows\media\Tada.wav"
                                     Case 10
                                     SoundName = "c:\Programmi\MemoRex\Suoni\Fanfare.wav"
                                     Case 11
                                     SoundName = "c:\Programmi\MemoRex\Suoni\Allarme.wav"
                          Case Else
                 'Beep
                 Exit Sub
                 End Select
   
                 P = sndPlaySound(SoundName, SND_ASYNC)
   
                 End Sub
Tenere presente che le precedenti due fasi (5° e 6°) devono risiedere sullo stesso modulo.

7° Esiste nel Modulo3 la seguente routine da me ancora non usata ne provata :

Code:
Public Sub AnnullaLinkList()
                 Dim Links As Variant
                 Links = ActiveWorkbook.LinkSources(xlOLELinks)
                 If Not IsEmpty(Links) Then
                 For i = 1 To UBound(Links)
                 ActiveWorkbook.SetLinkOnData Links(i), ""
                 Next i
                 End If
                 End Sub
che se attivata chiude tutti i canali DDE aperti tramite quei doppi apici nell’istruzione ActiveWorkbook.SetLinkOnData Links(i), ""

Credo che ho detto tutto , che sia stato chiaro e spero che possa essere di aiuto a qualcuno.
 
Upvote 0
Non mi è chiaro perchè deve essere necessario fare tutto quello che viene descritto.
Se il problema è non duplicare i canali DDE, non basta concentrali in un
unico foglio e negli altri fare riferimento a quell'unico foglio?

In altre parole:
mi serve avere =FDF|Q!'FNC.MI;14' in 10 fogli diversi.
Basta farsi un foglio che chiamerò DATIFDF dove metto nella cella C4 (esempio) =FDF|Q!'FNC.MI;14'

Poi nei dieci fogli in cui ho bisogno del valore 14 del titolo FNC basta fare
=DATIFDF!C4

Io ho fatto in questa maniera. Ho però letto attentamente i suggerimenti dati pensando che venisse spiegato qualche trucco per ottenere qualcosa di più, ma a me sembra che si ottenga lo stesso risultato. O c'è qualcosa che mi sfugge?

Per esempio a me farebbe comodo poter ricevere i dati non tramite una cella, ma tramite codice Visual Basic. Cioè ho un codice che avrebbe bisogno del valore 14 del titolo FNC,
deve per forza leggerlo dalla cella corrispondente nel foglio Excel o può andare a farselo dare direttamente da FDF tramite DDE?

Se capisco bene in questo Thread non viene detto nulla a riguardo.
Qualcuno è a conoscenza di un altro Thead che spiega quanto sopra?
Grazie
 
Upvote 0
Per galici:
ma è quello che ho già scritto:

""Allora cosa ho fatto:

1° sostituite le formule della sigla titolo e denominazione con delle costanti
in quanto so perfettamente che se chiedo il prezzo della sigla FNC.MI si tratta del titolo con denominazione FINMECCANICA.

2° le formule rimaste ridondanti degli altri fogli le ho sostituite con la funzione
Excel ” =nomefoglio!J8” dove J8 è la coordinata della cella dove è stata immessa la formula appropriata.

Per il resto che io sappia la formula deve stare nella cella.
 
Upvote 0
Non capisco però a cosa servano le SetLinkOnData.

Faccio la domanda in altro modo.
Se uno parte col piede giusto, nel fare un nuovo foglio da zero, non
ha bisogno delle SetLinkOnData e di scrivere macro.
Scrive direttamente le formule DDE in un singolo foglio e poi fa riferimento
a quel foglio. Tutto senza nessun SelectLinkOnData.

Faccio queste domande, non per criticare, ma perchè per un foglio che
stavo scrivendo adesso mi sono trovato a litigare con la SetLinkOnData e per questo mi sono messo a navigare cercando qualcuno che l'avesse già usata.

Ti spiego adesso quale è il problema che mi ha portato ad interessarmi di questo thread.

Il problema che ho io con la SetLinkOnData e che funziona solo con link che sono già presenti in LinkSources. Se un link non è già presente in
LinkSources non si può usarlo in SetLinkOnData.
Quello che cercavo di fare io (senza successo) era di aggiungere un nuovo link senza digitare la formula, ma appunto con un programma VBA.
Mi ha incuriosito il tuo messaggio, perchè tu citi la LinkSources solo quando citi spezzoni di codice, consigliati da altri, che tu NON hai usato. Immagino però che da qualche altra parte hai inserito una LinkSources.
A meno che semplicemente sai quali sono i link già presenti nel tuo foglio e usi quelli, associati al SetLinkOnData. Ma in questo caso il tuo codice VBA funziona solo sul tuo foglio.
 
Upvote 0
Se leggi tutta la spiegazione troverai anche :

Public 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</pre>altro non so dirti.
 
Upvote 0

Forum statistics

Threads
1,224,585
Messages
6,179,702
Members
452,938
Latest member
babeneker

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top