Italian Operazioni con SQLite

Schakalaka

Active Member
Licensed User
Longtime User
Ciao a tutti.
sto iniziando a sviluppare un' app per la gestione di magazzino con queste funzionalità:

- Conta dei prodotti tramite barcode
- Aggiornamento della quantità a ogni scansione
- Aggiornare la quantità con un valore scelto
- Aggiungere un nuovo prodotto da activity differente
- Estrarre il database in formato csv
- Convertire il db in json e caricarlo in un db mysql

ho creato un db con una tabella "products" con le colonne "id", "nome", "EAN", "qta"

Ho integrato con successo lo scanner bar code (https://www.b4x.com/android/forum/t...-100-embedded-in-b4a.63794/page-5#post-841800)
m aho difficoltà ad inteagire con sqlite:


A seguito della scansione, cerco il codice ean nel database:


B4X:
Sub searchcode 'ceraca nel database il codice EAN scannerizzato
    Private Query As String
    If sql1.ExecQuerySingleResult2("SELECT count(EAN) FROM products WHERE EAN = ?", Array As String(Label1.Text)) = 0 Then
        Log($"Codice non trovato: ${Label1.Text}."$)
        Label2.Text = $"Codice non trovato: ${Label1.Text}."$
    Else
        Log("Prodotto trovato")
        
    End If

End Sub

Come seconda cosa, vorrei estrarre dal db il corrispettivo "nome" del prodotto e "quantità"

con il codice attuale, alla scansione, non riesco ad estrarre il nome relativo al EAN, ma quello dell' ultimo record

B4X:
Private ResultSet1 As ResultSet
    
ResultSet1 = sql1.ExecQuery("SELECT * FROM products")

    
'We read only the rowid column and put them in the IDList
RowIDList.Initialize                                'initialize the ID list
Do While ResultSet1.NextRow
    'RowIDList.Add(ResultSet1.GetInt2(0))        'add the rowid's to the RowID list
    RowIDList.Add(ResultSet1.GetString2(0))
    
Loop
If RowIDList.Size > 0 Then
    CurrentIndex = 0                            'set the current index to 0
Else
    CurrentIndex = -1                            'set the current index to -1, no selected item
    ToastMessageShow("No items found", False)
End If

    
    Log(ResultSet1.GetColumnName(1))
    Log(ResultSet1.GetString("name"))
    Label2.Text = ResultSet1.GetString("name")
    Label3.Text = ResultSet1.GetString("qta")
    Dim val As Int = ResultSet1.GetString("qta")

    ResultSet1.Close
    
    ResultSet1 = sql1.ExecQuery("SELECT * FROM products")
    
    val = val + 1
    Private Query As String
    
    Query = "UPDATE products Set qta = ? WHERE id = " & CurrentIndex
    sql1.ExecNonQuery2(Query, Array As String(val))
    ToastMessageShow("Entry updated", False)
    
    Label3.Text = val


Allego il progetto
Grazie per il supporto
 

Attachments

  • BarcodeScanner.zip
    13.3 KB · Views: 239

LucaMs

Expert
Licensed User
Longtime User
sto iniziando a sviluppare un' app per la gestione di magazzino
Aggiungere un nuovo prodotto da activity differente
Primo "errore": dato che stai iniziando un nuovo progetto e non modificandone uno vecchio B4A, molto meglio farlo con le B4XPages!

Secondo e terzo "errore":
B4X:
    If sql1.ExecQuerySingleResult2("SELECT count(EAN) FROM products WHERE EAN = ?", Array As String(Label1.Text)) = 0 Then
        Log($"Codice non trovato: ${Label1.Text}."$)
        Label2.Text = $"Codice non trovato: ${Label1.Text}."$
    Else
usare le proprietà della View (Label1.Text) anziché nomi di variabili e dare nomi senza significato alle View (spero non anche alle variabili).

con il codice attuale, alla scansione, non riesco ad estrarre il nome relativo al EAN, ma quello dell' ultimo record
perché con questo sorgente:
B4X:
Private ResultSet1 As ResultSet

ResultSet1 = sql1.ExecQuery("SELECT * FROM products")


'We read only the rowid column and put them in the IDList
RowIDList.Initialize                                'initialize the ID list
Do While ResultSet1.NextRow
    'RowIDList.Add(ResultSet1.GetInt2(0))        'add the rowid's to the RowID list
    RowIDList.Add(ResultSet1.GetString2(0))

Loop
leggi tutta la tabella, non hai messo nella query che deve prelevare solo il record in cui ci sia l'EAN voluto, ovvero non hai aggiunto la clausola WHERE di SQL:
B4X:
ResultSet1 = sql1.ExecQuery2("SELECT * FROM products WHERE EAN = ?", Array As String(EANCercato))
In questo modo ottieni già l'elenco dei soli record che ti interessano (dovrebbe essere uno solo, no?), senza riempire una List di rowid (da non usare mai - o tranne in rari casi particolari).

Non ho scaricato il progetto, almeno per il momento.

Ripeto i suggerimenti principali:
  1. crea un progetto B4XPages
  2. dai alle View dei nomi che abbiano significato, non generici come Label1, EditText1, etc. In questo modo capirai molto meglio il sorgente al primo sguardo.
  3. non usare le View come dati [ SELECT count(EAN) FROM products WHERE EAN = ?", Array As String(Label1.Text)) ], usa sempre delle variabili (al posto di Label1.Text una variabile EANCercato, ad esempio).
--------------------------------------------------------------------------

P.S. NOTE SUCCESSIVE ALLO SCARICAMENTO DEL TUO PROGETTO.

Per provarlo dovrei trovare quella libreria dal nome un po' ridicolo ?, zbarbarcodescanner, che non so dove sia; perché non usare il barcode reader di Erel che "è un B4X" e quindi funzionerebbe anche con B4i-iOS (motivo in più per creare il progetto come B4XPages, ma non il solo e principale)? Ok, probabilmente non farai anche la versione per iOS ma, a parte il fatto che non si sa mai, in futuro, i vantaggi delle B4XPages sono anche tanti altri.

Vedo che il nome che hai dato al database SQLite è mySQL; è del tutto lecito ma essendo anche il nome di un DBMS, MySql appunto, gliene darei uno diverso.

Tornando a rowid ed al fatto che vuoi...
- Convertire il db in json e caricarlo in un db mysql
nota che in MySql non esiste quel campo speciale rowid, che è specifico di SQLite.

("Convertire... e caricarlo..." - sarebbe meglio aggiornare direttamente online i dati del server remoto MySql e, se non possibile, aggiornare i soli record modificati/aggiunti, non tutto il DB).

Ti suggerirei di fare la tabella "products" in questo modo:
B4X:
CREATE TABLE [Product](
  [EAN] TEXT PRIMARY KEY NOT NULL UNIQUE,
  [Name] TEXT,
  [Qta] INTEGER DEFAULT 0);
ovvero:
  1. dargli nome al singolare, "Product" e non "products" - mia mania ma soprattutto pratica consigliata.
  2. usare il campo EAN come chiave primaria della tabella (eliminando, quindi, il campo "id")
  3. dare zero come valore di default del campo Qta (in questo modo eviti i problemi di valori Null e conseguenti errori)

B4X:
GetSafeDirDefaultExternal
Molto meglio usare la File.DirInternal (se intendi creare solo il progetto B4A, altrimenti e meglio ancora, B4XPages e xui.DefaultFolder)
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Al collezionista potrebbe interessare.???

Da aggiustare un po' - verifica che il prodotto sia stato effettivamente trovato nel DB, ad esempio, prima di passarlo alla pagina prodotto.
Ripeto, era giusto una provoletta al volo, tanto per usare B4XPages e il barcode reader di Erel.

(Nome eccessivamente roboante, direi ?)
 

Attachments

  • Magazzino.zip
    88.6 KB · Views: 251

Schakalaka

Active Member
Licensed User
Longtime User
Ciao!
grazie dei consigli "strutturali" e dell' esempio in B4xpages.
sicuramente utile ed istruttivo.
 
Top