Ma qui comincio ad avere confusione: ho visto che c'è una proprietà che si chiama .Tables che mi restituisce l'elenco dei file (tabelle in linguaggio SQL)) contenuto nel Data Base... ma io voglio accedere a un solo file? Perché non trovo la proprietà per leggere quei dati?
Ho capito che devo lanciare un comando tipo "Select campo1, campo2, campo3 from tabella-che-mi-interessa" e che questo mi genera un flusso di record (da 0 a infiniti... )... ma non ho capito "come" leggere i dati reperiti e questo perché mi sfugge la logica che sta dietro a oggetti di tipo "result".
facciamo un esempio:
abbiamo un bd con una tabella clienti con i campi : nome indirizzo telefono
dobbiano cercare il nome relativo ad un dato telefono
dim numero as integer
dim hdata as result
dim $hconn as connection
dim sql as string
....conessione al db (questa la sai già)
sql="SELECT * from clienti where telefono=" & numero
hdata=$hconn.exec(sql)
' a questo punto nel result hdata abbiamo tutti i campi contenenti il numero 'cercato inquesto caso probabilmente uno solo
'vogliamo quindi visualizzare in nome del cliente in una textbox e l' indirizzo 'in un altra possiamo fare:
if hdata.available then
hdata.movefirst
textbox1.text=hdata!nome
textbox2.text=hdata!indirizzo
end if
$hconn.close
' se invece vogliamo avere tutti i nomi che iniziano per "m" e visualizzarli in una listbox facciamo:
dim sNomecliente as string
dim hdata as result
dim $hconn as connection
dim sql as string
sNomecliente="m"
sql="SELECT * from clienti where nome like'" & sNomecliente & "%'"
hdata=$hconn.exec(sql)
' a questo punto poniamo i risultati in una listbox
for each hdata
listbox1.add(hdata!nome)
next
$hconn.close
è più o meno chiaro?
Provo a fare un altro parallelo, così vediamo se ho capito :-)
Nella programmazione SQL esiste un costrutto chiamato cursore, che viene usato per contenere il risultato di un'operazione SQL.
Se prendiamo come esempio la base dati suggerita da fsurfing, potremmo avere un comando come questo
declare hData cursor for select SELECT * from clienti where telefono = :numero
dopodiché si lancia un semplice
A questo punto si possono usare comandi come FETCH per leggere (un record per volta) i risultati dentro hData.
Ci ho preso, vero? :-)
Per contribuire a quello che ha scritto fsurfing, la lettura dei singoli campi può essere effettuata anche così:
if hdata.available then
hdata.movefirst
'textbox1.text=hdata!nome
'textbox2.text=hdata!indirizzo
textbox1.text=hdata["nome"]
textbox2.text=hdata["indirizzo"]
end if
ovvero, si fà riferimento al nome della chiave dell'array (o Collection, se vogliamo precisare...).
il funzionamento di questi componenti è di una semplicità estrema
ma effettivamente il loro utilizzo non è spiegato molto bene dal manuale
il datasource si connette automaticamente alla connessione del db bisogna solo passargli il nome della tabella del db
ovvero se effettuiamo una connessione al nostro db con il metodo classico
sName = "nome_del_db"
WITH $hConn1
.Type = "sqlite3"
.Host = User.Home
.Login = ""
.Password = ""
END WITH
$hConn1.Name = sName
$hConn1.Open
WAIT
DataSource1.Table = "nome_della_tavola"
a questo punto il nostro datasourse e già funzionante
per far funzionare dataview e databrowser basterà fornire loro l' elenco dei nomi delle colonne da visualizzare
DataView1.Columns = ["nome_colonna1", "nome_colonna2", "nome_colonna3"]
volendo si possono definire le dimensioni delle colonne e il titolo con
WITH DataView1.GridView
.Columns[0].Text = "titolo_colonna1"
.Columns[0].Width = 100
.Columns[1].Text = "titolo_colonna2"
.Columns[1].Width = 100
.Columns[2].Text = "titolo_colonna3"
.Columns[2].Width = 100
END WITH
dovrebbe essere tutto
comunque ti posto un programmino di prova che ho realizzato tempo fa per provare questi componenti
Uh, in effetti è molto semplice :-)
IL file che hai postato l'ho visto in un'altra discussione e l'ho già letto, anche se ci ho capito (per ora) poco; in ogni caso grazie per avermelo segnalato, sicuramente quando ne capirò di più sarà molto meglio :-)
Adesso ho modificato il programma che sto facendo secondo le indicazioni, ma mi sa che c'è ancora qualcosa che non va, perché quando lo lancio mi dice "no current connection". Ho provato a metterlo in debug una riga per volta, e me le esegue tutte, fino a quando non deve riemettere il video dove si trova la DataView che ho inglobato nel DataSource...
provo a mettere il codice che sto usando, vediamo se qualche esperto riesce a vedere l'errore :-)
PUBLIC SUB btClienti_Click()
DIM dbInterventi AS NEW Connection
DIM pos AS Integer
DIM hDati AS Result
DIM sql AS String
DIM file AS String = "Clienti"
'Collegamento al Data Base
dbInterventi.Close()
WITH dbInterventi
.type = "mysql"
.host = "localhost"
.User = "root"
.Name = "Interventi"
END WITH
TRY dbInterventi.OPEN()
IF ERROR THEN Message.Error("Impossibile aprire la base dati")
IF ERROR THEN ME.Close
'Controllo che ci sia la tabella clienti
IF NOT dbInterventi.Tables.Exist(file) THEN Message.Error("Il file " & file & " non esiste...")
'Carico i dati nel risultato
sql = "Select Codice, RagioneSociale from Clienti"
hDati = dbInterventi.exec(sql)
'Carico i dati nel Data Source
dsDati.Table = file
'Carico i dati nel DataBrowser
dbDati.Columns = ["Codice", "RagioneSociale"]
WITH dbDati.GridView
.Columns[0].text = "Cliente"
.Columns[0].Width = 20
.Columns[1].text = "Ragione Sociale"
.Columns[1].Width = 100
END WITH
dbDati.Show
END
Non sono sicurissimo sul .Show finale, non credo serva effettivamente... ma l'errore me lo da comunque :-)
Bene, andando avanti con la gestione del mio progetto, ho finalmente capito (parola grossa) come aggiornare i dati del mio data base. Devo dire che è addirittura più versatile dell'RPG, ma anche in questo caso la logica è (molto vagamente) simile.
In ogni caso mi sono scontrato con un problema che sinceramente non capisco: nel video ci sono due spinbox per la gestione del campo Tariffa e Pagamento.
I valori riesco a scriverli correttamente nel file, ma poi non riesco a riportarli dentro le spinbox quando rileggo i dati.
Ho visto che la proprietà .text della spinbox è di sola lettura, e quindi lavoro su "value".
Nel file ho dei dati nulli, quindi ho fatto un piccolo controllo come questo:
SELECT CASE Val(hData!Tariffa)
CASE NULL
Tariffa.Value = Tariffa.MinValue
CASE ELSE
Tariffa.Value = Val(hData!Tariffa)
END SELECT
A me pare giusto, ma pare che il controllo non funzioni mai, perché nella spinbox trovo sempre il valore minimo (25 euro, economico, no?)
Dove cavolo sto sbagliando? :-)
Già che ci siamo vi faccio un'altra domanda: nella form i campi hanno lo stesso nome dei campi del file, per semplicità.
Ho capito come leggere l'elenco dei campi con un campo di tipo ResultFIelds (o quello che è), ma mi sono scontrato con un problemino.
Il mio obiettivo era di fare un loop per mettere ogni campo in quello che si chiama allo stesso modo nel form, una cosa del tipo
FOR EACH campo IN rDati.Fields
Campo.text = rDati!Campo
NEXT
Ma quando lo eseguo mi dice, ovviamente, che il campo CAMPO non ha una proprietà TEXT... anzi, non esiste proprio!
QUindi il problema è la possibilità di usare un CAMPO il cui nome sia contenuto in un altro CAMPO... sempre che si possa fare, ovviamente :-)
Ovviamente viceversa per quando scrivo sul file...
Il comando
non brilla di chiarezza direi.
Io preferisco di gran lunga assegnare i nomi delle textbox ad esempio, anteponendo sempre la natura dell'oggetto, così una textbox contenente il nominativo diverrà "tb_nominativo", così almeno non faccio confusione.
Ecco un esempio di assegnazione alle textbox sul form dei valori dei campi di un record:
WITH connessione
.Name = Avvio.nomeDB
.Type = "sqlite3"
.Open
.Begin
criterio = "id=&1"
parametro = avvio.posizione
Risultato = .Edit("agenti", criterio, parametro) '
Tb_Id.Text = risultato!id
tb_nick.text = risultato!nick
Tb_nominativo.Text = risultato!nominativo
Tb_cellulare.Text = risultato!cellulare
Tb_passw.Text = risultato!passw
.Commit
END WITH
Uff... niente da fare, non riesco a impostare il valore della spinbox con il campo contenuto del database: continua a dirmi che il valore atteso è "integer"ma che riceve "null"
Ho provato a controllare il null, ma in questo caso si limita a eseguire sempre quel ramo del codice.
Provo a farvi vedere cosa ho scritto:
sql = "Select * from Clienti where Codice = " & Right(tvMenu.Current.Key, 6)
hData = db.Exec(sql)
Codice.Text = hData!Codice
RagioneSociale.Text = hData!RagioneSociale
Indirizzo.Text = hData!Indirizzo
Localita.Text = hData!Localita
CAP.text = hData!CAP
Provincia.text = hData!Provincia
CodiceFiscale.text = hData!CodiceFiscale
PartitaIva.text = hData!PartitaIva
sb_Tariffa.Value = Val(hData!Tariffa)
sb_Pagamento.Value = Val(hData!Pagamento)
Quello che non capisco è perché il secondo campo, che è anche una spinbox, non mi dà errore...
Nel database mysql, i due campi sono configurati come decimali e "not null", quindi quel "null" proprio non lo capisco...
Uhm, dopo qualche simpatica bestemmia (tanto ormai il posto in paradiso me lo sono giocato...) sono venuto a capo di qualche cosa.
Innanzi tutto, la gerarchia datasource > databrowser si imposta con il "disegno" dell'interfaccia, e questo è abbastanza facile.
Una volta aperta la connessione con conn.open, è sufficiente indicare al datasource il nome della tabella (presente nel data base appena aperto) alla quale si desidera fare riferimento, con il comando
datasource.table = "Interventi"
A questo punto, indicando nel Databrowser le colonne da visualizzare (non ho capito come fare per vedere tutte le colonne, ma ci arrivo prima o poi), queste si vedono automagicamente :-)
databrowser.columns = ["DataIntervento", "Progetto", "TempoImpiegato"]
Bene, a questo punto funziona abbastanza bene e velocemente.
Ho anche cominciato a capire come funzionano i campi "datacontrol", e mi sembrano furbi e comodi.
Ma ho un altro problemino: il campo "progetto" vorrei inserirlo in una combobox, e ho visto che ne esiste un tipo proprio fatta per questo caso, che si chiama "datacombo".
Ma come faccio a metterci dentro l'elenco dei dati validi? Ho provato con la codifica normale, ma non funzia...
Un altro campo è di tipo checkbox (si/no, o booleano).
Come faccio a metterlo in un datacontrol?
Altra cosetta, piccola: se il file è vuoto, è normale che il programma vada in errore?
Quante domande, eh?
Però come vedete riesco anche ad arrangiarmi :-)