Conviene usare il termine "tabella" sempre e solo per indicare tabelle di database e con "DataTable" al sua "rappresentazione" in forma di oggetto presente nel linguaggio, così non si crea confusione tra le due cose.
La mia griglia si popola dei dati che ho memorizzato senza problemi.
Riesci quindi (in apertura del Form) a vedere quanto
al momento è contenuto nella tabella Storico.
La mia idea è che il PLC vada visto come sorgente dati del database e inserisce record nella tabella Storico, ma non li aggiorna (nel senso di operazioni "Update" di SQL), è corretto?
Quando apro la form dove visualizzo la datagridview verifico ed aggiungo nella tabella i nuovi record che leggo dal PLC. Però questi record si aggiornano nel PLC mentre questo sta lavorando. Il mio problema è che, una volta che ho salvato la riga nella tabella, non riesco ad aggiornala con i nuovi dati letti dal PLC. O meglio, usando le righe di codice postate, non ottengo il risultato richiesto.
In base alla mia affermazione precedente, qui non ho proprio capito cosa fa (o dovrebbe fare) il GridView (con annessi TableAdapter, BindingSource e DataSet) e cosa fa il PLC sul database.
Non ho idea di cosa sia il PLC ma per me potrebbe essere ad esempio un barcode reader che scrive le sue letture sul database. Va bene come supposizione?
La parte di codice che hai marcato con "Per aggiungere le nuove righe" è inserita in una apposita funzione, immagino.
E (se è corretto quanto detto) questa funzione termina con
History.Tables("Storico").Rows.Add(newrow)
e ti aspetti che tale riga sia
salvata sul database History?
La parte marcata con "Per pulire le tabelle" che termina con
Storico_BS.ResetBindings(True)
dovrebbe eliminare tutti i record dalla tabella "Storico"?
Ti rimando alla definizione ufficiale dei
DataSet tipizzati e
qui per tutto il resto e link agli esempi, sottolinenado questo:
È quindi possibile accedere mediante il nome alle tabelle e alle colonne, invece di utilizzare metodi basati sulle raccolte.
Come effetto più evidente avrai Storico.MiaColonna (che è un tipo ben preciso, stringa, intero, decimal...)
invece del generico Storico.Colums["nome colonna"] che contiene un Object.
Questo (lasciamo stare le performance) ti permette di scrivere codice più leggibile e più facilmente e evita dei possibili errori. Cosa succede se metti un intero in una colonna che accetta un altro tipo?
Il codice compila ma nel caso migliore va in errore durante l'esecuzione perché il comando SQL risultante scatena un errore, ma potrebbe riuscire a inserire le mele al posto delle pere senza che tu te ne accorga. E cosa succede se cambi il nome della colonna o la elimini?
Per questo è brutto vedere
DataRow newRow = ...
newRow("[nome colonna]") = [mio oggetto di QUALSIASI tipo]
invece di
tableAdapter.Insert( [elenco di parametri AGGIORNATO e di di tipo ESATTO]) e il corrispondente .Update(...)
Per ogni DataTable tipizzato esiste il DataRow tipizzato (tu avrai
StoricoRow) che è certamente migliore di un DataRow generico, ma in questo momento non riesco a mostrarti un esempio.
Forse è una precisazione inutile, perdonami se ripeto cose che già conosci, ma voglio rimarcare quanto segue.
Un DataSet è una rappresentazione completamente slegata dalla base dati.
Le operazioni che compi sui DataTable esistono solo in memoria.
Ogni DataRow ha delle proprietà che ne indicano lo stato, ovvero se sono rimaste invariate o se sono "dirty" (insert, update, delete) rispetto al database.
Il comando AcceptChanges() del DataTable (semplificando) scatena la creazione dei comandi SQL da usare e li esegue (tutti quelli necessari, in base allo "stato" di ogni DataRow).
Ho aggiunto un bottone alla mia toolbar ed alla pressione inserisco un record nella tabella ottenendo anche l'aggiornamento istantaneo della visualizzazione in griglia. Il metodo
Reload l'ho postato precedentemente e i dati sono ovviamente statici e non letti da controlli (o presi dalla griglia). Scusa se è C# ma è certamente leggibile, altrimenti chiedi (Monei è il mio DB, Entry è la mia versione del tuo "Storico").
private void toolStripButton2_Click(object sender, EventArgs e)
{
CreateEntry();
Reload();
}
private void CreateEntry()
{
MoneiDataSetTableAdapters.EntryTableAdapter tableDataAdapter = new MoneiDataSetTableAdapters.EntryTableAdapter();
tableDataAdapter.Insert(null, 123.45m, DateTime.Now, DateTime.Now, DateTime.Today, 2, null, "test - " + Guid.NewGuid().ToString());
moneiDataSet.Entry.AcceptChanges();
}
ciao