Condividi:        

vba excel: ultimo elemento avvalorato in array

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

vba excel: ultimo elemento avvalorato in array

Postdi karug64 » 25/09/16 19:40

Salve a tutti.
Esiste una funzione che restituisca l'ultimo elemento avvalorato di un array di interi (senza dover eseguire un ciclo for) ?

Dato arr_int(10) avvalorato tutto a ZERO se arr_int(1) = 3, arr_int(2) = 5 dovrei ottenere "3"

Grazie
Office 2010
karug64
Utente Senior
 
Post: 746
Iscritto il: 20/11/11 21:22

Sponsor
 

Re: vba excel: ultimo elemento avvalorato in array

Postdi Marius44 » 25/09/16 22:34

Ciao
sto seguendo molto attentamente lo sviluppo del tuo lavoro ma la domanda che poni mi mette fuori strada.

Che io sappia la funzione che chiedi non esiste.
Nella tua domanda chiedi "l'ultimo elemento avvalorato" ma nell'esempio la tua risposta è, chiamiamolo così, il primo (cioè 3, quello di posizione inferiore) mentre per la sequenza l'ultimo dovrebbe essere il 5.

Poichè ritengo che la domanda faccia riferimento ad array (orizzontali o verticali per lo schema) forse ti basterebbe sapere se l'indice di quell'array è avvalorato oppure no.

Oppure non mi è chiaro il problema.
Ciao,
Mario
Marius44
Utente Senior
 
Post: 655
Iscritto il: 07/09/15 22:00

Re: vba excel: ultimo elemento avvalorato in array

Postdi karug64 » 25/09/16 22:52

Marius44 ha scritto:Ciao
sto seguendo molto attentamente lo sviluppo del tuo lavoro ma la domanda che poni mi mette fuori strada.

Che io sappia la funzione che chiedi non esiste.
Nella tua domanda chiedi "l'ultimo elemento avvalorato" ma nell'esempio la tua risposta è, chiamiamolo così, il primo (cioè 3, quello di posizione inferiore) mentre per la sequenza l'ultimo dovrebbe essere il 5.

Poichè ritengo che la domanda faccia riferimento ad array (orizzontali o verticali per lo schema) forse ti basterebbe sapere se l'indice di quell'array è avvalorato oppure no.

Oppure non mi è chiaro il problema.
Ciao,
Mario


Ciao Mario.
Un lavoro che difficilmente vedrà la luce in considerazione della difficoltà dello stesso e del fatto che ho capito che l'unico sistema per risolverlo sembra essere ricorrere a tecniche di backtracking che non sono nel mio bagaglio di conoscenze informatiche. Oltre tutto non esiste codice disponibile su internet che possa fungere da guida (anche se in altri linguaggi. E' fin troppo evidente che vba non è proprio il massimo per fare questo lavoro ......). Inoltre, quasi tutto quello che si trova in rete, fa riferimento alla composizione di cruciverba "liberi", ossia hanno cruciverba in cui le caselle nere sono sistemate dal programma per "differenza", ossia per "chiudere" i buchi non compilabili con parole. Il mio progetto è diverso, prevede che la sistemazione delle caselle nere avvenga prima della compilazione, con qualche difficoltà ulteriore.

Detto questo, per il momento non mollo
L'esempio è stato fuorviante e me ne scuso:

non cerco il valore più basso tra gli avvalorati, ma il primo elemento "non avvalorato" dell'array.
Nell'esempio "3" è l'indice del primo elemento dell'array che non contiene valori. E' quello che vorrei ottenere senza un codice del tipo

Codice: Seleziona tutto
trov =0
for x = 1 to ubound(arr_int)
if x = 0 then
trov = x
exit for
endif
next x


poichè l'operazione andrà eseguita varie volte su un array voluminoso .... se avessi la possibilità di perdere meno tempo ....

Ma capisco che non esiste ....Grazie
Office 2010
karug64
Utente Senior
 
Post: 746
Iscritto il: 20/11/11 21:22

Re: vba excel: ultimo elemento avvalorato in array

Postdi Marius44 » 25/09/16 23:44

Ciao
NON MOLLARE. Ti riporto una frase che a me piace molto (e forse finirà a far parte della mia "firma digitale")
Un vincitore è un sognatore che non si è mai arreso. (N. Mandela)

Detto questo (e non conoscendo a fondo il tuo programma), fai una prova seguendo un'altra strada, cioè:
invece di avvalorare l'Array con tutti 0, non avvalorare nulla e ogni volta che devi assegnare un valore fai ReDim. In questo modo solo interrogando per sapere qual'è l'ultimo valore (UBound, per intenderci) potrai avere il tuo numero. Ovviamente tutto questo se puoi utilizzare un array vuoto da ridimensionare volta per volta.

Ciao,
Mario
Marius44
Utente Senior
 
Post: 655
Iscritto il: 07/09/15 22:00

Re: vba excel: ultimo elemento avvalorato in array

Postdi Anthony47 » 26/09/16 01:42

A parte che un loop fatto in un array in memoria e' alquanto veloce...

Supponiamo che quando scrivi arr_int(10) tu pensi ad un array che contiene 10 elementi, da 1 a 10, e tu lo utilizzi con dei cicli For I=1 to 10 / Next I
Trascuriamo invece che probabilmente gia' si tratta di un array di 11 elementi, da 0 a 10 (a meno che tu non abbia impostato Option Base 1) e trasformiamolo con certezza in un array di 11 elementi, da 0 a 10. Per questo lo dichiarerai con
Codice: Seleziona tutto
Dim arr_int(0 to 10) as Long

A questo punto userai arr_int(0) come indice dell'ultimo elemento scritto; in pratica, quando vuoi scrivere il "prossimo" elemento nell'array scriverai
Codice: Seleziona tutto
arr_int(arr_int(0)+1)=ValoreDelNuovoElemento
arr_int(0)=arr_int(0)+1

Spero che sia l'idea sia chiara...
Avatar utente
Anthony47
Moderatore
 
Post: 19196
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: vba excel: ultimo elemento avvalorato in array

Postdi karug64 » 26/09/16 07:09

Ottimo consiglio. Grazie
Office 2010
karug64
Utente Senior
 
Post: 746
Iscritto il: 20/11/11 21:22

Re: vba excel: ultimo elemento avvalorato in array

Postdi scossa » 26/09/16 10:02

Ciao,

karug64 ha scritto:Dato arr_int(10) avvalorato tutto a ZERO se arr_int(1) = 3, arr_int(2) = 5 dovrei ottenere "3"


Dovresti chiarire cosa intendi con "avvalorato tutto a ZERO" se intendi "non inizializzato" allora potresti usare
Application.WorksheetFunction.Match:

Codice: Seleziona tutto
Sub prova()
  Dim arr_int(10)
 
  arr_int(1) = 3
  arr_int(2) = 5
  arr_int(3) = 2
  arr_int(5) = 9
  Debug.Print Application.WorksheetFunction.Match(9 ^ 9, arr_int)
End Sub

che ti restituisce l'indice dell'ultimo elemento valorizzato (6 nell'esempio).

P.S.: eventualmente sostituire a 9^9 altra espressione che restituisca un numero sicuramente maggiore del valore massimo presente in arr_int().
Bye!
scossa

Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)
Avatar utente
scossa
Utente Senior
 
Post: 427
Iscritto il: 01/04/12 16:40
Località: Provincia di Verona

Re: vba excel: ultimo elemento avvalorato in array

Postdi Marius44 » 26/09/16 11:26

Buon giorno a tutti
Credo che forse siamo sulla strada sbagliata.
karug64 ha scritto:
Dato arr_int(10) avvalorato tutto a ZERO se arr_int(1) = 3, arr_int(2) = 5 dovrei ottenere "3"


Io ritengo che abbia inizializzato l'array con TUTTI 0(zero), che poi abbia inserito come primo elemento "3" e come secondo elemento "5" e gli interessi sapere quale elemento "prossimo" è disponibile.

Con l'esempio di scossa (ciao Marco) è vero che gli dice 6, ma è anche vero che l'indice 0 e l'indice 4 sono vuoti.

Con l'esempio di Anthony47 (ciao Antonio) aggiunge un elemento alla volta (e quindi puoi sapere qual'è il primo disponibile) ma non puoi lasciare "vuoti".

Non dimentichiamo che si tratta di un cruciverba. Quindi c'è la probabilità che dopo aver scritto una parola la si debba cancellare e quell'indice resta vuoto (o quegli indici, a seconda di come l'autore sta creando il codice).

Mi sbaglio oppure ho ragione?
Ciao,
Mario
Marius44
Utente Senior
 
Post: 655
Iscritto il: 07/09/15 22:00

Re: vba excel: ultimo elemento avvalorato in array

Postdi scossa » 26/09/16 13:19

ciao Mario,

un possibile workaround, per evitare il ciclo, può essere quello di usare una colonna di appoggio (in maniera impercettibile):
Codice: Seleziona tutto
Sub prova2()
  Dim arr_int(1 To 10) As Long, nIndx As Long
 
  arr_int(1) = 3
  arr_int(2) = 5
  arr_int(3) = 2
  arr_int(4) = 0
  Application.ScreenUpdating = False
  Range("AZ1:AZ10") = Application.Transpose(arr_int)
  nIndx = Evaluate("=MATCH(9^9,IFERROR((AZ1:AZ10)^0,""""))")
  Range("AZ1:AZ10").Clear
  Application.ScreenUpdating = True
  MsgBox "l'ultimo elemento valorizzato di arr_int è il " & nIndx & "°" 'nell'esempio 3°
End Sub


Ovviamente si sceglierà un range adeguato alla reale esigenza.
Bye!
scossa

Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)
Avatar utente
scossa
Utente Senior
 
Post: 427
Iscritto il: 01/04/12 16:40
Località: Provincia di Verona

Re: vba excel: ultimo elemento avvalorato in array

Postdi Anthony47 » 26/09/16 22:16

La preoccupazione di karug e' il tempo di esecuzione.
Il calcolo fatto con loop su un array di 10mila voci richiede un tempo non misurabile con la funzione Timer; lo stesso calcolo fatto tramite copia su worksheet e Confronta mi ha richiesto 40 msec; su 30mila voci: non misurabile /120 msec; su 3000 voci: non misurabile /13 msec.

Ma Match puo' essere usato gia' sull'array, se l'Array viene dichiarato Variant; questa soluzione e' solo leggermente piu' lenta del loop.
Codice: Seleziona tutto
pepp = Application.Match(9 ^ 9, myArr)
If IsError(pepp) Then pepp = 1

L'uso di Confronta /Match e' limitato a max 64000 voci (limite delle WorksheetFunctions).

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

Re: vba excel: ultimo elemento avvalorato in array

Postdi scossa » 27/09/16 09:14

Anthony47 ha scritto:Ma Match puo' essere usato gia' sull'array, se l'Array viene dichiarato Variant ....
Codice: Seleziona tutto
pepp = Application.Match(9 ^ 9, myArr)
....


Che era la mia prima proposta:
scossa ha scritto:
Codice: Seleziona tutto
Debug.Print Application.WorksheetFunction.Match(9 ^ 9, arr_int)

visto che, per un array variant, gli elementi non vengono inizializzati a 0.

Anthony47 ha scritto:L'uso di Confronta /Match e' limitato a max 64000 voci (limite delle WorksheetFunctions).

Già questo è un limite piuttosto fastidioso :-(
Bye!
scossa

Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)
Avatar utente
scossa
Utente Senior
 
Post: 427
Iscritto il: 01/04/12 16:40
Località: Provincia di Verona

Re: vba excel: ultimo elemento avvalorato in array

Postdi Anthony47 » 27/09/16 14:18

Ooppss...Confesso che mi era sfuggita la tua prima risposta...
Tuttavia con quella formulazione avrai un run_time error quando l Array è vuoto, cioè quando vorresti ottenere 0 (l'ultimo occupato) o 1 (il primo libero); con la formulazione che ho dato io il risultato sarà Error 2042, gestito dalla IsError sulla riga successiva.

Tutto questo ribadendo che il loop sul Array è la cosa più veloce, quindi se karug pensa di avere problemi di lentezza vada sul loop e si troverà bene, oltre a non avere limiti sulla dimensione.

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

Re: vba excel: ultimo elemento avvalorato in array

Postdi scossa » 27/09/16 15:44

Anthony47 ha scritto:Tuttavia con quella formulazione avrai un run_time error quando l Array è vuoto ....


Vero, infatti normalmente uso anch'io la formulazione senza WorksheetFunctions (lo uso per il suggerimento e poi la elimino), ma nel mio post l'ho lasciato per evidenziare che stavo utilizzando la funzione nativa di Excel "lato celle".

Comunque, se permetti uno sfogo, se chi pone un quesito lo facesse in modo chiaro ed esaustivo, anziché postare un mozzicone di codice (magari nemmeno quello), si farebbe meno fatica a dare risposte mirate.
Bye!
scossa

Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)
Avatar utente
scossa
Utente Senior
 
Post: 427
Iscritto il: 01/04/12 16:40
Località: Provincia di Verona

Re: vba excel: ultimo elemento avvalorato in array

Postdi Anthony47 » 27/09/16 23:14

Eh, karug non me ne vorra' ma credo che col suo progetto del "genera cruciverba" sia in mezzo al guano, quindi a chiedergli la precisione lo prendiamo in contropiede :D
Piuttosto speriamo di non averlo confuso (oltre le nostre intenzioni) con questa ampia varieta' di soluzioni.

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

Re: vba excel: ultimo elemento avvalorato in array

Postdi karug64 » 28/09/16 18:13

Anthony47 ha scritto:Eh, karug non me ne vorra' ma credo che col suo progetto del "genera cruciverba" sia in mezzo al guano


Già ... già .....

ma per il momento non demordo ...... ci deve essere una "soluzione" "logica" che non sia quella standard ......

Voglio immaginare che un problema in informatica non abbia una ed una sola soluzione ...... Poi se non la trovo allora lascio perdere (come già accennato in questo post..). D'altro canto questo proprio è un semplice "esercizio mentale" non finalizzato a nulla di particolare se non alla soddisfazione di riuscirci.

Grazie a tutti per gli interventi e .... tenetevi pronti per le prossime "domande" !!!
Office 2010
karug64
Utente Senior
 
Post: 746
Iscritto il: 20/11/11 21:22


Torna a Applicazioni Office Windows


Topic correlati a "vba excel: ultimo elemento avvalorato in array":


Chi c’è in linea

Visitano il forum: Nessuno e 31 ospiti