<cut>
Possiamo vedere il codice o andiamo sulla fiducia? 8-)
--
---------------------------
Mauro Gamberini
http://www.riolab.org/
'------------------
ho un piccolo problema che però mi rende un foglio di
lavoro praticamente inutilizzabile.
Praticamente costruisco una tabella di 500 righe per 10 colonne e dentro
a ogni cella ci metto una formula, che è una funzione scritta in VBA, a
cui passo una decina di parametri, ricavati da altre celle del foglio di
lavoro. Poi aggiungo un'altra colonna che fa la somma riga per riga
della tabella. Con i dati di questa colonna faccio un grafico.
Il problema è che variando un solo valore di una cella che contiene i
parametri iniziali, ci mette parecchi secondi ad aggiornare il grafico.
La funzione in VBA non ha cicli ma è semplice di 20 righe con qualche if
e operazioni matematiche. A dire il vero per 4 volte richiama un'altra
funzione, comunque semplicissima di 5 righe di operazioni matematiche.
C'è qualche variabile di appoggio per fare i calcoli.
Secondo voi sono tutti questi richiami a rallentare?
Ho provato a sostituire nelle celle della tabella qualche funzione SE
con qualche calcolo e va benissimo...
Insomma come si potrebbe fare per velocizzare un po'?
'------------------
Vedi Charles Williams a:
Excel Pages - Optimising Speed
http://www.decisionmodels.com/optspeedd.htm
---
Regards,
Norman
Microsoft Excel MVP
> Possiamo vedere il codice o andiamo sulla fiducia? 8-)
certo :-)
qui ho apportato io delle modifiche rispetto all'originale ma non ho
avuto miglioramenti
Function CND(X) As Single
Dim a1, a2, a3, a4, a5, L, K, F As Single
a1 = 0.31938153
a2 = -0.356563782
a3 = 1.781477937
a4 = -1.821255978
a5 = 1.330274429
L = Abs(X)
K = 1 / (1 + 0.2316419 * L)
F = 1 - ((1 / Sqr(2 * 3.141592654)) * (Exp(-L ^ 2 / 2)) * (a1 * K +
a2 * K ^ 2 + a3 * K ^ 3 + a4 * K ^ 4 + a5 * K ^ 5))
If X < 0 Then
CND = 1 - F
Else
CND = F
End If
End Function
---------------------------------------------------
Function BSfast(CallPut, Prezzo, Strike, Data, Scadenza, Riskfree1,
Riskfree2, DivYld, Vol) As Single
Dim d1, d2, b, nd1, nd2, nd1n, nd2n, T As Single
If Riskfree2 <> 0 Then
b = Riskfree1 - Riskfree2
Else
b = Riskfree1 - DivYld
End If
T = (Scadenza - Data) / 365
If T = 0 Then
If CallPut = "CALL" Then
If Prezzo > Strike Then
BSfast = Prezzo - Strike
Else
BSfast = 0
End If
ElseIf CallPut = "PUT" Then
If Prezzo > Strike Then
BSfast = 0
Else
BSfast = Strike - Prezzo
End If
End If
ElseIf T > 0 Then
d1 = (Log(Prezzo / Strike) + (b + Vol ^ 2 / 2) * T) / (Vol * Sqr(T))
d2 = d1 - Vol * Sqr(T)
If CallPut = "CALL" Then
nd1 = CND(d1)
nd2 = CND(d2)
BSfast = Prezzo * Exp((b - Riskfree1) * T) * nd1 - Strike *
Exp(-Riskfree1 * T) * nd2
ElseIf CallPut = "PUT" Then
nd1n = CND(-d1)
nd2n = CND(-d2)
BSfast = Strike * Exp(-Riskfree1 * T) * nd2n - Prezzo *
Exp((b - Riskfree1) * T) * nd1n
End If
End If
End Function
Grazie Norman, ho provato qualcosa ma purtroppo non ho ancora risolto
> certo :-)
> qui ho apportato io delle modifiche rispetto all'originale ma non ho
> avuto miglioramenti
ho provato a mettere questa funzione semplice al posto dell'altra
Function prova(X) As Single
prova = X * 1000
End Function
e non cambia molto, sempre lentissimo, più di 1 sec per aggiornare il
grafico
secondo me il rallentamento avviene quando vengono richiamate le
funzioni perchè se nelle celle della tabella scrivo la stessa formula,
cioè = X * 1000 va come una scheggia
non è che excel fa qualche controllo antivirus o qualcosa che rallenta
l'esecuzione di macro? I livelli di protezione li ho messi al minimo, ho
provato a disabilitare momentaneamente l'antivirus (AVG) ma nulla di nulla
'----------------
Grazie Norman, ho provato qualcosa ma purtroppo non ho ancora
risolto'----------------
Non ho tentato di seguire le tue funzioni, ma
vorrei fare alcune osservazioni generali circa le
tue dichiarazioni.
'-------------------
Function CND(X) As Single
Dim a1, a2, a3, a4, a5, L, K, F As Single
a1 = 0.31938153
a2 = -0.356563782
a3 = 1.781477937
a4 = -1.821255978
a5 = 1.330274429
'------------------
Questa equivale a:
Function CND(X As Variant) As Single
Dim a1 As Variant, a2 As Variant
Dim a3 As Variant, a4 As Variant
Dim L As Variant, K As Variant
Dim F As Single
Queste dichiarazione sono molto inefficienti;
meglio sarebbe:
'=============>>
Public Function CND(X As Single) As Single
Const a1 As Single = 0.31938153
Const a2 As Single = -0.356563782
Const a3 As Single = 1.781477937
Const a4 As Single = -1.821255978
Const a5 As Single = 1.330274429
[...]
End Function
'<<===========
'------------------
Function BSfast(CallPut, Prezzo, Strike, Data, Scadenza, Riskfree1,
Riskfree2, DivYld, Vol) As Single
Dim d1, d2, b, nd1, nd2, nd1n, nd2n, T As Single
'------------------
Queste dichiarazioni sono equivalenti a:
Function BSfast(CallPut As Variant, Prezzo As Variant, _
Strike As Variant, Data As Variant, _
Scadenza As Variant, Riskfree1 As Variant, _
Riskfree2 As Variant, DivYld As Variant, _
Vol As Variant) As Single
Dim d1 As Variant, d2 As Variant, b As Variant, _
nd1 As Variant, nd2 As Variant, nd1n As Variant, _
nd2n As Variant, T As Single
Meglio sarebbe:
'=============>>
Function BSfast(CallPut As Single, Prezzo As Single, _
Strike As Single, Data As Single, _
Scadenza As Single, Riskfree1 As Single, _
Riskfree2 As Single, DivYld As Single, _
Vol As Single) As Single
Dim d1 As Single, d2 As Single, b As Single
Dim nd1 As Single, nd2 As Single, nd1n As Single
Dim nd2n As Single, T As Single
[...]
End Function
'<<=============
Per quanto riguarda la velocita' di calcolazione,
prova a utilizzare il modo di calcolo manuale:
Menu | Strumenti | Opzioni | Linguetta Calcolo | [x] Manuale
Quando necessario, ricalcola il foglio con un
pulasante collegato alla procedura:
'=============>>
Public Sub MyRecalc()
Application.CalculateFull
End Sub
'<<=============
> Queste dichiarazione sono molto inefficienti;
> meglio sarebbe:
perfetto, credo che contribuisca anche questo.
però mettendo anche la semplice funzione
Private Function prova(X As Single) As Single
prova = X * 1000
End Function
va sempre molto lento, cosa che non fa se metto direttamente nella cella
la formuletta =X*1000
mi sa che dovrò mettere il calcolo in manuale, peccato perchè lo scopo
era quello di agire su un pulsante di selezione e vedere poi le
variazioni sul grafico
grazie ancora
ciao
'----------------
perfetto, credo che contribuisca anche questo.
però mettendo anche la semplice funzione
Private Function prova(X As Single) As Single
prova = X * 1000
End Function
va sempre molto lento, cosa che non fa se metto direttamente nella cella
la formuletta =X*1000
mi sa che dovrò mettere il calcolo in manuale, peccato perchè lo scopo
era quello di agire su un pulsante di selezione e vedere poi le
variazioni sul grafico
'----------------
Non conosco il tuo progetto, ma non sarebbe possibile
chiamare la macro di calcolo dal tuo pulsante?
Se ti fosse utile, e senza alcuna promessa, potresti
mandarmi i tuo file:
norman_jones@NOSPAMbtconnectDOTcom
(Cancella "NOSPAM" e sostituisci "DOT" con un punto)
"Bem" wrote
> Private Function prova(X As Single) As Single
> prova = X * 1000
> End Function
> va sempre molto lento, cosa che non fa se metto direttamente nella cella la formuletta =X*1000
Questo e perche le funzione standrad sono programmati nell C.
Penso che ci possano essere soltanto 3 motivi per usare una funzione dall'utente su un foglio di calcolo:
- l'operazione non puň essere fatta per le funzione standard
- per controllare la volatilita della formula e ciň non puň essere fatto via le funzioni standard
- per evitare le formule matriciale molto pesanti (molti calcoli ridondandar)
Non riesco vedere nessuno di questi nel tuo esempio.
Saluti,
KL
[MVP - Microsoft Excel]
RU: http://www.mvps.ru/Program/Default.aspx
ES: http://mvp.support.microsoft.com/?LN=es-es
EN: http://mvp.support.microsoft.com/?LN=en-us
Profile: https://mvp.support.microsoft.com/profile=AB32F8EE-8ED3-4AB9-ADDA-9E6C73C09A36
beh quello era solo un esempio semplice.
la funzione che io uso, come riportato nell'altro post, è la seguente...
diventa un po' difficile ricrearla con le formule standard
ciao
*********************************************
Function CND(X) As Single
Dim a1, a2, a3, a4, a5, L, K, F As Single
a1 = 0.31938153
a2 = -0.356563782
a3 = 1.781477937
a4 = -1.821255978
a5 = 1.330274429
L = Abs(X)
K = 1 / (1 + 0.2316419 * L)
F = 1 - ((1 / Sqr(2 * 3.141592654)) * (Exp(-L ^ 2 / 2)) * (a1 * K +
a2 * K ^ 2 + a3 * K ^ 3 + a4 * K ^ 4 + a5 * K ^ 5))
If X < 0 Then
CND = 1 - F
Else
CND = F
End If
End Function
---------------------------------------------------
Function BSfast(CallPut, Prezzo, Strike, Data, Scadenza, Riskfree1,
Riskfree2, DivYld, Vol) As Single
Dim d1, d2, b, nd1, nd2, nd1n, nd2n, T As Single
If Riskfree2 <> 0 Then
> beh quello era solo un esempio semplice.
> la funzione che io uso, come riportato nell'altro post, è la seguente...
> diventa un po' difficile ricrearla con le formule standard
Vedi questo essempio per la funzione CND:
http://www.telefonica.net/web2/kl2/SSHEET.StandardFormula.xls
'---------------
Penso che ci possano essere soltanto 3 motivi per usare una funzione
dall'utente su un foglio di calcolo:
- l'operazione non puň essere fatta per le funzione standard
- per controllare la volatilita della formula e ciň non puň essere fatto via
le funzioni standard
- per evitare le formule matriciale molto pesanti (molti calcoli
ridondandar)
'---------------
Penso che questa affermazione sia troppo forte e
io potrei contemplare anche altri motivi per l'uso
di una UDF. Ad esempio:
(1) La comodita': una UDF potrebbe essere molto
piiu' facile per un utente che una lunghissma
formula
(2) Secondo la esigenza, una UDF potrebbe essere
piu' veloce. Solitamente, l'uso di una` formula
sarebbe piu' veloce, ma il contrario e' anche
possibile.
(3) Per sotituire una funzione difettosa di Excel.
(4) Per utilizzare un algoritmo superiore a quello
utilizzato da Excel.
> Penso che questa affermazione sia troppo forte e
> io potrei contemplare anche altri motivi per l'uso
> di una UDF. Ad esempio:
>
> (1) La comodita': una UDF potrebbe essere molto
> piiu' facile per un utente che una lunghissma
> formula
Il mio post comincia per "penso che..." e come non sono Norman Jones, non contemplo il tuo primo caso perche per me comodita
raramente compensa la perdita di velocita nell foglio di calcolo :-) Ditto cio, potrebbe aceptare il punto per situazioni
eccezionali.
> (2) Secondo la esigenza, una UDF potrebbe essere
> piu' veloce. Solitamente, l'uso di una` formula
> sarebbe piu' veloce, ma il contrario e' anche
> possibile.
Mi puoi gentilmente fare una demostrazione de questa affirmazione con una formula che non utilizze operazioni matriciale?
Altrimenti, e incluso nell 4o punto dell mio post (per evitare le formule matriciale molto pesanti - molti calcoli
ridondanti)
> (3) Per sotituire una funzione difettosa di Excel.
Credo que cio e incluso nell primo punto dell mio post (l'operazione non puo essere fatta per una funzione standard [difettosa])
> (4) Per utilizzare un algoritmo superiore a quello
> utilizzato da Excel.
Credo che cio e una versione del tuo punto 2.
Grazie e saluti,
'------------------
> (1) La comodita': una UDF potrebbe essere molto
> piiu' facile per un utente che una lunghissma
> formula
Il mio post comincia per "penso che..." e come non sono Norman Jones, non
contemplo il tuo primo caso perche per me comodita
raramente compensa la perdita di velocita nell foglio di calcolo :-) Ditto
cio, potrebbe aceptare il punto per situazioni
eccezionali.
'------------------
Ripeto la mia asserzione che una funzione utente
possa essere utilizzata anche da un utente che non
sia in grado di inserire una formula molto complessa.
Potrebbe anche essere molto piu veloce (e molto piu'
sicuro!) che l'utente scriva un semplice = Pippo(A1)
anziche' la suddetta formula, lunga e complessa.
'------------------
> (2) Secondo la esigenza, una UDF potrebbe essere
> piu' veloce. Solitamente, l'uso di una` formula
> sarebbe piu' veloce, ma il contrario e' anche
> possibile.
Mi puoi gentilmente fare una demostrazione de questa affirmazione con una
formula che non utilizze operazioni matriciale?
Altrimenti, e incluso nell 4o punto dell mio post (per evitare le formule
matriciale molto pesanti - molti calcoli
ridondanti)
'------------------
A questo proposito,, ti riferisco, per via di esempio,
alla conversazione tra Charles Williams
(www.DecisionModels.com ) e Tushar Mehta
(www.tushar-mehta.com ):
Math involved. Excel speed optimization question.
UDF vs. longer excel equation
http://tinyurl.com/365y67
'----------------
> (3) Per sotituire una funzione difettosa di Excel.
Credo que cio e incluso nell primo punto dell mio post (l'operazione non puo
essere fatta per una funzione standard [difettosa])
'----------------
Dissento! Il problema non si riferrisci all'impossibilita'
di ottenere una risultato, ma, anzi, allo risultato stesso!
Vedi i tanti post da Harlan Grove, Jerry W Lewis,...
Bug in Excel's RAND() Function
http://tinyurl.com/3cx3oz
Randomly distributed normal deviates
http://tinyurl.com/32cqe3
Random number generator expression used
http://tinyurl.com/2k9v9l
Polynomial curvefit
http://tinyurl.com/34yypq
Comunque, e per risparmiare un po' di tempo,
vedi la Mea Culpa di Microsoft:
http://support.microsoft.com/?kbid=828888
Description of improvements in the statistical functions
in Excel 2003 and in Excel 2004 for Mac
'---------------
> (4) Per utilizzare un algoritmo superiore a quello
> utilizzato da Excel.
Credo che cio e una versione del tuo punto 2.
'------------------
C'e' una grande differenza di principio tra un risultato
erraneo ed un algoritmo migliorato!
A mio parere, le funzione utente rappresentano
uno strumento estremamente potente ed utile - la
differenza fra noi e che io non limiterei l'uso dello
strumento alle tre casi ristretti enunciati da te.
Credo che sia saggio utilizzare lo strumento adatto,
dato tutte le circonstanze, e di non escludere uno in
base alle asserzioni esagerate.
Nei miei progetti, sono molto contento di utilizzare
gli strumenti e le formule offerti da Excel in
congiunzione felice agli strumenti di VBA - compreso
e d'importanza, le funzioni utente.
----------------------------
> Ripeto la mia asserzione che una funzione utente
> possa essere utilizzata anche da un utente che non
> sia in grado di inserire una formula molto complessa.
> Potrebbe anche essere molto piu veloce (e molto piu'
> sicuro!) che l'utente scriva un semplice = Pippo(A1)
> anziche' la suddetta formula, lunga e complessa.
----------------------------
Ripeto: Aceptato
----------------------------> A questo proposito,, ti riferisco, per via di esempio,
> alla conversazione tra Charles Williams
> (www.DecisionModels.com ) e Tushar Mehta
> (www.tushar-mehta.com ):
>
> Math involved. Excel speed optimization question.
> UDF vs. longer excel equation
> http://tinyurl.com/365y67
Rispetto molto le opinioni di Charles e Tushar, pero sono sotto l'impressione di che nella conversazione sudetta
1) parlano precisamente di che una UDF potrebbe essere piu veloce che una formula matriciale oppure multiple formule inserite in
multiple celle (o matrice)
2) non c'e indicazione a un caso specifico
> Dissento! Il problema non si riferrisci all'impossibilita'
> di ottenere una risultato, ma, anzi, allo risultato stesso!
> Vedi i tanti post da Harlan Grove, Jerry W Lewis,...
Per me - questione semantica. Potrrebe formulare il mio primo punto come: Il risultato cercato non puo essere ottenuta per mezzo di
una funzione standard (il risultato erroneo non e il risoltato cercato, no?)
Ciao Norman,
----------------------------
> Ripeto la mia asserzione che una funzione utente
> possa essere utilizzata anche da un utente che non
> sia in grado di inserire una formula molto complessa.
> Potrebbe anche essere molto piu veloce (e molto piu'
> sicuro!) che l'utente scriva un semplice = Pippo(A1)
> anziche' la suddetta formula, lunga e complessa.
----------------------------
Ripeto: Aceptato
----------------------------
> A questo proposito,, ti riferisco, per via di esempio,
> alla conversazione tra Charles Williams
> (www.DecisionModels.com ) e Tushar Mehta
> (www.tushar-mehta.com ):
>
> Math involved. Excel speed optimization question.
> UDF vs. longer excel equation
> http://tinyurl.com/365y67
----------------------------
Rispetto molto le opinioni di Charles e Tushar, pero sono sotto l'impressione di che nella conversazione sudetta
1) parlano precisamente di che una UDF potrebbe essere piu veloce che una formula matriciale oppure multiple formule inserite in
multiple celle (o matrice)
2) non c'e indicazione a un caso specifico
----------------------------
> Dissento! Il problema non si riferrisci all'impossibilita'
> di ottenere una risultato, ma, anzi, allo risultato stesso!
> Vedi i tanti post da Harlan Grove, Jerry W Lewis,...
----------------------------
Per me - questione semantica. Potrrebe formulare il mio primo punto come: Il risultato cercato non puo essere ottenuta per mezzo di
una funzione standard (il risultato erroneo non e il risoltato cercato, no?)
----------------------------
> C'e' una grande differenza di principio tra un risultato
> erraneo ed un algoritmo migliorato!
----------------------------
Nell tuo punto 2 non parli di risultati arranei, ma di velocita :-) Non vedo la relazione.
----------------------------
> A mio parere, le funzione utente rappresentano
> uno strumento estremamente potente ed utile - la
> differenza fra noi e che io non limiterei l'uso dello
> strumento alle tre casi ristretti enunciati da te.
>
> Credo che sia saggio utilizzare lo strumento adatto,
> dato tutte le circonstanze, e di non escludere uno in
> base alle asserzioni esagerate.
>
> Nei miei progetti, sono molto contento di utilizzare
> gli strumenti e le formule offerti da Excel in
> congiunzione felice agli strumenti di VBA - compreso
> e d'importanza, le funzioni utente.
----------------------------
Completamente d'accordo :-) Solo tentavo resumire le mie osservazioni
Saluti,
'----------------
[...]
Nell tuo punto 2 non parli di risultati arranei, ma di velocita :-) Non vedo
la relazione.
[...]
'----------------
Mi riferivo a:
>> Per sotituire una funzione difettosa di Excel.
Saluti.
così era anche per me parecchi anni fa. lavorando per altri,
ormai sono disposto a sacrificare velocità,
parsimonia e (forse) comprensibilità pur di non dover
spiegare come attivare le macro, come bypassare
qualche antivirus troppo premuroso, come
recuperare e registrare qualche componente mancante,
come ingannare qualche mail server intransigente.
ne avevamo già parlato:
http://groups.google.com/group/microsoft.public.it.office.excel/msg/d455396ecd6830ab
[non uso ancora vsto2005+excel2007, ma i tentativi
di utilizzo di vsto2003+excel2003 non hanno
prodotto risultati minimamente soddisfacenti]
.f
'-------------------
Se ti fosse utile, e senza alcuna promessa, potresti
mandarmi i tuo file:
'-------------------
Ho ricevuto il tuo file e credo che abbia risolto
il problema,
Innanzitutto, credo che il tuo problema abbia
poco da fare con le tue funzioni utente ma credo
che abbia molto da fare con le il modo in cui
Excel ricalcola il workbook.
Per quanto riguarda le tue funzioni, credo che si
possa eliminare la complessita; come fattore dal
momento che non si risolvi il problema sostituendo
le funzioni con la semplice:
'=============>>
Public Function Prova(X As Single) As Single
Prova = X * 1000
End Function
'<<=============
Pertanto:
(1) ho cancellato la LinkedCell (cella collegata)
del tuo secondo SpinButton e ho inserito la
seguennte procedura nel modulo del foglio
'=============>>
Private Sub SpinButton2_Change()
Dim myVal As Variant
myVal = Me.SpinButton2.Value / 100
With Application
ThisWorkbook.Sheets("Strat").Range("P23").Value = myVal
Me.Range("I23").Value = myVal
End With
End Sub
'<<=============
(2) Ho modificato le formule che usano la funzione
in modo che si riferissero alla cella che è
aggiornato dal SpinButton e che, ora, si trova.
sul foglio di calcolo ("Strat").
Ti ho mandato il mio file di prova.
'--------------------
così era anche per me parecchi anni fa. lavorando per altri,
ormai sono disposto a sacrificare velocità,
parsimonia e (forse) comprensibilità pur di non dover
spiegare come attivare le macro, come bypassare
qualche antivirus troppo premuroso, come
recuperare e registrare qualche componente mancante,
come ingannare qualche mail server intransigente.
ne avevamo già parlato:
http://groups.google.com/group/microsoft.public.it.office.excel/msg/d455396ecd6830ab
[non uso ancora vsto2005+excel2007, ma i tentativi
di utilizzo di vsto2003+excel2003 non hanno
prodotto risultati minimamente soddisfacenti]
'--------------------
Provo a gettare almeno uno sguardo ad ogni post, ma
la tua risposta in quel thread mi e' sfuggito!
Grazie per il link molto interessante e molto pertinente.
sfuggita
Avrei voluto aggiungere che credo sia meglio sotstituire
le dichiarazioni 'Single' con Double.
Io avevo cambiato le tue dichiarazione, utilizzando il
tipo Single, unicamente per dimostrare un errore nel
modo di dichiarare le tue varibili; poi, ho dimenticato
di spiegare che il Double tipo sarebbe meglio!
Infatti, con un pc moderno, un Double è molto più
efficiente e, in ogni modo, Excel convertirà un Single
a un Double.
In modo analogo, utilizzerei il tipo Long anziche' il tipo
Integer.
Ho corretto l'esempio. Ci era un problema di precedenza e una certa confusione con le variabili. Finalmente, in questo caso la
formula e più veloce che la UDF, ma ci sembra essere mancanza di precisione nelle formule del foglio di calcolo dovuto la
limitazione del Punto Flottante.
> (1) ho cancellato la LinkedCell (cella collegata)
> del tuo secondo SpinButton e ho inserito la
> seguennte procedura nel modulo del foglio
> (2) Ho modificato le formule che usano la funzione
> in modo che si riferissero alla cella che č
> aggiornato dal SpinButton e che, ora, si trova.
> sul foglio di calcolo ("Strat").
>
> Ti ho mandato il mio file di prova.
Ciao Norman, grazie mille, ho ricevuto il file e funziona molto bene.
Ho applicato tutti i tuoi consigli
1. inserito il Spinbutton_change
2. messo tabella e spinbutton nello stesso foglio
3. assegnato tipo double a tutte le variabili nella funzione, tranne una
Va quasi perfettamente, nel senso che ogni tanto rallenta, anche se non
capisco bene quando, sembra casuale... sto comunque utilizzando la
funzione "bsfast" al posto di "prova" ed č effettivamente un po' piů
pesante... mi sembra che lasciando un valore nel linkedcell degli
spinbutton (quindi non campo vuoto perň sempre con la routine
spinbutton_change) sia piů veloce: avrň le allucinazioni? :-)
Mi era venuto in mente: mettendo il calcolo in manuale e imponendo il
ricalcolo (perň solo della cartella aperta) inserendo qualche riga di
codice nella routine spinbutton_change si potrebbe velocizzare
ugualmente? Come si puň fare nel concreto?
'-----------------------
ho ricevuto il file e funziona molto bene.
Ho applicato tutti i tuoi consigli
1. inserito il Spinbutton_change
2. messo tabella e spinbutton nello stesso foglio
3. assegnato tipo double a tutte le variabili nella funzione, tranne una
Va quasi perfettamente, nel senso che ogni tanto rallenta, anche se non
capisco bene quando, sembra casuale... sto comunque utilizzando la
funzione "bsfast" al posto di "prova" ed è effettivamente un po' più
pesante... mi sembra che lasciando un valore nel linkedcell degli
spinbutton (quindi non campo vuoto però sempre con la routine
spinbutton_change) sia più veloce: avrò le allucinazioni? :-)
Mi era venuto in mente: mettendo il calcolo in manuale e imponendo il
ricalcolo (però solo della cartella aperta) inserendo qualche riga di
codice nella routine spinbutton_change si potrebbe velocizzare
ugualmente? Come si può fare nel concreto?
Ciao Norman, grazie mille, ho ricevuto il file e funziona molto bene.
Ho applicato tutti i tuoi consigli
1. inserito il Spinbutton_change
2. messo tabella e spinbutton nello stesso foglio
3. assegnato tipo double a tutte le variabili nella funzione, tranne una
Va quasi perfettamente, nel senso che ogni tanto rallenta, anche se non
capisco bene quando, sembra casuale... sto comunque utilizzando la
funzione "bsfast" al posto di "prova" ed è effettivamente un po' più
pesante... mi sembra che lasciando un valore nel linkedcell degli
spinbutton (quindi non campo vuoto però sempre con la routine
spinbutton_change) sia più veloce: avrò le allucinazioni? :-)
Mi era venuto in mente: mettendo il calcolo in manuale e imponendo il
ricalcolo (però solo della cartella aperta) inserendo qualche riga di
codice nella routine spinbutton_change si potrebbe velocizzare
ugualmente? Come si può fare nel concreto?
'-----------------------
A me, il file aggiornato funzionava abbastanza bene.
Tuttavia, il file che mi avevi mandato utilizzava
soltanto la tua funzione Prova. Se vorresti mandarmi
un file di esempio che utilizza le funzioni vere, lo
sguarderò di nuovo.
> > http://www.telefonica.net/web2/kl2/SSHEET.StandardFormula.xls
>
> Ho corretto l'esempio. Ci era un problema di precedenza e una certa confusione con le variabili. Finalmente, in questo caso la formula e più veloce che la UDF, ma ci sembra essere mancanza di precisione nelle formule del foglio di calcolo dovuto la limitazione del Punto Flottante.
ciao KL,
chiedevo se questa riga, tratta dal tuo esempio,
Dim a1, a2, a3, a4, a5, L, K, F As Single
è volutamente così a titolo sperimentale.
--
()---cucchiaino
> chiedevo se questa riga, tratta dal tuo esempio,
>
> Dim a1, a2, a3, a4, a5, L, K, F As Single
>
> č volutamente cosě a titolo sperimentale.
No, cio e il codice originale di Bem. Io avrebbero specificato il tipo per ogni variabile/utilizzato i costanti. Per che?
...e nell primo caso avrebbero utilizzato Double per tutti variabili.
> Ciao cucchiaino,
ciao Kirill
> > chiedevo se questa riga, tratta dal tuo esempio,
> >
> > Dim a1, a2, a3, a4, a5, L, K, F As Single
> >
> > č volutamente cosě a titolo sperimentale.
>
> No, cio e il codice originale di Bem.
ops! scusa.
> Io avrebbero specificato il tipo per ogni variabile/utilizzato i costanti.
infatti ero sicuro che normalmente le avresti dichiarate.
> Per che?
Avevo pensato per un attimo che le avevi lasciate Variant per verificare
il grado di precisione dei risultati nei vari casi ...
()---cucchiaino
> Se vorresti mandarmi
> un file di esempio che utilizza le funzioni vere, lo
> sguarderņ di nuovo.
Perfetto, te lo mando allora.
E' interessante notare quanto margine di miglioramento ci sia in un
foglio excel agendo nei punti giusti.
Ciao
> ciao KL,
> chiedevo se questa riga, tratta dal tuo esempio,
>
> Dim a1, a2, a3, a4, a5, L, K, F As Single
>
> č volutamente cosě a titolo sperimentale.
Ciao, no č un mio errore :-), non sono molto pratico di VB
Volevo assegnare a tutte le variabili il tipo single, ma ho usato la
sintassi di altri compilatori
'------------------
'------------------
Ho ricevuto il tuo file.
Oltre ai miei suggerimenti originali, prova a sostituire
il codice nel modulo del foglio Strat con la seguente
versione:
'=============>>
Option Explicit
'-------------------->>
Private Sub SpinButton1_Change()
Dim myval As Double
myval = Me.SpinButton1.Value + Me.Range("C12").Value
With Application
Me.Range("G21").Value = myval
.OnTime Now + TimeValue("00:00:00"), "CalcIt"
End With
End Sub
'-------------------->>
Private Sub SpinButton2_Change()
Dim myval As Double
myval = Me.SpinButton2.Value / 100
With Application
Me.Range("K21").Value = myval
.OnTime Now + TimeValue("00:00:00"), "CalcIt"
End With
End Sub
'<<=============
Nel modulo standard (Modulo1), sostituisci
il codice con:
'=============>>
Option Explicit
'-------------------->>
'Distribuzione Normale
Public Function ND(X)
ND = 1 / Sqr(2 * 3.141592654) * Exp(-X ^ 2 / 2)
End Function
'-------------------->>
'Distribuzione Normale Cumulata
Public Function CND(X As Double) As Double
Const a1 As Double = 0.31938153
Const a2 As Double = -0.356563782
Const a3 As Double = 1.781477937
Const a4 As Double = -1.821255978
Const a5 As Double = 1.330274429
Dim L As Double
Dim K As Double
Dim F As Double
L = Abs(X)
K = 1 / (1 + 0.2316419 * L)
F = 1 - ((1 / Sqr(2 * 3.141592654)) * _
(Exp(-L ^ 2 / 2)) * _
(a1 * K + a2 * K ^ 2 + a3 _
* K ^ 3 + a4 _
* K ^ 4 + a5 * K ^ 5))
If X < 0 Then
CND = 1 - F
Else
CND = F
End If
End Function
'-------------------->>
Public Function BSfast( _
CallPut As String, Prezzo As Double, _
Strike As Double, _
Data As Double, Scadenza As Double, _
Riskfree1 As Double, Riskfree2 As Double, _
DivYld As Double, Vol As Double) As Double
Dim d1 As Double
Dim d2 As Double
Dim b As Double
Dim nd1 As Double
Dim nd2 As Double
Dim nd1n As Double
Dim nd2n As Double
Dim T As Double
If Riskfree2 <> 0 Then
b = Riskfree1 - Riskfree2
Else
b = Riskfree1 - DivYld
End If
T = (Scadenza - Data) / 365
If T = 0 Then
If CallPut = "CALL" Then
If Prezzo > Strike Then
BSfast = Prezzo - Strike
Else
BSfast = 0
End If
ElseIf CallPut = "PUT" Then
If Prezzo > Strike Then
BSfast = 0
Else
BSfast = Strike - Prezzo
End If
End If
ElseIf T > 0 Then
d1 = (Log(Prezzo / Strike) + (b + Vol ^ 2 / 2) * T) _
/ (Vol * Sqr(T))
d2 = d1 - Vol * Sqr(T)
If CallPut = "CALL" Then
nd1 = CND(d1)
nd2 = CND(d2)
BSfast = Prezzo * Exp((b - Riskfree1) * T) _
* nd1 - Strike _
* Exp(-Riskfree1 * T) * nd2
ElseIf CallPut = "PUT" Then
nd1n = CND(-d1)
nd2n = CND(-d2)
BSfast = Strike * Exp(-Riskfree1 * T) _
* nd2n - Prezzo _
* Exp((b - Riskfree1) * T) * nd1n
End If
End If
End Function
'-------------------->>
Public Sub CalcIt()
Application.Calculation = xlCalculationAutomatic
End Sub
'<<=============
Ti ho mandato il file aggiornato.
> Ho ricevuto il tuo file.
>
> Oltre ai miei suggerimenti originali, prova a sostituire
> il codice nel modulo del foglio Strat con la seguente
> versione:
Ora va come una scheggia!
Complimenti per la competenza e ti ringrazio ancora per la disponibilità.
Ciao
> Ora va come una scheggia!
A meno che tu sia napoletano, non capisco
l'uso della parola 'scheggia'!
Quando esplode, una bomba produce schegge
che viaggiano a una notevole velocità.
--
---------------------------
Mauro Gamberini
http://www.riolab.org/
'---------------
> A meno che tu sia napoletano, non capisco
> l'uso della parola 'scheggia'!
Quando esplode, una bomba produce schegge
che viaggiano a una notevole velocità.
'---------------
Ah! Grazie, Mauro - ho capito!
In inglese sarebbe 'Shrapnel' - io stavo pensando
di 'splinter':
"1a frammento irregolare, spec. ruvido, appuntito e tagliente,
staccato da un corpo solido o da un oggetto spezzato:
una s. di legno" [De Mauro]
> A meno che tu sia napoletano, non capisco
> l'uso della parola 'scheggia'!
no, non sono napoletano, anzi, dal lato opposto :-)
ma penso sia un'espressione usata in tutta Italia
> In inglese sarebbe 'Shrapnel' - io stavo pensando
> di 'splinter':
>
> "1a frammento irregolare, spec. ruvido, appuntito e tagliente,
> staccato da un corpo solido o da un oggetto spezzato:
> una s. di legno" [De Mauro]
scheggia va bene sia per indicare un frammento di una bomba che di un
pezzo di legno, almeno non mi vengono in mente 2 termini diversi come in
inglese...
comunque il concetto è che questo frammento va veloce
sia che si stacchi da una bomba esplosa sia da un pezzo di legno o
roccia o altro magari a causa di un urto violento
ciao ;-)
'-------------------
no, non sono napoletano, anzi, dal lato opposto :-)
ma penso sia un'espressione usata in tutta Italia
'-------------------
Grazie!
Io mi riferivo al significato 4 e non conosceovo 1b!
http://www.demauroparavia.it/103119
Comunque, Maauro ha spiegato il significato.
Grazie ancora.
e (ovviamente)
Maauro ===> Mauro
>Vedi Charles Williams a:
>
> Excel Pages - Optimising Speed
> http://www.decisionmodels.com/optspeedd.htm
Segnalo anche, sempre da Charles Williams, il documento
Improving Performance in Excel 2007
http://msdn2.microsoft.com/en-us/library/aa730921.aspx
Faccio presente che le soluzioni lì indicate sono valide per tutte le
versioni di Excel
|Applies to: Microsoft Office Excel 2007, Microsoft Office Excel 2003,
|Microsoft Excel 2002, Microsoft Excel 2000
--
Tiziano Marmiroli
Microsoft MVP - Office System
'----------------
Segnalo anche, sempre da Charles Williams, il documento
Improving Performance in Excel 2007
http://msdn2.microsoft.com/en-us/library/aa730921.aspx
'----------------
Grazie per la segnalazione; è un ottimo link ed
altamente utile!
"Tiziano Marmiroli" wrote
> Improving Performance in Excel 2007
> http://msdn2.microsoft.com/en-us/library/aa730921.aspx
> Faccio presente che le soluzioni li indicate sono valide per tutte le
> versioni di Excel
Credo che potete trovare questa conversazione interessante: http://tinyurl.com/2qmkmw