trattamento righe di un array



  • trattamento righe di un array
    di ANTONIO AVENOSO (utente non iscritto) data: 28/05/2017 10:52:38

    E' possibile trattare come un'unica entità le singole righe di un array n x n ? L'idea è di creare una variabile strutturata su più campi (con type) e di assegnare una singola riga di un array a questa variabile "in un colpo solo", ovvero evitando l'uso di indici.
    Spero di essermi spiegato...



  • di patel data: 28/05/2017 12:19:28

    mai fatto ma penso che sia possibile, un'altyernativa è fare un array di array, dove ogni riga è un array





  • di Vecchio Frac data: 28/05/2017 17:03:47

    @Antonio
    Hai già fatto qualche prova?





  • di Vecchio Frac data: 28/05/2017 17:11:20

    E soprattutto perchè? E' un esercizio o devi risolvere un problema reale?





  • di Vecchio Frac data: 28/05/2017 17:15:00

    Un risultato simile a quello che fa il codice seguente?
    Però non applicato a Excel, ma a un oggetto generico giusto? Tipo che potrebbe funzionare anche in Word o Access, diciamo.

     
    Option Explicit
    
    Sub test()
    Dim v As Range
    
        Set v = Range("A1:J10")
        v.Rows(3) = Array(1, 0, 3, 2, 6, 2, 8, 9, 4, 5)
    
    End Sub






  • di ANTONIO AVENOSO (utente non iscritto) data: 29/05/2017 08:46:31

    Scusate se non mi sono fatto vivo prima, ma le risposte ricevute erano finite nello SPAM e ieri non ho avuto modo di controllare la posta. Vi ringrazio per aver preso in considerazione il problema e cerco di rispondere più o meno a tutto quello che avete scritto:

    Il problema corrisponde ad un caso reale; potrei trovare delle soluzioni alternative ma approfitto del problema per cercare di ampliare le mie scarse, frammentarie e scoordinate nozioni di VBA.

    la risposta di Vecchio frac in cui esemplifica:

    v.Rows(3) = Array(1, 0, 3, 2, 6, 2, 8, 9, 4, 5)

    è stata per me illuminante sull'uso di range.rows

    Anche il suggerimento di Patel di un array di array mi ha suggerito prove da fare.

    Ho fatto alcune prove che trovate nel codice allegato. Nei commenti segnalo gli errori su cui mi sono arenato.

     
    Option Explicit
    Type entrata
     cat_merc As String
     Val_W As Double
     Val_B As Double
    End Type
    Option Base 1
    
    Sub lettura_entrata()
    
    Dim ent_cor As entrata
    Dim ranget As entrata
    Dim entr As Variant
    Dim rng As Range
    
    
    Set rng = Range("Entrata") ' Entrata = nome assegnato alle celle B6:D8, con questo contenuto
    '
    '
    '   Giocattoli      300 200
    '   Alimentari      200 100
    '   Abbigliamento   100 50
    '
    
    '
    ' Questo funziona - E' rudimentale ma rende l'idea
    '
    ent_cor.cat_merc = rng(1).Value
    ent_cor.Val_B = rng(2).Value
    ent_cor.Val_W = rng(3).Value
    
    MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
    
    ent_cor.cat_merc = rng(4).Value
    ent_cor.Val_B = rng(5).Value
    ent_cor.Val_W = rng(6).Value
    
    MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
    
    ent_cor.cat_merc = rng(7).Value
    ent_cor.Val_B = rng(8).Value
    ent_cor.Val_W = rng(9).Value
    
    MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
    '
    ' dopo di che questo sembra essere perfettamente legittimo
    '
    ranget = ent_cor
    MsgBox ("-" & ranget.cat_merc & " - " & ranget.Val_B & " - " & ranget.Val_W)
    
    '
    ' Altro tentativo
    '
    entr = rng.Rows(1) ' Ho scoperto che questo si può fare grazie a risposte sul sito
    
    
    '
    '   ent_cor.cat_merc = entr       ' così da errore : tipo non corrispondente
    '
    '   ent_cor.cat_merc = entr(1)    ' così da errore : indice non compreso nell'intervallo
    '
    
    
    ' ranget = entr  ' Questo maldestro tentativo di banale assegnazione
    
    
    ' da il seguente errore (decisamente al di la della mia capacità attuae di comprensione"
    '
    ' "Solo i tipi pubblici definiti dall'utente definiti
    ' in moduli di oggetto pubblici possono essere utilizzati
    ' come parametri o tipi restituiti per routine pubbliche di
    ' moduli di classe o come campi di tipi pubblici definiti dall'utente"
    
    '
    ' Lo stesso errore viene segnalato se provo a scrivere quello che dal mio punto di vista
    ' sarebbe la soluzione ideale:
    
    ' ent_cor = rng.Rows(1)
    
    End Sub
    



  • di patel data: 29/05/2017 09:16:57

    allega un file di esempio con dati e descrizione di cosa vuoi ottenere





  • di Vecchio Frac data: 29/05/2017 09:48:39

    Prova il codice grezzo che allego sotto.
    Si applica solo a Excel (infatti gli passo un oggetto Range).
    Sul tipo di errore ricevuto ci sarebbe da parlare per un bel po'... benvenuto nel magico mondo imperfetto di VBA e dei suoi falsi oggetti :)
     
    'nel modulo standard
    Sub test()
    Dim ent_cor As New oEntrata
    
        ent_cor.assign Range("Entrata").Rows(1).Cells
        
        MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
    
    End Sub
    
    
    
    'in un modulo di classe chiamato oEntrata (premi F4 nel modulo di classe per cambiarne il nome da Classe1 a oEntrata)
    Option Explicit
    
    Public cat_merc As String
    Public Val_W As Double
    Public Val_B As Double
    
    
    Sub assign(r As Range)
    Dim v As Variant
        
        v = Application.Transpose(Application.Transpose(r))
        cat_merc = v(1)
        Val_W = v(2)
        Val_B = v(3)
        
    End Sub






  • di Vecchio Frac data: 29/05/2017 09:52:09

    però, se resti in Excel, e senza pensare a creare un nuovo oggetto (però l'idea era carina per generalizzare e uscire da Excel), puoi farlo anche dal tuo codice, mantenendo il tuo Type, col trucco del doppio Transpose.
     
        ' Lo stesso errore viene segnalato se provo a scrivere quello che dal mio punto di vista
        ' sarebbe la soluzione ideale:
        
         'ent_cor = rng.Rows(1)
         
        Dim v As Variant
            v = Application.Transpose(Application.Transpose(Range("Entrata").Rows(1).Cells))
            ent_cor.cat_merc = v(1)
            ent_cor.Val_W = v(2)
            ent_cor.Val_B = v(3)






  • di ANTONIO AVENOSO (utente non iscritto) data: 29/05/2017 11:08:22

    Premesso che le ultime risposte di Vecchio Frac offrono scenari interssanti cerco di precisare meglio.

    La mia idea era:
    - disporre in una matrice di più righe i miei dati
    - Ogni riga corrisponderebbe, ad esempio, a giorni diversi
    - In ogni riga avere celle con contenuti di tipo diverso ma con una struttura definita (per es.: reparto, entrate, uscite etc…)
    - Assegnare un nome alla matrice

    Dopo di che poter scrivere un codice in cui:
    - definisco un mio tipo (con Type) di dati corripondente alla struttura della riga
    - Riesco a gestire i dati con un ciclo di questo tipo (trascrivo in italiano l’equivalente del codice VBA):

    Per ogni riga del mio range
    Assegna (“in un colpo solo”) il contenuto della riga ad una variabile del tipo_strutturato
    Elaboro le singole componenti del mio tipo
    Passo alla riga successiva

    Allego un esempio (banale) di dati ed i codici tentati sinora...
     
    Dati 
    
    Giocattoli	300	200
    Alimentari	200	100
    Abbigliamento	100	50
    Cartoleria	1000	300
    Attrezzature	500	200
    
    
    Codice
    
    Option Explicit
    Type entrata
     cat_merc As String
     Val_W As Double
     Val_B As Double
    End Type
    Option Base 1
    
    Sub lettura_entrata()
    '
    ' Questo banalmente funziona ....
    '
    Dim ent_cor As entrata
    Dim ranget As entrata
    Dim entr As Variant
    Dim rng As Range
    Dim indice As Integer
    
    
    
    Set rng = Range("Entrata")
    '
    ' Questo funziona - E' rudimentale ma rende l'idea
    '
    For indice = 1 To rng.Rows.Count
        ent_cor.cat_merc = rng(indice, 1).Value
        ent_cor.Val_B = rng(indice, 2).Value
        ent_cor.Val_W = rng(indice, 3).Value
        
        MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
        
    '
    ' dopo di che questo sembra essere perfettamente legittimo
    '
        ranget = ent_cor
        MsgBox ("-" & ranget.cat_merc & " - " & ranget.Val_B & " - " & ranget.Val_W)
    
    Next indice
    
    End Sub
    
    
    Sub lettura_entrata_1()
    
    ' Questa sarebbe la mia soluzione ideale .... ma così non funziona e
    ' da il seguente errore (decisamente al di la della mia capacità attuae di comprensione"
    '
    ' "Errore di compilazione - Solo i tipi pubblici definiti dall'utente definiti
    ' in moduli di oggetto pubblici possono essere utilizzati
    ' come parametri o tipi restituiti per routine pubbliche di
    ' moduli di classe o come campi di tipi pubblici definiti dall'utente"
    
    
    Dim ent_cor As entrata
    Dim ranget As entrata
    Dim entr As Variant
    Dim rng As Range
    Dim indice As Integer
    
    
    
    Set rng = Range("Entrata")
    
    
    For Each entr In rng
        ent_cor = entr
        MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
    Next
    
    End Sub
    
    
    Sub lettura_entrata_2()
    '
    ' Peraltro anche questa variante, meno soddisfacente ma ancora accettabile, non funziona ...
    ' segnalando: errore di run time: tipo non corrispondente
    '
    Dim ent_cor As entrata
    Dim ranget As entrata
    Dim entr As Variant
    Dim rng As Range
    Dim indice As Integer
    
    
    
    Set rng = Range("Entrata")
    
    For Each entr In rng
    
        ent_cor.cat_merc = entr(1)
        ent_cor.Val_B = entr(2)
        ent_cor.Val_W = entr(3)
        
        MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
           
    Next
    
    End Sub
    
    Sub lettura_entrata_3()
    '
    ' Altro ingenuo tentativo fallito : La variabile for each deve essere del tipo variant o object
    '
    Dim ent_cor As entrata
    Dim ranget As entrata
    Dim entr As Variant
    Dim rng As Range
    Dim indice As Integer
    
    
    
    Set rng = Range("Entrata")
    
    For Each ranget In rng
    
        ent_cor = ranget
      
        MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
           
    Next
    
    End Sub
    
    
    Sub lettura_entrata_4()
    '
    ' Altro ingenuo tentativo fallito : La variabile for each deve essere del tipo variant o object
    '
    Dim ent_cor As entrata
    Dim ranget As entrata
    Dim entr As Variant
    Dim rng As Range
    Dim indice As Integer
    
    
    
    Set rng = Range("Entrata")
    
    For Each entr In rng
    
        ent_cor = entr
      
        MsgBox ("-" & ent_cor.cat_merc & " - " & ent_cor.Val_B & " - " & ent_cor.Val_W)
           
    Next
    
    End Sub



  • di Vecchio Frac data: 29/05/2017 11:43:28

    cit. "
    - definisco un mio tipo (con Type) di dati corripondente alla struttura della riga
    - Riesco a gestire i dati con un ciclo di questo tipo (trascrivo in italiano l’equivalente del codice VBA): "
    ---> Io ho capito perfettamente l'esigenza e anche il problema :)
    Tu hai, semplicemente, bisogno di una base dati da interrogare con DAO (o ADO) e con i potenti metodi che un motore database offre.
    Nota che puoi mantenere la base dati in Excel (non c'è bisogno di Access) e che puoi sfruttare DAO (o ADO).
    Non vorrei inoltre dire stupidaggini, ma forse anche Workbooks.OpenDatabase può fare al caso tuo.






  • di ANTONIO AVENOSO (utente non iscritto) data: 29/05/2017 17:16:44

    Vi ringrazio tutti per i numerosi spunti di analisi forniti. Ora sto meditando in quale direzione proseguire. Grazie ancora