Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Array tra le property di un OCX/Classe

Salve a tutti,
sto scrivendo un ocx (ma il problema si estende alle classi) e mi serve di avere tra le
varie property get/let una che mi gestisca un array, creato con una "Redim" quando viene
chiamato per la prima volta il metodo AddItem,  ed aggiornato con "Redim Preserve" con
successive AddItem...
Il problema e' che l'array e' bidimensionale e che non so come fare per leggere e scrivere
nella posizione "indexX, indexY" dell'array usando le istruzioni:
Property Get List
...
Property Let List
...
Qualcuna sa fornirmi qualche indicazione?
Grazie.



ma questo array "dove sta"? Viene passato come parametro, è una variabile privata della classe o
cosa?
Puoi postare il codice incriminato? 
Ciao,
Moreno
#sirri#@#morenosoft#.com
(togliete "#" dall'indirizzo)
Moreno Sirri VB Site - 
http://www.msvbsite.net
---------------------------------------------------------------------------
Le risposte alle tue domande le trovi sul Sito Comune di questo NewsGroup:
 
http://www.it-lang-vb.net
---------------------------------------------------------------------------

Ma... in verità mi vengono in mente due metodi:
il primo spurio, da cioccolataio a Chiasso
il secondo migliore, ma perfettibile.
Come primo metodo, ma lo sconsiglio e mi vergogno, 
puoi sempre passare alle property una string
del tipo "123#2345", che poi con le dovute 
forzature tramite Mid e cast [Clng, Cint ...]
divengono gli indici dell'array.
Ma poi bisogna pulirsi la bocca dal vomito. :-)))
Altrimenti definisci una classe Vector, in cui dichiari
i campi dell'array e le indicizzazioni. Costruisci
la relativa collection Vectors, e alle/dalle Property 
primigenie passi/ottieni, Set a nastro quindi su istanza 
locale nella tua classe delle Vector e Vectors, gli elementi
di cui hai bisogno.
Sembra complicato ma in verità è banale.
In verità, or ora mi è venuta in mente la terza via,
scorciatoia verso il Vespasiano:
       - Property Let e Get anche per gli indici 
Tutto senza Guttalax. :-)))
Ciao
    Adriano


Penso che tu possa usare un variant al posto dell'array... Il variant si
comporta anche da array... Non mi piace usare i variant... però... a quanto
pare a volte servono...
    Ciao
            Allanon

 ha scritto
| ma questo array "dove sta"? Viene passato come parametro, è una variabile privata della
classe o
| cosa?
| Puoi postare il codice incriminato?
Option Explicit
Private m_list() As String       ' **** ECCO L'ARRAY...
Private m_ColumnCount As Integer
_______________________________________________
Public Property Get ColumnCount() As Integer
  ColumnCount = m_ColumnCount
End Property
_______________________________________________
Public Property Let ColumnCount(p_ColumnCount As Integer)
  m_ColumnCount = p_ColumnCount
End Property
_______________________________________________
Public Sub AddItem(item As String)
  m_list(getNextIndex, 0) = item
End Sub
_______________________________________________
Public Sub Clear()
  ReDim m_list(0, 0)
  '*** non sono sicuro sull'affidabilità di questa istruzione
End Sub
_______________________________________________
Private Function getNextIndex() As Long
  Dim i As Integer
  Dim ArrayCount As Long
  ArrayCount = GetArrayItemsCount(m_list)
   '*** qui c'e' un errorino... che devo correggere: la dimensione che
           devo aggiornare e' la prima delle due
  If ArrayCount > 0 Then
    ReDim Preserve m_list(ArrayCount + 1, m_ColumnCount)
  Else
    ReDim m_list(1, m_ColumnCount)
  End If
  getNextIndex = UBound(m_list)
   '*** qui c'e' un errorino... che devo correggere
End Function
_______________________________________________
Private Function GetArrayItemsCount(ByVal arr As Variant) As Long
  On Error Resume Next
  GetArrayItemsCount = UBound(arr) - LBound(arr) + 1
  ' on error function returns 0
End Function
#############################
Per il momento ho simulato la get/let con le seguenti procedure:
Public Function GetItem(index As Integer, column As Integer) As String
  GetItem = m_list(index, column)
End Function
Public Sub SetItem(index As Integer, column As Integer, item As String)
  m_list(index, column) = item
End Sub

 ha scritto nel messaggio news:3AF940B8...@corner.ch...
| Come primo metodo, ma lo sconsiglio e mi vergogno,
| puoi sempre passare alle property una string
| del tipo "123#2345", che poi con le dovute
| forzature tramite Mid e cast [Clng, Cint ...]
| divengono gli indici dell'array.
| Ma poi bisogna pulirsi la bocca dal vomito. :-)))
Bleargh, lasciamo perdere... :)
| Altrimenti definisci una classe Vector, in cui dichiari
| i campi dell'array e le indicizzazioni. Costruisci
| la relativa collection Vectors, e alle/dalle Property
| primigenie passi/ottieni, Set a nastro quindi su istanza
| locale nella tua classe delle Vector e Vectors, gli elementi
| di cui hai bisogno.
| Sembra complicato ma in verità è banale.
|
| In verità, or ora mi è venuta in mente la terza via,
| scorciatoia verso il Vespasiano:
|        - Property Let e Get anche per gli indici
| Tutto senza Guttalax. :-)))
Non e' complicato, ma poi la gestione delle istanze della classe diventa molto poco
intuitiva e soprattutto macchinosa: il mio intento e' quello di utilizzare la classe in
questa maniera:
  Dim lista as New MyLista
  lista.ColumnCount = 4
  for i=0 to 10
      lista.AddItem "pippo" & i, i      ' posizione (i,0) nell'array
      lista.List(i, 1) = "pluto" & i
      lista.List(i, 2) = "paperino" & i
      lista.List(i, 3) = "topolino" & i
      Debug.Print lista.List(i, 0)
  next i
  lista.Clear

Il mio intento e' quello di utilizzare la classe in questa maniera:
  Dim lista as New clsMyList


 ha scritto
| Penso che tu possa usare un variant al posto dell'array... Il variant si
| comporta anche da array... Non mi piace usare i variant... però... a quanto
| pare a volte servono...
Array o Variant, alla fine non risolvo il problema del let/get...

  lista.Clear
Perdonami ma io continuo a pensare che in VB, proprio
geneticamente al linguaggio, l'insieme classe-collection
sia diploide.
In verità è molto affascinante spingersi oltre le convenzioni
ma spesso i limiti sono oggettivi.
Non puoi ad esempio, cercare stratagemmi per aggirare i
limiti della redim: a meno che non sia tu a gestire
lo stack. E direttamente, non solo i pointers.
La potenza di classe-collection, ma ribadisco è
assolutamente opinione mia e forse non condivisa,
sono persuaso sia molto meno macchinosa di tutto il
settaggio di columncount, redim, preserve a cui 
sei costretto dall'utilizzo degli array. 
È vero questi sono più veloci, ma se utilizzati 
direttamente, non se devi perdere tempo a calcolare 
l'offset sulla base di parametri dinamici.
Hai il tuo oggetto lista, una classe, con l'operatore
new ne allochi quante ne vuoi, le scorri nella 
coll, implementando _NewEnum, con For Each, o
anche con .count, in ogni momento sai dove sei
nella collection, mah...
E poi, non trascurare che la multidimensionalità degli
array è una astrazione strumentale;
fisicamente gli elementi sono contigui, almeno per
i registri EBX ed SI, poi page e segment fanno altro.
Spassionatamente: classe e collection, non altro.
A proposito, buon lavoro.
Ciao 
    Adriano


 wrote in message
51bK6.2968$2i2....@news1.tin.it...

Devi dichiarare le property in questo modo:
Private m_List() As String
Public Property Get List(ByVal X As Integer, ByVal Y As Integer) As String
'aggiungere i controlli del caso per evitare Index Out of Bounds
List = m_List(X, Y)
End Property
Public Property Let List(ByVal X As Integer, ByVal Y As Integer, ByVal
strNewValue As String)
'aggiungere i controlli del caso per evitare Index Out of Bounds
m_List(X, Y) = vNewValue
End Property
tutto qui... a proposito, in un messaggio seguente c'erano queste istruzioni
ArrayCount = GetArrayItemsCount(m_list)
   '*** qui c'e' un errorino... che devo correggere: la dimensione che
           devo aggiornare e' la prima delle due
ReDim Preserve m_list(ArrayCount + 1, m_ColumnCount)
non so se ho intrepretato male il codice, comunque fai attenzione che con gli
array multidimensionali puoi usare 'Redim Preserve' solo se modifichi l'ultima
dimensione...
Ciao
--
Luca Dormio
luca....@tin.it

"Arj" <A...@Arj.exe> ha scritto
| ATTNE: Redim Preserve agisce solo sull'ultima dimensione
|        delle matrici.
|        Cito da MSDN: 'If you use the PRESERVE keyword,
|                       you can resize only the last array
|                       dimension [cut]
|                       However, if your array has 2 or more
|                       dimensions, you can change the size
|                       of only the last dimension and still
|                       preserve the contents of the array'
|
|        Nella Clear io userei la funzione Erase.
Questi problemi li ho risolti: adesso ho un controllo OCX che funziona... con gli Array...
:)
| E poi, non trascurare che la multidimensionalità degli
| array è una astrazione strumentale;
| fisicamente gli elementi sono contigui, almeno per
| i registri EBX ed SI, poi page e segment fanno altro.
Si, si, lo so, per lo meno in C (e quasi in ogni altro linguaggio) e' cosi'...
| Spassionatamente: classe e collection, non altro.
Appena avro' un attimo di tempo convertiro' gli array con le collection (o ne faro' un ocx
separato) seguendo appunto il tuo consiglio.
Ammetto che sono ignorante in materia e quindi non so se la Collection mi darebbe una
pulizia di codice e una manutenibilità migliore che con gli Array...
A parte tutto, Grazie!
Adesso pero' ho altri problemi, di natura logistica, nel gestire le proprietà degli
oggetti che inserisco nell'OCX. Cambio Thread per chiarezza...

"Luca Dormio" <lucaFAV...@tinFAVA.it> ha scritto
| Devi dichiarare le property in questo modo:
|
| Private m_List() As String
|
| Public Property Get List(ByVal X As Integer, ByVal Y As Integer) As String
| 'aggiungere i controlli del caso per evitare Index Out of Bounds
| List = m_List(X, Y)
|
| End Property
|
| Public Property Let List(ByVal X As Integer, ByVal Y As Integer, ByVal
| strNewValue As String)
| 'aggiungere i controlli del caso per evitare Index Out of Bounds
| m_List(X, Y) = vNewValue
| End Property
Ok, grazie! Era quello che cercavo e l'avevo già trovato tra i vecchi post: ho faticato
non poco per trovarlo...
| tutto qui... a proposito, in un messaggio seguente c'erano queste istruzioni
|
| ArrayCount = GetArrayItemsCount(m_list)
|    '*** qui c'e' un errorino... che devo correggere: la dimensione che
|            devo aggiornare e' la prima delle due
| ReDim Preserve m_list(ArrayCount + 1, m_ColumnCount)
|
| non so se ho intrepretato male il codice, comunque fai attenzione che con gli
| array multidimensionali puoi usare 'Redim Preserve' solo se modifichi l'ultima
| dimensione...
Si, l'ho letto sulla guida...
Grazie dell'aiuto!