Popolare una collection con Row di Excel

Ciao a Tutti,
sto cercando di popolare una collection con delle righe di excel che sono state
estratte da una Matrice .Il mio scopo sarebbe poi andare ad analizzare la collection,
con sort vari in base a diverse colonne e leggere i dati all'interno, per poi scriverli in altro foglio.

Con il codice che incollo sono riuscito a popolare una collection con delle row ,ma poi quando vado a gestire la collection non trovo nessun dato

Mi e vi chiedo , se non ho capito il concetto delle Row in un foglio excel, e quindi non devo popolare
la collection con row per il mio scopo , ma con altro. Se si, con cosa??

Se qualcuno mi può aiutare , ne sarei molto grato.Grazie in anticipo

Public Sub ScanMatrice(matrix As String, foglio As String, ByRef coll As Collection)
' prende tutte le righe con qualcosa
' e passa poi alla riga dopo.


    Dim wb As Workbook
    Dim ws, ws_d As Worksheet
    Dim rng, c As Range
    Dim num, nrig, i As Integer
    Dim str As String
   
    Set wb = ActiveWorkbook
    Set ws = wb.Worksheets(foglio)
    ws.Activate
   
   
    Set rng = ws.Range(matrix)
    rng.Select
   
    iMyR = rng.Row
    iMyC = rng.Column
    NrR = rng.Rows.Count
    NrC = rng.Columns.Count
    
    'scansiona solo le righe
    For i = 1 To NrR
   
        num = num + 1
        If rng(i, 3).value <> "" Then
            coll.Add Item:=Rows(iMyR + i - 1), Key:=CStr(num)
        End If
       
    Next i
    MsgBox "collection " & matrix & " alla fine ha elementi " & coll.Count
   

 

End Sub

'VADO A RIPRENDERE I DATI DENTRO ALLA COLLECTION
Public Sub PRINT(col As Collection)
    Dim r As Range
    Dim str As String
    Dim i As integer

    i=0
 
    Set wb = ActiveWorkbook
    Set ws = wb.Worksheets("Test")
   
    ws.Activate
   
   
    For Each r In col
 i=i+1
       
 ws.Rows(i) = r   'mi aspetto una riga identica nel nuovo foglio ma non c'è
       
        str = r.Cells(i, 3).value ' mi aspetto dei valori, MA NON C'è NULLA
   
    Next r
   
End Sub

 

Informazioni domanda


Ultimo aggiornamento febbraio 21, 2018 Visualizzazioni 307 Si applica a:
Risposta

Ciao a Tutti,
sto cercando di popolare una collection con delle righe di excel che sono state
estratte da una Matrice .Il mio scopo sarebbe poi andare ad analizzare la collection,
con sort vari in base a diverse colonne e leggere i dati all'interno, per poi scriverli in altro foglio.

Con il codice che incollo sono riuscito a popolare una collection con delle row ,ma poi quando vado a gestire la collection non trovo nessun dato

Mi e vi chiedo , se non ho capito il concetto delle Row in un foglio excel, e quindi non devo popolare
la collection con row per il mio scopo , ma con altro. Se si, con cosa??

Se qualcuno mi può aiutare , ne sarei molto grato.Grazie in anticipo

<cut>


Metti dei dati nelle celle A1:A10 del Foglio1.

Questo codice popola la Collection con quanto contenuto nelle celle A1:A10 e controlla che non ci siano keys uguali(non è ovviamente possibile) utilizzando il contenuto della cella come valore di item e di key. Alla fine mostra tutti i valori in una MsgBox:

Public Sub m()

    Dim sh As Worksheet
    Dim c As Range
    Dim rng As Range
    Dim col As Collection
    Dim v As Variant
    Dim s As String
   
    Set sh = ThisWorkbook.Worksheets("Foglio1")
    Set col = New Collection
   
    With sh
        Set rng = .Range("A1:A10")
        On Error Resume Next
        For Each c In rng
            col.Add c.Value, CStr(c.Value)
        Next
    End With
   
    For Each v In col
        s = s & v & vbNewLine
    Next
   
    MsgBox s
   
    Set c = Nothing
    Set rng = Nothing
    Set sh = Nothing
   
End Sub

Questa invece assegna una key diversa ad ogni item della Collection. Mostro poi il valore di un determinata key nella MsgBox(ti ricordo che la key va sempre passata come stringa):

Public Sub m()

    Dim sh As Worksheet
    Dim c As Range
    Dim rng As Range
    Dim col As Collection
    Dim s As String
    Dim lCont As Long
   
    Set sh = ThisWorkbook.Worksheets("Foglio1")
    Set col = New Collection
    lCont = 1
   
    With sh
        Set rng = .Range("A1:A10")
        For Each c In rng
            col.Add c.Value, CStr(lCont)
            lCont = lCont + 1
        Next
    End With
   
    MsgBox col(3)
   
    Set c = Nothing
    Set rng = Nothing
    Set sh = Nothing
   
End Sub

 

Questo codice invece, inserisce nella Collection una serie di riferimenti alle celle A:D di un Range che parte da riga 1 e arriva a riga n e poi mostra i valori di un iitem della Collection in una MsgBox:

Public Sub m()

    Dim sh As Worksheet
    Dim c As Range
    Dim rng As Range
    Dim col As Collection
    Dim s As String
    Dim lng As Long
    Dim lRiga As Long
   
    Set sh = ThisWorkbook.Worksheets("Foglio1")
    Set col = New Collection
   
    With sh
        lRiga = .Range("A" & .Rows.Count).End(xlUp).Row
        For lng = 1 To lRiga
            col.Add .Range("A" & lng & ":D" & lng), CStr(lng)
        Next
    End With
   
    For Each c In col(4)
        s = s & c.Value & vbNewLine
    Next
   
    MsgBox s
   
    Set c = Nothing
    Set rng = Nothing
    Set sh = Nothing
   
End Sub

Un file con l'esempio dell'ultima macro, qui:

http://www.maurogsc.eu/esempiforum11/collectionrighe.zip

 

Una Collection non può essere ordinata nativamente, ma deve appoggiarsi a una routine esterna. Partendo da qui, cosa vuoi fare esattamente?

Grazie.

--
Mauro Gamberini
Microsoft© MVP (Excel)
http://www.maurogsc.eu

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Risposta

Ciao Mauro e grazie,

 

mi sembra di capire che per raccogliermi delle righe di excel, aggiungendo al membro di una collection TUTTA una riga, senza preoocuparmi di definire da che colonna e fino a che colonna prendere i dati, con la seguente assegnazione:

col.Add Rows(idx), CStr(Key) non porti a nulla !! Mi confermi questo?

 

Infatti vedo che in tutti i casi mi hai definito i confini del range.

 

Io devo scansionare una serie di Sheet all'interno dei quali esistono 5 aree distinte , identificate con un nome ciascuna ( Area1,Area2,Area3,Area4,Area5).

Ogni area,è una matrice di righe e colonne variabili.

La mia intenzione sarebbe scansionare tutti gli sheet e caricare delle collection pubbliche definite a livello di progetto, ciascuna delle quali conterrà tutte le righe della stessa area di tutti gli sheet. Quindi se abbiamo 100 sheet, ed in ciascuno è presente Area1 con 10 righe, alla fine di tutta la scansione, mi troverò 1000 righe caricate su collection1 .

Collection1 conterrà solo righe di Area1, ....collection5 solo di Area5.

Al termine di questa raccolta dati, vorrei processare singolarmente ogni singola collection, ordinandola, e producendo una lista ordinata secondo una key che potrebbe essere diversa di volta in volta. ad esempio, ordinamento per "Categoria" o per "Valore" che corrispondono a colonne diverse in quelle righe che avevo raccolto in collection1.

Fatto ciò , ma questa è la meno, una scrittura completa di tutte le righe ordinate in un foglio nuovo ( Report di AREA1) che conterrà tutte le righe delle AREE1 raccolte nei vari Sheets. 

 

 Gli esempi che mi hai postato, mi indicano già una strada possibile da poter sviluppare, ma questa mi costringe a definire la Colonna Inizio e la Colonna fine del range che devo aggiungere alla collection, creandomi dei problemi se Domani qualcuno mi aggiunge una colonna in una AREA.

Per questo motivo, volevo aggiungere la riga INTERA pescandola dall insieme ROWS() , cosi' mi tutelerei da variazioni.

Ciao e Grazie


Non vedo il motivo di tutto ciò.

E' molto più semplice avere 5 fogli(che puoi anche nascondere se l'utente non deve vederli) e popolarli con le varie aree. Le Collection che vuoi fare, risiedono in memoria e quindi sono soggette ad una serie di problemi:

  • ci vuole tempo per caricarle
  • occupano memoria
  • non sono flessibili
  • al primo errore non gestito la memoria si vuota e devi ricrearle
  • la loro gestione deve essere perfetta o trovi dati non allineati con l'origine

Vedi qui il file areenomi un semplice esempio fatto utilizzando i fogli:

https://skydrive.live.com/#cid=0361684D94BB851A&id=361684D94BB851A%21169

 

  • i fogli possono contenere dati permanenti
  • in caso di errore non perdo i dati
  • sono più semplici da gestire
  • posso utilizzare tutto quello che espongono (riordini, filtri, ecc)
  • come ho già scritto, posso nasconderli e l'utente non li vede

Per ciò che riguarda le tabelle che tu chiami Area1, Area2, ....Area(n). Un Range devi definirlo per forza. Excel 2007/2010 hanno 16384 colonne. Non mi sembra il caso di caricare in una Collection oggetti di quelle dimensioni quando posso sapere in qualsiasi momento il Range della tabella e di conseguenza il numero di righe e colonne. Di una tabella se separata da altre tabelle/celle sul foglio, possiamo recuperare il Range semplicemente utilizzando la proprietà CurrentRegion di una qualsiasi delle sue celle.

Inoltre, ma non ho capito, se le tue aree hanno un nome(inteso come Name dato al Range, come ho fatto io nell'esempio), quel Range si può identificare e ciclare come meglio credi, senza dover prendere n colonne e n righe a caso, oppure utilizzare per intero come ho fatto nell'esempio.

 

Questo codice invece, inserisce 5 righe intere(del Foglio1 nell'esempio) nella Collection. Il numero di colonne dipende dalla versione di Excel.:

Public Sub m_1()

    Dim sh As Worksheet
    Dim col As Collection
    Dim lng As Long
   
    Set sh = ThisWorkbook.Worksheets("Foglio1")
    Set col = New Collection
   
    For lng = 1 To 5
        col.Add Range(lng & ":" & lng), CStr(lng)
    Next
   
    'conto le colonne della prima riga
    '(diverso risultato per
    'diversa versione di Excel)
    MsgBox col(1).Columns.Count
    'recupero il valore della colonna AB
    'della terza riga
    MsgBox col(3).Range("AB1").Value
    'oppure
    MsgBox col(3).Cells(1, 28).Value
   
    Set col = Nothing
    Set sh = Nothing
   
End Sub

--
Mauro Gamberini
Microsoft© MVP (Excel)
http://www.maurogsc.eu

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.