I concetti di base della programmazione

Traduzione dalla Versione inglese "Programmers Guide"


Quando si programma non si fa altro che creare dati e manipolarli attraverso una seri di istruzioni. I dati ed i loro contenitori sono il materiale grezzo del programmatore. Gli strumenti che servono per manipolare questo materiale grezzo sono i comandi, le funzioni e gli operatori.

Immagazzinare i dati

I dati sui quali si lavora probabilmente contengono quantità in tempo, denaro e voci contabili, come probabilmente date, nomi, descrizioni, eccetera. Ogni porzione di dati è di un determinato tipo, ovvero appartiene ad una categoria che offre la possibilità di manipolarli in modo similare.
Naturalmente è sempre possibile lavorare direttamente con questi dati senza memorizzarli, ma così facendo si perderebbe la maggior parte della flessibilità e della potenza di Visual FoxPro; Visual FoxPro, infatti, fornisce numerosi tipi di contenitori per i dati, così da semplificarne la gestione.
Le varie tipologie di dati sono determinanti per come poi andremo a gestirli ed immagazzinarli. E' infatti possibile eseguire la moltiplicazione tra due numeri, ma non si possono moltiplicare tra loro due caratteri. Si possono stampare caratteri in maiuscolo, ma non si possono stampare in maiuscolo dei numeri !
Le più importanti categorie di dati che Visual FoxPro è in grado di gestire sono elencati nella seguente tabella:

Categorie di dati

Tipo Esempi
Numerico 1233.1415- 7
Carattere "Stringa di testo""123""01/01/98"
Logico .T..F.
DataDataTempo {^1998-01-01} {^1998-01-01 12:30:00 p}

Contenitori


I contenitori permettono di eseguire le stesse operazioni su diverse porzioni di dati. Ad esempio è possibile eseguire la somma di tutte le ore lavorate da un impiegato, moltiplicarle per la paga oraria e, dedotte le tasse, determinare lo stipendio percepito. E' possibile eseguire questo calcolo per ogni impiegato ed ogni mese di paga. Memorizzando questa informazione in un apposito contenitore, ed eseguendo direttamente le operazioni su tale contenitore, saremo in grado di sostituire automaticamente i vecchi valori con i nuovi ogni volta che il programma rieseguirà il calcolo.
Le più importanti categorie di contenitori di dati che Visual FoxPro è in grado di gestire sono elencati nella seguente tabella:

Tipo Descrizione
Variabile Singoli elementi di dati contenuti nella memoria RAM (Random Access Memory) del calcolatore.
Tabella Record Righe contenenti campi, ognuno dei quali può immagazzinare una predefinita quantità di dati.Le tabelle vengono salvate su disco.
Matrici (Array) Elementi multipli di dati contenuti nella memoria RAM del calcolatore.

Manipolare i dati


Contenitori e categorie rappresentano, insieme agli operatori alle funzioni ed ai comandi, i mattoni necessari per la manipolazione dei dati.
Utilizzare gli Operatori
Gli operatori legano i dati l'uno all'altro. Di seguito vengono elencati gli operatori più comunemente utilizzati in Visual FoxPro.

Operatore Categorie di dati utilizzati Esempio Risultato
= Tutte ? n = 7 Stampa .T. se il valore memorizzato nella variabile n vale 7, altrimenti stampa .F.
+ Numeric, Character, Date, DateTime ? "Fox" + "Pro" Stampa "FoxPro"
! o NOT Logical ? !.T. Stampa .F.
*, / Numeric

? 5 * 5
? 25 / 5

Stampa 25
Stampa 5

Note L'inserimento di un punto interrogativo (?) davanti ad una espressione, provoca la stampa del risultato della espressione all'interno della finestra correntemente attiva (usualmente la finestra principale di Visual Foxpo) preceduta da un carattere di ritorno a capo (CR).

Occorre tener presente che è necessario, con ogni operatore, utilizzare sempre lo stesso tipo di dati. I seguenti comandi immettono due valori numerici all'interno di due variabili. In questo esempio, alle variabili sono stati assegnati nomi che iniziano con la lettera 'n', in maniera tale da capire immediatamente che il loro contenuto è di tipo numerico, anche se naturalmente è possibile definirle con qualsiasi combinazione di caratteri alfanumerici o caratteri di sottolineatura (underscore).

nFirst = 123
nSecond = 45

In quest'altro caso, invece, vediamo come inserire all'interno di variabili dei valori di tipo carattere. Alle variabili sono stati assegnati nomi che iniziano con la lettera 'c', in maniera tale da capire immediatamente che il loro contenuto è di tipo carattere.

cSecond = "45"

Le seguenti due operazioni, addizione e concatenazione, forniranno risultati diversi, proprio a causa del diverso tipo di variabili utilizzate.

? nFirst + nSecond
? cFirst + cSecond

Risultato

168
12345

Dal momento che la variabile cFirst è di tipo carattere, mentre nSecond è di tipo numerico, otterremo un errore di tipo mismatch (accoppiamento non valido) se si tentasse la seguente operazione:
? cFirst + nSecond

E' possibile aggirare questo problema utilizzando le funzioni di conversione. Per esempio, la funzione STR( ) convertirà in stringa di caratteri un dato numero, mentre la funzione VAL( ) restituirà il valore numerico equivalente ad una stringa di caratteri contenente numeri. Queste funzioni, insieme alla LTRIM( ), che rimuove tutti gli spazi a sinistra della stringa, permetteranno, ad esempio, di effettuare le seguenti operazioni:

? cFirst + LTRIM(STR(nSecond))
? VAL(cFirst) + nSecond

Risultato
12345
168

Utilizzare le Funzioni

Le funzioni restituiscono sempre un determinato tipo di dati. Ad esempio, le funzioni STR( ) e VAL( ), utilizzate negli esempi precedenti, restituiscono, rispettivamente, stringhe di caratteri e valori numerici. Come tutte le funzioni, le varie tipologie di dati restituiti verranno specificate di volta in volta.

In Visual FoxPro, esistono cinque sistemi per chiamare una funzione:

Alcuni altri esempi di funzioni utilizzate in questo capitolo sono:

Funzione Descrizione

ISDIGIT( )

Restituisce vero (.T.) se il primo carattere a sinistra di una stringa rappresenta un numero; in caso contrario, restituisce falso (.F.).

FIELD( )

Restituisce il nome di un campo.

LEN( )

Restituisce il numero di caratteri contenuti in una stringa.

RECCOUNT( )

Restituisce il numero di records presenti all'interno della tabella attiva.

SUBSTR( )

Estrae uno specifico numero di caratteri da una stringa, partendo da una determinata posizione.

 

Utilizzare I comandi

Un comando provoca l'esecuzione di una determinata azione. Ogni comando ha una sintassi specifica che occorre rispettare affinché possa essere correttamente compiuta l'azione. Esistono, inoltre, delle proposizioni associate ai comandi che permettono di specificare con maggiore esattezza ciò che si vuole eseguire.


Ad esempio, il comando USE, che permette di aprire e chiudere tabelle, può essere utilizzato in diverse maniere:

Sintassi del comando USE Descrizione

USE

Chiude la tabella aperta nell'area di lavoro corrente.

USE

customer Apre la tabella CUSTOMER nell'area di lavoro corrente chiudendovi, contemporaneamente, ogni altra tabella aperta.

USE customer IN 0

Apre la tabella CUSTOMER nella successiva area di lavoro disponibile.

USE customer IN 0 ; ALIAS mycust

Apre la tabella CUSTOMER nella successiva area di lavoro disponibile ed assegna all'area l'alias mycust.

Alcuni esempi di comandi mostrati in questo capitolo sono:

Comando Descrizione

DELETE

Attiva il marcatore di cancellazione in uno specifico record all'interno di una tabella.

REPLACE

Sostituisce il valore di un record con uno nuovo.

GO

Posiziona il puntatore su uno specifico record all'interno di una tabella.

 

Controllare il flusso di un programma


Visual FoxPro include una speciale categoria di comandi che racchiudono "wrap around" altri comandi o funzioni, determinando quando e quante volte questi altri comandi e funzioni verranno eseguiti. Questi comandi permettono la scelta condizionale (conditional branching) e l'esecuzione di cicli (looping), due potentissimi strumenti di programmazione. Successivamente verranno mostrati programmi in grado di attivare scelte condizionali e cicli.


Questi concetti sono descritti in maggior dettaglio nel seguente esempio.

Supponiamo di avere 10,000 dipendenti e di volere aumentare lo stipendio del 6%, a quelli che guadagnano fino a $30,000 e del 3% a tutti gli altri. Nell'esempio seguente vediamo l'applicazione in grado di effettuare l'operazione.
Questo programma parte dal presupposto di avere, nell'area corrente, una tabella aperta contenente un campo numerico chiamato salary
Programma esemplificativo su come applicare un incremento di salario

Codice Commenti
SCAN Il codice che si trova tra SCAN ed ENDSCAN viene eseguito per ogni record presente in tabella. Dopo l'esecuzione del ogni blocco di codice che si trova tra SCAN ed ENDSCAN , il puntatore di record viene posizionato su record successivo.
IF salary >= 30000.00 REPLACE salary WITH ; salary * 1.03 Per ogni record, nel caso in cui il salario sia di un valore maggiore od uguale a 30,000, il valore stesso viene aumentato del 3%. Il punto e virgola (;) posto dopo l'istruzione WITH, sta ad indicare che il comando prosegue sulla riga successiva.
ELSE
REPLACE salary WITH ; salary * 1.06
Per ogni altro record il salario viene maggiorato del 6%.
ENDIF
ENDSCAN
Dichiarazione di fine della condizione (IF). Istruzione che termina la sequenza di codice da eseguire per ogni record presente in tabella.

L'esempio di cui sopra utilizza sia la scelta condizionale (IF), sia il looping (SCAN…ENDSCAN) al fine di controllare il flusso del programma.

Scelta Condizionale (Conditional Branching)

La scelta condizionale permette di verificare delle condizioni e, in base ai risultati, eseguire differenti operazioni. Esistono due comandi in Visual Foxpro di effettuare questa operazione:

Il codice che compare tra la prima istruzione (IF o CASE) e l'ultima (ENDIF o ENDCASE) verrà eseguito solo nel caso in cui la condizione logica risultante da tali istruzioni risulterà vera (.T.).
Nell'esempio appena visto, l'istruzione IF viene utilizzata per distinguere due situazioni: quella in cui il salario sia uguale o maggiore a $ 30,000, e quella in cui il salario sia inferiore a $30,000. In base al verificarsi di una condizione o dell'altra, verranno eseguite diverse operazioni..
Nell'esempio seguente, nel caso in cui il valore memorizzato nella variabile nWaterTemp sia inferiore a 100, non verrà eseguita alcuna operazione:

* imposta una variabile logica a vero (.T.), nel caso in cui sia soddisfatta una * condizione (if).

IF nWaterTemp >= 100
       lBoiling = .T.
ENDIF

Nota L'asterisco posto all'inizio di una riga di programma indica che si tratta di un commento. Le righe di commento aiutano il programmatore a ricordare lo scopo di un determinato segmento di programma e sono completamente ignorate da Visual FoxPro.

Nel caso in cui ci si trovi a dover valutare diverse possibilità di scelta, l'utilizzo del comando DO CASE ... ENDCASE può risultare più efficiente e semplice da verificare rispetto alla implementazione di molte istruzioni di tipo IF.

I Cicli (Looping)


Il Looping permette di eseguire una o più linee di codice in maniera ricorsiva. Esistono tre comandi in Visual FoxPro che permettono questo:

SCAN viene utilizzato nel caso in cui si debbano eseguire una serie di operazione per ogni record presente in una tabella, come nell'esempio appena descritto. Il ciclo di SCAN permette di scrivere del codice che verrà eseguito per ogni record, spostando ogni volta il puntatore del record in avanti di una posizione all'interno della tabella.
E' possibile utilizzare, invece, l'istruzione FOR nei casi in cui si sappia già quante volte è necessario eseguire un determinato blocco di istruzioni. Per esempio, nel caso in cui si sappia a priori quanti campi sono presenti in una determinata tabella. Siccome in Visual FoxPro la funzione FCOUNT( ) restituisce proprio questo valore, sarà possibile utilizzare un ciclo di tipo FOR per, ad esempio, stampare i nomi di tutti i campi presenti in una tabella:

FOR nCnt = 1 TO FCOUNT( )
     ? FIELD(nCnt)
ENDFOR

Il DO WHILE, invece, è utilizzato nelle situazioni in cui si voglia eseguire una porzione di codice per tutto il periodo in cui venga rispettata una determinata condizione. Può darsi che non si sappia affatto quante volte verrà eseguito il codice, si deve solo decidere quando terminarne l'esecuzione. Per esempio, ammettiamo di avere una tabella contenente nomi ed iniziali di alcune persone e di avere la necessità di cercare un determinato nominativo attraverso le iniziali.
La prima volta che ci troveremmo di fronte alla necessità di inserire il nominativo di una persona che ha le stesse iniziali di una già presente in tabella … inizieremmo ad avere i primi problemi.
Per toglierci d'impaccio potremmo decidere di aggiungere un numero alle iniziali. Per esempio, il codice identificativo di Michael Suyama potrebbe essere MS. La prima persona con le stesse iniziali, Margaret Sun, potrebbe essere identificata con il codice MS1. Quando andremo ad aggiungere Michelle Smith alla tabella, il suo codice identificativo dovrebbe essere MS2.

Un ciclo DO WHILE ci permetterà di trovare il giusto numero da aggiungere alle iniziali.
Esempio di programma in grado di generare un identificativo univoco utilizzando un ciclo DO WHILE

Codice Commenti
NHere = RECNO() Salva il numero di record.
cInitials = LEFT(firstname,1) + ;       LEFT(lastname,1)nSuffix = 0
Desume le iniziali della persona in base alla prima lettera dei campi firstname e lastname. Crea una variabile dove memorizzare il numero da aggiungere alle iniziali, se necessario.
LOCATE FOR person_id = cInitials Verifica se in tabella esistono altre persone con le stesse iniziali.
DO WHILE FOUND( ) Nel caso in cui venga trovato un altro record contenente un person_id uguale al valore memorizzato in cInitials, la funzione FOUND( ) restituirà il valore vero (.T.) e verrà eseguito il codice contenuto all'interno del ciclo DO WHILE. In caso contrario la riga di codice eseguita sarà la prima presente dopo l'istruzione ENDDO.
     nSuffix = nSuffix + 1 cInitials = ;      LEFT(cInitials,2); +      ALLTRIM(STR(nSuffix)) Prepara un nuovo suffisso e lo inserisce in coda alle iniziali.
     CONTINUE CONTINUE riesegue l'ultimo comando LOCATE ed il programma verificherà nuovamente la presenza del valore contenuto in cInitials (appena calcolato) nel campo person_id di un altro record. In caso positivo, FOUND( ) riporterà un valore vero (.T.) e verrà eseguito nuovamente il codice presente all'interno del ciclo DO WHILE; in caso contrario FOUND( ) riporterà un valore falso(.F.) ed il programma potrà procedere nella esecuzione della riga successiva all'istruzione ENDDO.
ENDDO Fine del ciclo DO WHILE.
GOTO nHereREPLACE person_id WITH cInitials Torna al numero di record (memorizzato all'inizio del programma) e registra il codice identificativo univoco nel campo person_id.

Ecco come, non sapendo a priori quante volte troveremo in tabella la corrispondenza ad un determinato valore, sia necessario utilizzare il ciclo DO WHILE.

 

Traduzione dalla Versione inglese "Programmers Guide" a cura di Alessandro Bindi

© FoxPro e Visual FoxPro sono un marchi registrati da Microsoft Corporation

 

Febbraio 2002
 

FoxPro e Visual FoxPro® sono un marchi registrati da Microsoft Corporation

Fonte: "Programmers Guide Visual FoxPro®" di Microsoft© in lingua inglese.
Questa guida ha il solo scopo di fornire le indicazioni
per muovere i primi passi con questo bellissimo strumento.

 


dal 22 Giugno 1999
webmaster@foxitaly.com