Ricerca di un elemento in una matrice

di il
5 risposte

Ricerca di un elemento in una matrice

Data una matrice

ReDim DaCalc(500)

DaCalc(1) = "11"
DaCalc(2) = "22"

Al di là del fatto che di norma mi tengo un contatore per cui so quanti elementi sono caricati.
Esiste una funzione per sapere il numero massimo di elementi caricati? 
UBound(DaCalc) mi restituirebbe 500, ma io voglio la funzione che mi restituisca 2 (se esiste).

Esiste una funzione per sapere se un dato è nella matrice?
Non parlo di una ricerca sequenziale (banale da fare ma inefficente).

In pratica qualcosa tipo 
NellaMatrice(DaCalc,"11")  che restituisca True o 1
NellaMatrice(DaCalc,"13")  che restituisca False o 0

5 Risposte

  • Re: Ricerca di un elemento in una matrice

    26/01/2023 - paoloholzl ha scritto:


    ReDim DaCalc(500)

    Esiste una funzione per sapere il numero massimo di elementi caricati? 
    UBound(DaCalc) mi restituirebbe 500, ma io voglio la funzione che mi restituisca 2 (se esiste).

    Tu allochi 500 (o 501) elementi, Ubound non può che restituirti 500.

    La funzione che tu vorresti dovrebbe trovare il primo elemento non inizializzato della matrice. Rimarrebbe da capire cosa voglia dire (per VBA) elemento di una matrice non inizializzato : null, 0, stringa vuota, altro? Niente ti vieta però di trovare tu un valore iniziale da assegnare alla matrice tale per cui possa scriverti tu la funzione di scorrimento/ricerca del primo elemento libero.

    Un altro approccio per quello che richiedi è partire con una matrice con un solo elemento e effettuare un redim (elementi attuali+1) ogni volta che aggiungi un elemento. Così potresti sfruttare anche l'Ubound (al netto dell'offset eventuale di +1). Certo non è il massimo per le prestazioni, oltremodo se già conosci il numero di elementi caricati puoi utilizzarlo al posto dell'Ubound.

  • Re: Ricerca di un elemento in una matrice

    Dovresti usare una Collection e non un Array

  • Re: Ricerca di un elemento in una matrice

    Se Dimensioni la matrice a 500 è ovvio che ti restituisce 500 ma se usi il Redim Preserve al momento di aggiungere hai che UBOUND è allineato esattamente con il Numero di Elementi.

    Tuttavia è molto più lento, ma anche quì da capire la tua esigenza in termini di prestazioni, quindi un “relativamente” più lento è più adatto.

    Come ha suggerito Antonio, in questi casi è più funzionale usare una Collection che, passando come KEY il valore in stringa… es:

    Dim i As Integer
    Dim c As Collection
    Set c = New Collection
    For i=1 to 100
    	c.Add i, cstr(i)
    Next

    Per sapere quanti sono:

    Debug.Print c.Count

    Per cercare ad esempio se esiste un elemento:

    Dim cItem
    cItem=c.Item("1")
    Debug.print cItem

    Deve restituire 1, ovviamente non confondere la KEY con il Valore dell'Item, Accedendo alla Collection Item dell'oggetto collection passo la KEY e viene restituita la DefaultProperty che è Value.

    Le collection, sono estremamente veloci se vengono usate senza la KEY, ma con la KEY si perdono prestazioni in modo significativo in fase di INSERIMENTO, diventa invece estrememamente veloce in fase di Ricerca se si usa la KEY.

  • Re: Ricerca di un elemento in una matrice

    Giusto per completezza una cosa simile:

    Function Exist(p_C as Collection, sKey As String) As Boolean
        On Error Resume Next
        Exist = (p_C.Item(sKey).Key = sKey)
    End Property

    Io uso una classe che contiene già metodi/proprietà/Eventi come Upgrade della collection base, ma tu puoi usarla come l'ho modificata per avere un Boolean di ritorno.

  • Re: Ricerca di un elemento in una matrice

    Molto interessante grazie

Devi accedere o registrarti per scrivere nel forum
5 risposte