Italian Ci riprovo...

Luigi S

Member
Licensed User
Maremma... chi me l'ha fatto fare! Che poi... mi appassiono!
C'è un po' troppo da lavorare.
Ad esempio, il DB è sbagliato. Hai dei campi primari univoci Integer con autoincremento (giusto) ma poi nelle tabelle collegate hai questi campi dichiarati come TEXT

Tabella Componenti:
"ID" INTEGER PRIMARY KEY AUTOINCREMENT e va benissimo

Tabella Aeromodelli:
"IDcomponenti" TEXT questa è la chiave esterna, collegata alla tabella Componenti; anche questa, quindi, dev'essere INTEGER


Poi... chiamare l'Activity Input_Aeromodello per Update o Save??? Mah!
Ecco lo sapevo, prima mi hai fatto i complimenti e mo te stai a rimagnà tutto.... 😄

In realtà inizialmente molti campi li avevo fatti INTEGER, poi siccome so niubbo e non so bene come sia meglio per fare quello che ho in mente, alla prima occasione in cui ho aggiunto/modificato un po di nomi campi, l'ho cambiati pensando che in ogni caso un INTEGER lo scrivo in un TEXT e non il contrario...

Mentre l'activity l'avrei dovuta chiamare Save_Update_Delete_Aeromodello ma mi sembrava lungo.... però pensandoci la potevo chiamare SUDAeromodello 😄
 

LucaMs

Expert
Licensed User
Mentre l'activity l'avrei dovuta chiamare Save_Update_Delete_Aeromodello ma mi sembrava lungo.... però pensandoci la potevo chiamare SUDAeromodello
Non mi riferivo al nome (anche se sono convinto che usare dei prefissi che indichino il tipo di oggetto sia sempre un'ottima scelta e le Activity le chiamo actAeromodello... ehm, non è che tutte le mie Activity si chiamino proprio così 😂) ma al fatto che la chiami per un Save o per un Update. Non mi è chiarissimo; potrei capire che venga chiamata solo per la visualizzazione, nel qual caso disabiliterei tutte le EditText, o per Update o Insert (nuovo record).
 

LucaMs

Expert
Licensed User
Ecco lo sapevo, prima mi hai fatto i complimenti e mo te stai a rimagnà tutto....
Nell'immagine del primo post non ci sono i tipi di dato usati nel DB e poi nel progetto.
In generale, per essere un neofita, vedere che hai preparato un modello di DB e tabelle, mi sembrava già un buona cosa e lo penso ancora.
 

Luigi S

Member
Licensed User
Ti devo ringraziare per quello che hai fatto per me, veramente tanto, con dei commenti solutivi di gran qualità, a prova di niubbo.
Ho provveduto a sistemare quasi tutto di quel poco rimasto che non hai fatto tu, seguendo i tuoi insegnamenti.
Ma ti devi esser fatto prendere dalla mano, (o dalla scopa 😄 ) nel ripulire e ottimizzare il codice, che hai dimenticato il problema dell'update!
Cerca LG965 (è il mio nick un po ovunque tranne qui) e trovi i miei commenti.
Grazie ancora!
PS ho visto che sei di Roma, io sto a Latina....
 

Attachments

LucaMs

Expert
Licensed User
Ti devo ringraziare per quello che hai fatto per me, veramente tanto, con dei commenti solutivi di gran qualità, a prova di niubbo.
Infatti, se c'è voluta oltre un'ora uno dei motivi è che ho preferito scrivere molti commenti, anche più generali, che aiutassero; commenti spesso non brevi.
Pare che se vuoi aiutare qualcuno che ha fame, non dovresti dargli del pesce ma insegnargli a pescare ;)

Ma ti devi esser fatto prendere dalla mano, (o dalla scopa 😄 ) nel ripulire e ottimizzare il codice, che hai dimenticato il problema dell'update!
Dimentico molte cose, per via dell'età ma soprattutto... per un dono della natura 😄:confused:, ma questo non l'ho certo dimenticato. Il fatto è che erano talmente tante le cosa che avrei voluto cambiare (se non fossi tanto modesto e gentile, direi: "che vanno cambiate") che dopo tanto "lavoro" (GdF: gratuito, eh 😄) non ho proseguito. Inoltre, non mi era chiaro il modo in cui tu volessi usare la Activity di "input", - ecco, la sto facendo troppo lunga anche qui...

PS ho visto che sei di Roma, io sto a Latina....
Pensa che qui mi è capitato di conoscere un altro membro che... abitava a 1 o forse 1,5 km da me, prima di trasferirsi a... 5 o 6 km da me 😄

Cerca LG965 (è il mio nick un po ovunque tranne qui) e trovi i miei commenti.
Ok, so già che me ne pentirò (perché la tentazione di lavorarci parecchio mi verrà sicuramente) ma gli dò un'occhiata lo stesso.
 

LucaMs

Expert
Licensed User
Allora... c'ho sgobbato fino ad adesso...

Ho cambiato moltissimo - avevo commentato con un prefisso <LM2> ma, avendo poi rivoluzionato tutto, ho rimosso molti di questi commenti e non ne ho aggiunti altri, sorry.

Talmente "stanco" che... non ho nemmeno provato a lanciarlo!

Ti servirà da "studio".

Nota importante: anziché lanciare l'update di un record in base al Nome del modello di aereo, dovresti usare l'ID della tabella Aeromodelli (stessa cosa per ogni tabella).
Purtroppo hai usato quella inutilissima cosa che è la ListView, anziché una CustomListView! e quindi il valore che ti viene restituito al click è il testo della label, ovvero il nome del modello.

Ho già rivoluzionato (e lavorato) anche troppo, per cui non me la sento di fare anche questa modifica. C'ho lavorato talmente tanto, che... mi converrebbe completarla io e vendertela!!!

Quindi:

1 - non lamentarti se ha dei bug (visto che non l'ho nemmeno lanciata); eventualmente esegui il progetto in modalità Debug, metti un breakpoint da qualche parte ed esegui il progetto una linea alla volta, premendo F8;

2 - dopo aver corretto eventuali bug, studia il sorgente e completalo (ti basterà usare parecchio il copia e incolla ;))

3 - e questo è rivolto a chiunque legga: FATEMI SANTO 😇, anche se ancora sono (quasi) vivo 😂
 

Attachments

Last edited:

LucaMs

Expert
Licensed User
Uhm... credo di averci lavorato circa 3 ore. Ai bei tempi, questo ti sarebbe costato tra i 40€ ed i 60€ L'ORA; non so nemmeno se IVA compresa o no, in quanto... non li incassavo io ma l'azienda per la quale lavoravo 😄:(:(:(

(ah, più mi sembra 40€ per il solo "diritto di chiamata").
 

LucaMs

Expert
Licensed User
Eh, c'è anche una cosa molto importante da fare...

I campi di tipo Data-ora. Vorrai visualizzali in un formato "umano", leggibile, ma nel DB andranno salvati come Long.
Per fare questo, dovrai usare dei "date picker" o "time picker", ovvero delle view da prelevare dal sito, al posto o in aggiunta alla EditText relativa.
 

Luigi S

Member
Licensed User
Accidenti... ora che lo so non devo postarti nulla dopo le 20.00, altrimenti non ti ci faccio dormire la notte! Questa è vera passione!
Non credo che serva dire altro...
Io stamattina sono andato al campo volo a fare un paio di voletti con uno dei miei modelli e non pensavo che al ritorno avrei trovato tutto questo...
Ora vado che c'ho da studiare... :)
 

Luigi S

Member
Licensed User
ti aggiorno sui miei progressi
'Activity.Finish 'LG965 ho decommentato questa riga altrimenti non ricarica il DB e non si vede l'Aeromodello appena inserito, hai soluzioni migliori? Perchè ho visto che li hai commentati tutti.
'<LM2> Il motivo per cui "non ricarica il db" non è dovuto a questo.
' Vedremo più avanti. Activity.Finish nella Main non andrebbe usato.
Già... è bastato questo
Sub Activity_Resume
ShowDBTable 'display the database in the LIstView
End Sub
E' corretto?

Poi ho sistemato il btnSave in alto a destra aggiungendo un paio di msgbox di conferme, finora nessun bug.

Ora devo fare il Delete e i date/time piker.
 

Luigi S

Member
Licensed User
Aggiornamento..
pensavo di riuscirci e invece...
Ho scritto questo in modDB_PrjUtils
B4X:
Public Sub AeromodelliDelete(Nome As String)   'LG965 start

    Query = "DELETE FROM Aeromodelli WHERE Nome = ?"
    Log (Nome)
    Starter.DB.ExecQuery2(Query, Array As String(Nome))
    Log ("sono qui")
    Log (Nome)
    
End Sub                                                            'LG965 end
e questo in Main

B4X:
Sub lvAeroMod_ItemLongClick (Position As Int, Value As Object)
    Msgbox2Async("Eliminare?", "", "SI", "", "No", Null, False)
    Wait For Msgbox_Result (Result As Int)
    If Result = DialogResponse.POSITIVE Then
        '...
    
    modDB_PrjUtils.AeromodelliDelete(Value)
    
    End If
End Sub
i log sono corretti, ma non cancella nulla che manca?
 

LucaMs

Expert
Licensed User
Nota che ci sono ancora dei problemini, dato che hai usato una, direi obsoleta, intuile e pure antipatica 😁, ListView.

Se elimini un record che sia in relazione con altri di un'altra (o più altre) tabella, potresti avere la necessità di eliminare anche i record di questa.

Ad esempio...

Hai la tabella Aeromodelli e la tabella Voli. In questa seconda, per ogni volo hai vari dati (Data ed ora di Partenza - che hai chiamato ad cazzum DataOra 😁, DurataVolo (sarebbe stato meglio Arrivo e poi, se serve, fai il calcolo dei minuti, come differenza), Esito (e questo dovrebbe essere legato ad un'altra tabella con i tipi di esiti possibili, compreso "Precipitato" 😆😈).

Se elimini un Aeromodello, devi eliminare tutti i voli associati a quell'Aeremodello (certo, se si volessero conservare i vecchi voli, dovresti impedire l'eliminazione di quel modello, al limite dovresti aggiungere un campo nella tabella Aeromodelli che indichi se sia ancora in vita o no). Ma la tabella Voli non ha certo il nome del modello, ha l'ID del modello, come chiave esterna.

Quindi, quando l'utente fa un lungo click sull'elenco dei modelli, si dovrebbe ottenere l'ID del modello, non il suo nome, ed usare questo sia per visualizzarne i dettagli nella actAeromodello - singolo click, sia per andare ad eliminare il modello e le relazioni (record con la chiave esterna uguale a quell'ID) nelle altre tabelle, come la tabella Voli (ma non solo questa).

Come "scappatoia", devi aggiungere una funzione nella modDB_PrjUtils che, dal nome del modello, restituisca il suo ID (beh, puoi anche usare la AeromodelliGetByNome, che però ti restituisce un oggetto di tipo tAeromodello e in questo anche il suo ID) e poi andare ad eliminare nella tabella Voli tutti i record in cui la chiave esterna IDaeromodelliVoli (nome più corretto sarebbe stato IDAeromodelli - le tabelle hanno come identificativo il solo "ID", come identificativi di tabelle correlate IDNomeTabellaCorrelata).

Ripeto, nel caso specifico non eliminerei né il modello né le tabelle associate, visto che possono essere dati utili in futuro, anche se quel modello di aereo non esiste più, quindi meglio aggiungere un campo che indichi se il modello esista ancora (o usare il campo Stato - e pure qui... dovresti avere una tabella Stati associata).
 
Last edited:

Luigi S

Member
Licensed User
E si il discorso non fa una piega... mi hai convinto, è bene tenere in lista i modelli che furono... e userò lo stato per scriverci "precipitato"
E come giocare a scacchi devi prevedere tutte le mosse possibili... il problema e che io ne riesco a prevedere un paio... 😄
Ok ti prometto che la prossima activity uso clv, ma basta attivare la libreria xCustomListView o devo scaricare qualcosa (forse me l'hai gia detto...) e magari poi la metto pure in Main
Infine ho trovato un bug... posso inserire due modelli con lo stesso nome, sto provando a far qualcosa per evitarlo.
 

LucaMs

Expert
Licensed User
.. il problema e che io ne riesco a prevedere un paio...
Il problema è che tutti noi abbiamo la voglia di vedere il nostro sw funzionante al più presto e che sia perfetto, mentre dovremmo pensarci bene prima.

Ok ti prometto che la prossima activity uso clv, ma basta attivare la libreria xCustomListView o devo scaricare qualcosa (forse me l'hai gia detto...)
La libreria è già preinstallata (con l'installazione di B4A), non ti serve altro, solo selezionarla (= importarla)
 

fishwolf

Well-Known Member
Licensed User
Io me sa che non ci vedo più...
dove stà secondo voi l'errore di sintassi ?
B4X:
Connection.mySQL.ExecNonQuery("INSERT INTO Aeromodelli VALUES ('" & NomeAeroModID & "','" & edtDataInsMod.Text & "','" & edtDescrizione.Text &"'))
manca la doppia apice alla fine
B4X:
Connection.mySQL.ExecNonQuery("INSERT INTO Aeromodelli VALUES ('" & NomeAeroModID & "','" & edtDataInsMod.Text & "','" & edtDescrizione.Text & "')")
metterei comunque la query in una stringa, in questa maniera puoi fare il log della stringa per un debug della stessa
 
Last edited:

LucaMs

Expert
Licensed User
metterei comunque la query in una stringa, in questa maniera puoi fare il log della stringa per un debug della stessa
Infatti, nel progetto gli ho messo un modulo per la gestione del DB, con una variabile Query globale (a livello di modulo, non di "processo" - che poi sarebbe di progetto) e in ogni metodo viene impostata quella ed eseguita.
 
Top