Logo dell'UIC Logo TUV

Unione Italiana dei Ciechi e degli Ipovedenti ETS - APS

 

Uiciechi.it

torna alla visualizzazione del numero 11 del Uiciechi.it

Numero 11 del 2021

Titolo: gli script di jaws 14a. Le procedure guidate: gestione dei pulsanti ed elementi base.

Autore: Abramo Volpato.


Articolo:
gli script di jaws 14a. Le procedure guidate: gestione dei pulsanti ed elementi base.

Di Abramo Volpato.

14.1. Oltre i confini degli script per Jaws.

Se proponiamo degli elementi di codice, che funzionano regolarmente nella personale configurazione di chi scrive, vuol dire che ciò è comunque fattibile. Chi avesse un minimo di conoscenza dei linguaggi di programmazione, tuttavia, si potrebbe rendere facilmente conto che stiamo forse un po' uscendo dall'ambito per il quale era stata pensata la possibilità di personalizzare il funzionamento di Jaws.

Se il nostro obiettivo è costruire delle procedure guidate, in queste pagine è comunque spiegato come raggiungerlo. Certo, potrete rendervi conto anche voi che non saranno perfette, tutt'altro, e saranno pure un po' lente, in quanto devono lavorare sopra ad altre applicazioni, ma funzionano, ed è tutto ciò che conta!

Tornando ai contenuti, in quest'ultimo capitolo termineremo gli elementi di carattere accessorio, per poterci poi dedicare finalmente al cuore della nostra procedura. Il capitolo si chiuderà trattando prima gli script necessari agli iniziali collaudi, e quindi dedicandoci alle altre funzioni di gestione che, come "MuoveDato ()", si occupano materialmente di utilizzare i dati inseriti per compiere delle azioni concrete.

Così come nel capitolo precedente, all'inizio ci baseremo sui blocchi creati attorno alle funzioni chiamate direttamente dall'elemento principale. Siccome, dopo quelli già affrontati nello scorso capitolo, i blocchi mancanti sono solo tre, inizieremo comunque dal più corposo, dedicato alla gestione delle scelte operate nella finestra di dialogo primaria. Gli altri due, composti ciascuno da una sola funzione, ci consentiranno poi almeno di terminare gli elementi preparatori.

Il primo dei restanti blocchi sarà quello relativo, appunto, alla funzione di gestione delle procedure, ed al collaudo delle funzionalità che ancora mancano per la ricerca di elementi. Gli ultimi due blocchi riguarderanno le macro testuali, con gli script che attivano tale categoria di elaborazione, e gli script a gestione personale, che avranno in più anche qualche altra funzione riservata a questa categoria.

Con la certezza che si tratti davvero dell'ultima volta, vi chiediamo di iniziare ancora completando per prima cosa i nostri file esterni.

Esercizio 14.1.1. Aggiornare il file Personale delle Costanti.

GIU = "giù", ; termine omonimo
MAX_LUNGO = 120, ; numero delle colonne per il sommario nelle voci di scelta
MODIFICA = "Modifica", ; termine omonimo
ELIMINA = "Elimina", ; termine omonimo
DUPLICA = "Duplica", ; termine omonimo
DATI_SCRIPT = 5, ; numero degli elementi nel record di dati sugli script a gestione personale
TABELLA = "Tabella", ; termine omonimo

Esercizio 14.1.2. Aggiornare il file Personale delle Variabili Globali.

Int gnUscita, ; valore per l'uscita dai cicli

Esercizio 14.1.3. Aggiornare il file Personale dei Messaggi.

; raggiunto il numero massimo di voci di elaborazione consentite
@hlpMassimoVoci
Raggiunto il limite massimo di voci.
@@
; voce unica in una finestra di elaborazione
@hlpUnicaVoce
Unica voce presente.
@@
; ultima voce in una finestra di elaborazione
@hlpUltimaVoce
Ultima Voce.
@@
; Prima voce in una finestra di elaborazione
@hlpPrimaVoce
Prima voce.
@@
; campo non valido per la funzione richiesta
@msgNoCampoValido
Impossibile %1re voci a questo livello della procedura.
@@
; conferma cancellazione
@msgCancella
Eliminare %1%2 %3?
@@
; cancellazione riuscita
@msgOkCancella
Rimozione effettuata.
@@
; assenza di script registrati nell'archivio di configurazione personale
@hlpNoArchivioScript
Nessuno script personale registrato.
@@
; tre termini seguiti dal carattere Punto
@msg3Punto
%1. %2. %3.
@@
; titolo per la scelta degli script a gestione personale da duplicare
@ttlDuplicaScript
Selezionare lo script da duplicare. Ok conferma, Esc annulla.
@@
; conferma della duplicazione di uno script
@msgCopiaScript
Script duplicato.
@@
; Errore nella copia di uno script
@msgErroreCopia
Impossibile copiare script.
@@
; frase negativa
@hlpNessuna
Nessuna %1.
@@
; elenco azioni eseguite in una schermata di scelta
@lstEseguiteVoci
modifica|aggiunta|rimozione|duplicazione
@@
; elenco azioni sulle voci in una schermata di scelta
@lstAzioniVoci
modifica|aggiunge|elimina|duplica
@@
; etichetta di pulsante non riconosciuta
@hlpNoEtichetta
Etichetta %1 non riconosciuta.
@@
; trascrizione ambito riuscita
@hlpOkAmbito
Ambito salvato.
@@
;errore nella trascrizione dell'ultimo ambito selezionato nella finestra di scelta
@hlpErroreAmbito
Impossibile aggiungere l'ambito %1.
@@
; titolo che informa dei dati già registrati per lo script rilevato
@ttlScriptPresente
I dati per lo script %1 sono già registrati.
@@
; conferma generica alla sovrascrittura
@msgSovrascrittura
Confermate la sovrascrittura?
@@
; avviso di ricerca avviata
@msgAvvioRicerca
Ricerca in corso...
@@
; macro non registrata
@ttlNoMacro
Nessuna macro %1 alla posizione %2.
@@
; base per titolo nella modifica o aggiunta di una voce in un elenco
@ttlElaboraVoce
%1re %2 alla posizione %3.
@@
; suffisso per la posizione di un elemento
@msgPosizione
alla posizione %1.
@@
; mancata impostazione dei tasti di uno script personale come gli ultimi premuti
@hlpNoUltimiTasti
Impossibile impostare i tasti di attivazione di %1 come gli ultimi premuti.
@@
; mancata impostazione dei tasti di uno script personale come gli ultimi premuti - versione corta
@hlpNoUltimiTasti_corto
Impossibile impostare i tasti.
@@
; base per la chiamata della funzione che esegue gli script dall'Aiuto in linea
@hlpEsegueLink
ImpostaEsegue ("%1", "%2")
@@
; mancato rilevamento dei dati sugli script a gestione personale
@hlpNoDatiScript
Dati dello script personale %1 assenti o incompleti.
@@
; mancato rilevamento dei dati sugli script a gestione personale - versione corta
@hlpNoDatiScript_corto
Errore nei dati personali.
@@
; cursore non posizionato in una tabella o in un foglio elettronico
@hlpNoTabella
Non siamo in una cella.
@@
; ambito di azione degli script non riconosciuto
@hlpNoAmbito
Impossibile riconoscere l'ambito %1 per gli script personali.
@@
; ambito di azione degli script non riconosciuto - versione corta
@hlpNoAmbito_corto
%1 non riconosciuto.
@@

14.2. Pulsanti e scelte.

Con gli elementi di questo blocco, composto da ben dodici funzioni, affrontiamo il vero motore della procedura, quello che consente di operare delle scelte e di eseguire le azioni conseguenti. Sono concentrate qui, infatti, le funzioni per inserire, modificare, cancellare, spostare o duplicare, le varie voci elaborate, gestendo soprattutto le diverse e variabili pressioni dei pulsanti opzionali.

Come al solito, rinviamo alle note dei singoli elementi per maggiori dettagli, mentre gli argomenti più importanti saranno illustrati da un titolo a parte. E proprio da uno di questi inizieremo subito.

14.2.1. Valori minimi e massimi per validare le pressioni dei tasti.

Per come è stata predisposta, ogni procedura guidata può avere un proprio numero di pulsanti, e ad essi può essere affidato qualsiasi tipo di compito. Non tutti i pulsanti, tuttavia, possono essere validi in tutti i momenti, perché non si può, ad esempio, inserire un'ulteriore voce, se ne sono già state create il numero massimo, oppure spostarne una verso l'alto, se si è già sul primo elemento di un elenco.

Se da un lato tale versatilità è necessaria, dall'altro è altrettanto indispensabile che i controlli sui pulsanti premuti non siano legati troppo alle singole procedure. Per questo, nel caricare la configurazione dei vari tipi di procedura, si è previsto che ogni pulsante si porti appresso dei valori minimi e massimi, i quali ne stabiliscano i limiti d'utilizzo.

Tali valori, confrontati al numero della voce su cui è posizionato il cursore, determinerà di volta in volta se la pressione di un pulsante sia consentita oppure no in quel momento. Il primo elemento di codice che andremo a realizzare, dunque, si occupa proprio di questo, confrontando i valori minimi e massimi dei singoli pulsanti con quello corrente, e restituendo il risultato di tale controllo.

Esercizio 14.2.2. La funzione PulsanteValido.

FileScript. Default.JSS

Nome. PulsanteValido

Descrizione. Determina la validità del pulsante premuto, sulla base del numero totale delle voci e della posizione di quella selezionata, impostando casomai i messaggi d'errore che saranno pronunciati al ritorno nella finestra di dialogo.

Ritorni. Di tipo Int. L'esito del controllo, TRUE o FALSE.

Parametri.

1. sNome. L'etichetta del pulsante premuto. Di tipo String.

2. iTasto. Il valore del tasto suppletivo eventualmente premuto. Di tipo Int.

Novità.

1. La costante "GIU", la quale corrisponde all'omonimo termine, e che sta ad indicare lo spostamento verso il basso di una voce.

Fasi.

1. Nella struttura che compone la funzione, una serie di controlli alternativi, legati ai valori minimi e massimi consentiti per il pulsante premuto, restituisce un valore positivo qualora almeno uno di essi sia stato rilevato come vero.

2. Nel caso invece che nessun controllo sia stato ritenuto valido, un'ulteriore struttura esegue una serie di controlli, per impostare in un avviso il tipo di errore riscontrato, quindi restituisce un risultato nullo.

Note.

1. Per rendere semplice la loro impostazione, i valori minimi e massimi sono specificati solo quando abbiano un valore diverso da quelli predefiniti, che corrispondono ad 1, come minimo, e il numero totale delle voci elaborate, come massimo; qualora essi non siano stati specificati, i controlli della funzione assumono quindi i valori predefiniti.

Codice.

Int Function PulsanteValido (string sNome, int iTasto)
Var
Int iMinimo, ; valore minimo della voce selezionata
Int iMassimo; valore massimo della voce

; estrae il valore minimo per la sua visualizzazione
Let iMinimo = StringToInt (StringSegment (gsMinimi, PIPE, iTasto))
; estrae anche l'eventuale valore massimo
Let iMassimo = StringToInt (StringSegment (gsMassimi, PIPE, iTasto))
; se il minimo non è specificato, oppure se la voce corrente è maggiore o uguale a tale valore,
If (!iMinimo || gnVoce >= iMinimo)
; e ancora, se è il massimo a non essere specificato, o la voce corrente è minore o uguale a tale valore,
&& (!iMassimo || gnVoce <= iMassimo)
; se poi, il pulsante non è quello di aggiunta, oppure vi è almeno un'altra voce possibile,
&& (sNome != AGGIUNGE || gnTotali <= iMassimo)
; se, infine, non si tratta del pulsante di spostamento in basso, oppure vi è almeno un'altra voce,
&& (sNome != GIU || gnVoce < gnTotali) Then
Return TRUE; restituisce l'esito positivo del controllo
Else; altrimenti, in caso di errore,
; se si è chiesta l'aggiunta di una voce, e il numero delle voci è già al massimo consentito,
If sNome == AGGIUNGE && gnTotali > iMassimo Then
Let gsAvviso = hlpMassimoVoci; imposta un avviso, da far leggere poi
ElIf gnVoce == gnTotali Then; se ci si trova sull'ultima voce,
If gnVoce == 1 Then; se è stata immessa una sola voce,
Let gsAvviso = hlpUnicaVoce; imposta l'avviso da leggere al ritorno nella finestra di dialogo
Else; altrimenti,
Let gsAvviso = hlpUltimaVoce; imposta l'avviso relativo
EndIf; fine controllo ultima voce
ElIf gnVoce == 1 Then; se si è comunque nella prima voce,
Let gsAvviso = hlpPrimaVoce; imposta il relativo avviso
EndIf; fine controllo errori
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo validità pulsante
EndFunction

14.2.3. L'ordine delle chiavi numeriche nei record.

Nei due primi tipi di procedura, quello della ricerca di elementi e delle macro testuali, il numero prestabilito delle voci è da un minimo di 1 ad un massimo di 9. Per il numero limitato delle voci, e soprattutto a causa del valore progressivo che è utilizzato per numerarle, le chiavi dei record con i dati relativi a ciascuna voce devono essere sempre in ordine sequenziale.

In altre parole, ciò significa che la prima voce avrà sempre come chiave il numero 1, la seconda il 2, la terza il 3, e così via. Se però noi dovessimo cancellare una chiave, ad esempio la numero 2, si creerebbe una sequenza irregolare, essendo rimaste solo le chiavi 1 e 3.

Per questo, sarebbe necessario ripristinare l'ordine corretto, rinominando la chiave numero 3 nella numero 2. A tale compito, in particolare, sarà dedicata una nostra funzione, che incontreremo più avanti.

Anche con gli script a gestione personale, se noi dovessimo cancellarne uno che non fosse l'ultimo inserito, si creerebbe un buco nella sequenza corretta. In questo caso, tuttavia, le chiavi dei restanti script registrati non sarebbero rinominate, non solo perché avevamo stabilito un numero massimo ben più elevato di script, ma soprattutto perché il numero della chiave è strettamente correlato allo script reale che serve per attivarli, rendendo perciò molto complicato rinominare tutti i rimanenti script uno ad uno.

Se però noi lasciamo uno o più buchi nella sequenza corretta, quando noi inseriamo un altro script a gestione personale, dovremmo per forza utilizzare la prima chiave libera, in modo da sfruttare al massimo i numeri da 1 a 99, il valore massimo che avevamo prestabilito per questa tipologia di voci. E proprio per individuare quale sia questa prima chiave libera nella sequenza di quelle esistenti, realizzeremo il successivo elemento di codice.

Sull'argomento, va precisato che la voce aggiunta, nel caso degli Elementi di ricerca e delle Macro testuali, sarà sempre inserita sotto alla voce corrente. Ad esempio, se noi avessimo cinque voci, dalla 1 alla 5, e fossimo posizionati sulla numero 3, se premiamo il pulsante per inserirne una nuova, questa sarà immessa come nuova numero 4, facendo scalare la precedente 4 come 5, e la 5 come 6.

Se invece noi volessimo inserire una voce nella prima schermata delle elaborazioni del terzo tipo, quelle ad esempio degli script personali, il nuovo nome di script sarà in ogni caso inserito dopo l'ultimo di quelli presenti. Come detto, tuttavia, se l'elenco sequenziale dei numeri di chiave avesse dei buchi, sarebbe utilizzato il primo numero di chiave libero, altrimenti, se fossero presenti un numero di chiavi uguale al numero massimo di quelle registrate, il nuovo script avrebbe anche in questo caso l'ultima chiave esistente aumentata di un'unità.

Esercizio 14.2.4. La funzione PrimaLibera.

FileScript. Default.JSS

Nome. PrimaLibera

Descrizione. Restituisce la prima chiave libera, in forma testuale, cercando nell'elenco di quelle possibili.

Ritorni. Di tipo String. La chiave in forma testuale.

Note.

1. Nel ciclo che costituisce la funzione, il valore usato come limite è quello della costante con il numero massimo di voci.

2. Non è previsto alcun risultato nullo, anche se la funzione lo restituirebbe in caso di errore, poiché il flusso giunge alla funzione solo se esiste almeno una chiave libera tra quelle registrate.

Codice.

String Function PrimaLibera ()
Var Int i; contatore del ciclo

For i = 1 To MAX_VOCI; scorre i possibili valori
If !LeggeRecord (gsArchivio, gsSezione, IntToString (i)) Then; se il record è vuoto,
Return IntToString (i); restituisce il primo valore non utilizzato
EndIf; fine controllo record
EndFor; fine scansione valori
EndFunction

Esercizio 14.2.5. La funzione AggiornaElenco.

FileScript. Default.JSS

Nome. AggiornaElenco

Descrizione. Toglie o aggiunge una voce all'elenco dei dati registrati, aggiornando l'ordine delle altre voci eventualmente presenti.

Ritorni. Di tipo Int. True per la riuscita dell'aggiornamento, FALSE per il suo fallimento.

Parametri.

1. iValore. Il numero della voce selezionata. Di tipo Int.

2. sCorrente. Se specificato, indica di aggiungere il contenuto del record attivo, inserendolo come ultimi dati di quelli trascritti. Di tipo String. Parametro Opzionale.

Fasi.

1. All'interno di un'unica struttura di controllo, nel caso si sia lasciato vuoto il secondo parametro, e quindi che si sia cancellata una voce, si fa partire un ciclo che sovrascrive i record esistenti, partendo dalla voce successiva a quella corrente, sino all'ultima registrata.

2. Nel caso in cui invece si sia specificato il contenuto di un record come parametro, indicando con ciò di dover inserire una nuova voce tra quelle esistenti, il ciclo ne scorre l'elenco a ritroso, partendo dall'ultima registrata e tornando sino a quella corrente, il cui testo è appunto il parametro indicato.

3. Se durante la trascrizione dei record non si fossero verificati errori, i quali avrebbero quindi già causato il ritorno alla funzione chiamante con un risultato nullo, viene invece restituito un esito positivo.

Note.

1. Questa è la funzione citata nella premessa, che viene chiamata nei due casi elencati nelle fasi, la cancellazione o l'inserimento di una voce, usando la presenza o meno del secondo parametro per determinare quale tipo di riscrittura dei dati mettere in atto.

Codice.

Int Function AggiornaElenco (int iValore, string sCorrente)
Var
Int i, ; contatore del ciclo
String sDato

If !sCorrente Then; se l'ultimo parametro non è stato specificato,
For i = iValore +1 To gnTotali; scorre le voci per ridurne l'elenco
; rileva il dato relativo alla voce successiva
Let sDato = LeggeRecord (gsArchivio, gsSezione, IntToString (i))
; se il dato non viene salvato,
If !ScriveRecord (gsArchivio, gsSezione, IntToString (i - 1), sDato)
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo scrittura dato
EndFor; fine scansione voci
Else; altrimenti, se si deve aggiungere una voce all'elenco,
For i = gnTotali To iValore Descending; scorre le voci per ridurne l'elenco
If i > iValore Then; se il contatore è superiore all'ultima voce da aggiornare,
; rileva il dato relativo alla voce precedente
Let sDato = LeggeRecord (gsArchivio, gsSezione, IntToString (i - 1))
Else; altrimenti,
Let sDato = sCorrente; imposta la voce passata come parametro
EndIf; fine controllo voce da scrivere
If !ScriveRecord (gsArchivio, gsSezione, IntToString (i), sDato); se il dato non viene salvato,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo scrittura dato
EndFor; fine scansione voci
EndIf; fine controllo tipo di aggiornamento
Return TRUE; se nessun altro controllo è intervenuto, restituisce l'esito positivo
EndFunction

Collaudo.

1. In questo caso, dopo aver compilato la funzione, evidenziamo di rendere opzionale il secondo parametro.

Esercizio 14.2.6. La funzione AggiungeVoce.

FileScript. Default.JSS

Nome. AggiungeVoce

Descrizione. Inserisce una voce nelle schermate di scelta.

Ritorni. Di tipo Int. L'esito dell'inserimento, TRUE o FALSE.

Novità.

1. Le nostre funzioni "PrimaLibera ()" e "AggiornaElenco ()".

Fasi.

1. Un primo controllo serve solo ad impedire che il flusso prosegua qualora la funzione sia chiamata quando si stanno elaborando i campi dal secondo in poi; tale situazione non dovrebbe in teoria mai verificarsi, e potrebbe quindi essere causata solo da un qualche errore nella procedura.

2. Una seconda struttura imposta la chiave del record da aggiungere all'elenco, sulla base del tipo di elaborazione in atto, e casomai servendosi della nostra funzione "PrimaLibera ()".

3. Si tenta poi di inserire il testo da aggiungere; se tale aggiunta è annullata, o fallisce per qualche problema, il flusso viene interrotto restituendo un risultato nullo.

4. Se invece prosegue, si controlla dapprima se esistono ulteriori voci registrate dopo quella appena inserita; se così è, tramite la nostra funzione "AggiornaElenco ()", si fanno scalare le voci presenti, a partire da quella posta subito dopo quella corrente sino all'ultima registrata, in modo da lasciare spazio alla voce appena inserita; se tutto procede al meglio, è aggiornata la posizione della voce attiva nell'elenco, restituendo l'esito positivo, altrimenti viene restituito un risultato nullo.

Note.

1. Questa rappresenta la prima di una serie di funzioni chiamate a gestire la pressione di un tasto opzionale, che in questo caso è la prima parte del suo nome, "Aggiunge".

Codice.

Int Function AggiungeVoce ()
Var String sRecord; dati temporanei

If gnCampo > PRIMA Then; se si è dalla seconda schermata in poi,
Let gsAvviso = FormatString (msgNoCampoValido, AGGIUNGE); formatta l'avviso,
Return FALSE; e interrompe il flusso, restituendo un risultato nullo
EndIf; fine controllo numero campo
If gnTipo == TERZA Then; se si sta elaborando il terzo tipo di procedura,
Let gnValore = gnTotali + 1; pone a video la nuova voce dopo l'ultima presente
Let gsChiave = PrimaLibera (); individua la prima chiave libera tra quelle possibili
Else; altrimenti, nei primi due tipi di procedura,
Let gnValore = gnValore +1; aggiunge la nuova voce appena dopo quella corrente
Let gsChiave = ChiaveCorrente (gnValore); crea la chiave rendendo testuale la posizione
EndIf; fine controllo chiave
; rileva l'eventuale dato esistente
Let sRecord = LeggeRecord (gsArchivio, gsSezione, gsChiave)
; se non vi è stato alcun inserimento,
If !AggiornaCampo (AGGIUNGE, gsSezione, gsChiave, NULLO) Then
Let gsChiave = ChiaveCorrente (gnVoce); ripristina la chiave attiva,
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo scrittura voce
Delay (ATTESA); sospende temporaneamente il flusso
Let gnTotali = gnTotali + 1; aggiorna il contatore delle voci complessive
If gnValore < gnTotali Then; se vi sono altre voci dopo quella inserita,
If AggiornaElenco (gnValore + 1, sRecord) Then; se l'aggiornamento delle altre voci riesce,
Let gnVoce = gnValore; aggiorna il puntatore della selezione
Else; altrimenti, se l'aggiornamento fallisce,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo esito aggiornamento
Else; altrimenti, se quella inserita è l'ultima voce dell'elenco,
Let gnVoce = gnValore; aggiorna il puntatore della selezione
EndIf; fine controllo primi due tipi di procedura
Return TRUE; se nessun altro controllo è intervenuto, restituisce l'esito positivo
EndFunction

14.2.7. Estrarre un campo tramite un indice.

Poniamo di avere un record con la chiave "Tasti", il cui contenuto siano tre campi:

1. Invio.

2. FrecciaSu.

3. FrecciaGiù.

Tradotto in una sola riga di dati, il record sarebbe così composto:

Tasti=Invio|FrecciaSu|FrecciaGiù

Per estrarre il contenuto di un campo da questo record, è necessario sapere la posizione che occupa tale contenuto, e poi mettere questo valore come terzo parametro nella funzione nativa "StringSegment ()". Se noi non conoscessimo tale posizione, dovremmo però servirci dell'altra funzione nativa, "StringSegmentIndex ()", incontrata nell'ottavo capitolo, ponendo come terzo parametro, stavolta, direttamente la stringa testuale che stiamo cercando.

Nel caso in cui noi avessimo però solo il nome inglese di un tasto, come stringa da cercare, ma avessimo bisogno di ricavarne la traduzione in italiano, dovremmo costruire un record che avesse lo stesso numero di campi di quello originale in italiano, ovviamente con la versione inglese dei tasti, così come il seguente:

Keys=Enter|UpArrow|DownArrow

Questo record, gemello di quello con i tasti nella nostra lingua, prende il nome di "indice", che a noi serve, appunto, solo ad "indicarci" dove sia la posizione del tasto nel record in italiano.

Ad esempio, se noi avessimo da estrarre dal record originale il campo con la versione tradotta del nome inglese del tasto "UpArrow", cioè "FrecciaSu", dovremmo quindi prima cercarne la posizione nel record che ci fa da indice, e poi usare quel valore per estrarre la stringa da noi voluta.

Se noi ipotizziamo di memorizzare il contenuto dei due record in altrettante variabili testuali, che abbiano ciascuna il prefisso "s" prima del nome della chiave, noi dovremmo usare le seguenti due istruzioni:

Let iPosiz = StringSegmentIndex (sKeys, PIPE, "UpArrow", TRUE); rileva la posizione,
Return StringSegment (sTasti, PIPE, iPosiz); e restituisce il campo richiesto

Questo, dunque, sarà il compito del nostro prossimo elemento, con l'unica differenza di usare la nostra funzione "CampoTrovato ()", al posto della prima funzione nativa, poiché in essa avevamo appunto già usato "StringSegmentIndex ()", oltre all'impostazione di un separatore dei campi predefinito.

Esercizio 14.2.8. La funzione EstraeCampo.

FileScript. Default.JSS

Nome. EstraeCampo

Descrizione. Individua e restituisce il contenuto di un campo in un record usato come indice, per restituirne il contenuto del campo equivalente nel record d'origine.

Ritorni. Di tipo String. Il contenuto del campo individuato.

Parametri.

1. sRecord. Il record d'origine da cui estrarre il contenuto del campo individuato nell'indice. Di tipo String.

2. sCampo. La stringa di cui cercare la presenza tra i campi del record indice. Di tipo String.

3. sIndice. L'eventuale record parallelo dove effettuare la ricerca; se non specificato, viene utilizzato il record d'origine. Di tipo String. Parametro Opzionale.

4. sSeparatore. L'eventuale separatore alternativo degli elementi; se non specificato, viene utilizzato il carattere Pipe, Ascii 124. Di tipo String. Parametro Opzionale.

Note.

1. Così come anticipato nei dettagli dei parametri, qualora il record indice non sia specificato, viene usato come indice lo stesso record d'origine; in questo modo, la funzione non serve a restituire il contenuto del campo, che abbiamo già dovendolo specificare, bensì può essere usata per indicarci soltanto se il campo esista oppure no.

Codice.

String Function EstraeCampo (string sRecord, string sCampo, ; primi due parametri,
string sIndice, string sSeparatore); seconda riga con gli altri due
Var Int iPosiz; posizione del campo nel record

If !sIndice Then; se non è stato indicato un record che faccia da indice,
Let sIndice = sRecord; utilizza l'elenco originale anche per cercare direttamente il campo
EndIf; fine controllo record indice
If CampoTrovato (sIndice, sCampo, iPosiz, sSeparatore) Then; se un campo è stato trovato,
Return StringSegment (sRecord, sSeparatore, iPosiz); lo prende casomai dal record originale
Else; altrimenti,
Return NULLO; restituisce una stringa vuota
EndIf; fine controllo campo
EndFunction

Collaudo.

1. Anche in questo caso, dopo la compilazione, segnaliamo la necessità di rendere opzionali gli ultimi due parametri.

Esercizio 14.2.9. La funzione ScambiaVoci.

FileScript. Default.JSS

Nome. ScambiaVoci

Descrizione. Registra la voce corrente, scambiandone la posizione nell'elenco con quella precedente o successiva.

Ritorni. Di tipo Int. True per uno scambio riuscito, FALSE per il fallimento.

Parametri.

1. sCorrente. Il contenuto della voce selezionata. Di tipo String.

2. sVerso. Se si specifica la costante GIU, la voce sarà scambiata con quella successiva; se invece si indica qualsiasi altro dato testuale, la voce selezionata sarà scambiata con quella che la precede nell'elenco. Di tipo String.

***

Per ulteriori spiegazioni, scrivere a:
Abramo Volpato, oppure, a: Nunziante Esposito



Torna alla pagina iniziale della consultazione delle riviste

Oppure effettua una ricerca per:


Scelta Rapida