Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Esame / conteggio elementi in ListBox

    Scusate, premesso che ho ripreso a programmare da qualche settimana (quando ero giovane usavo Visual Basic 5 e ora sono passato a Visual Basic Express 2013) sto letteralmente impazzendo da ieri per un problema apparentemente semplice.

    Dunque, al termine di una elaborazione su un TextBox - il cui contenuto non è possibile conoscere a priori - passo il risultato a una ListBox di stringhe (che, per semplicità, può essere impostata con Sorted = True) con alcuni elementi che possono anche essere ripetuti. esempio:

    ....
    Hello word
    paperino
    paperino
    pippo
    pluto
    pluto
    pluto
    ....

    Sto cercando disperatamente una routine che (1) individui le varie stringhe diverse tra loro (ripeto: non è possibile sapere a priori né quante sono, la loro lunghezza, il loro contenuto), (2) le enumeri e (3) fornisca - per esempio in una ListBox secondaria, il risultato. Esempio di ciò che vorrei ottenere:

    Hello Word 1
    paperino 2
    pippo 1
    pluto 3


    Ho provato di tutto (For ... next , While ... wend, For Each ... next, ma mi scontro sempre con problemi di indici.
    Forse è stato già detto qualcosa al riguardo, ma non sono stato capace di trovarlo.
    Grazie in anticipo a chi potrà darmi qualche dritta!

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Visto che i dati sono ordinati non mi sembra complesso fare quello che chiedi.Cosa hai scritto nei tuoi tentativi? Quale algoritmo hai scelto?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Trovata soluzione!

    Mi autorispondo(!) Dopo una notte insonne, mi sono ricordato che, prima del 2000(!), avevo sviluppato qualcosa di simile. L'ho rintracciato (benedetti i Back-Up) e dopo qualche minuto l'ho adattato al mio programma. Ecco la soluzione:

    'Conteggio ed "estrazione" elementi da List_Originale e inserimento in List_Supporto
    For I = 0 To List_Originale.Items.Count - 1
    X = 0
    For J = I To List_Originale.Items.Count - 1
    Buf1 = List_Originale.Items(I)
    Buf2 = List_Originale.Items(J)
    If Buf1 = Buf2 Then
    ' X = n. di ripetizioni; Y = 1/0 Flag presenza/assenza ripetizione
    X = X + 1 : Y = 1
    Else
    Y = 0 ' Y=0 Stop presenza ripetizioni
    End If
    If Y = 1 Then W = J ' Inutile riprendere da X=0
    Next J
    I = W ' Per evitare errore: I=J provoca eccezione perché esterno al ciclo
    If Y = 0 Then LIst_Supporto.Items.Add(X & " " & Buf1)
    Next I
    If (Y = 1) = True Then LIst_Supporto.Items.Add(X & " " & Buf1)

    In effetti ero vicinissimo alla soluzione. L'errore che commettevo era legato alla sintassi del Visual Basic 5, cui ero abituato.
    Con VB5, infatti, se Y> 0 (e quindi, anche se Y=1) il confronto...
    If Y = 1 Then LIst_Supporto.Items.Add(X & " " & Buf1)
    ...viene riconosciuto TRUE.
    Con Visual Studio Express, invece, il confronto è di tipo Boolean, quindi è indispensabile la forma If (Y = 1) = True altrimenti Y=1 viene riconosciuto come False.
    E' la prima cosa che si impara passando da vecchie versioni VB a VSE 2013, ma - soprattutto nell'adattare vecchi listati - ci si abitua con difficoltà. Ovviamente il compilatore non segnala alcun errore né incongruenza.
    L'altra novità (che, lo confesso, ancora non ho ben compreso) è la segnalazione di errore grave se si utilizza una variabile che "esce" (??) da un ciclo.
    E' il motivo per cui ho dovuto usare W=J e poi I=W. Scrivendo "direttamente" I=J viene segnalato errore.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Con VB5, infatti, se Y> 0 (e quindi, anche se Y=1) il confronto...
    If Y = 1 Then LIst_Supporto.Items.Add(X & " " & Buf1)
    ...viene riconosciuto TRUE.
    Con Visual Studio Express, invece, il confronto è di tipo Boolean, quindi è indispensabile la forma If (Y = 1) = True altrimenti Y=1 viene riconosciuto come False.
    Se Y è un intero quello che hai scritto non ha molto senso ...

    segnalazione di errore grave se si utilizza una variabile che "esce" (??) da un ciclo.

    Che vuol dire "una variabile che esce da un ciclo" ? Di quale errore grave parli ?
    Scusa ma anche questo non mi pare chiaro ...

    Quello che devi fare con VB.NET (e che non si faceva con VB5/6 creando molte volte situazioni confuse) è dichiarare esattamente il tipo di ogni variabile o oggetto usato.

    Comunque, una soluzione potrebbe essere

    codice:
    
    
    codice:
            Dim i As Integer
            Dim curr As String
            Dim cnt As Integer = 1
            Dim prec As String = ListBox1.Items(0).ToString()
    
    
            ListBox2.Items.Clear()
    
    
            For i = 1 To ListBox1.Items.Count - 1
                curr = ListBox1.Items(i)
    
    
                If prec <> curr Then
                    ListBox2.Items.Add(prec + " " + cnt.ToString())
                    prec = curr
                    cnt = 1
                Else
                    cnt = cnt + 1
                End If
            Next
            ListBox2.Items.Add(prec + " " + cnt.ToString())
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Quote Originariamente inviata da oregon Visualizza il messaggio
    1) Che vuol dire "una variabile che esce da un ciclo" ? Di quale errore grave parli ? Scusa ma anche questo non mi pare chiaro ...

    2) Comunque, una soluzione potrebbe essere (eccetera)
    1) Prova a scrivere la routine evitando il passaggio W=J e poi I=W, cioè

    ...
    Next J

    I = J
    If Y = 0 Then LIst_Supporto.Items.Add(X & " " & Buf1)
    Next I

    ...e vedrai l'errore segnalato.

    2) Mah, la mia routine, come ho detto, funziona perfettamente e per ora la uso così. Però mi hai dato alcune idee, su cui lavorerò. Grazie per l'attenzione.

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Quote Originariamente inviata da GrandeTimoniere Visualizza il messaggio
    1) Prova a scrivere la routine evitando ...
    Beh, ovviamente se modifichi parte del codice è ovvio che puoi avere malfunzionamenti, ma si deve capire il perché.

    Il fatto è sostanzialmente che il codice non è chiaro ...

    1) modifichi il valore dell'indice dela For I all'interno del ciclo mentre questo sta operando (non è un buona regola di programmazione)

    2) è ovvio che all'uscita dal ciclo for J sia arrivato oltre il valore di ListBox1.Items.Count-1 e quindi che a quel punto non debba essere utilizzato come valore indice della stessa listbox (è la base di funzionamento della For..Next, in VB5 come in tutte le altre versioni)

    3) la If (Y = 1) = True non ha senso ... basta scrivere If Y = 1 e funziona ugualmente.

    E' anche importante capire come hai dichiarato tutte le variabili all'inizio.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Quote Originariamente inviata da oregon Visualizza il messaggio
    1) modifichi il valore dell'indice dela For I all'interno del ciclo mentre questo sta operando (non è un buona regola di programmazione)

    2) è ovvio che all'uscita dal ciclo for J sia arrivato oltre il valore di ListBox1.Items.Count-1 e quindi che a quel punto non debba essere utilizzato come valore indice della stessa listbox (è la base di funzionamento della For..Next, in VB5 come in tutte le altre versioni)

    3) la If (Y = 1) = True non ha senso ... basta scrivere If Y = 1 e funziona ugualmente.
    Sono mortificato: hai perfettamente ragione! Eppure - lo giuro - il programma ha iniziato a funzionare benissimo soltanto quando ho scritto If (Y = 1) = True. Con la forma If (Y = 1) = True, facendo elaborare una riga alla volta, nella finestra di "controllo immediato", digitando
    ? Y = 1
    ...risultava:
    False

    Poi mi sono ricordato di aver letto da qualche parte (ma non ricordo dove) che, a differenza delle versioni precedenti di VB, in fase di controlli If ... Then, il compilatore VB.NET converte automaticamente il valore dell'espressione IF in booleano e ricordavo che True non è =1 (oppure False non è =0, non ricordo bene).
    Rimane da chiedersi perché diavolo il programma ha iniziato a funzionare bene soltanto con If (Y = 1) = True. Ora funziona indifferentemente con entrambe le versioni. Mah...

    Per quanto riguarda l' "uscita" da For ... Next, hai ancora (potevi dubitarne?) ragione tu: a parte l'errore concettuale (all'uscita, il valore di J era più alto di quello che mi serviva e avrebbe comunque comportato un errore) l'errore segnalato - e che impedisce del tutto l'inizio dell'elebaorazione - è J non dichiarato: Non è accessibile a causa del livello di protezione. Tra l'altro, procedendo un'istruzione alla volta nella versione funzionante, all'uscita del ciclo For J posizionando il mouse su J, il compilatore addirittura si rifiuta di fornire il valore, nemmeno null o simile!
    Visual Basic 5 (da cui provengo) mi aveva viziato, nel senso che accettava tali ineleganze. Cosa che VB.NET non lascia passare.
    Grazie ancora per i consigli.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.