Newsgroup: it.comp.lang.visual-basic
Titolo: Runtime error 13 in VB6

salve a tutti,
è il mio primo intervento su codesto newsgroup e riguarda Visual Basic 6.
Ho messo a punto una semplice routine
TransposedArray (arrMaster as Variant) as Variant
che scambia righe con colonne un array GENERICO bidimensionale.
L'algoritmo è banale: creo una variabile locale (anch'essa Variant) e, dopo
averla ridimensionata appropriatamente, vi copio tutti gli elementi.
Il punto è che quando assegno la funzione ad una variabile array specifica,
ottengo il runtime error 13 (Type Mismatch). Dopo lunghe ore passate a
provare e riprovare, sono riuscito finalmente a capire che in effetti la
funzione TransposedArray restituisce un array di array, anziché un array
bidimensionale, come invece mi aspettavo, e questo manda in "chiasso" il
runtime. D'altra parte, l'uso di variabili Variant è l'unica maniera per
passare e restituire array generici, sia pur col limite del late binding e
di conseguenza di una ridotta efficienza. Ho cercato in lungo e in largo sul
web, ma tutto quello che sono riuscito a trovare è che, in entrambi i casi,
"the array elements are accessed in the same way". Il mio problema, mi
sembra, dimostra drammaticamente che non è proprio così....
Qualche suggerimento per aggirare l'ostacolo (eccetto che scrivere routine
specifiche per ogni tipo di variabile)?
Grazie per l'eventuale aiuto
Maurizio

 ha scritto nel messaggio 
news:46b9d342$0$36439$4faf...@reader5.news.tin.it...

Non so se ho capito bene, ma la soluzione è sempre la stessa: usare il tipo 
più specifico possibile.
Se ti serve un array di variant usa un
Dim vArray() As Variant
e non un
Dim vArray As Variant
dove ci finirà dentro un array.
La seconda soluzione potrebbe andare bene se ti serve qualcosa tipo un 
variant che contiene un array di interi e quindi la
Dim iArray() as integer
...
iArray = vArray
dovrebbe funzionare (sto andando a memoria), ma se la tua funzione 
restituisce un array di array significa che ha l'implementazione errata.
Ciao
Ciao 

 restituisce un array di array significa che ha l'implementazione errata.
Ciao Fabio, grazie per la risposta.
A me l'implementazione (che allego per conoscenza) non sembra errata, tra
l'altro è simile ad altre reperibili sul web. Confermo che la funzione
resituisce un array di array, che è impossibile da assegnare ad un array
specifico (
p.es
. Let strArray() = TransposeArray2D(strArray())) in quanto dà
runtime error 13. Scrivere routine specifiche significa scriverne una per
ogni tipo (Long, Double, String, ecc.) e, cosa ancora più preoccupante,
mantenerle in maniera sincronizzata nel futuro dell'applicazione.
Ovviamente avevo provato anche Dim arrWork() As Variant, ma non cambia
nulla.
Maurizio
Public Function TransposeArray2D(ByVal arrMaster As Variant) As Variant
    Dim i As Long, j As Long
    Dim LowBound1 As Long
    Dim LowBound2 As Long
    Dim HighBound1 As Long
    Dim HighBound2 As Long
    Dim arrWork As Variant
    Let LowBound1 = LBound(arrMaster, 2)
    Let LowBound2 = LBound(arrMaster, 1)
    Let HighBound1 = UBound(arrMaster, 2)
    Let HighBound2 = UBound(arrMaster, 1)
    ReDim arrWork(LowBound1 To HighBound1, LowBound2 To HighBound2)
    For i = LowBound1 To HighBound1
        For j = LowBound2 To HighBound2
            Let arrWork(i, j) = arrMaster(j, i)
        Next j
    Next i
    Let TransposeArray2D = arrWork
End Function

 Maurizio
Eh, sì... gli array e i variant fanno un po' a pugni :)
Comunque c'è una via d'uscita piuttosto semplice e che tra l'altro migliora 
le prestazioni:
Public Sub TransposeArray2D(ByVal arrMaster As Variant, ByRef arrDestination 
As Variant)
    Dim i As Long, j As Long
    Dim LowBound1 As Long
    Dim LowBound2 As Long
    Dim HighBound1 As Long
    Dim HighBound2 As Long
    Let LowBound1 = LBound(arrMaster, 2)
    Let LowBound2 = LBound(arrMaster, 1)
    Let HighBound1 = UBound(arrMaster, 2)
    Let HighBound2 = UBound(arrMaster, 1)
    ReDim arrDestination(LowBound1 To HighBound1, LowBound2 To HighBound2)
    For i = LowBound1 To HighBound1
        For j = LowBound2 To HighBound2
            Let arrDestination(i, j) = arrMaster(j, i)
        Next j
    Next i
End Sub
-------------
Dim a() As Long
Dim b() As Long
ReDim a(0 To 1, 0 To 2)
a(0, 0) = 1
a(0, 1) = 2
a(0, 2) = 3
a(1, 0) = 4
a(1, 1) = 5
a(1, 2) = 6
Call TransposeArray2D(a, b)
p.s.: ma usate ancora il Let??? Il passaggio a VB.Net sarà davvero lungo... 
:(
Ciao 

 lungo...
Immaginavo un simile commento. Da sempre uso il VB6 scrivendo classi ed
oggetti (sugli oggetti sto preparando un post per il NG), quindi credo di
essere tecnicamente pronto per il dotnet. L'uso del Let è un vezzo che
deriva dall'aver imparato il BASIC nel 1981 sull'ormai preistorico Sinclair
ZX81 (che usava i Tokens), ed inoltre personalmente ritengo che scrivere
codice cominciando SEMPRE con un comando (quelli colorati in azzurro
sull'IDE per intenderci), anziché talvolta con argomenti (in nero sull'IDE)
sia tecnica certamente più prolissa, ma esteticamente più coerente. Va da sé
che continuo anche ad usare Call e Rem!
Per incredibile che possa sembrare, uno dei motivi per il mio mancato
passaggio a dotnet è stata la soppressione d'ufficio del comando Let. Quindi
Fabio non me ne voglia per il mio stile volutamente retrò....
Maurizio

 che continuo anche ad usare Call e Rem!
Io ho iniziato gli stessi anni (non ricordo) con il basic di un Philips MSX 
(il primo basic Microsoft!) e non ho mai usato la LET :)
Passato da qbasic a VB4 ho abbandonato il prolisso REM con '.
La Call la uso sempre (in VB6, in 
vb.net
 non esiste più per una sintassi 
migliore) perchè permette un debug migliore, è più bello da leggere e 
rimuove problemi di retrocompatibilità pazzeschi (le parentesi senza Call 
forzano i parametri a ByVal anche se nella definizione della sub sono 
ByRef!).
Ciao