Newsgroup: it.comp.lang.visual-basic
Titolo: Classe nella classe (VBA)

Buongiorno a tutti.
Ho creato una classe (chiamata TStrList) per gestire una lista di
stringhe (usando come oggetto di base una collection e aggiungendo poi
altri metodi) ma ora mi trovo di fronte ad un problema che non riesco
a risolvere: vorrei aggiungere un metodo (chiamiamolo AddList) che mi
permette di aggiungere ad una TStrList i membri di un'altra TStrList,
ma ricevo un 'Runtime error 438' ogni volta che lo chiamo. Ecco un
estratto del codice:
Private Lista As Collection
Private Sub Class_Initialize()
    Set Lista = New Collection
End Sub
Private Sub Class_Terminate()
    Set Lista = Nothing
End Sub
Public Property Get Count() As Long
    Count = Lista.Count
End Property
Public Function Item(ByVal i As Long) As String
    Item = Lista.Item(i)
End Function
Public Sub Remove(ByVal i As Long)
    Lista.Remove (i)
End Sub
Public Sub Add(ByVal Str As String)
    Lista.Add (Str)
End Sub
Public Sub AddList(ByRef aStrList As TStrList)
    Dim i As Long
    For i = 1 To aStrList.Count
        Lista.Add (aStrList.Item(i))
    Next i
End Sub
Ora se scrivo un codice tipo:
Dim StrList1 As New TStrList
Dim StrList2 As New TStrList
StrList1.Add ("pippo")
StrList2.AddList (StrList1)
mi da errore sull'ultima riga, come se non riconoscesse il metodo...
suggerimenti?
Grazie!

 suggerimenti?
Togli le parentesi.
-- 
S.

 Togli le parentesi.
Ma lol, funziona! Grazie!
Si ma come mai a volte servono e a volte no ste parentesi in VBA?!?
...abituato come sono al Delphi, ste piccole cose mi stanno facendo
uscire matto :-))
Saluti...

 Si ma come mai a volte servono e a volte no ste parentesi in VBA?!?
Quando fai un'assegnazione allora metti le parentesi, quando è una 
chiamata a una routine che non deve restituire nessun valore (o non lo 
devi assegnare) allora non metti le parentesi.
ciao
stefano

 uscire matto :-))
In aggiunta a quanto scritto dal mio omonimo, se proprio vuoi mettere le 
parentesi anteponi "Call" al nome della funzione.
Questa delle parentesi è una delle svariate features di VB6 che mi fanno 
venire i conati.
-- 
S.

 venire i conati.
Se poi come me sei abituato a programmare in Delphi, i conati
raddoppiano!

On 14 Mar, 23:33, Stevie <jstevie__@__gmail__.com> wrote:

Il problema non sono le parentesi in se, è' la combinazione tra
parentesi e parametro di tipo oggetto che crea il problema, perchè le
parentesi in quel contesto hanno uno scopo preciso, questo:
http://msdn.microsoft.com/it-it/library/chy4288y(VS.80).aspx
solo che siccome nella maggior parte dei casi la cosa è ininfluente,
si tende a far confusione e a lasciarle.
Dovresti toglierle non solo dalla riga incriminata, ma anche dal
codice interno degli altri metodi, tipo 'Lista.Add (Str)'
'Lista.Remove (i)' ecc... sono tutte scorrette.
Tra l'altro, se notate, l'editor stesso cerca di evidenziare la
differenza di uso di queste parentesi superflue, perchè le stacca di
uno spazio, cosa che non fa quando invece servono, es. le chiamate di
funzioni, dove sono attaccate al nome.
Comunque, è vero, è un meccanismo ingannevole che per fortuna in .NET
è sparito.
Un altro piccolo inciso; nel metodo AddList la dichiarazione ByRef è
anch'essa dubbia... i parametri di tipo oggetto sono per loro stessa
natura dei riferimenti, quindi dichiararli ByVal/ByRef serve a dire
"Voglio che il *puntatore* all'oggetto venga passato per valore/
riferimento"
In entrambi i casi puoi comunque accedere ai membri dell'oggetto
stesso, l'unica differenza è che se passi il puntatore per
riferimento, puoi reimpostarlo nel corpo della funzione con un Set x =
y cosa che però non sembra servire in AddList
Nota la differenza tra questo codice
Public Sub AddList(ByRef aStrList As TStrList)
    Dim i As Long
    For i = 1 To aStrList.Count
        Lista.Add (aStrList.Item(i))
    Next i
    'Aggiunta per test
    Set aStrList = New TStrList
End Sub
Dim StrList1 As New TStrList
Dim StrList2 As New TStrList
StrList1.Add "pippo"
StrList2.AddList StrList1
'0 se ByRef, 1 se ByVal
Debug.Print StrList1.Count

Non conoscevo questa differenza tra ByRef e ByVal sui parametri di
tipo oggetto (io pensavo fosse obbligatorio il ByRef, passando cmq un
puntatore).
In effetti e' piu' sicuro usare ByVal anche sugli oggetti, a meno di
specifiche esigenze.
Grazie mille per avermi chiarito un'altro aspetto del VBA!

A questo punto pero' mi chiedo: quando serve usare il "Call" per
richiamare una procedura e quando no?
Ad es. con il Call sono costretto ad usare le parentesi...

VeGeTa_CuBe wrote:

Usare Call non è mai strettamente necessario. Lo fai solo se non ti 
interessa il valore restituito da una funzione (posto che questa lo 
restituisca).
-- 
S.

Chiarissimo!
Grazie!

...gia' che ci siamo, sempre rigurado alla mia classe TStrList, in VBA
non si puo' fare un OVERLOAD

[Scusate, attacco epilettico sul tasto ENTER :-) ...dicevo...]
...gia' che ci siamo, sempre rigurado alla mia classe TStrList, in VBA
non si puo' fare un OVERLOAD dei metodi, vero?
In Delphi avrei creato due metodi Add, uno con parametro una stringa,
l'altro con unaTStrList (evitando quindi di definire AddList), ma ho
un vago ricordo che questo sia fantascenza in VBA :-)
Ri-grazie!