Ultima modifica: 21 Marzo
1999
Ken Mayer, Senior SQA Engineer
dBASE, Inc.
Questo documento HOW TO è mirato a:
Esaminare i metodi di lavoro OOP con gli array;
Esaminare l'uso degli array con gli oggetti di interfaccia utente.
Se state cercando i concetti base o altri aspetti non trattati da questo How To, guardate in ARRAY1.HTM e/o nel manuale di riferimento al linguaggio o nella guida in linea.
Se avete letto ARRAY1.HTM o
avete già lavorato con gli array ( in dBase o in altri linguaggi di
programmazione) dovreste avere le conoscenze di base su come "funzionano" gli
array. È importante comprendere che gli array in Visual dBase sono
oggetti.
Quasi tutti i metodi discussi in questo How To hanno
funzioni dBase corrispondenti.
Come dicevamo prima gli array
essendo oggetti hanno associati dei metodi. Differenzieremo questi metodi in
gruppi, basati sui loro scopi e si tenterà di sostituire le funzioni
corrispondenti con i relativi metodi più comodi da usare rispetto le
funzioni.
In un paio di casi, parleremo di funzioni in quanto non
esistono metodi corrispondenti. La differenza principale tra un metodo ed una
funzione è la sintassi della "chiamata", un metodo è chiamato così:
aNomeArray.nomemetodo(parametri)
mentre una funzione è chiamata in questo modo:
aFunzione(aNomeArray,parametri)
NOTA: Nel tentativo di rendere questa discussione più utile possibile, allegati a questo documento ci sono un paio di brevi programmi che visualizzano i contenuti di un array. Il primo programma è utile solo per array uni-dimensionali. Il secondo non dovrebbe essere usato con array uni-dimensionali in quanto si usa il metodo per determinare la dimensione di un array. Per entrambi programmi bisogna usare i seguenti comandi: do show1 with
aCity |
Il metodo OOP
"NEW"
Il modo più semplice
per creare un array in Visual dBase è usare il metodo NEW.
aMioArray = new array()
L'istruzione precedente dice a dBase che "aMioArray" sarà un oggetto array, con associati i relativi metodi, ma come potete osservare nell'istruzione precedente non si definiscono le dimensioni dell'array (numero di righe, colonne, dimensioni...).
Potete essere più espliciti e dire a dBase che il vostro array avrà 10 righe e 2 colonne, usando:
aMioArray = new array(10,2)
Il Metodo
Procedurale
Per fare la
stessa cosa dell'istruzione precedente usando il vecchio codice procedurale,
dovrete usare:
declare aMioArray[10,2]
Il vantaggio del primo modo risiede
nel fatto che è orientato agli oggetti e più a lungo userete Visual dBase, più
vi troverete ad usare questo tipo di sintassi di
programmazione.
Il metodo degli Array Letterali
Potete
anche definire un array nel modo seguente (ciò è utile per esempio per array
uni-dimensionali, cioè ad una colonna, ma non per array a più dimensioni), se
sapete già in anticipo quali saranno i valori da memorizzare:
aMioArray =
{"elemento1","elemento2","elemento3","etc."}
Inserire elementi in un array può essere facile come quando assegnate un valore ad una variabile di memoria, o può essere un po' più complicato come quando analizzate una tabella per ottenere da essa i valori che vi necessitano.
Il Metodo
ADD()
Questo è il modo più elegante per aggiungere
elementi ad un array uni-dimensionale (colonna singola). Per usare questo metodo
l'array deve essere già istanziato (usando uno dei metodi mostrati sopra). Una
volta creato l'oggetto array potete aggiungere gli elementi molto
facilmente:
aMioArray.Add("valore")
Dove "valore" è ciò che desiderate
aggiungere all'array ( nota: un valore in questo esempio potrebbe
essere di tipo carattere, numerico, logico, data, array...).
Se per
esempio, avete un array che contiene un elenco di città è probabile che ne
vogliate aggiungere
un'altra. Supponete di avere l'array seguente
(chiamato aCity):
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | Miami |
Riga 4 | New York |
Per aggiungere alla lista la città "Sydney" usate la seguente istruzione:
aCity.Add("Sydney")
Mandando in esecuzione l'istruzione precedente l'array adesso sarà simile al seguente:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | Miami |
Riga 4 | New York |
Riga 5 |
Sydney |
Il metodo
GROW (array.Grow() aGrow() )
Se avete un array
multi-colonna, il metodo Add() non funzionerà correttamente. Vi permetterà di
aggiungere elementi nella prima colonna, ma non nelle altre. Per gestire questa
operazione dovreste considerare invece, l'uso del metodo GROW()
Sintassi: nomearray.Grow(<espN>)
|
Esempio: Se avete l'array seguente:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | Los Angeles | 10.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | New York | 25.000.000 |
e volete aggiungere elementi in entrambe le colonne:
aCity.Grow(1) // aggiunge una riga aCity[5,1] = "Sydney" aCity[5,2] = "2,000,000"
RICORDATE: la RIGA è la prima parte del
subscript, la colonna la seconda.
In una situazione come questa,
se non sapete quante righe ci sono attualmente nell'array è probabile che
vogliate usare la funzione aLen(), per assicurarvi di essere nella riga
corretta:
aCity.Grow(1) // aggiunge una riga
// memorizza nel var. nRow il numero di righe nell'array
nRow = aCity.subscript( aCity.size, 1)
aCity[nRow,1] = "Sydney"
aCity[nRow,2] = "2,000,000"
Dal quale otterremo un array simile al seguente:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | Los Angeles | 10.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | New York | 25.000.000 |
Riga 5 |
Sydney | 2.000.000 |
Il metodo GROW() è anche utile se desiderate aggiungere una colonna al vostro array. Facciamo un passo indietro, se definite l'array aCity con una sola colonna:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | Miami |
Riga 4 | New York |
Riga 5 |
Sydney |
e volete aggiungere una seconda colonna potete farlo tramite l'uso del metodo GROW():
aCity.Grow(2) // aggiunge una colonna
Naturalmente a questo punto, l'array sarà simile al seguente:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | false |
Riga 2 | Los Angeles | false |
Riga 3 | Miami | false |
Riga 4 | New York | false |
Riga 5 |
Sydney | false |
Potreste aggiungere i dati all'array nel seguente modo:
aCity[1,2] = "4,000,000"
aCity[2,2] = "10,000,000"
aCity[3,2] = "8,000,000"
aCity[4,2] = "25,000,000"
aCity[5,2] = "2,000,000"
Quindi il vostro array sarà simile al seguente:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | Los Angeles | 10.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | New York | 25.000.000 |
Riga 5 |
Sydney | 2.000.000 |
Il metodo
INSERT() ( e aInsert() )
Qualche
volta è necessario aggiungere un elemento ad un array in una posizione ben
precisa piuttosto che alla fine dell'array.
Per fare questo potreste
usare il metodo INSERT() per inserire l'elemento/i in una posizione/i specifica
dell'array.
Sintassi: nomearray.Insert(<espN posizione>[,<espN riga/colonna>])
|
Lavorando con un array uni-dimensionale simile al seguente:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | New York |
Riga 4 |
Sydney |
e volete inserire "Miami" nella riga 3:
aCity.Insert(3)
L'esecuzione dell'istruzione precedente vi darà un array simile al seguente:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | false |
Riga 4 |
New York |
e se avete la necessità di cambiare il valore dell'elemento nella riga 3:
aCity[3] = "Miami"
NOTA: l'ultima riga ora contiene "New York" e l'ultima riga che conteneva "Sydney" è scomparsa. Questo perché il metodo Insert() (e la funzione AINSERT () ) inserisce letteralmente qualche cosa nell'array corrente, ma non lo ridimensiona. |
Per ridimensionare l'array dovete usare il metodo Grow() ( o la funzione AGROW() ):
aCity.Grow(1) // 1 per la riga, 2 per la colonna
aCity.Insert(3) // nuova riga in posizione 3
aCity[3] = "Miami"
il risultato ottenuto sarà:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | Miami |
Riga 4 | New York |
Riga 5 |
Sydney |
Se state lavorando con un array multi-colonna, potreste avere la necessità di inserire una nuova colonna, ciò può essere fatto nel seguente modo:
immaginate di avere il seguente array:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | Los Angeles | 10.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | New York | 25.000.000 |
Riga 5 |
Sydney | 2.000.000 |
e volete spostare la colonna 2 a destra, facendola diventare colonna 3 ed inserire una nuova colonna 2 che conterrà altri dati:
aCity.Grow(2) // aggiunge una nuova colonna aCity.Insert(2,2) // inserisce una nuova colonna in posizione 2
i comandi precedenti ci daranno un array simile al seguente:
Colonna 1 | Colonna 2 | Colonna 3 | |
Riga 1 | San Francisco | false | 4.000.000 |
Riga 2 | Los Angeles | false | 10.000.000 |
Riga 3 | Miami | false | 8.000.000 |
Riga 4 | New York | false | 25.000.000 |
Riga 5 |
Sydney | false | 2.000.000 |
E di nuovo, potreste sostituire i valori nella nuova colonna:
aCity[1,2] = qualcosa etc.
FILL() (e
aFill() )
Fill è usato per mettere valori in un array, per
esempio riempiendo un array con valori di default.
Sintassi: nomearray.fill(<esp> [,<espN inizio>] [,<espN conteggio>])
|
Esempio: supponete che state usando un array che dovrà contenere i totali di alcuni valori, è probabile che vogliate assumere per default che tutti gli elementi dell'array siano inizializzati con il valore 0:
aTotal = new array(20) // istanza
aTotal.Fill(0)
Potete specificare che il riempimento dell'array parti da una posizione ben precisa, ad esempio se voleste inizializzare solamente gli ultimi 15 elementi dell'array aTotal, potete specificare:
aTotal.Fill(0,6) // partenza dall'elemento 6
Potete anche specificare il numero di elementi da inizializzare. Ad esempio inserire il valore 0 solo nei primi cinque elementi dell'array aTotal:
aTotal.Fill(0,1,5)
DIR() e
DIREXT() (e le funzioni aDir()/aDirExt())
Per alcune
situazioni è necessario ottenere informazioni dalla directory. Potete per
esempio fornire al vostro utente un'opzione che gli permetta di aprire una
specifica tabella. Per fare ciò è utile mostrargli l'elenco di tutte le tabelle
della directory.
Questo può essere fatto con i metodi DIR() e
DIREXT()
Sintassi: nomearray.dir([<<espC specifica nome file>>] [,<espC elenco attributi file>])
|
Sintassi: nomearray.dirExt([<<espC specifica nome file>>] [,<espC elenco attributi file>])
|
Esempio:
aTables = new array() aTables.Dir("*.DBF")
Con le istruzioni precedenti otterrete l'elenco di tutti i file .DBF nella directory corrente. L'unico problema è che il metodo Dir() restituirà le colonne seguenti:
1 | 2 | 3 | 4 | 5 |
Nome File | Dimensione | Data | Ora | Attributi (Dos) |
Carattere | Numerico | Data | Carattere | Carattere |
Cosa bisogna fare se
effettivamente volevate solo i nomi dei file?
Una semplice
soluzione è copiare gli elementi dalla prima colonna in un altro
array:
aTable1 = new array() // istanza oggetto array
aTable1.Dir("*.DBF") // esecuzione metodo Dir()
aTable2 = new Array() // altro oggetto array// numero di righe nel primo array
for nRow = 1 to aTable1.subscript( aTable1.size,1)
aTable2.Add(aTable1[nRow,1]) // aggiunge solo l'elemento // che si trova nella prima colonna
next
Il secondo array conterrà solamente
i nomi di file.
Esiste comunque, un'opzione più breve: utilizzare
il metodo resize() per cambiare il numero di colonne nell'array.
aTable = new Array()
aTable.Dir("*.DBF")
aTable.resize( aTable.subscript(aTable.size, 1) , 1, 1 )
Potreste desiderare permettere all'utente di vedere il nome del file "breve". Per ottenere questa informazione, invece di usare il metodo DIR(), usate il metodo DIREXT():
aTable1.DirExt("*.DBF")
L'istruzione precedente restituirà un array contenente le stesse informazioni ottenute con il metodo Dir(), ma aggiungerà delle colonne supplementari a destra:
6 | 7 | 8 | 9 |
Nome File "Alias" | Data Creazione |
Ora Creazione |
Data Ultimo Accesso |
Nome File
DOS nome breve |
Data | Carattere | Data |
La prima colonna conterrà il nome
del file lungo Windows.
Memorizzare i record di una tabella (o solo certi
campi) in un array
NOTA: i
seguenti comandi sono di tipo "XDML" (XBase DML ), non ci sono comandi
equivalenti a questi di tipo OODML.
COPY TO ARRAY <nomearray> ...
APPEND FROM ARRAY <nomearray> ...
REPLACE FROM ARRAY <nomearray> ...
Ci sono due modi per copiare i dati da una tabella ad un array. Se definite un array uni-dimensionale, copierete solamente un record nell'array, ma dovete definire il numero dei campi che devono essere copiati, per esempio, se voi voleste solo i primi cinque campi:
aMioArray = new array(5) // istanza
copy to array aMioArray
Con l'ultima istruzione si
copieranno i primi cinque campi del record corrente nell'array aMioArray.
Notate, che questo memorizza efficacemente il vostro record in una sola
colonna.
Se definite un array che ha due colonne (o più, ma
solo due saranno usate da questo comando), dovete definire il numero di record
(che si associano al numero di righe nell'array) ed il numero di campi (che si
associano al numero di colonne nell'array).
con i
comandi:
aMioArray = new array(2,3)
copy to array aMioArray
si copieranno nell'array i primi tre
campi del record corrente e del successivo della tabella corrente (due record).
Ciò è diverso dal primo esempio, perché dBase memorizza i dati nell'array come
se fossero una tabella, le righe sono i record, le colonne sono i campi
(qualcosa di simile al comando BROWSE in dBase).
Se voleste copiare
tutti i record e tutti i campi contenuti in una tabella, potreste usare una
combinazione delle funzioni RECCOUNT() e FLDCOUNT() al momento dell'istanza
dell'array:
aMioArray = new array(reccount(),fldcount())
copy to array aMioArray
In più potete stabilire la copia di specifici campi:
aMioArray = new array(reccount(),1) // record contati, 1 colonna
copy to array aMioArray fields FirstName
Potete specificare anche la "visibilità" tramite
gli operatori "NEXT" o "FOR" . Ci sono molte opzioni per questo comando,
controllate nella guida in linea le informazioni circa "COPY TO
ARRAY".
Ci sono molti modi per realizzare una routine che riempia
un array. Di seguito alcuni esempi:
// ciascuno di questi esempi da per scontato che la tabella sia aperta
// usando la nuova sintassi OODML:
nomequery.rowset.first() // ci assicura di essere all'inizio della tabella
for i = 1 to Nomequery.rowset.count()
nomearray.Add(nomequery.rowset.fields["nomecampo"].value)
nomequery.rowset.next()
nextnomequery.rowset.first() // ci assicura di essere all'inizio della tabella
do while not Nomequery.rowset.endOfSet
nomearray.Add(nomequery.rowset.fields["nomecampo"].value)
Nomequery.rowset.next()
enddo
Ci sono volte che potreste voler
cancellare un elemento, una riga o una colonna. Per questa operazione c'è un
trucco. Dovete rammentare quando usate i metodi o le funzioni dBase che
gestiscono la cancellazione (elementi, colonne e righe ), che dBase sposta
l'elemento/riga/colonna alla fine dell'array e sostituisce i valori
contenuti in questi elementi con il valore logico falso (in realtà "vuoto",
vedete la discussione sulla funzione EMPTY() in ARRAY1.HTM). Se cancellate un
elemento/riga /colonna in un array e successivamente usate i metodi/funzioni di
ordinamento di array, otterrete un errore.
Cancellare un elemento in un array
uni-dimensionale:
Sintassi: <oRef>.delete(<posizione espN> [, <riga/colonna espN>])
|
Per esempio,nell'array aCity, simile al seguente:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Los Angeles |
Riga 3 | Miami |
Riga 4 | New York |
Riga 5 |
Sydney |
Se voleste rimuovere il secondo elemento:
aCity.Delete(2)
Dopo aver eseguito questo comando l'array conterrà i seguenti valori:
Colonna 1 | |
Riga 1 | San Francisco |
Riga 2 | Miami |
Riga 3 | New York |
Riga 4 | Sydney |
Riga 5 |
false |
Cancellare una riga (array ad una o più dimensioni ):
nomearray.Delete(nRow,1)
Supponete una versione dell'array aCity simile a
quella mostrata sotto:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | Los Angeles | 10.000.000 |
Riga 3 | New York | 25.000.000 |
Riga 4 | Miami | 8.000.000 |
Riga 5 |
Sydney | 1.000.000 |
Per cancellare la seconda riga di questo array, il comando:
aCity.Delete(2,1)
Modificherà l'array nel seguente:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | New York | 25.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | Sydney | 1.000.000 |
Riga 5 |
false |
false |
Cancellare una colonna (Array a più dimensioni):
nomearray.Delete(nColumn,2) // 2 significa "colonna"
Ipotizzate l'array aCity simile al
seguente:
Colonna 1 | Colonna 2 | Colonna 3 | |
Riga 1 | San Francisco | 4.000.0000 | 678 |
Riga 2 | Los Angeles | 10.000.000 | 123 |
Riga 3 | New York | 25.000.000 | 456 |
Riga 4 | Miami | 8.000.000 | 678 |
Riga 5 |
Sydney | 1.000.000 | 1234 |
Il comando per cancellare la seconda colonna dovrà essere:
aCity.Delete(2,2)
Il quale vi darà un array simile al seguente:
Colonna 1 | Colonna 2 | Colonna 3 | |
Riga 1 | San Francisco | 678 | false |
Riga 2 | Los Angeles | 123 | false |
Riga 3 | New York | 456 | false |
Riga 4 | Miami | 678 | false |
Riga 5 |
Sydney | 1234 | false |
Rimuovere gli
elementi/righe/colonne cancellati dall'array:
In
tutti i tre casi mostrati, il problema è come notato che l'elemento/riga/colonna
cancellata si trova ancora nell'array, quindi, se usate il metodo
ReSize:
Imposta un array alle dimensioni specificate e restituisce un valore numerico che rappresenta il numero di elementi che si trovano nell'array modificato. Sintassi: <oRef>.resize(<righe espN> [,<colonne espN> [, <valori mantenuti espN>]]
|
Gli esempi che seguiranno si basano dal punto di vista del codice su gli esempi precedenti: Rimuovere un elemento da un array uni-dimensionale:
aCity.Delete(2) nRows = aCity.subscript(aCity.size,1) aCity.Resize(nRows-1)
Rimuovere una riga di un array multi-colonna:
aCity.Delete(2,1) nRows = aCity.subscript(aCity.size,1) aCity.Resize(nRows-1)
Rimuovere una colonna da un array multi-colonna:
aCity.Delete(2,2) nColumns = aCity.subscript(aCity.size,2) nRows = aCity.subscript(aCity.size,1) // Nota, il parametro RIGHE qui // deve contenere un valore > 0. aCity.Resize(nRows,nColumns-1)
Qualche volta è utile copiare i
contenuti di un array. Pensandoci su probabilmente ci saranno innumerevoli
situazioni in cui potrebbe essere utile copiare un array, includendo il caso di
tenere una copia "di riserva" se l'utente fa qualche cosa di veramente
strano ai dati originali.
In questo caso è utile la funzione
dBase aCopy() in quanto vi permette di copiare i contenuti di un array in un
altro. Il più semplice modo per compiere questa operazione è assicurarsi
che l'array di "destinazione" (target) sia già istanziato e sia grande
abbastanza da contenere i dati del primo array.
|
Se voleste copiare un array
uni-dimensionale:
nRows = aCity.subscript(aCity.size,1)
aBackup = new array(nRows)
aCopy(aCity,aBackup)
Se avete necessità di copiare un array multi-colonne:
nRows = aCity.subscript(aCity.size,1)
nCols = aCity.subscript(aCity.size,2)
aBackup = new array(nRows,nCols)
aCopy(aCity,aBackup)
In alcune situazioni, potreste voler copiare solamente alcuni dei dati da un array ad un altro. La funzione aCopy() ha dei parametri per gestire questa situazione (per maggiori dettagli vedete nella guida di riferimento al linguaggio).
Saper scandire un array per trovare
un elemento può essere molto utile. In Visual dBase, questo è fatto con il
metodo SCAN() (o con la funzione ASCAN()).
Se la ricerca ha successo
questo metodo restituisce il numero del primo elemento dell'array che
corrisponde all'espressione cercata, altrimenti restituisce
0.
|
Per esempio, se volete cercare la città "Miami" nell'array (versione uni-dimensionale), il metodo scan() vi restituisce in quale riga si trova:
nFoundRow = aCity.Scan("Miami")
? aCity[nFoundRow]
Il metodo SCAN() è "case-sensitive", cioè tiene conto dei caratteri minuscoli e maiuscoli.
Se state usando questo metodo con un array multi-colonna, aumenta la complessità, in quanto vi sarà dato il numero di elemento, non la riga. Per semplificare potete combinare il valore restituito con il metodo SUBSCRIPT()
nElement = aCity.Scan("Miami")
nRow = aCity.Subscript(nElement,1)
nColumn = aCity.Subscript(nElement,2)
? aCity[nRow,nColumn]
Qualche volta i dati immessi in un
array non hanno un ordine ben preciso e molto probabilmente avete la necessità
di ordinarli. Il metodo sort() ordina gli elementi di un oggetto array
monodimensionale o ordina le righe di un oggetto array
bidimensionale.
|
Esempio:
aCity.Sort()
Il comando precedente ordina l'array aCity sulla prima colonna. se ci sono più colonne, le righe saranno tutte spostate con i relativi elementi nella prima colonna.
Presumete di avere il seguente array prima dell'operazione di ordinamento:
Colonna 1 | Colonna 2 | |
Riga 1 | San Francisco | 4.000.000 |
Riga 2 | Los Angeles | 10.000.000 |
Riga 3 | New York | 25.000.000 |
Riga 4 | Miami | 8.000.000 |
Riga 5 |
Sydney |
1.000.000 |
e dopo:
Colonna 1 | Colonna 2 | |
Riga 1 | Los Angeles | 10.000.000 |
Riga 2 | Miami | 8.000.000 |
Riga 3 | New York | 25.000.000 |
Riga 4 | San Francisco | 4.000.000 |
Riga 5 |
Sydney |
1.000.000 |
Per ordinare invece sulla seconda colonna:
aCity.Sort(2)
La quale ci darà:
Colonna 1 | Colonna 2 | |
Riga 1 | Sydney | 1.000.000 |
Riga 2 | San Francisco | 4.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | Los Angeles | 10.000.000 |
Riga 5 |
New York |
25.000.000 |
Ci sono alcuni metodi/funzioni che
possono essere utili in unione con gli altri, di seguito daremo un breve
sguardo.
Element()
|
Se lavorando con un array avete la necessità di trovare uno specifico elemento potete utilizzare il seguente frammento di codice:
nElement = aCity.Element(1)
In un array unidimensionale, il
metodo ELEMENT() è ridondante, risulta essere più utile in un array
multi-dimensionale. I parametri vi permettono di specificare i
subscript.
Per esempio, in un array bi-dimensionale potreste
specificare la riga e la colonna:
?aCity.Element(3,2) // riga 3, colonna 2
Il comando precedente dovrebbe restituire un valore 6, in quanto si tratta del sesto elemento di questo array. Se l'array avesse più colonne, il valore restituito non sarebbe 6. Per esempio, in un array a tre colonne usando lo stesso comando visto sopra, restituirebbe 8.
Subscript()
Questo metodo può essere
veramente utile. Se conoscete il numero elemento potete determinare il numero di
riga o di colonna dell'elemento in un
array
|
Esempio:
?aCity.Subscript(nElement,1) // riga
?aCity.Subscript(nElement,2) // colonna
Questo vi darà le informazioni sull'attuale subscript (riga/colonna). Si può anche visualizzare il contenuto di un specifico elemento, potrebbe essere utile se state utilizzando il metodo Scan():
nElement = aCity.Scan("25,000,000")
nRow = aCity.Subscript(nElement,1)
nColumn = aCity.Subscript(nElement,2)
? aCity[nRow,nColumn]
aLen()
|
Se <espN> è... |
ALEN() restituisce... |
non fornito |
Il numero di elementi dell'array |
0 |
Il numero di elementi dell'array |
1 |
Per un array
monodimensionale, il numero di elementi |
2 |
Per un array
monodimensionale, 0 (zero) |
|
Se avete già lavorato con gli
oggetti di interfaccia utente (qualsiasi oggetto ponete su una scheda è un
oggetto di interfaccia utente), probabilmente avete dato uno sguardo agli
oggetti comboboxes, listboxes, e tabboxes. Ognuno di questi oggetti possiede una
proprietà chiamata datasource. In questa proprietà immetteremo le opzioni che
vogliamo siano visualizzate da questi oggetti. Tra le diverse possibilità di
formato che accetta la proprietà datasource c'è l'oggetto array. Lo scopo di
questo documento è discutere sugli array, così se non sapete come usare un
Combobox, Listbox, o TabBox, potete fermarvi qui poiché non affronterò questi
oggetti in maniera dettagliata, eccetto dove la proprietà datasource entra in
campo.
Comboboxes e listboxes
Comboboxes e
Listboxes possono usare array nella proprietà datasource.
Attenzione: se tentate di usare un array
multi-dimensionale o multi-colonna, noterete che la lista di opzioni che
dovrebbero mostrare i suddetti oggetti sembra un po' strana.
Esempio:
Colonna 1 | Colonna 2 | |
Riga 1 | Sydney | 1.000.000 |
Riga 2 | San Francisco | 4.000.000 |
Riga 3 | Miami | 8.000.000 |
Riga 4 | Los Angeles | 10.000.000 |
Riga 5 |
New York |
25.000.000 |
Se impostate la vostra proprietà
datasource per leggere: "ARRAY aCity", dove "acity" è un array simile a quello
visto sopra, ciò che sarà visualizzato nel vostro combobox o listbox
è:
Sydney 1,000,000 San Francisco 4,000,000 Miami 8,000,000 Los Angeles 10,000,000 New York 25,000,000
E ciò non è quello che volete che
accada. (Una possibile soluzione è copiare solo la prima colonna dell'array in
un altro array ...)
In più, un problema che qualche volta fa
ammattire un po' è:
"Dove definite l'array in modo tale che il
modulo Impostazione Schede non lo "uccida" e sia disponibile quando si manda in
esecuzione la scheda ?"
La ragione di questa domanda risiede
nel fatto che quando state progettando una scheda e l'array non esiste
Impostazione scheda vi permetterà di lavorare, ma se voi mandate in esecuzione
la scheda otterrete un errore.
Quindi, dove dovete definire il
vostro array?
Molto dipende da dove ricavate i dati per
l'array. Se l'array è un array "statico" (volendo dire che i valori memorizzati
nell'array non subiranno modifiche ), e l'unico uso che voi avete per l'array è
l'elenco (intendendo con questa affermazione che non si ha bisogno di compiere
alcun lookups nell'array o in qualsiasi altra parte del codice della scheda ),
dovreste usare un array letterale. Se l'array si ottiene da un campo di una
tabella, dovreste definire queste informazioni quando la scheda viene
aperta (usando il metodo di OnOpen).
L'Array
Letterale
Potete definire il vostro array letterale sia
manualmente sia tramite l'uso del "Generatore visuale di Array". Per farlo
manualmente nella proprietà DataSource digitate:
ARRAY {"San Francisco","Los Angeles", etc.}
Per usare il generatore di array,
cliccate sul pulsante strumento della proprietà DataSource. Questo attiverà il
generatore. Questo strumento è così facile da usare che non è necessario
approfondire la discussione.
L'inconveniente per un array letterale
definito in questo modo è che esso non ha nome. Se per qualsiasi ragione avete
bisogno di esaminare i valori in esso contenuti bisognerà prevedere del lavoro
aggiuntivo da parte vostra (un metodo potrebbe essere quello di mostrare il
valore della proprietà datasource: form.combobox1.datasource, potete memorizzare
questo valore in una variabile di memoria di tipo carattere e tramite un analisi
(parse) di essa risalire ai contenuti dell'array, ma non è il metodo più
efficiente da utilizzare con un array ).
Se avete bisogno di usare la
proprietà datasource con un array altrove nel vostro codice, non usate un array
letterale.
Definire la
proprietà DataSource senza usare un array
letterale
Se non volete (o decidete che non è utile
per i vostri scopi ) usare un array letterale, allora dove e come definite il
vostro array per la proprietà datasource?
Due luoghi immediatamente saltano in mente:
negli eventi scheda Open o ReadModal;
nell'evento Open dell'Oggetto.
In entrambi i casi è una buona idea
che l'array sia definito come una proprietà custom della scheda o
dell'oggetto, altrimenti appena il metodo ha eseguito il suo codice,
l'array non è più disponibile. (otterrete errori che vi segnalano
che l'array non esiste ). Naturalmente potreste definire l'array "Pubblico", ma
questo provoca alcuni problemi, come ad esempio ricordarsi di rilasciare l'array
quando chiudete la scheda.
NOTA: Potreste scaricare FORMVAR.HOW come
fonte di ulteriori informazioni sull'uso di questi metodi per una scheda e per
gli oggetti scheda...
Per fare questo, quando istanziate
l'array, aggiungete semplicemente il riferimento oggetto all'array. Ricordate un
array è un oggetto, ma in questo caso potete fare in modo che sia una proprietà
di un altro oggetto:
form.aCity = new array()
oppure
form.ComboBox1.aCity = new array()
L'unico inconveniente è che dovete
riferirvi all'intero "percorso" ogni volta che avete bisogno di riferivi
all'array. Il vantaggio è che non avete bisogno che l'array sia pubblico (PUBLIC
aCity ), e non dovete preoccuparvi circa il rilascio dalla memoria quando avete
finito con l'array. Quando chiudete la scheda, anche l'oggetto array scomparirà,
poiché è una proprietà della scheda .
Una volta che avete istanziato
l'array, potete aggiungergli gli elementi di cui avete bisogno (questo è solo
uno esempio ):
form.aCity.Add("San Francisco")
form.aCity.Add("Los Angeles")
form.aCity.Add("Miami")
form.aCity.Add("New York")
form.aCity.Add("Sydney")
Quando fate quanto su indicato, non impostate la proprietà datasource fino a che non avete avete riempito l'array. Poi aggiungete l'istruzione:
form.Combobox1.Datasource = "ARRAY form.aCity"
oppure
form.Combobox1.Datasource = "ARRAY form.Combobox1.aCity"
Cosa accade se l'array viene
modificato?
In alcuni casi, il contenuto di un array può
cambiare. Visual DBase non sempre visualizza le modifiche e questo potrebbe
essere causa di confusione. Un semplice stratagemma è aggiungere l'istruzione
seguente dopo che avete aggiornato i contenuti dell'array :
form.Combobox1.Datasource = form.Combobox1.Datasource
Questo costringe dBase ad aggiornare
la proprietà datasource stessa e di conseguenza sarà visualizzato l'array
aggiornato.
TabBoxes
Il tabBox, pur essendo uno
strumento piuttosto utile per le schede multi-pagina,, non richiede un array
complesso per la proprietà datasource. In effetti avete soltanto bisogno di
array letterali a meno che per qualche ragione avete bisogno successivamente di
riferirvi ai contenuti dell'array. La maggior parte delle volte questo non è
necessario.
Comunque, in una discussione nel NG uno dei membri del
dBVIPS mi ha mostrato un metodo piuttosto semplice ed elegante per usare un
array letterale con il controllo tabbox relativamente alla proprietà datasource,
che consente di utilizzare il testo del separatore correntemente selezionato.
Provate il seguente codice associato col metodo OnSelChange del
TabBox:
PROCEDURE TabBox1_OnSelChange
// se ci sono più pagine:
form.PageNo := this.CurSel
// memorizza l'array letterale in un array temporaneo,
// rimuovendo la parola "array" dalla proprietà datasource ...:
aTabArray = right(this.datasource,aLen(this.datasource)-6))
// memorizza il testo contenuto nel corrente tabbox in una proprietà custom
// del controllo tabbox:
this.TabText = &aTabArray.[this.CurSel]
Se avete bisogno di sapere il testo
del tabbox esso sarà contenuto in questa proprietà custom.
Una prova
potrebbe essere di aggiungere questo frammento di codice:
msgbox(this.TabText)
Il quale mostrerà il contenuto del testo del corrente separatore...
Se guardate attentamente gli esempi
in questo documento, vedrete che molto codice è coinvolto nel trovare il numero
di righe e colonne di un array. Sarebbe bello se poteste consultare solo l'array
per scoprire queste informazioni. Un mio amico, Gary white ha trovato una buona
soluzione: un oggetto array custom, il codice completo è nel file GWARRAY.CC,
incluso nel file .zip che contiene questo documento.
AVVISO: l'autore è un membro del dBVIPS (dBASE Volunteer Internet Peer Support). Un gruppo di volontari che offrono assistenza tecnica per dBase, Inc. sul newsgroups di Visual dBase (news.dbase2000.com). Se avete domande che riguardano questo documento, o su Visual dBase potete comunicare direttamente con l'autore e i dBVIPS nel newsgroups. Attualmente non è offerta assistenza tecnica "privata" tramite E-mail privato dai membri del dBVIPS.
I file How sono creati come servizio gratuito dai membri del dBVIPS per aiutare gli utenti ad imparare ad usare più efficacemente Visual dBase. Questi documenti sono redatti dai membri del dBVIPS e dall'Assistenza Tecnica di dBase Inc. (per assicurare qualità). Questo file How To non può essere affisso altrove senza il permesso esplicito dell'autore che trattiene tutti i diritti sul documento.
Copyright 1999, Kenneth J. Mayer. All rights reserved.
EoHT: ARRAY2.HTM -- March 21, 1999 -- KJM