Newsgroup: it.comp.lang.visual-basic
Titolo: Creare liste di stringe in VBA (CATIA)

Ciao a tutti.
Ho da poco iniziato a pacioccare con gli script VBA di CATIA V5
(analoghi a quelli per Office, per chi non conoscesse CATIA), e ho
incontrato un problema (probabilmente banale) ma che non riesco a
superare.
Quello che vorrei fare e' creare una List di String (per l'unico
motivo di poter poi usare i metodi Sort e Reverse). In VB
'tradizionale' dovrebbe essere:
Dim MiaLista As New List(Of String)
ma in VBA mi da errore il compilatore, aspettandosi un 'end of
statement' dopo la parola List.
Provando con:
Dim MiaLista As New List
da invece l'errore 'invalid use of New keyword'.
Riducendo ancora a:
Dim MiaLista As List
non da errore alla compilazione, ma poi quando uso un qualuque metodo
(ad es. MiaLista.Add("pippo")) all'esecuzione dello scrip mi da
l'errore 'type mismatch', suppongo poiche' non ho definito che la
lista sia di stringhe.
Quello che sto sbagliando e' il modo corretto di creare la List in VBA
(sempre che tale classe esista, a questo punto mi viene il dubbio...),
evidentemente diverso dal VB classico (che peraltro uso poco,
programmando da tempo sostanzialmente solo piu' in Delphi).
Qualcuno mi sa dare un aiutino per venirne a capo?
Grazie!

 ha scritto nel messaggio 
news:0e8fb7a3-5cd6-4122...@v19g2000yqn.googlegroups.com...

GLi errori sembrano indicare la mancanza di inserimento nei riferimenti 
della libreria di CATIA...
Ciao.
-- 
Sergio MAZZA 

 della libreria di CATIA...
Ovvero?
In teoria per fare sta List di String non uso nulla che abbia a che
fare con Catia e le sue librerie (credo), ma semplicemente funzioni
del VBA...
Il resto del programma che sto scrivendo usa funzioni di Catia, che
funzionano regolarmente senza problemi...
Boh... sono sempre piu' perplesso...


Quando parli di VBA devi paragonarlo al vb 'classico', vb6 per 
intenderci, che non ha costrutti tipo
Dim MiaLista As New List(Of String)
che sono invece delle successive versioni .NET di vb....
VBA non conosce i generics.
Puoi provare a utilizzare una Collection, al posto della List(of 
String), ma ovviamente non ha tutte quelle comodità che .NET mette a 
disposizione.
Roberto


wrote:

Azz, come temevo allora...
Avevo gia' pensato di ripiegare sulle collection, solo che non hanno
metodi per l'ordinamento tipo Sort o Reverse...
Mi sa che mi tocchera' scrivere da me il codice per l'ordinamento, che
palle...
Non c'e' modo di accedere da VBA alle classi del nuovo 
VB.NET
, vero?

palle...
Non perderti in un bicchier d'acqua.
Puoi usare tranquillamente una Collection.
Ogni Item verrà inserito al giusto posto,
tramite questa classe.
Incolla questo codice in una nuova classe:
Private Type MyError
    ErrNumber As Long
    ErrSource As String
    ErrDescription As String
End Type
Private m_Col As Collection
Private m_bUniqueValues As Boolean
Private m_iOptionCompare As VbCompareMethod
Private LocalError As MyError
Public Property Get bUniqueValues() As Boolean
    bUniqueValues = m_bUniqueValues
End Property
Public Property Let bUniqueValues(ByVal bbUniqueValues As Boolean)
    m_bUniqueValues = bbUniqueValues
End Property
Public Property Get OptionCompare() As VbCompareMethod
    OptionCompare = m_iOptionCompare
End Property
Public Property Let OptionCompare(ByVal x As VbCompareMethod)
    m_iOptionCompare = x
End Property
Private Sub Class_Initialize()
    Set m_Col = New Collection
End Sub
Private Sub Class_Terminate()
    Set m_Col = Nothing
End Sub
Public Property Get NewEnum() As IUnknown
    Set NewEnum = m_Col.[_NewEnum]
End Property
Public Property Get Count() As Long
    Count = m_Col.Count
End Property
Public Function Item(Optional ByVal Lindex As Long, Optional ByVal skey As 
String) As String
    On Error GoTo ErrorH
    If LenB(skey) Then
        Item = m_Col.Item(skey)
    Else
        Item = m_Col.Item(Lindex)
    End If
    Exit Function
ErrorH:
    LocalError = ErrorRaiser(Lindex, skey)
    With LocalError
        Err.Raise .ErrNumber, .ErrSource, .ErrDescription
    End With
End Function
Public Sub Remove(Optional ByVal Lindex As Long, Optional ByVal skey As 
String)
    On Error GoTo ErrorH
    If LenB(skey) Then
        m_Col.Remove skey
    Else
        m_Col.Remove Lindex
    End If
    Exit Sub
ErrorH:
    LocalError = ErrorRaiser(Lindex, skey)
    With LocalError
        Err.Raise .ErrNumber, .ErrSource, .ErrDescription
    End With
End Sub
Public Sub Add(ByVal S As String, Optional ByVal skey As String)
    Dim L As Long, U As Long, M As Long
    Dim icomp As Integer, Sitem As String
    If m_Col.Count = 0 Then
        m_Col.Add S
    Else
        L = 1
        U = m_Col.Count
        If U = 1 Then
            M = U
            Sitem = m_Col.Item(M)
            icomp = StrComp(Sitem, S, m_iOptionCompare)
        Else
            Do While U >= L
                M = (L + U) \ 2
                Sitem = m_Col.Item(M)
                icomp = StrComp(Sitem, S, m_iOptionCompare)
                Select Case icomp
                    Case -1
                        L = M + 1
                    Case 0
                        If m_bUniqueValues Then Exit Sub
                        Exit Do
                    Case 1
                        U = M - 1
                End Select
            Loop
        End If
        If LenB(skey) Then
            If icomp = 1 Then
                m_Col.Add S, skey, Before:=M
            Else
                m_Col.Add S, skey, After:=M
            End If
        Else
            If icomp = 1 Then
                m_Col.Add S, Before:=M
            Else
                m_Col.Add S, After:=M
            End If
        End If
    End If
End Sub
Public Function ExistsInCollection(ByVal S As String, Optional ByVal iMode 
As Integer) As Long
    Dim L As Long, U As Long, M As Long
    Dim icomp As Integer, Sitem As String
    On Error GoTo ErrorH
    If m_Col.Count Then
        Select Case iMode
            Case 0
                L = 1
                U = m_Col.Count
                Do While U >= L
                    M = (L + U) \ 2
                    Sitem = m_Col.Item(M)
                    icomp = StrComp(Sitem, S, m_iOptionCompare)
                    Select Case icomp
                        Case -1
                            L = M + 1
                        Case 0
                            ExistsInCollection = M
                            Exit Function
                        Case 1
                            U = M - 1
                    End Select
                Loop
            Case 1
                L = CLng(S)
                m_Col.Item L
                ExistsInCollection = L
            Case 2
                Sitem = m_Col.Item(S)
                L = ExistsInCollection(Sitem, 0)
                ExistsInCollection = L
        End Select
    End If
ErrorH:
End Function
Private Function ErrorRaiser(Optional ByVal Lindex As Long, Optional ByVal 
skey As String) As MyError
    Dim LerrNum As Long, SerrDesc As String
    If m_Col.Count = 0 Then
        LerrNum = 6000
        SerrDesc = "Empty Collection"
    Else
        If LenB(skey) Then
            On Error Resume Next
            m_Col.Item skey
            If Err.Number Then
                LerrNum = 6001
                SerrDesc = "Not Matching Key"
                Err.Clear
                On Error GoTo 0
            End If
        Else
            If Lindex = 0 Then
                LerrNum = 6002
                SerrDesc = "Key And Index are both Missing"
            Else
                On Error Resume Next
                m_Col.Item Lindex
                If Err.Number Then
                    LerrNum = 6003
                    SerrDesc = "Invalid Index"
                    Err.Clear
                    On Error GoTo 0
                End If
            End If
        End If
    End If
    With ErrorRaiser
        .ErrNumber = vbObjectError + LerrNum
        .ErrDescription = SerrDesc
        .ErrSource = TypeName(Me)
    End With
End Function
-- 
Ciao Fede
By Chicco Production
http://bcp.freetools.it

 [...]
Piu' o meno quello che mi sono messo a fare io (anche se in maniera
piu' semplice... buona pero' l'idea di ordinarle gia'
all'inserimento!), sclerando per le definizioni delle classi (simile
ma non del tutto a quella di Delphi che uso normalmente)...
sicuramente col tuo esempio ci mettero' molto meno!
Grazie!

Ora pero' ho un'altra domanda veramente banale, quasi mi vergogno...
ma come diavolo devo creare il mio oggetto una volta definita la mia
classe?!?
Nel senso, ho definito una classe TStrList ridotta all'osso (giusto
per fare un passo alla volta):
Private Sub Class_Initialize()
    Dim Lista As 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
Poi suppongo di dover dichiarare la mia variabile con qualcosa tipo:
Dim MiaStrList As New TStrList
Ma fatto cio', quando eseguo mi da l'errore 'Object Required' appena
chiamo un metodo tipo MiaStrList.Add("..."), come se non fosse stato
eseguito il 'constructor' (come viene chiamato in Delphi).
Mi sorge quindi il dubbio che oltre a dichiarate il tipo, debba anche
richiamare esplicitamente il 'constructor' (come in Delphi, dove si
eseguirebbe qualcosa tipo MiaStrList:=TStrList.Create), sbaglio? Ma
allora come lo richiamo (visto che il metodo Class_Initialize e'
privato)?
In secondo luogo, nell'albero dei progetti, se seleziono il Class
Modules 'TStrList' e spulcio nelle Properties, ne trovo 2:
 - La prima e' il nome: poco da dire...
 - La seconda e' "Istancing": dall'aspetto piu' critico, posso
impostarla o come 'Private' o come 'PublicNotCreatable'. Di default e'
Private e cosi' l'ho lasciata, sbagio?
Scusate ma la documentazione in Internet riguardo al VBA e' veramente
scarsa...
Grazie a tutti in anticipo!

Azz... subito dopo aver postato mi sono accorto di un paio di errori:
 - mancava una riga tipo: Private Lista As Collection (...puo' sempre
essere utile...)
 - nella Class_Initialize avevo scritto "Dim Lista As New Collection"
invece di "Set Lista = New Collection" (le differenze tra i due
costrutti non mi sono ancora chiare, lo ammetto ih ih)
Ora tutto funziona, "figata" :-)
Grazie e scusate del disturbo!

E gia' che ci sono aggiungo una nuova domanda:
 - Si puo' definire (sempre in riferimento alla mia classe TStrList)
l'Item() cone Default Property?
Grazie e ciao!

 Grazie a tutti in anticipo!
Qui trovi tutti i riferimenti al VBA integrata nelle applicazioni Microsoft
http://msdn.microsoft.com/en-us/office/aa905357.aspx
Ciao.
-- 
Sergio MAZZA 

 Qui trovi tutti i riferimenti al VBA integrata nelle applicazioni Microsofthttp://
msdn.microsoft.com/en-us/office/aa905357.aspx
Grazie del link, puo' sempre tornare utile!
Pero' io non mi devo interfacciare coi programmi MS, ma con CATIA (di
cui cmq ho tutta la documentazione necessaria).
Ma a parte questo, in realta' il mio problema maggiore e' trovare
documentazione riguardo al linguaggio VBA vero e proprio, programmando
da anni solo piu' in Delphi e avendo quindi rimosso il VB :-))