|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Jan 2004
Città: Monza
Messaggi: 36
|
[VBA] DDE+Excel
Ciao a tutti, spero che l'argomento non sia già stato affrontato, se così è mi scuso per il search superficiale...
Ho una cella con un datafeed realtime che cambia ogni secondo. Vorrei in un intervallo delta_t (ad esempio 3 min) registrare il valore a t=0 e a t=3 ed il valore minimo e massimo. Ho provato con le semplici formule di excel, ma riesco esclusivamente a ricopiare il valore della formula, che quindi continua a variare nel tempo. In poche parole vorrei una storicizzazione del valori suddetti. Sapete darmi qualche suggerimento o darmi qualche link utile? Grazie e buona serata. |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Anzitutto un consiglio : rinomina il thread con un bel [ Excel VBA ] iniziale. Non vorrei che ti chiudessero la discussione. Una precisazione : oltre al valore iniziale/finale/max/min lo storico prevede la registrazione dei valori ad ogni secondo sullo stesso Foglio in cui è presente la cella DDE ? |
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Jan 2004
Città: Monza
Messaggi: 36
|
Mi scuso per la niubbaggine e per non aver letto le regole del forum, ma non riesco a modificare il titolo, prego i moderatori di farlo per me.
Lo storico che voglio creare non richiede la memorizzazione dato per dato ma esclusivamente i valori di min, max, iniziale e finale con timeframe definito. cella DDE x [cambia continuamente] time t=iniz. min max t=finale 3 X0 Xmin Xmax X3- 6 X3+ Xmin Xmax X6- 9 .................................................... 12 ..................................................... |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Il programma deve generare una tabella, sempre su Foglio1, e ogni 3 minuti riportare i 4 valori [ inizio / min / max / fine ] rilevati sui 180 ( 3x60 ) secondi di ogni intervallo. Corretto ? |
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Jan 2004
Città: Monza
Messaggi: 36
|
Corretto!
Sto cercando nelle funzioni "importazione dati" ma mi sa che non ci cavo nulla di buono... |
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Jan 2004
Città: Monza
Messaggi: 36
|
Dopo svariati tentativi sono arrivato a questa macro, dal sito di Microsoft
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 Quello che fa è rilevare il cambiamento della cella DDE e, in corrispondenza di tale cambiamento, fa partire la macro "LinkChange". Ora si tratta dunque di strutturare la macro LinkChange in modo da ricopiare i dati che intercetta nella colonna di fianco. Da lì poi con le formule normali si riesce a rispondere alle esigenze che ho citato nel primo post (min,max,iniziale,finale) Qualcuno è in grado di aiutarmi a scrivere questa macro di copia valori? |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Sei riuscito con quel metodo ?
Io invece sono riuscito a risolvere il tuo quesito con qualche chiamata alle API ( ho chiamato da Excel il Timer di sistema... ), un paio di Sub ,e un bell'Array per i valori... |
|
|
|
|
|
#8 |
|
Member
Iscritto dal: Jan 2004
Città: Monza
Messaggi: 36
|
Fra 30 minuti ti posto tutto
Edit: prima del previsto Dim bRunNow As Boolean Sub Test1() With ActiveWorkbook bRunNow = .Worksheets("Foglio1").Range("C1").Value If bRunNow Then .SetLinkOnData "FDF|Q!'F.MI;Last'", "Test2" Else .SetLinkOnData "FDF|Q!'F.MI;Last'", "" End With End Sub Sub Test2() ddedati = "C3:C3" TWS = "Foglio1" SWS = ActiveSheet.Name Range(ddedati).Copy Sheets(TWS).Select If Range("C3").Value < Range("F2").Value Or Range("F2").Value = 0 Then Range("F2").Value = Range("C3").Value 'Calcolo Min If Range("C3").Value > Range("E2").Value Or Range("E2").Value = 0 Then Range("E2").Value = Range("C3").Value 'Calcolo Max Range("G2").Value = Range("C3").Value 'Calcolo Current Sheets(SWS).Select End Sub Sub ButtonTest() Test1 End Sub Sub Restarta() DeltaT = "00:03:00" CellaFlag = "N1" dati = "E2:G2" DWS = "Foglio1" CWS = ActiveSheet.Name Range(dati).Copy Sheets(DWS).Select Range("J65536:L65536").End(xlUp).Offset(1, 0).Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False Range("G2").Copy Range("I65536").End(xlUp).Offset(1, 0).Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False Range(dati).Select Selection.ClearContents Sheets(CWS).Select If Range(CellaFlag).Value = 0 Then Range(CellaFlag).Interior.ColorIndex = xlNone Exit Sub End If Application.OnTime Now + TimeValue(DeltaT), "Restarta" Range(CellaFlag).Interior.ColorIndex = 3 End Sub ![]() Se hai qualche domanda specifica fai pure... Mi piacerebbe sapere anche la tua soluzione, visto che cmq questa non mi soddisfa appieno. Ciao e buona serata! Ultima modifica di Kimiko : 13-03-2008 alle 21:36. |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
1. Ho un file Excel, che può contenere anche solo un foglio, Foglio1. 2. Foglio1 è organizzato come segue : - Cella A1 : contiene i valori DDE. - Colonne da B a F : Tabella valori ( 1 nuova riga ogni intervallo -> 180 sec. ). - 2 CommandButton : Start e Stop registrazione valori. Vedi figura : ![]() 3. Codice che esegue il CommandButton START : Codice:
Private Sub CommandButton1_Click()
Sheets("Foglio1").Range("C2:F4").ClearContents
Sheets("Foglio1").Range("C2").FormulaR1C1 = Sheets("Foglio1").Range("A1").Value
intervallo = 180 'SECONDI
contaSecondi = 0
contaIntervalli = 2
CommandButton1.Enabled = False
ReDim arrayValori(0)
StartTimer
End Sub
Codice:
Private Sub CommandButton2_Click()
EndTimer
CommandButton1.Enabled = True
End Sub
Codice:
Public intervallo As Integer
Public contaIntervalli As Integer
Public contaSecondi As Integer
Public arrayValori() As Double
Public TimerID As Long
Public TimerSeconds As Single
Public Declare Function SetTimer Lib "user32" ( _
ByVal HWnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" ( _
ByVal HWnd As Long, _
ByVal nIDEvent As Long) As Long
Public Sub StartTimer()
TimerSeconds = 1 'Intervallo di Intervento Timer in Secondi.
TimerID = SetTimer(0&, 0&, TimerSeconds * 1000&, AddressOf TimerProc)
End Sub
Public Sub EndTimer()
On Error Resume Next
KillTimer 0&, TimerID
End Sub
Public Sub TimerProc(ByVal HWnd As Long, ByVal uMsg As Long, _
ByVal nIDEvent As Long, ByVal dwTimer As Long)
AGG_ARRAY_VALORI (Sheets("Foglio1").Range("A1").Value)
If contaSecondi = intervallo Then
Sheets("Foglio1").Range("F" & contaIntervalli).FormulaR1C1 = Sheets("Foglio1").Range("A1").Value
Sheets("Foglio1").Range("D" & contaIntervalli).FormulaR1C1 = arrayValori(1)
Sheets("Foglio1").Range("E" & contaIntervalli).FormulaR1C1 = arrayValori(UBound(arrayValori))
ReDim arrayValori(0)
contaIntervalli = contaIntervalli + 1
contaSecondi = 0
End If
If (contaSecondi - 1) Mod intervallo = 0 And contaIntervalli > 2 Then
Sheets("Foglio1").Range("C" & contaIntervalli).FormulaR1C1 = Sheets("Foglio1").Range("A1").Value
End If
contaSecondi = contaSecondi + 1
End Sub
Public Sub AGG_ARRAY_VALORI(valore As Double)
Dim valRedim As Long
valRedim = UBound(arrayValori) + 1
ReDim Preserve arrayValori(valRedim)
arrayValori(valRedim) = valore
Dim Temp As Double
Dim i As Long
Dim j As Long
For j = 2 To UBound(arrayValori)
Temp = arrayValori(j)
For i = j - 1 To 1 Step -1
If (arrayValori(i) <= Temp) Then GoTo 10
arrayValori(i + 1) = arrayValori(i)
Next i
i = 0
10 arrayValori(i + 1) = Temp
Next j
End Sub
|
|
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Jan 2004
Città: Monza
Messaggi: 36
|
L'aspetto è professionale, più tardi (o domani, meglio
Grazie comunque. |
|
|
|
|
|
#11 | ||||
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Quote:
Quote:
Chiaramente, se devi costruire un'applicazione complessa che fa pesante uso dei Timer, il mio consiglio è di utilizzare VB6 o VB NET, che offrono un ottimo supporto all'interazione con Excel. Quote:
|
||||
|
|
|
|
|
#12 |
|
Junior Member
Iscritto dal: Jan 2009
Messaggi: 10
|
Ciao marco,
Per quanto riguarda il DDE non l'ho implementato io ma è un collegamento alla banca dati tramite un programma da loro foirnito. L'azzeramento è dovuto al loro collegamento e non è 1 problema specifico dell'utenza (succede raramente, è solo un istante e non c'e perdita di dati..... solo che mi sballa il grafico Le celle DDE sono già 2 (ne ho aggiunta una io alla tua macro) e diventerebbero 6 |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Per quanto riguarda l'ultimo problema, ossia la temporizzazione di una Macro ( Sub o Function ) si può risolvere semplicemente con le stesse chiamate API del mio esempio precedente. In questo caso il codice necessario sarà qualcosa di simile a questo : > In un Modulo : Codice:
Public TimerID As Long
Public TimerSeconds As Single
Public Declare Function SetTimer Lib "user32" ( _
ByVal HWnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" ( _
ByVal HWnd As Long, _
ByVal nIDEvent As Long) As Long
Public Sub StartTimer()
TimerSeconds = 1 'Intervallo di Intervento Timer in Secondi.
TimerID = SetTimer(0&, 0&, TimerSeconds * 1000&, AddressOf TimerProc)
End Sub
Public Sub EndTimer()
On Error Resume Next
KillTimer 0&, TimerID
End Sub
Public Sub TimerProc(ByVal HWnd As Long, ByVal uMsg As Long, _
ByVal nIDEvent As Long, ByVal dwTimer As Long)
Dim adesso As String
adesso = Format(Now, "yyyy/mm/dd hh:mm:ss")
Sheets("Foglio1").Range("A1").FormulaR1C1 = adesso
If CDate(adesso) = "2009/01/12 14:40:00" Then
'Lancio la macro desiderata :
MACRO
End If
End Sub
Public Sub MACRO()
MsgBox "MACRO Lanciata."
End Sub
Codice:
Private Sub cmd_start_Click()
cmd_start.Enabled = False
StartTimer
End Sub
Codice:
Private Sub cmd_stop_Click()
EndTimer
cmd_start.Enabled = True
End Sub
|
|
|
|
|
|
|
#14 |
|
Junior Member
Iscritto dal: Jan 2009
Messaggi: 10
|
Grazie, sempre molto gentile
ora provo a mettere in pratica i tuoi suggerimenti ......... se per un po non mi senti non preoccuparti, sto sbattendo la testa ciao pupic Ps: ora ho capito che l' API non è l' "Associazione Programmatori Italiani" |
|
|
|
|
|
#15 |
|
Junior Member
Iscritto dal: Jan 2009
Messaggi: 10
|
Ciao Marco, ...... ancora io
volevo allegare il file del foglio completo dei 3 titoli x un tuo consiglio ma anche zippato supera la dimensione consentita Volevo chiederti informazioni sugli array (faccio riferimento al range "D" = arrayValori(1)) : nella tua macro, dove sono specificate le variabili dell'array ? E dove è specificato che sono relative alla cella A1 ? Se ho fatto una domanda stupida |
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Codice:
Public arrayValori() As Double Qui : Codice:
AGG_ARRAY_VALORI (Sheets("Foglio1").Range("A1").Value)
|
|
|
|
|
|
|
#17 |
|
Junior Member
Iscritto dal: Jan 2009
Messaggi: 10
|
Grazie per i chiarimenti
ciao |
|
|
|
|
|
#18 |
|
Junior Member
Iscritto dal: Jan 2009
Messaggi: 11
|
ciao,
ho letto il tuo post "Dati real time x excel " ma sopratutto questo "[VBA] DDE+Excel " un paio di anni fa ci ho perso un tot di tempo, dovendo poi rinunciare, per mancanza risultati, per fare sostanzialmente la stessa cosa che cercavi di far tu... e mi pare che avete in qualche modo risolto io ho in una cella di excel i dati che arrivano in realtime, ( pz, o, h, l, c, ) tutti in una riga quello che non sono mai riuscito a fare, e che mi servirebbe e che ogni minuto quella riga si "fissasse" con tutti i suoi valori e riprendesse il flusso di dati alla riga sotto, e cosi via per tutta la giornata ( il problema di recuperare dati persi o storici per ora non mi serve, mi basta il realtime della giornata strutturato nel modo che ho cercato di spiegarti ) mi potete aiutare? qualcuno e' riuscito a costruire un foglio excel che fa una roba simile? mi fareste un enorme favore,,, sono zero a programmare, e non saprei neanche costruire una macro copiando il codice postato da MarcoGG intanto grazie cmq ciao marco |
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Da quello che ho capito, ogni minuto vorresti registrare i valori sulla stessa riga in cui sta la cella DDE ( o le celle DDE ), e poi spstare la riga-DDE verso il basso. Poco pratico, forse. Non sarebbe meglio copiare i valori su una nuova riga ad ogni scatto di clock, e mantenere la DDE sempre al suo posto ? |
|
|
|
|
|
|
#20 |
|
Junior Member
Iscritto dal: Jan 2009
Messaggi: 10
|
Ciao Marco&Marco …… tutti Marco
La prima macro di Marco funziona egregiamente, devi solo partire da due soli dati DDE e cioè il “prezzo ultimo” e il volume, il resto lo fa la macro. Capisco la tua necessità e la difficoltà di applicare la macro, anche se basta copiarla; ci ho lavorato anch’io parecchio partendo a studiare il VBA da zero (adesso non sono tanto più in là …… forse a 0,5 con gli array sono ancora in pieno oceano Atlantico su una barca a remi Dim adesso As String adesso = Format(Now, "yyyy/mm/dd hh:mm:ss") Sheets("Foglio1").Range("A1").FormulaR1C1 = adesso If CDate(adesso) = "2009/01/12 14:40:00" Then.... L’ho posizionato ovunque nella tua prima macro ma senza risolvere Buona domenica a tutti Pupic |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:43.














x la macro (
:








