Valutazione 4.87/ 5 (100.00%) 5838 voti

Condividi:        

Plotter di funzioni

Vuoi potenziare i tuoi documenti Word? Non sai come si fa una macro in Excel? Devi creare una presentazione in PowerPoint?
Oppure sei passato a OpenOffice e non sei sicuro di come lavorare al meglio?

Moderatori: Anthony47, Flash30005

Plotter di funzioni

Postdi recalcatiiti » 30/08/16 13:48

Buongiorno a tutti,

propongo di seguito una goffa macro che mi permette di disegnare grafici di funzioni in una variabile.

Codice: Seleziona tutto
Sub disegna()
Range("C2,K1").Clear
Range("G2:H2000").Clear
Range("C2").Value = Range("B5").Value
If Range("N2").Value = 0 Then
Do
Range("C2").Value = Range("C2").Value + Range("B4").Value
Range("K1").Value = Range("K1").Value + 1

    Range("B2").Select
    Selection.Copy
    Range("H1").Offset(Range("K1").Value, 0).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
Range("C2").Select
    Selection.Copy
    Range("G1").Offset(Range("K1").Value, 0).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False


If Range("K2").Value <> 0 Then
Range("A1").Select
Exit Sub
End If
Loop Until Index > 1
End If
End Sub


Funziona, ma è veramente lenta, per calcolare 10000 valori impiega (sul mio pc) 10/15 min.

Come si può notare, la macro si appoggia ad alcune celle nel foglio le quali mi permettono, tramite funzioni logiche, di iterare la formula (funzione) un numero a piacere di volte con incremento a mia scelta. Chiaramente, la macro è lenta per questo motivo.

Allego il file contente il plotter. https://www.dropbox.com/s/mevc4nlvu6sste5/plotter_funzioni.xlsm?dl=0

La formula/funzione si inserisce in B2.

Ciò che per me è importante, oltre alla costruzione del grafico, è il report di tutti i valori calcolati.

La mia domanda è questa, posso ottenere lo stesso risultato del file d'esempio, ma più velocemente?

Vi ringrazio TUTTI, anticipatamente

dimenticavp, utilizzo Excel2010

sr
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Sponsor
 

Re: Plotter di funzioni

Postdi wallace&gromit » 30/08/16 15:18

ciao,
sicuramente mettendo:
Codice: Seleziona tutto
Application.ScreenUpdating = False

all'inizio, qualcosa ottieni.
Ma tutto quel copia e incolla non mi convince, magari si può trovare di meglio.
stato 2014: Office2003/2013 su win7
Avatar utente
wallace&gromit
Utente Senior
 
Post: 1421
Iscritto il: 16/01/12 14:21

Re: Plotter di funzioni

Postdi recalcatiiti » 30/08/16 15:44

Grazie w&g!
C'è sicuramente modo di implementarla, così è veramente becera.
Però, migliora già molto con questa aggiunta.
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi wallace&gromit » 30/08/16 15:54

la seconda parte, quella dove si inseriscono i valori nella colonna G può essere scritta così:
Codice: Seleziona tutto
Range("C2").Copy Destination:=Range("G1").Offset(Range("K1").Value, 0)

ma per la formula questo principio non funziona, ovviamente
stato 2014: Office2003/2013 su win7
Avatar utente
wallace&gromit
Utente Senior
 
Post: 1421
Iscritto il: 16/01/12 14:21

Re: Plotter di funzioni

Postdi Marius44 » 30/08/16 16:05

Ciao
In aggiunta all'ottimo suggerimento di W&G (che saluto) elimina tutti quei .Select e vedrai che miglioramento!
In altre parole la macro diventa questa (in E2 ho indicato il tempo impiegato)
Codice: Seleziona tutto
Sub disegna_bis()
itime = Timer
Range("C2,K1").Clear
Range("G2:H2000").Clear
Range("C2").Value = Range("B5").Value
Application.ScreenUpdating = False
If Range("N2").Value = 0 Then
    Do
        Range("C2").Value = Range("C2").Value + Range("B4").Value
        Range("K1").Value = Range("K1").Value + 1
        Range("B2").Copy
        Range("H1").Offset(Range("K1").Value, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
        Range("C2").Copy
        Range("G1").Offset(Range("K1").Value, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
        If Range("K2").Value <> 0 Then
            Range("A1").Select
            Exit Sub
        End If
        ftime = Timer: Cells(2, 5) = ftime - itime
    Loop Until Index > 1
End If
Application.ScreenUpdating = True
End Sub

Prova e fai sapere. Ciao,
Mario
Marius44
Utente Senior
 
Post: 143
Iscritto il: 07/09/15 22:00

Re: Plotter di funzioni

Postdi recalcatiiti » 30/08/16 16:33

Eccellente Marius, 68 sec per 10000 iterazioni!
Grazie!
Sì può fare di meglio?
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi wallace&gromit » 30/08/16 17:16

Certo che si può, ma forse la cosa ti deluderà:

tieni l'ultima versione dei dati fino a 10000 iterazioni, sostituisci i valori in G3 e H3 con le formule

Codice: Seleziona tutto
=G2+$B$4

=SEN(LN(G3))
le selezioni entrambe ed estendi fino in fondo (doppio clic sul quadratino verde in basso a destra). Fatto in un batter d'occhio!
stato 2014: Office2003/2013 su win7
Avatar utente
wallace&gromit
Utente Senior
 
Post: 1421
Iscritto il: 16/01/12 14:21

Re: Plotter di funzioni

Postdi Anthony47 » 31/08/16 00:13

Questa dovrebbe essere piu' veloce delle altre macro pubblicate, potrebbe essere competitiva col metodo W&G:
Codice: Seleziona tutto
Sub disegna_zzz()
Dim out(), Iteraz As Long, myIncr As Double, cVal As Double, myFun As String, myInd As Long, cFun
myFun = Range("b2").Formula
'
itime = Timer
Range("C2,K1").Clear
Range("G2:H20000").Clear
Range("C2").Value = Range("B5").Value
myIncr = Range("B4").Value
Iteraz = Range("B3").Value
ReDim out(1 To Range("B3").Value, 1 To 2)
'Application.ScreenUpdating = False
cVal = Range("B5").Value
If Range("N2").Value = 0 Then
    Do
        cVal = cVal + myIncr
        cFun = Evaluate(Replace(myFun, "(C2)", "(" & Replace(CStr(cVal), ",", ".", , , vbTextCompare) & ")", , , vbTextCompare))
        myInd = myInd + 1
        out(myInd, 1) = cVal
        out(myInd, 2) = cFun
        If myInd >= Iteraz Then
            Range("G2").Resize(Iteraz, 2).Value = out
            MsgBox ("Completato, sec. " & Format(Timer - itime, "0.00"))
            Exit Do
        End If
'DoEvents
    Loop Until Index > 1
End If
Application.ScreenUpdating = True
End Sub
Dal foglio prende i dati e scrive solo i risultati, quindi le varie celle K1, K2, e la stessa C2 non vengono usate; non so se questo e' un problema.
Ho continuato a usare quel criptico Loop Until Index > 1 (per dire "Loop e basta"), anche se non immagino a cosa possa servire.

Ciao
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13904
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: Plotter di funzioni

Postdi recalcatiiti » 31/08/16 08:18

Ciao a tutti,
w&g grazie per il consiglio, ma preferisco un processo completamente automatico.
Infatti, grazie Anthony, 10^5 iterazioni in 3 s perfetto.

Risolta la questione, vorrei alzare la posta.

E' possibile limitare tutti i valori positivi ad ad un valore positivo PosMax (locato, ad esempio in B6) e tutti i valori negativi ad un valore negativo NegMin (locato, ad esempio in B7)? Questo per escludere i punti di infinito che distruggono completamente la scala del grafico.

Grazie a tutti, a presto
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi recalcatiiti » 31/08/16 10:23

Ciao Anthony,
è sorto un problema con la tua macro.
Allego il file:
https://www.dropbox.com/s/rd2goylihf4j6gz/plotter_funzioni_anthony.xlsm?dl=0

Nel file allegato, volevo rappresentare la funzione f(x)=sen(x)+x il cui grafico è il seguente:
https://www.dropbox.com/s/0ymerdwa9c2kh1q/54544.JPG?dl=0

Per qualche motivo, la macro produce i soli valori di sen(x) considerando "+x" come una costante con valore uguale al valore iniziale inserito dall'utente. (quindi, in questo caso, il grafico risultante è della funzione f(x)=sen(x)+1

Ho provato con altre funzioni della stessa famiglia (del tipo f(x)=g(x)+x), hanno tutte lo stesso problema.

Funzioni di funzioni (del tipo f(x)=g(z(x)) come f(x)=sen(ln(x)) vengono disegnate correttamente.

Si può ovviare a questo problema?

Grazie, a presto
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi recalcatiiti » 31/08/16 16:37

Ciao,

al quesito sulla limitazione ho risolto con una banale formula del tipo: =SE(H2<=$B$6;$B$6;SE(H2>=$B$7;$B$7;H2)) poi il grafico lo costruisco da questi dati, però se si può implementare nella macro ben venga!

Permane il problema esposto nel post precedente, parecchio strano..
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi Anthony47 » 01/09/16 01:32

L'errore di calcolo e' dovuto al fatto che, per evitare di lavorare sul foglio Excel, simulo la formula nel vba (altrimenti per 10^5 iterazioni dovresti aspettare piu' di 3 sec); e la simuazione aveva dei limiti...
Credo di aver risolto con questo vincolo:
-ho assegnato alla cella C2 il "nome" xxx
-nelle formule invece di C2 bisognera' scrivere xxx; esempi
=SEN(xxx)/Log(xxx) =Sen(xxx)+1/xxx
Questo consente al vba di individuare nelle formule la variabile X e di calcolarne correttamente il risultato.
Ho inoltre previsto la possibilita' di inserire sull'asse Y un limite superiore e uno inferiore, e la rappresentazione su scala logaritmica vs lineare. Questo viene gestito nelle impostazioni del grafico, non nel calcolo della serie.
La macro inoltre ora imposta sul foglio di partenza due intervalli nominati rispettivamente PEPPOX e PEPPOY, con i soli dati della serie calcolata. Il grafico di Foglio3 ora usa questi intervalli, in modo da plottare solo i valori calcolati.
Tutto questo e' contenuto nel file pubblicato qui:
https://www.dropbox.com/s/vqyz8z86a8407 ... .xlsm?dl=0

La macro principale e' stata modificata:
Codice: Seleziona tutto
Sub disegna_zzz()
'Vedi http://www.pc-facile.com/forum/viewtopic.php?f=26&t=107387
Dim out(), Iteraz As Long, myIncr As Double, cVal As Double, myFun As String, myInd As Long, cFun
'
Foglio1.Select
myFun = Range("b2").Formula
'
itime = Timer
Range("C2,K1").ClearContents
Range("G2:H" & Rows.Count).ClearContents
Range("C2").Value = Range("B5").Value
myIncr = Range("B4").Value
Iteraz = Range("B3").Value
ReDim out(1 To Range("B3").Value, 1 To 2)
Application.ScreenUpdating = False
Foglio3.ChartObjects(1).Chart.HasTitle = True
'If Foglio1.Range("B8").Value = "Log" Then scTy = " - Asse Y LOGARITMICO" Else scTy = " - Asse Y Lineare"
Foglio3.ChartObjects(1).Chart.ChartTitle.Text = Mid(Replace(myFun, "xxx", "x"), 2, 999) & scTy
'
cVal = Range("B5").Value
If Range("N2").Value = 0 Then
    Do
        cVal = cVal + myIncr
        cFun = Evaluate(Replace(myFun, "xxx", Replace(CStr(cVal), ",", ".", , , vbTextCompare), , , vbTextCompare))
        myInd = myInd + 1
        out(myInd, 1) = cVal
        If IsError(cFun) Then out(myInd, 2) = "" Else out(myInd, 2) = cFun
        If myInd >= Iteraz Then
            Range("G2").Resize(Iteraz, 2).Value = out
            Exit Do
        End If
'DoEvents
    Loop Until Index > 1
End If
'Il grafico e' basato su questi 2 "nomi":
ActiveWorkbook.Names("peppoX").RefersTo = ActiveSheet.Range("G2").Resize(myInd, 1)
ActiveWorkbook.Names("peppoY").RefersTo = ActiveSheet.Range("H2").Resize(myInd, 1)
'
Call GraFormat          'Imposta limiti su asse y
Application.ScreenUpdating = True
Application.Goto Range("A1")
MsgBox ("Completato, sec. " & Format(Timer - itime, "0.00"))
End Sub

E' presente anche una Sub GraFormat(), che si occupa di impostare sul grafico la scala (lineare o logaritmica) e gli eventuali limiti inferiore e superiore dell'asse Y; oltre che alcune macro di evento nei moduli vba del workbook, di Foglio1 e di Foglio3.

Foglio1 e' protetto con password Segreta.

Ciao a tutti
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13904
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: Plotter di funzioni

Postdi wallace&gromit » 01/09/16 08:55

Applausi, applausi per Anthony (cantare alla Fabri Fibra).

Sono anche fiero di me stesso: ti conosco abbastanza per avere azzeccato al primo colpo la password Segreta.

Per recalcatiiti posso chiederti una mia curiosità: hai anche tu figli liceali che ti fanno impazzire con quesiti su temi oramai sepolti da anni o lo fai per tua passione personale?
stato 2014: Office2003/2013 su win7
Avatar utente
wallace&gromit
Utente Senior
 
Post: 1421
Iscritto il: 16/01/12 14:21

Re: Plotter di funzioni

Postdi recalcatiiti » 01/09/16 11:43

Grazie!

Direi standing ovation per Anthony (il quale,a volte, mi pare troppo modesto).
Complimenti sinceri!

Tutto funziona bene.

Il piccolo smacco, che non dipende da te (Anthony), risiede nel fatto che excel non è in grado di calcolare il valore delle funzioni fondamentali per x molto grandi (ad esempio f(x)=sen(x) può essere calcolata solo per valori inferiori a ~10^8,127809882), magari riesci ad aggirare anche questo?! No, non voglio rubarti altro tempo, anche perché temo non si possa.

[OT]
per w&g: certo che puoi.
No, semplice passione, ed essendo in ferie mi piace dedicargli un pò di tempo.
Normalmente, per produrre un grafico, utilizzerei https://www.wolframalpha.com/ o al limite se voglio maneggiarlo di più MathLab http://www.mathlab.mtu.edu/mediawiki/index.php/Main_Page. Ma in definitiva Excel, per certi aspetti, ha una marcia in più. Mi permette, ad esempio, di produrre enormi tabelle di numeri (per questo la richiesta esplicita) e di manipolarli in modi inaccessibili rispetto agli strumenti sopracitati. E poi devo ammettere che excel è un programma molto fascinoso, se posso utilizzarlo per qualcosa (e si può utilizzare per tutto), lo utilizzo. ah ah ah

Ciao a tutti, e grazie ancora Anthony!
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi Anthony47 » 05/09/16 02:21

Eh eh, ne ho mangiate di lucertole prima di arrivare a quel codice...

Perche' il calcolo del Seno vada in crisi con valori > 10^8,127809882927 non lo so (immagino che sia un overflow nello sviluppo della serie di Taylor usata per il calcolo); certamente si potrebbe scrivere una userfunction che superi questo limite, ma la stessa cosa si puo' fare direttamente nella formula ricordando che Seno e' una funzione periodica con periodo pari a 2*Pi.Greco; quindi scrivendo come formula, invece che =SEn(xxx), =SEN(RESTO(xxx;2*PI.GRECO()))

Ciao a tutti.
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13904
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: Plotter di funzioni

Postdi recalcatiiti » 05/09/16 09:07

Ci avevo pensato, ma mi sono accorto che non migliora di molto. Infatti per x > 10^12,8496796874, restituisce errore.
In più, credo mi darai conferma, ci sono dei limiti generali che determinano un range di valori ammissibili. Il limite positivo si attesta a ~1.8*10^308 quello negativo intorno a ~ 10^-307. Ad esempio la funzione esponenziale f(x)=2^x, può essere calcolata per valori x <= 1,023999999999*10^3 dando come risultato massimo 1.79769313484981*10^308. Oppure per f(x)=1/x il valore inferiore ammissibile è ~ 0,22251*10^(-307), altrimenti verrà restituito l'errore #DIV/0!. Anche le funzioni logaritmiche si comportano in modo simile. Dispongo di altri esempi se interessati.

Mi parlavi di userfunction che possono aggirare il problema, ma lo possono fare definitivamente?

Ciao.
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03

Re: Plotter di funzioni

Postdi Anthony47 » 06/09/16 01:51

Beh, passare da 10^8 a 10^12 vuol dire moltiplicare per 10mila, non proprio noccioline...

Comunque quelli che descrivi sono i limiti propri di Excel in quanto a valori minimi e massimi consentiti dalla rappresentazione in virgola mobile secondo lo standard ANSI/IEEE Std 754-1985 in doppia precisione (64 bit) con 15 digit significativi. Vedi
https://support.office.com/it-it/articl ... eb276e8eaa

Una userfunction puo' eseguire un calcolo specifico; per la divisione di un numero grande a piacere e un divisore di max 15 cifre vedi ad esempio viewtopic.php?f=26&t=74566&p=423130#p423017
Se vuoi sostituire piu' funzioni serviranno piu' userfunction; con l'ovvio limite che volendo usare il Pc per i calcoli il vincolo della rappresentazione in virgola mobile a 64 bit si ripresenta immediatamente anche se con un'altra faccia.

Insomma credo che, a pensarci bene, 15 digit di precisione e valori compresi tra 2,2251*10^308 e 9,99999999999999*10^307 siano piu' che sufficienti per arrivare su Plutone senza errori.

Ciao
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13904
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: Plotter di funzioni

Postdi recalcatiiti » 06/09/16 19:41

Magari potessimo contare sempre su precisioni del genere, molto dell'innarrivabile oggigiorno non sarebbe più tale.

Detto ciò, mi sarebbe piaciuto non avere limitazioni, ma ahimè, non si può avere tutto. E quello che hai tirato fuori è più che abbastanza, davvero un ottimo strumento.

Ti ringrazio Anthony a presto
Excel 2010
recalcatiiti
Utente Junior
 
Post: 76
Iscritto il: 12/10/15 15:03


Torna a Applicazioni Office Windows


Topic correlati a "Plotter di funzioni":


Chi c’è in linea

Visitano il forum: patel e 15 ospiti