| Autore |
Discussione  |
|
|
Fryc
Nuovo Utente
4 Messaggi |
Inserito il - 28/12/2005 : 07:41:04
|
Vorrei scrivere qualche linea di codice VBA che automatizzi il processo di sincronizzazione di serie storiche finanziarie. Cioe' in un foglio excel abbiamo le serie storiche di un indice e di vari titoli che lo compongono. Tipicamente questi valori non saranno allineati in quanto saranno presenti dei "buchi". Cio' che vorrei ottenere e' che, prendendo come riferimento la serie storica dell'indice, tutti i dati relativi ai singoli titoli siano "allineati" con quelli dell'indice. C'e' qualcuno interessato alla cosa che puo' darmi una mano?
Grazie Ciao
|
|
|
Diego Vassallo
Amministratore
 
156 Messaggi |
Inserito il - 28/12/2005 : 14:47:11
|
Il problema è piuttosto semplice e si presta ad infinite migliorie e modifiche .. io ti mando un codice elementare e molto didattico con la routine di sincronizzazione.. studiala un attimo. il foglio che mi hai mandato chiamalo mib30.xls e non mib30.XLS altrimenti il codice non funziona. Poi .. aggiungi un foglio e chiamalo "sincro" il foglio dei dati chiamalo "dati" A questo punto il codice che allego ti sincronizza l'indice con alleanza. Siccome l'ho buttato giù al volo se ci sono problemi o errori segnalamelo.
questo è il file su cui lavorare
http://www.finanza24ore.biz/public/Diego%20Vassallo/allegatiForum/mib30.zip
Sub sincronizza()
Application.ScreenUpdating = False '§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ ' verifica che non ci siano buchi nell'indice With Workbooks("mib30.xls").Worksheets("dati") fine1 = Application.WorksheetFunction.CountA(.Range("A:A")) End With Set topcell = Workbooks("mib30.xls").Worksheets("dati").Cells(65534, 1) If IsEmpty(topcell) Then Set topcell = topcell.End(xlUp) fine2 = topcell.Row If fine1 <> fine2 Then MsgBox ("buco nello storico dell'indice di riferimento"): Exit Sub ' pulisce il foglio sincro Workbooks("mib30.xls").Worksheets("sincro").Cells.Clear '§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ ' ciclo su tutti i giorni dell'indice sinc = 3 contincolla = 3 Do 'For sinc = 3 To fine2 valoredata = Workbooks("mib30.xls").Worksheets("dati").Cells(sinc, 1).Value valoreclose = Workbooks("mib30.xls").Worksheets("dati").Cells(sinc, 2).Value valorevolumi = Workbooks("mib30.xls").Worksheets("dati").Cells(sinc, 3).Value 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ' range in cui effettuare la sincronizzazione rangelavoro = "d1:d" & fine2 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX With Workbooks("mib30.xls").Worksheets("dati").Range(rangelavoro) Set c = .Find(valoredata, LookIn:=xlValues , lookat:=xlwhole) If Not c Is Nothing Then ' trovato firstAddress = c.Address riganelfilediAgg = Split(c.Address, "$")(2) riganelfilediAgg = CInt(riganelfilediAgg) copiadata = Workbooks("mib30.xls").Worksheets("dati").Cells(riganelfilediAgg, 4).Value copiaclose = Workbooks("mib30.xls").Worksheets("dati").Cells(riganelfilediAgg, 5).Value copiavolumi = Workbooks("mib30.xls").Worksheets("dati").Cells(riganelfilediAgg, 6).Value ' incolla tutti i valori Workbooks("mib30.xls").Worksheets("sincro").Cells(contincolla, 1).Value = valoredata Workbooks("mib30.xls").Worksheets("sincro").Cells(contincolla, 2).Value = valoreclose Workbooks("mib30.xls").Worksheets("sincro").Cells(contincolla, 3).Value = valorevolumi Workbooks("mib30.xls").Worksheets("sincro").Cells(contincolla, 5).Value = copiadata Workbooks("mib30.xls").Worksheets("sincro").Cells(contincolla, 6).Value = copiaclose Workbooks("mib30.xls").Worksheets("sincro").Cells(contincolla, 7).Value = copiavolumi contincolla = contincolla + 1 Else 'MsgBox "non trovata" End If End With ' copia il valore sinc = sinc + 1 Loop While sinc <= fine2 Application.ScreenUpdating = True
End Sub
30/01/2006 ho fatto una piccola modifica a questa routine, non ho controllato se funziona, ma credo non dovrebbe dare problemi. In ogni caso la routine più sotto funziona correttamente. |
 |
|
|
Fryc
Nuovo Utente
4 Messaggi |
Inserito il - 30/12/2005 : 10:30:02
|
Citazione: Messaggio inserito da Diego Vassallo
Il problema è piuttosto semplice e si presta ad infinite migliorie e modifiche .. io ti mando un codice elementare e molto didattico con la routine di sincronizzazione.. studiala un attimo.
Innanzitutto grazie. Mi studiero' con calma il codice e se c'e' qualcosa che non va o che non mi e' chiaro riscrivo. Da una prima prova sembra che funzioni proprio bene. Complimenti
|
 |
|
|
Fryc
Nuovo Utente
4 Messaggi |
Inserito il - 02/01/2006 : 22:30:23
|
Da ulteriori prove ho notato che ci sono dei problemi con la sincronizzazione. Questi problemi vengono fuori se si estende il codice e si prova a sincronizzare anche gli altri titoli oltre il primo. I problemi derivano da 2 cose: 1) ci sono alcuni giorni nelle serie storiche dei titoli che non sono presenti nella serie dell'indice 2) ci sono alcuni giorni nella serie dell'indice che non sono presenti nelle serie dei titoli. Quando si verifica almeno uno di questi eventi, la sincronizzazione salta.... Per rendersene conto occorre provare a sincronizzare tutti i titoli del foglio allegato.
Ciao |
 |
|
|
Diego Vassallo
Amministratore
 
156 Messaggi |
Inserito il - 03/01/2006 : 15:24:37
|
vero. Nel caso una data sia presente nell'indice , ma non nel titolo da confrontare si potrebbe ovviare in due modi. 1) eliminare i dati relativi alla data presente nell'indice ma non nel titolo da confrontare 2) aggiungere nel titolo confrontato una sessione "immaginaria" utilizzando i dati della seduta precedente. Quale procedura preferiresti ? Riesci da solo o preferisci che modifichi il codice ?
Considero solo questa situazione anomala in quanto prendo come riferimento l'indice .. quindi se una data è presente nel titolo , ma non nell'indice, il programma non ne tiene conto e la salta.
|
 |
|
|
Fryc
Nuovo Utente
4 Messaggi |
Inserito il - 03/01/2006 : 16:16:35
|
La seduta immaginaria mi sembra la soluzione economicamente piu' corretta. Per quanto riguarda la seconda soluzione anomala e' vero che il programma non ne tiene conto e la salta pero' finira' comunque per crearsi uno sfasamento o mancata sincronizzazione dovuta al ciclo do..loop, o mi sbaglio? Cmq il modo migliore e vedere all'opera il programma e se alla fine tutte le 5 serie risultano perfettamente allineate allora la scelta e' stata giusta. Se modifichi tu il foglio forse e' meglio.....
Ciao |
 |
|
|
Diego Vassallo
Amministratore
 
156 Messaggi |
Inserito il - 05/01/2006 : 20:25:45
|
ok ricevuto... domani mi ci metto è posto la seconda release della routine. allora creo una seduta immaginaria.
|
 |
|
|
Diego Vassallo
Amministratore
 
156 Messaggi |
Inserito il - 06/01/2006 : 12:32:55
|
No, il problema non è nella mia routine. Ho provato a fare ogni genere di porcheria su una serie di un titolo e sincronizza alla perfezione.. il problema è nel file che mi hai inviato. Se ci fai caso le colonne delle date hanno dei problemi di formato. Non sono in formato data , ma in formato testo;la mia routine le trasforma in automatico. Però senza un controllo specifico in fase di conversione excel tende a fare cose strane. Se provi a mettere nelle colonne delle date il formato corretto vedrai che non ci sono problemi. Fammi sapere.
|
 |
|
|
Diego Vassallo
Amministratore
 
156 Messaggi |
Inserito il - 24/01/2006 : 14:35:51
|
La routine postata è affetta da strani problemi a causa dell'utilizzo del metodo find. Propongo in alternativa un metodo brutale per effettuare la sicronizzazione. E' efficace ed abbastanza veloce. Per vedere la velocità di eseguzione ho attivata la statusbar di excel. Buon lavoro.
Sub sincronizzazione_brutale()
' le serie storiche devono essere ordinate in ordine crescente per data ' altrimenti rimuovere la riga indicata da tante XXXXXXXXXX ' così facendo però i tempi di analisi aumentano sensibilmente
Application.ScreenUpdating = False Application.DisplayStatusBar = True
' ciclo sull'indice '§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ ' verifica che non ci siano buchi nell'indice With Workbooks("mib30.xls").Worksheets("dati") fine1 = Application.WorksheetFunction.CountA(.Range("A:A")) End With Set topcell = Workbooks("mib30.xls").Worksheets("dati").Cells(65534, 1) If IsEmpty(topcell) Then Set topcell = topcell.End(xlUp) fineindice = topcell.Row Set topcell = Workbooks("mib30.xls").Worksheets("dati").Cells(65534, 4) If IsEmpty(topcell) Then Set topcell = topcell.End(xlUp) finetitolo = topcell.Row If fineindice <> fine1 Then MsgBox ("buco nello storico dell'indice di riferimento"): Exit Sub Workbooks("mib30.xls").Worksheets("sincro").Cells.Clear ' ciclo sull'indice rigasincro = 3 prossimarigadipartenza = 3 For indice = 3 To fineindice Application.StatusBar = "analizzata " & indice & " su " & fineindice dataindice = Workbooks("mib30.xls").Worksheets("dati").Cells(indice, 1).Value prezzoindice = Workbooks("mib30.xls").Worksheets("dati").Cells(indice, 2).Value volumeindice = Workbooks("mib30.xls").Worksheets("dati").Cells(indice, 3).Value ' ciclo annidato per la sincronizzazione For titolo = prossimarigadipartenza To finetitolo datatitolo = Workbooks("mib30.xls").Worksheets("dati").Cells(titolo, 4).Value prezzotitolo = Workbooks("mib30.xls").Worksheets("dati").Cells(titolo, 5).Value volumetitolo = Workbooks("mib30.xls").Worksheets("dati").Cells(titolo, 6).Value If datatitolo = dataindice Then Workbooks("mib30.xls").Worksheets("sincro").Cells(rigasincro, 1).Value = dataindice Workbooks("mib30.xls").Worksheets("sincro").Cells(rigasincro, 2).Value = prezzoindice Workbooks("mib30.xls").Worksheets("sincro").Cells(rigasincro, 3).Value = volumeindice Workbooks("mib30.xls").Worksheets("sincro").Cells(rigasincro, 4).Value = datatitolo Workbooks("mib30.xls").Worksheets("sincro").Cells(rigasincro, 5).Value = prezzotitolo Workbooks("mib30.xls").Worksheets("sincro").Cells(rigasincro, 6).Value = volumetitolo rigasincro = rigasincro + 1 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx ' riga da togliere se le serie storiche NON sono ordinate If titolo > 30 Then prossimarigadipartenza = titolo - 5 Else prossimarigadipartenza = 3 Exit For End If Next Next End Sub |
 |
|
| |
Discussione  |
|