Condividi:        

Prendere un pezzo di una matrice

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

Prendere un pezzo di una matrice

Postdi By Sal » 07/07/15 16:39

Ciao questa volta chiedo aiuto per una matrice con VBA

ho una matrice con molti elementi, tipo Matrice(1 to 50000, 1 to 16)


ora dovrei scrivere in un altra matrice gli elementi che sono nella matrice primaria

diciamo che dovrei prendere gli elementi dal numero 4000 al numero 14000 e solo della chiamiamola "Colonna" 8 del secondo range.

con il VBA ho creato questa

Codice: Seleziona tutto
ReDim rng(x)
For k = x - (Limite2 - 1) To x
    rng(n) = Calc(k, 4)
    n = n + 1
Next k



dove rng e la matrice nuova x è il numero di elelmenti, visto che mi interessa 1 valore dei 16

limite2 è un numero fisso diciamo 1000

quindi il ciclo parte da un valore della matrice di 1000 numeri precedenti fino al valore di x attuale e li scrive nella matrice rng

questo perche mi serve la media di quei 1000 valori

che ottengo con

Codice: Seleziona tutto
Calc(x, 5) = WorksheetFunction.Average(rng)



ora questo ciclo di 1000, e ce ne sono 4 anche più di 1000, mi comportano un grosso ritardo nell'esecuzione del codice, visto che questi cicli si ripetono per 50000 elementi.

in effetti vorrei eliminare il ciclo cosi diminuirei l'esecuzione della macro.

in un primo momento avevo optato per

Codice: Seleziona tutto
Calc(x, 5) = WorksheetFunction.Average(Calc(x - Limite1, 4), Calc(x, 4))



ma va in errore, forse non ho impostato bene la cosa.

ci sarebbe una soluzione diversa del Ciclo For....next, per calcolare la media di n valori precedenti alla x della matrice Calc()

Ciao By Sal (8-D
A rileggerci By Sal
Avatar utente
By Sal
Utente Junior
 
Post: 83
Iscritto il: 27/08/06 14:40

Sponsor
 

Re: Prendere un pezzo di una matrice

Postdi Anthony47 » 09/07/15 01:33

Purtroppo hai scritto bene quel che hai fatto, meno bene quel che devi ottenere....
Dunque...
Hai un array Calc(1 to 50000, 1 to 16)

Da questo array vorresti prelevare da "riga" 4000 a 14000 (quindi 10mila righe) il contenuto della sola "colonna" 8 (quindi 1 colonna).
Se e' cosi', non capisco l' uso di " = Calc(k, 4)" per popolare il nuovo array; ne' perche' usi ReDim rng(x) (avrei visto piu' significativo usare Redim rng(Limite2), visto che il ciclo For k /Next k si ripete per "Limite2" volte.

Insomma mi sono perso tra l'incoerenza dei vari scritti e la mancanza dell'obiettivo.
Il fatto che l' istruzione Calc(x, 5) = WorksheetFunction.Average(Calc(x - Limite1, 4), Calc(x, 4)) vada in errore non mi stupisce, visto che il target della funzione e' incoerente con quanto la funzione si aspetta.

In linea di massima, se vuoi mettere in un array di 10000 elementi il contenuto di una specifica colonna di un altro array e calcolarne la media userai qualcosa come
Codice: Seleziona tutto
Sub testazz()
Dim Calc, RnG()
Dim myStart As Long, myLungh As Long, myCol As Long, K As Long, N As Long
'
Calc = Range("A1:P50000").Value
'
'Debug.Print ">>>>>>>>"
myStart = 500: myLungh = 10000: myCol = 5     '<< Partenza, Lunghezza, N° Colonna
ReDim RnG(1 To myLungh)
mytim = Timer
N = 1
For K = myStart To (myStart + myLungh - 1)
    RnG(N) = Calc(K, myCol)
    N = N + 1
Next K
myave = Application.WorksheetFunction.Average(RnG)
'Debug.Print "> " & Format((Timer - mytim), "0.0000")
End Sub

Questo ciclo impiega, sul Pc in cui ho fatto i test, circa 3 msec per eseguirsi; quindi se lo devi ripetere 50mila volte serviranno 150 sec, cioe' circa 2.5 minuti...
L'accesso diretto ai dati del foglio, ad esempio usando
Codice: Seleziona tutto
    myave = Application.WorksheetFunction.Average(Sheets("Foglio1").Range("A1").Offset(myStart - 1, myCol - 1).Resize(myLungh, 1))
sarebbe almeno 5 volte piu' lento.

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: Prendere un pezzo di una matrice

Postdi By Sal » 18/07/15 08:15

Ciao Antony, scusa se non ti ho risposto, ma solo ora sono passato sul forum, per un altro problema che metterò in un nuovo post.

non mi arrivano le notifiche delle risposte, devo vedere nel pannello se ci sia l'opzione.

Comunque ho risolto eliminando il ciclo, lo dico in modo che possa servire ad altri

non sto qui a spiegare come si ottiene una media, ma ho fatto la somma dei dati e li ho divisi per il numero di elementi da considerare, questa la procedura che ho usato nel VBA

Codice: Seleziona tutto
    DDA = DDA + CDbl(Calc(X, 4))
    If X >= Lim2 Then  Calc(X, 6) = DDA / Dist2
    DDA = DDA - CDbl(Calc(X - (Dist2 - 1), 4)


DDA è una variabile double per la sommatoria dei dati, Lim2 è il limite dove inserire il risultato della formula MEDIA() che ottengo con

Codice: Seleziona tutto
Calc(X, 6) = DDA / Dist2


dove Dist2 rappresenta il range diciamo da 1 a 500, quindi 500 rappresenta il divisore per la media

la successiva riga elimina il primo elemento dei 500 in modo che al prossimo passaggio verrà aggiunto un nuovo elemento con la prima riga, in questo modo si avrà sempre una sommatoria di 500 elementi per la media ma variabile per la posizione di x che è il ciclo principale.

non so se mi sono spiegato bene, nel caso posso cercare di esporlo meglio.

il prossimo problema sono sottrazioni, per il quale aprirò come detto un nuovo post.

Ciao By Sal :)
A rileggerci By Sal
Avatar utente
By Sal
Utente Junior
 
Post: 83
Iscritto il: 27/08/06 14:40


Torna a Applicazioni Office Windows


Topic correlati a "Prendere un pezzo di una matrice":


Chi c’è in linea

Visitano il forum: Gianca532011 e 74 ospiti