Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Eliminazione elemento array

Ciao gente!
Non sapete se esiste una funzione vb6 che mi consenta di eliminare un
elemento (di posizione da me scelta) di un array e ricompattare l'array?
Es:
    Array(1) = "pippo"
    Array(2) = ""
    Array(3) = "pluto"
Io voglio eliminare Array(2) e fare in modo che l'array diventi
    Array(1) = "pippo"
    Array(2) = "pluto"
Ciao e thanx!

 ha scritto

Non ho provato:
elemento_da_eliminare=2    '<<< Da adeguare
for elemento=elemento_da_eliminare+1 to ubound(Array)
    Array(elemento-1)=Array(elemento)
next elemento
redim preserve Array(Ubound(Array)-1)

 ha scritto nel messaggio
news:BZXg9.15458$my3.2...@twister2.libero.it...

Se il tuo array usa un tipo di dato tale per cui ogni elemento occupa lo
stesso numero di byte (per es. array numerici), puoi cavartela rapidamente
con CopyMemory, per esempio:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Public Sub DeleteFromArray(ByRef arValues() As Long, ByVal Index As Long)
'Questo esempio lavora su array di Long, si puo' adattare
'ad altri tipi simili modificando semplicemente la dichiarazione.
'Index e' l'elemento da eliminare
Dim ItemLen As Long, ItemCount As Long
'stabiliamo l'occupazione in bytes di un elemento qualsiasi
'(in questo caso scegliamo quello da rimuovere) e il numero di elementi
ItemLen = Len(arValues(Index))
ItemCount = UBound(arValues) + 1
'shiftiamo a sinistra gli elementi dell'array;
'in questo modo quello con indice=Index viene sovrascritto.
CopyMemory ByVal VarPtr(arValues(Index)), ByVal VarPtr(arValues(Index + 1)),
_
 (ItemCount - Index) * ItemLen
'ora eliminiamo l'ultimo elemento (doppio)
ReDim Preserve arValues(LBound(arValues) To UBound(arValues) - 1)
End Sub
Se pero' stai usando array di stringhe a lunghezza variabile o altri tipi
non omogenei la cosa non funziona altrettanto bene, visto che dovresti
calcolare da Index fino in fondo l'occupazione in byte complessiva, e quindi
non puoi fare a meno di un ciclo.
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 non puoi fare a meno di un ciclo.
ottima possibilita' per chiarirmi un dubbio :-). le stringhe, in vb, sono
puntatori? se lo fossero il metodo che hai illustrato funzionerebbe, tenendo
come occupazione di un elemento 4 bytes (o quanto e' grosso un puntatore), o
no?
grazie, assa.

 no?
Ho provato tempo fa il seguente esempio:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 (lpvDest As Long, lpvSource As Long, ByVal cbCopy As Long)
Private Sub Command1_Click()
Dim strSorgente As String, strDestinazione As String
strSorgente = "Musica"
strDestinazione = "        classica"
CopyMemory ByVal StrPtr(strDestinazione), ByVal StrPtr(strSorgente), 12
Debug.Print strDestinazione
End Sub
Il numero 12 sono i byte da copiare , prova a partire da 1 e ad aumentare
progressivamente.
giuseppeD

 wrote in message
news:am75q7$371ig$1...@ID-60516.news.dfncis.de...

Le stringhe sono puntatori anche in VB, quindi non sono char[] bensì char*.
Questo significa che se distruggi i puntatori con lo shift di un array,
perdi la memoria allocata - dovresti prima disallocarla, cosa che in VB non
è semplice come fare free(). Oltre a questo va detto che VB è molto geloso
delle variabili che alloca (se gliele togli da sotto potrebbe un tantino
incavolarsi) e che la gestione delle stringhe è tutta particolare, anche per
la conversione Unicode>Ansi. In particolare, non puoi passare un array di
stringhe ad una funzione esterna da VB: dovresti passarlo come array, non
puoi passare il primo elemento per puntatore, come invece faresti con un
array di qualsiasi altro tipo che non contenga stringhe, ma allora dovresti
gestire la struttura nella funzione chiamata (ammesso e non concesso che VB
passi davvero il puntatore all'array e soprattutto che la sintassi sia
accettata), cosa che ovviamente una semplice memmove non fa. Se passi il
primo elemento, devi dichiarare una funzione che accetta Byval As String e
questo in vb comporta: (a) l'allocazione di una stringa ansi temporanea; (b)
la traduzione della stringa da passare in ansi; (c) la chiamata della
funzione esterna con un puntatore alla stringa ansi temporanea; (d) al
ritorno dalla funzione, la conversione della stringa temporanea nella tua
stringa originale. Se quindi cerchi di leggere oltre il puntatore o se
cerchi di leggere oltre la stringa, finisci in memoria di qualcun altro,
perché stai puntando a memoria volatile allocata per la bisogna.
Il metodo descritto da Luca funziona benissimo su array di tipi standard
(eccetto stringa a lunghezza variabile) e su arrai di UDT che non contengano
stringhe a lunghezza variabile (come del resto lo stesso Luca sottolinea).
--
rumplestiltskin

 Le stringhe sono puntatori anche in VB, quindi non sono char[] bensì
char*.
[...]
Perdonate il refuso, sono di fretta.
--
rumplestiltskin