OODML & Schede

Creare una semplice scheda con Visual dBASE 7
Ultima Modifica: 7 Ottobre 1999
Ken Mayer, Senior SQA Engineer
dBASE, Inc.

Scopo di questo documento   

Questo documento è destinato ad aiutare gli sviluppatori sia principianti sia esperti, che iniziano a lavorare con Visual dBASE 7 (e versioni successive), affinché, comprendano le basi su come una scheda interagisce con il DML (Data Manipulation Language) Orientato agli Oggetti di Visual dBASE 7. Per raggiungere l'obiettivo che si prefigge questo documento, aiuteremo lo studente, a creare una scheda basata su una delle tabelle di esempio, incluse con l'ambiente di sviluppo di Visual dBASE7. La scheda sarà via via provata, così, lo studente potrà vedere le varie fasi di sviluppo...

Questo documento non affronterà le problematiche legate alle Schede Custom, Controlli Custom ecc. Esistono altri documenti HOW TO che trattano l'argomento, c'è anche un tutorial...

Letture Suggerite  

Prima di Iniziare 

Essendoci la possibilità che i files di esempio inclusi con Visual dBASE 7, con il passare del tempo potrebbero cambiare, questo progetto non è basato su una particolare tabella. Quindi, se la tabella che utilizzeremo per la suddetta scheda non è più disponibile, per raggiungere gli scopi che si prefigge questo documento, è possibile usarne un'altra qualsiasi.  Questo documento non è tabella dipendente... 

Prima di fare qualsiasi cosa, carica Visual dBASE 7.x. Dovresti vedere la finestra del "Centro di Controllo". A questo punto, abbiamo bisogno di spostarci su una cartella di lavoro. Per questo progetto utilizzeremo come directory di lavoro la cartella SAMPLES che viene creata quando installiamo Visual dBASE.

 
Il Centro di Controllo in Visual dBASE 7.x

Per fare questo,clicca sul pulsante, vicino al combox "Cerca In" . Apparirà la finestra di dialogo "Scegli directory" che ti permetterà di lavorare sulla struttura delle cartelle/directory del tuo disco rigido (o dischi rigidi). Trova la cartella "Visual dBASE", e sotto essa (doppio clic ), dovresti vedere la cartella "SAMPLES". Doppio clic su quest'ultima ed infine clicca sul pulsante "OK" .  


La finestra "Scegli Directory"

Vedrai nel centro di controllo diversi files, ignorali non li useremo.  


Creare la Scheda

Per creare una nuova scheda, usando il "Centro di Controllo" clicca sul separatore "Schede". Vedrai due icone "Senza nome", clicca sulla seguente:    
Dovresti vedere apparire una nuova scheda simile a quella mostrata nell'immagine seguente: 


Una Scheda Vuota 


Con la scheda vuota, vedrai anche alcune "tavolozze",... le useremo tra un attimo. Adesso abbiamo bisogno di inserire un riferimento alla tabella. 

Inserire un oggetto Query nella scheda 

Il riferimento alla tabella è un oggetto query. Questo oggetto apparirà come un'icona con le lettere "SQL" ( ) . Per inserire l'oggetto query nella scheda, vai sul "Centro di Controllo" e seleziona il separatore "Tabelle". Vedrai l'elenco delle tabelle che sono memorizzate nella directory SAMPLES. Come detto prima, non importa quale tabella useremo. Questo documento pensato per Visual dBASE 7.01 utilizzerà la tabella fish in quanto essa è inclusa con Visual dBASE. Se non esiste nella directory SAMPLES, usa qualsiasi altra tabella... 

Clicca sulla tabella che desideri usare, e tieni il pulsante del mouse premuto e trascina l'icona della tabella sulla superficie di lavoro della scheda. Questa azione è chiamata "Drag and Drop."  

Ora, esamina che cosa è successo... hai messo un'icona nella scheda (vedi figura sotto): 


 
Una Scheda Vuota con un Oggetto Query

In più, la proprietà "rowset" della scheda è impostata automaticamente. E' molto importante notare, come questa proprietà sia molto usata, infatti  essa si riferisce all'oggetto rowset.  

Cerca la proprietà rowset della scheda utilizzando il modulo "Ispezione".  

Nella proprietà rowset della scheda, dovresti vedere qualche cosa come: form.fish1.rowset (invece di "fish1" potrebbe esserci un altro nome, in quanto dipende dalla tabella che hai trascinato sulla superficie della scheda).  

A questo punto, potrebbe sembrare di non aver fatto molto, ma, invece, hai davvero finito una parte del lavoro... ora  la scheda ha una tabella principale  con cui lavorare... 

Inserire alcuni Campi nella Scheda 

Stiamo per usare la "Tavolozza Campi" dalla quale trascineremo i campi della tabella alla scheda.  

La "Tavolozza Campi" contiene l'elenco dei campi della  tabella, e per impostazione predefinita visualizza le icone di ciascun campo, le icone mostrano a sua volta il "tipo" di controllo (oggetto) che sarà messo sulla scheda (l'entryfields,combobox, ecc.).

Per i nostri scopi, trascina alcuni campi, non importa quali, sulla superficie della scheda. Assicurati di inserire almeno uno o due entryfields, ci serviranno più avanti quando proveremo la scheda.  


Scheda con i controlli trascinati dalla Tavolozza Campi
 

L'immagine mostrata come esempio usa tutti i campi della tabella "Fish". Nota che i colori, sono impostati  automaticamente, perché la tabella, quando fu creata dal "Borland Samples Group", aveva definito delle proprietà custom, includendo anche le impostazioni della proprietà "colorNormal". 

Una proprietà importante usata per tutti gli oggetti "datalinked" (controlli che sono collegati ai dati nel rowset) è la proprietà "dataLink". Per vederla, clicca su uno degli oggetti entryfield, e tramite il modulo Ispezione clicca sulla proprietà "DataLink" . Vedrai qualcosa di simile: 

form.fish1.rowset.fields ["Name"]

Ciò è stato ottenuto, quando hai trascinato l'oggetto dalla "Tavolozza Campi" alla superficie della scheda. Lo stesso si può ottenere anche manualmente, trascinando un entryfield dalla "Tavolozza Componenti", e successivamente impostare la proprietà "datalink" tramite il modulo Ispezione. 

Interagire con i dati  

Adesso che abbiamo realizzato tutto questo, come interagiamo con i dati? 

Bene, se mandi semplicemente  in esecuzione la scheda, hai già la possibilità di utilizzarla, e potresti considerare l'interazione con i dati cosa fatta... 
Puoi vederlo mandando in esecuzione la scheda, tramite un clic sul pulsante che si trova nella barra degli  strumenti. Prima di poter mandare in esecuzione la scheda, la prima volta dovrai assegnarle un nome. Nella finestra di dialogo che apparirà digita "Tutorial" e clicca il pulsante "Salva". La scheda ora sarà lanciata. 

Con la scheda in esecuzione, puoi osservare che cambia la barra strumenti (toolbar) in cima allo schermo, e vedrai i pulsanti di navigazione... puoi anche mettere il cursore in un entryfield e modificare i dati. Ci sono gli altri pulsanti nella toolbar che cambieranno se cambi i dati, c'è un pulsante "Aggiungi" per aggiungere una riga (record) alla tabella, e così via.  

Comunque, quello che vogliamo realizzare è essere capaci di fare questo genere di cose da noi. In una applicazione reale puoi volere che l'utente non veda l'ambiente di sviluppo così...  

... torna indietro in "modalità sviluppo", clicca sul pulsante    

Mettere dei Pulsanti sulla Scheda  

Perché i pulsanti? Perché essi  sono il metodo standard  per navigare in una tabella!

Creeremo una serie di pulsanti, i quali avranno associato del codice all'evento onClick. 

Questi pulsanti, potrebbero essere dal punto di vista "visuale", ben progettati. In questo caso li distingueremo l'uno dall'altro, con del semplice testo. Se vuoi fare di più pensaci... ma, per i nostri scopi,  concentreremo l'attenzione su come questi oggetti comunicano col rowset... non ci stiamo preoccupando del lato estetico... 

Pulsanti di Navigazione 

Cominceremo con i pulsanti di navigazione. Che cosa sono i pulsanti di navigazione standard? 

Bene, sicuramente avrai la necessità di poter "scorrere" una tabella riga dopo riga, così hai bisogno dei pulsanti "Successivo" e "Precedente". Vorrai probabilmente poter andare all'inizio e alla fine della tabella (prima riga/ultima riga). Quindi in tutto ci servono quattro pulsanti.

Cominceremo con il pulsante "Primo". Nell'esempio, li metterò, in basso a destra della scheda... ...ovviamente puoi inserirli dove meglio credi... 

In modalità sviluppo dovresti vedere sullo schermo la "Tavolozza Componenti", altrimenti, per visualizzarla clicca sul tasto destro e selezionala dal menu che apparirà. 

Il pulsante "Primo" 

Sulla pagina "Standard" della Tavolozza Componenti, vedrai diversi controlli. Ci serve un "pushbutton". Clicca sull'oggetto pushbutton e trascinalo sulla superficie della scheda. 


Pagina standard della Tavolozza Componenti

Il testo visualizzato sul  pulsante, assume per impostazione predefinita il nome dell'oggetto, nel nostro caso sarà  "Pushbutton1".  Modifichiamolo. 

Così, con il pulsante selezionato vai nel modulo Ispezione e cerca la proprietà "name". Tale proprietà  sarà sotto la categoria "Identificazione". Clicca sulla proprietà, e sul lato destro , digita "PUSHTOP" e premi il tasto <Invio>.  

Successivamente, trova la proprietà "text" la quale sarà sotto la categoria "Varie". Clicca su "text" e immetti "Primo" ed infine premi <Invio>.  


modifica delle proprietà del pulsante inserito nella scheda

Dovresti vedere che il testo sul pulsante  adesso mostra "Primo".

Adesso, a questo punto, quando in fase di esecuzione l'utente clicca sui pulsanti, non accadrà  nulla.

Evidentemente dobbiamo aggiungere del codice al pulsante. Il codice per questo pulsante sarà abbastanza semplice... ma la domanda è: dove assegniamo il codice?  

Guarda nel modulo Ispezione ed individua il separatore "Eventi",  cliccaci su, e vedrai apparire una lista di "Eventi".  

Clicca sull'evento "onClick". il quale visualizza "Null",  dovresti vedere anche due piccoli pulsanti:

 Clicca sul pulsante   e vedrai una piccola finestra che accede all'editor di sorgenti con su scritto:  

   function PUSHTOP_onClick
      
          return

Qualsiasi codice, che vuoi sia eseguito quando l'utente preme il pulsante, deve essere compreso tra   l'istruzione "function"  e l'istruzione "return".  

Il codice di cui abbiamo bisogno è piuttosto semplice, servirà per  "andare"  alla prima riga del rowset.  Questo, si ottiene eseguendo un metodo del rowset, chiamato "first()". Digita il seguente codice: 

      form.rowset.first()

L'istruzione precedente, verifica se alla proprietà della scheda  "rowset", sia stato  assegnato  qualcosa. Se a questa proprietà, nessun rowset è stato assegnato, questo codice non funzionerà. Presumendo che un rowset sia stato assegnato, esegue poi il metodo first() (le parentesi sono necessarie per eseguire il codice).  

Tutto qui. Così nella finestra "editor di sorgenti"  dovresti vedere: 

   function PUSHTOP_onClick
        form.rowset.first()
      return

Per provare questo pulsante, abbiamo bisogno di mandare in esecuzione la scheda. Così, clicca sul pulsante   Con la scheda in esecuzione, abbiamo bisogno di spostarci su un'altra riga, (cominciamo per default dalla prima). Usa i pulsanti di navigazione, nella barra strumenti in alto sullo schermo, per spostarci di un paio di record nel rowset  (usa il pulsante successivo). Ora, per spostarci sulla prima riga, invece di  usare il pulsante nella barra degli strumenti, usa il pulsante che abbiamo appena creato sulla nostra scheda, e dovresti trovarti nella prima riga della tabella.

Ora che abbiamo creato un pulsante, per inserire gli altri le cose dovrebbero essere più semplificate ...

Il pulsante "Successivo"

 Per aggiungere il pulsante "Successivo" fai i seguenti passi: 

Ora siamo alla parte più interessante. Il codice può essere molto semplice, e noi faremo prima la versione "semplice"...  

Immetti il codice:  

        form.rowset.next()

Nell'editor di sorgenti  il codice immesso dovrebbe essere simile al seguente: 

   function PUSHSUCC_onClick
      form.rowset.next()
      return

Come fatto prima, proviamo questo pulsante... manda in esecuzione la scheda. Usa il pulsante "Successivo" per spostarci sulla prossima riga. Continua fino a quando non raggiungi la fine della tabella, quando arrivi alla fine... otterrai un una riga vuota!!.  

Ora, che cosa è successo? 

Il "cursore" dei dati sta puntando alla "fine del rowset", e tutti i campi sulla scheda non visualizzano niente. Sicuramente non vuoi che i tuoi utenti si trovino in questa situazione... essi potrebbero pensare che questa è una riga valida, e tenterebbero di immettere dei dati... ciò deve essere impedito!  

Così, come possiamo risolvere questo problema?  

Evidentemente abbiamo bisogno di modificare del codice. Torna in modalità sviluppo (usa il pulsante ).  

Il metodo next() dell'oggetto rowset, restituisce un valore logico (vero o falso ). Se next() ha successo, il valore restituito sarà "vero", viceversa sarà "falso".  

Quello che vogliamo fare, é navigare sui dati usando il metodo next() del rowset, e se tale metodo restituirà "falso", vorrà dire che siamo alla "fine del rowset", così, abbiamo bisogno di tornare indietro di una riga ( ciò si ottiene usando il metodo next(), con un parametro opzionale che si riferisce al numero di righe da navigare, in questo caso useremo " -1". Il segno negativo vuol dire spostarsi indietro nella tabella). Visualizzeremo poi un messaggio all'utente che lo informa che non può proseguire nella navigazione sui dati. Il codice è davvero abbastanza semplice:  

   if ( not form.rowset.next() )
         form.rowset.next( -1 )
         msgbox( "Fine del rowset", "Impossibile Proseguire", 64 )
      endif

Adesso modifichiamo il codice: seleziona il pulsante PushSucc, nel modulo Ispezione seleziona il separatore  "Eventi", e clicca sull'evento "onClick", e poi il pulsante   Modifica il codice nell'editor di sorgenti: 

   function PUSHSUCC_onClick
         if ( not form.rowset.next() )
            form.rowset.next( -1 )
            msgbox( "Fine del rowset", "Impossibile Proseguire", 64 )
         endif
      return

Per dettagli sull'uso della funzione msgbox() vedi nella guida in linea.  

Adesso proviamo quanto fatto, manda di nuovo in esecuzione la scheda e prova navigare fino all'ultima riga, dovresti ottenere il messaggio di errore che abbiamo creato e non vedremo la fine del rowset...  

Il Pulsante "Precedente" 

Per aggiungere il pulsante "Precedente" fai i seguenti passi: 

Inserisci il codice seguente:  

   function PUSHPREV_onClick
      if ( not form.rowset.next(-1) )
         form.rowset.next()
         msgbox( "Inizio del rowset", "Impossibile Proseguire", 64 )
      endif
    return

Nota che questo codice, è quasi simile a quello usato per il pulsante "Successivo"... l'istruzione "If" controlla se possiamo navigare "indietro"  nella tabella, e così via...  

Prova quello che hai fatto mandando in esecuzione la scheda...  

Il Pulsante "Ultimo"   

Per aggiungere il pulsante "Ultimo" fai i seguenti passi:  

Immetti codice come il seguente:  

   function PUSHBOTT_onClick
      form.rowset.last()
     return

Una volta ancora, puoi provare quanto fatto mandando in esecuzione la scheda... 

La tua scheda adesso, dovrebbe essere simile a quella mostrata sotto: 


Scheda con i pulsanti di Navigazione

 Pulsanti di Editing  

Adesso che possiamo navigare nella tabella, abbiamo la necessità di avere dei pulsanti che ci permettano di modificare, aggiungere, cancellare le righe, e, salvare o abbandonare le modifiche. Suona come un ordine dall'alto? Bene, non proprio..., ma c'è una serie di nuove cose da imparare...  

Bisogna tenere presente che per default, il rowset di una scheda è in modalità "edit". Ciò significa che quando un utente clicca su un campo e digita qualcosa, sta in effetti modificando i dati. Questo, altresì significa, che un utente potrebbe modificare accidentalmente qualcosa, senza effettivamente volerlo.  

La situazione si complica, se l'utente chiude la scheda o clicca su un pulsante di navigazione, le modifiche effettuate alla riga, saranno salvate automaticamente...

...Così, cosa possiamo fare?  

Esiste una proprietà dell'oggetto rowset chiamata autoEdit, essa per default assume il valore vero. Significa che la riga è automaticamente in modalità modifica. Se vuoi impedire che l'utente modifichi automaticamente la riga, la soluzione è semplice: devi impostare questa proprietà a falso.  

Per cambiare questa proprietà abbiamo bisogno di selezionare, l'oggetto query... così, clicca sull'oggetto query ,  attiva il modulo Ispezione e seleziona la proprietà "rowset" (la quale visualizza "Oggetto"), e poi clicca sul pulsante . Dovresti vedere la proprietà autoEdit (sotto la categoria "Varie"), e dovrebbe mostrare il valore "vero". Doppio clic, per modificarla in "falso."  

Per vedere se funziona, manda in esecuzione la scheda. Clicca su un entryfields, e tenta di digitare qualcosa... nota che non puoi, perché la proprietà autoEdit adesso è impostata a falso. 

Il Pulsante "Aggiungi Riga" 

Per aggiungere il pulsante "Aggiungi Riga", fai i seguenti passi:  

Immetti codice come il seguente: 

   function PUSHADDRIGA_onClick
      form.rowset.beginAppend()
   return

Osserva, che quando l'utente cliccherà su questo pulsante, la scheda verrà "pulita". Tutti gli oggetti che sono collegati ai dati ("datalinked"), saranno improvvisamente vuoti, così che l'utente potrà aggiungere i dati in una nuova riga. 

Quello che tu (o l'utente) hai fatto a questo punto, è creare una riga vuota. Comunque non è effettivamente vero, finché l'utente non salva la riga. In altre parole, fino a quando le modifiche non saranno salvate, la nuova riga si trova in quello che è chiamato "buffer".  L'utente può salvare la riga usando il pulsante "salva" (quello che chiama il metodo save() del rowset), o navigando nel rowset (usando i pulsanti di navigazione)... in entrambi i modi, la riga sarà salvata. 

Un altro effetto dell'utilizzo del pulsante "Aggiungi Riga", è la modifica di una proprietà del rowset chiamata "state". Più avanti daremo un'occhiata a questa proprietà. 

Il Pulsante "Modifica Riga" 

Per aggiungere il pulsante "Modifica Riga", fai i seguenti passi:  

    function PUSHEDITRIGA_onClick
      form.rowset.beginEdit()
    return

Il metodo beginEdit() del rowset, permette all'utente di modificare il contenuto di una riga. L'utente   non agisce direttamente sulla riga, ma, su una sua copia. Appena la riga sarà salvata, la copia di essa che si trova nel buffer sostituirà la riga corrente. Questo è importante, perché esiste  il metodo abandon() (che vedremo presto) che permette all'utente di abbandonare le modifiche effettuate nella riga.  

Come con il pulsante "Aggiungi Riga", cliccando su questo pulsante (in esecuzione) impostiamo il rowset in uno speciale "stato". In più, se l'utente modifica la riga,  impostiamo un'altra proprietà del rowset chiamata "modified" al valore "vero" (per default essa è impostata a falso). Questa proprietà può essere piuttosto utile, ne parleremo più avanti...  

Il Pulsante  "Cancella Riga" 

Per aggiungere il pulsante "Cancella Riga" fai i seguenti passi: 

Immetti il codice seguente: 

Il problema cancellando una riga in una tabella in Visual dBASE 7, usando l'OODML (come stiamo facendo qui) è che la riga non è facilmente recuperabile. Quindi, in questi casi, è utile chiedere all'utente tramite una finestra di dialogo, se realmente vogliono cancellare la riga.  Se l'utente clicca sul pulsante "Sì" la riga verrà cancellata. 

   function PUSHCANCRIGA_onClick
      if msgbox( "Vuoi Cancellare questa Riga?", "Cancella Riga?", 36 ) == 6
         form.rowset.delete()
      endif
    return

Il Pulsante "Salva Riga" 

Per aggiungere il pulsante "Salva Riga" fai i seguenti passi:  

Immetti il codice seguente: 

   function SAVEROWBUTTON_onClick
      form.rowset.save()
     return

Il pulsante "Abbandona le Modifiche"  

Per aggiungere il pulsante  "Abbandona Modifiche" fai i seguenti passi: 

Quando si abbandonano le modifiche, potresti volerlo chiedere prima all'utente... come fatto prima tramite una finestra di dialogo, anche perché il pulsante  potrebbe essere stato premuto accidentalmente... 

Immetti il codice seguente: 

   function PUSHLASCIAMODIFICHE_onClick
      if msgbox( "Abbandona le modifiche su questa riga?", "Abbandona Modifiche?", 36 ) == 6
         form.rowset.abandon()
      endif
     return

A questo punto, la tua scheda dovrebbe essere simile alla seguente:  


Scheda con i Pulsanti di Edit 

Le proprietà "State" e "Modified" del Rowset

La proprietà modified, è usata quando una riga è impostata in modalità edit (modifica), per determinare se il buffer della riga è stato modificato. Puoi controllare facilmente il valore di questa proprietà semplicemente usando: 

    if form.rowset.modified
       // fai qualcosa  
       endif

Ciò risulta piuttosto utile, in quelle situazioni dove hai bisogno di controllare, il valore di questa proprietà. Per esempio:

Per controllare questo tipo di situazione, puoi aggiungere del codice ai tuoi pulsanti di navigazione ( qui non lo faremo, ma è una buona idea...) 

In più, potresti avere bisogno di impostare questa proprietà associata al codice della tua scheda, e ciò puoi farlo semplicemente assegnando un valore: 

   form.rowset.modified := true // oppure falso se ha necessità che sia falso 

La proprietà "state", è una di quelle che viene cambiata continuamente, è basata sullo stato attuale del rowset. Ci sono sei diversi possibili stati: closed, browse, edit, append, filter e locate. Per default, il  rowset è in modalità browse, ma, se l'utente modifica i dati, la modalità del rowset si trova in edit, se si  aggiunge una nuova riga, la modalità sarà append e così via. "Closed" significa che l'oggetto query ha la proprietà active impostata a falso. 

Le diverse modalità che può assumere la proprietà "state", sono determinate da numeri, da 0 fino al 5.  

0 Closed
1 Browse
2 Edit
3 Append
4 Filter
5 Locate

Stabilire in che "stato" si trova il rowset quando la scheda è in esecuzione presenta alcune difficoltà.  Potresti aggiungere un oggetto testo alla scheda che mostra il valore di questo "stato", o potresti usare un campo calcolato che aggiorna un entryfield anch'esso per mostrare il valore di "stato" del rowset. Il vantaggio usando un campo calcolato è l'aggiornamento automatico, mentre un campo testo avrebbe bisogno di essere aggiornato con del codice appropriato. Il codice seguente è una versione semplificata, di quanto suddetto, basato su un lavoro di Gary White : 

Adesso, prova a mandare in esecuzione la scheda... clicca sul pulsante "Aggiungi Riga", e la parola "View" dovrebbe cambiare in "Append". Click sul pulsante "Abbandona" (seleziona "Sì"). Clicca sul pulsante "Modifica Riga" , nota che i controllo rowstate visualizza "Edit"...   Clicca di nuovo sul pulsante "Abbandona" (e seleziona nuovamente "Sì" ...). 

Filter by Form (Filtro tramite Scheda)

È possibile permettere all'utente di "filtrare" i dati in base ad un criterio. Un metodo utile a tal scopo è usare la tecnica "filtro tramite scheda". Possiamo realizzarlo mettendo un pulsante su una scheda, e usando il metodo beginFilter del rowset. Tale metodo "pulirà" i controlli datalinked sulla scheda, permettendo all'utente di specificare su quali dati deve essere basata la condizione di filtro. Per esempio, potrebbero digitare uno specifico nome che loro vogliono esaminare nel campo nome (se ne esiste uno). Una volta che la condizione di filtro è immessa, poi l'utente avrebbe bisogno di applicarla e potrebbe essere fatto con lo stesso pulsante, o con un altro... questi pulsanti "direbbero" a dBASE di trovare tutte le righe che soddisfano la condizione(i) specificata e visualizzarle sulla scheda. L'utente potrebbe muoversi attraverso la tabella con le condizioni di filtro applicate. 

Infine , dovresti avere un metodo per rilasciare la condizione di filtro... 

Il Pulsante Filtro 

Per aggiungere il pulsante filtro fai i seguenti passi: 

   function FILTERBUTTON_onClick
      do case
         // siamo in modalità  "beginFilter":
         case this.text == "Filter"
              // cambia il testo
              this.text := "Filtro in Esecuzione"
              // salva l'attuale bookMark così possiamo ritornare  
              // su di esso:
              form.bookMark = form.rowset.bookMark()
              // imposta la scheda in modalità  "filtro" 
              form.rowset.beginFilter()
            
         // siamo in modalità "Run" (applyFilter() )
         case this.text == "Run Filter"
              // i controlli collegati con dataLink non vengono aggiornati 
              form.rowset.notifyControls := false
              // applica il filtro  -- se non troviamo un abbinamento  
              // rilasceremo la condizione di filtro...
              try 
                 if not form.rowset.applyFilter()  // se non trova una corrispondenza
                    // imposta il testo del pulsante in "Filter"
                    this.text := "Filter"
                    // cancella le condizioni di filtro
                    form.rowset.clearFilter()
                    try
                       //tenta di andare indietro al  'bookMark'
                       // se non ci riesce andiamo alla prima riga 
                       // della tabella
                       form.rowset.goto( form.bookMark )
                    catch ( exception e )
                       form.rowset.first()
                    endtry
                    // Informa l'utente che nessun abbinamento è stato trovato 
                    msgbox( "Nessuna riga soddisfa la condizione di filtro", "Errore Condizione Filtro", 48 )
                 else
                    // altrimenti il filtro è applicato, 
                    // ed in questo caso il testo sul pulsante dovrà indicare
                    //  "Clear Filter" ...
                    this.text := "Clear Filter"
                 endif
              catch ( dbexception e )
                 msgbox( "Condizione di filtro non applicabile ai campo memo", "Errore Condizione Filtro", 48 )
                 form.rowset.goto( form.bookmark )
                 this.text := "Filter" 
              endtry

          
              form.rowset.notifyControls := true  //Specifica se i controlli collegati con dataLink vengono aggiornati
// man mano che cambiano i valori del campo o si sposta il cursore di riga. form.rowset.refreshControls() // Effettua l'aggiornamento di tutti i controlli collegati con dataLink alla riga attiva // cancella il filtro case this.text == "Clear Filter" // reset text this.text := "Filter" // cancella le condizioni di filtro... form.rowset.clearFilter() endcase return

Prima di provare quanto su descritto, abbiamo bisogno di fare un'altra cosa, e cioè impostare la proprietà "filterOptions" del rowset per permettere una maggiore flessibilità:

Se non fai questo, per default per il filtro sarà impostato a " 0 - Lunghezza e M/m esatte" , così il filtro non può trovare facilmente un abbinamento. 

Adesso, vai in esecuzione... prova ad attivare una condizione di filtro esistente, una non esistente ecc... funziona bene ed è abbastanza elegante. Nota che il controllo "Rowstate" è aggiornato automaticamente... 

Altri metodi di Filtraggio Dati

Ci sono problemi con la modalità "Filter-by-Form", essi dipendono dal fatto che le condizioni di filtro presumono "uguaglianza". Non puoi specificare condizioni come "minore di" e così via, e  non puoi usare le operazioni logiche "And", oppure "OR" . Per questo avresti bisogno di creare una scheda più complessa... 

Locate by Form ( trova tramite Scheda)

La capacità di trovare una riga in una tabella tramite la scheda è simile al modo di lavoro utilizzato con filter-by-form, anche se leggermente diverso. Il filtro limita la visualizzazione alle righe che soddisfano la condizione immessa.. Locate trova la prima riga che risponde alla "condizione" immessa, ma nessun filtro è applicato ai dati...  

Il pulsante Locate 

Per aggiungere il pulsante "Locate" abbiamo bisogno di seguire i seguenti passi: 

        // here's where all the work starts:
        do case
           // Siamo adesso in modalità "locate by form" :
           case this.text == "Locate"
                this.text := "Run Locate"
                form.bookmark = form.rowset.bookmark()
                form.rowset.beginLocate()

           // Siamo in modalità "Run"  ...
           case this.text == "Run Locate"
                // se l'utente è in modalità 'run' ma non ha
                // modificato nulla sulla scheda
                if not form.rowset.modified
                   this.text := "Locate"
                   form.rowset.abandon()
                   return
                endif

                // problema facendo un locate su 
                // campi memo:
                try // primo  'try'
                    // qui si effettua la ricerca:
                   form.rowset.notifyControls := false
                   if not form.rowset.applyLocate()
                      this.text := "Locate"
                      try // secondo /innestato try
                         form.rowset.goto( form.bookMark )
                      catch ( exception e )
                         form.rowset.first()
                      endtry
                      msgbox( "Nessuna riga soddisfa la condizione", "Errore Locate", 48 )
                   else
                      // Abbiamo trovato un abbinamento ...
                      //  visualizziamo se vogliamo continuare la ricerca
                      this.text := "Continua Locate"
                      // salva questo bookmark ...
                      form.bookmark = form.rowset.bookmark()
                   endif
                catch ( exception e )
                   msgbox( "Non posso effettuare la ricerca in un campo memo", "Error Locate", 48 )
                   form.rowset.goto( form.bookmark )
                   this.text := "Locate"
                endtry // end of catch for memo

                form.rowset.notifyControls := true
                form.rowset.refreshControls()

           // continuiamo la ricerca
           case this.text == "Continue Locate"
                // guarda per il successivo abbinamento:
                if not form.rowset.locateNext()
                   form.rowset.goto( form.bookmark )
                   msgbox( "No ci sono altre righe che soddisfano la condizione", "Error Locate", 48 )
                   this.text := "Locate"
                else
                   form.bookmark = form.rowset.bookmark()
                endif
        endcase

Similmente a quello che abbiamo fatto per il filtro, la proprietà locateOptions del rowset, determina come vengono confrontati i valori per quanto riguarda la posizione. E, come fatto per la proprietà  "filterOptions", imposta la proprietà  locateOptions  a "3 - Lunghezza parziale e ignora M/m". Questo risolverà e renderà possibile trovare la maggior parte di abbinamenti. 

L'opzione locate è piuttosto utile, ma ha delle limitazioni simili a quanto detto per i filtri. Quindi, se devi fare qualcosa di più complesso come sempre devi scrivere il codice ad hoc... 

Un Pulsante in più per Chiudere la Scheda

C'è solo un altro pulsante di cui abbiamo bisogno, é il pulsante "chiudi". Non è veramente necessario, ma può essere utile... l'utente può chiudere una scheda dal pulsante "X"  sulla barra del titolo della scheda.  

Il Pulsante Chiudi 

Per aggiungere il pulsante chiudi fai i seguenti passi: 

   function CLOSEBUTTON_onClick
      form.close()
      return

Sommario

Bene, dopo tutto questo, si spera che tu abbia una migliore padronanza nell'interazione tra i dati e la scheda. Tieni presente che molte cose sono state solo accennate. Non abbiamo parlato dell'uso dell'oggetto "grid" o di metodi più complessi per il filtraggio o la ricerca dei dati ed altro ancora. Come detto  all'inizio di questo documento, ci sono altri documenti  "How To" ed un "Tutorial" per approfondire questi argomenti... 
In aggiunta ai documenti "How To" nello stesso sito dove hai scaricato questo documento puoi scaricare la biblioteca dUFLP (dBASE Users' Function Library Project)  


Rinuncia: mentre l'autore è un impiegato di dBASE, Inc., i contenuti di questo documento non delineano nessuna politica della compagnia. Se  hai domande riguardo a questo documento,  o su Visual dBASE puoi comunicare direttamente con l'autore e i dBVIPS nel newsgroups adatto su internet. 
I files .HOW sono creati come un libero servizio  dai membri di dBVIPS e dagli impiegati di dBASE, Inc. per aiutare gli utenti ad imparare ad usare più efficacemente Visual dBASE. Tali documenti sono redatti dai membri del dBVIPS e dBASE, Inc. Supporto Tecnico (per assicurare qualità). Questo files non può essere esposto altrove senza il permesso esplicito dell'autore che trattiene tutti i diritti sul documento. 

Tutela in base ai diritti d'autore 1999, Mayer di J. di Kenneth. Tutti i diritti riservati. 

Informazioni su dBASE, Inc. può essere trovato a: 

http://www.dbase.com/

N.d.T. (nota del traduttore): Il traduttore ha ottenuto dall'autore, l'autorizzazione alla pubblicazione delle traduzioni in italiano di tutti i suoi documenti. (A.C.)

                                                

 

Traduzione in italiano di Antonio Campagna - Gennaio 2001