trattamento righe di un array
Hai un problema con Excel? 
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
Vuoi Approfondire?