z DataSetu do mdb   zodpovězená otázka

VB.NET, ADO.NET, Databáze, .NET

Dobrý den,

poradil by prosím někdo s tím jak na to? Chtěl bych dostat data uložená v DataSetu do souboru mdb?

V dataSetu mám DataTable, kam se přes vstupní textBoxy vkládají do řádků za běhu hodnoty.

Jak ale tyto hodnoty co nejjednodušeji odsud dostat do mdb?

Za jakoukoliv radu děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,

napadají mne v podstatě dva způsoby.

První by spočíval v tom, že byste si předem vytvořil novou databázi v programu MSACCESS se stejně nadefinovanou strukturou tabulky jakou máte v DataSetu. Pak by nebyl problém přes OLEDB provider v ADO.NET provádět aktualizaci MDB souboru.

Druhou možností je využití ADOX. Sám s ním nemám žádné zkušenosti, ale přes něj by mělo být možné zakládat databáze v ACCESSU a vytvářet nové tabulky.

Více si o této problematice můžete přečíst např. zde: http://www.codeguru.com/cpp/data/mfc_dat...

Po vytvoření požadované databáze a tabulky bych pak aktualizaci prováděl pomocí ADO.NET jako v případě první možnosti.

Zasvěcenější Vám ale možná poradí lepší a schůdnější způsob, jak tento problém vyřešit.

Hodně zdaru.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky za Vaši reakci.

Snažil jsem se jít přesně tou první cestou co píšete...

Vše v poho, jen však do momentu, kdy chci data uložit do mdb. (aktualizovat) Procházel jsem několik vzorových příkladů a snažil načerpat info tam ale i přesto to pořád nefunguje.

Prostě něco dělám špatně ale co je horší, že už nevím kde chybu dál hledat. Zřejmě mám nějak pokřivený pohled na celkový process jak by to mělo být správně podle struktury objektů ADO.NET aby to celé spolu mohlo fungovat :-(

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkuste prosím zveřejnit tu část kódu, která se stará o aktualizaci MDB souboru a chybu, kterou Vám to vypisuje. Možná bychom mohli zjistit, kde je problém.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak to by jste mi opravdu hodně pomohl!

Kód je tady: není to nic světoborného, jen bych potřeboval aby to umělo načíst data, přidat, smazat a uložit. Něco ale dělám blbě, a fakt nevím co...

Předem díky za kritiku a jakékoliv info.

Imports System.Data.OleDb

Public Class Form1

    Private da As OleDbDataAdapter
    Private dtKolo As DataTable = New DataTable("Kolo")     'tabulka s daty v paměti
    Private dsHealth As DataSet = New DataSet("Health")     'hlavní DataSet pro uložení tabulek       

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'nastavit připojení k databázi a SQL příkaz
        Dim strConn As String = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = E:\DATA DISK\kolo.mdb;"
        Dim strQuery As String = "SELECT * FROM [Kolo]"
        Dim conn As OleDbConnection = New OleDbConnection(strConn)

        'pomocí DataAdapteru načíst data do DataTable
        da = New OleDbDataAdapter(strQuery, conn)
        da.Fill(dtKolo)

        'přidej DataTable do DataSetu
        dsHealth.Tables.Add(dtKolo)

        With DataGridView1

            'připojit DataTable jako zdroj dat na DataGrid
            .DataSource = dtKolo

            'a nastavit počáteční šířky sloupců (0 a 1 - fixně, zbytek Auto)
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            .Columns(0).Width = 30
            .Columns(1).Width = 150

        End With

        'data načtena v DataSetu Health, Table dtKolo a zobrazena v DataGridView - až potud zdá se ok...

    End Sub


    'vznikl požadavek na uložení nového řádku
    Private Sub btnAddRow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddRow.Click

        'jaký je aktuální datum a čas
        Dim tempDay As Date = Microsoft.VisualBasic.Now

        Dim row As DataRow
        row = Me.dtKolo.NewRow
        row("ID") = dtKolo.Rows.Count + 1
        row("Day") = tempDay
        row("Distance") = "10"
        row("Time") = "33:22"
        row("Pulse") = "111"
        row("AvgSpeed") = 10 / 2 'příklad, pak bude výpočet
        row("Memo") = "Good day!"

        'přidej řádek do dtKolo
        dtKolo.Rows.Add(row)

    End Sub

    'vznikl požadavek na uložení dat zpět do podkladové databáze
    Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click

        'vytvořit CommandBuilder - SQL Insert, Delete, Update
        Dim cmd As OleDbCommandBuilder = New OleDbCommandBuilder(da)

        'když tam nic není, nedělej nic, jinak..
        If Not dtKolo Is Nothing Then
            Try
                da.Update(dtKolo)        'tady to hodí držku, OleDbException - syntaktická chyba v příkazu INSERT INTO ??
                '                         ale proč když by měl object OleDbCommandBuilder tento dotaz vytvořit...
                dtKolo.AcceptChanges()

                'při chybě vyhoď hlášku
            Catch exc As OleDbException
                MessageBox.Show(vbCrLf & exc.Message)
                Exit Sub
            
            End Try
        End If

    End Sub

    'vznikl požadavek na smazání řádku na pozici kurzoru
    Private Sub btnDeleteRow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeleteRow.Click

        'idea : když se smaže řádek z dtKolo a pak se provede Save, změny se převedou do podkladové dbf
        Dim tmpPozice As Integer = Me.DataGridView1.CurrentCell.RowIndex
        dsHealth.Tables("Kolo").Rows.RemoveAt(tmpPozice)

    End Sub

    'vznikl požadavek na znovu načtení dat z podkladové databáze
    Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click
        ' potom zkopírovat kód z event Load
    End Sub

End Class

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,

takže k Vašemu programu.

První problém bude v názvu polí tabulky dtKolo.

Pole "Memo", "Day" a "Time" jsou klíčová slova, která by se neměla používat pro názvy sloupců tabulek. Doporučuji je přejmenovat např. na "Pozn", "Den" a "Cas" nebo nějak podobně.

Druhým problémem je, že v tabulce nemáte definován žádný primární klíč, podle kterého by pak následně probíhala aktualizace pomocí CommandBuilder. V tabulce sice máte pole "ID", ale toto není definováno jako primární klíč. Ideální je přímo v souboru MDB v tabulce KOLO vytvořit primární klíč a přiřadit mu vlastnost AutoIncrement.

V programu pak u DataAdaptéru nastavit vlastnost MissingSchemaAction na hodnotu AddWithKey, tak jak je to v kódu níže. Tím určíte, že DataSet, který vznikne načtením zdrojových dat bude mít přesně stejnou strukturu jako tabulka Kolo v souboru MDB včetně primárního klíče.

Určitě by bylo lepší v programu použít přísně typový dataset, který by kopíroval strukturu tabulky Kolo z MDB souboru a pro vázání dat použít objekt BindingSource, který hodně usnadňuje práci.

Nechtěl jsem příliš šťourat do Vašeho kódu, ale přesto jsem si dovolil pár úprav. Ty důležité jsou pak okomentovány přímo v kódu.

Ještě ke struktuře tabulky KOLO v databázi ACCESS:

Pole ID - Automatické číslo. Pole ID je zároveň primárním klíčem

Pole DEN - číslo (defaultní nastavení)

Pole DISTANCE - text (defaultní nastavení)

Pole CAS - text (defaultní nastavení)

Pole PULSE - text (defaultní nastavení)

Pole AVGSPEED - číslo (defaultní nastavení)

pole POZN - memo


Imports System.Data.OleDb

Public Class Form1
    Private da As New OleDbDataAdapter
    Private dsHealth As New DataSet
    Private con As OleDbConnection
    Private cb As OleDbCommandBuilder

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Definice spojovacího řetězce
        Dim strCon As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\kolo.mdb;"
        Dim strQuery As String = "SELECT * FROM kolo"
        con = New OleDbConnection(strCon)

        da.SelectCommand = New OleDbCommand(strQuery, con)

        ' Vytvoření CommandBuilder včetně aktualizačních příkazů
        cb = New OleDbCommandBuilder(da)
        da.InsertCommand = cb.GetInsertCommand()
        da.DeleteCommand = cb.GetDeleteCommand()
        da.UpdateCommand = cb.GetUpdateCommand()

        ' Tímto řádkem se definuje, že datový adaptér si ze zdrojové databáze natáhne schéma včetně primárního klíče, 
        ' který je nutný k následné aktualizaci pomocí třídy CommandBuilder
        da.MissingSchemaAction = MissingSchemaAction.AddWithKey

        Try
            ' Načtení dat ze zdroje 
            da.Fill(dsHealth, "Kolo")

            ' Naplnění objektu DataGridView
            With Me.DataGridView1
                .DataSource = dsHealth
                .DataMember = "Kolo"
            End With
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    Private Sub btnAddNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddNew.Click
        ' Přidání nového řádku do tabulky Kolo v DataSetu 
        Dim drKolo As DataRow = dsHealth.Tables("Kolo").NewRow
        With drKolo
            .Item("DEN") = Date.Now.Day
            .Item("Distance") = "10"
            .Item("CAS") = "33:22"
            .Item("Pulse") = "111"
            .Item("AvgSpeed") = 10 / 2
            .Item("POZN") = "Good day!"
        End With
        dsHealth.Tables("Kolo").Rows.Add(drKolo)
    End Sub

    Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        ' Uložení změn do zdroje dat, provede se voláním metody Update objektu DataAdapter
        ' Před samotnou aktualizací proběhne ověření, zda došlo k nějaké změně v DataSetu 
        Dim dtSave As DataTable = dsHealth.Tables("Kolo").GetChanges
        If Not dtSave Is Nothing Then
            Try
                ' Aktualizace zdroje dat
                da.Update(dtSave)

                ' Změny byly zapsány do zdroje dat, můžeme tedy potvrdit změny v DataSetu
                dsHealth.Tables("Kolo").AcceptChanges()
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End If
    End Sub
End Class

Doufám, že to pomůže. Pokud by cokoliv bylo nejasné nebo by s něčím byl problém, rád poradím, případně zašlu kompletní projekt včetně souboru MDB.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Vážený pane,

mockrát díky za Vaši pomoc!

Několikrát jsem pročítal MSDN a tuny různých zdroj kódů kolem toho a pořád jsem měl pocit že mi něco uniká. Vaše komentáře v kódu jsou naprosto jasné. Díky za ně! Zítra ihned odzkouším. Ono je někdy opravdu těžké se orientovat v prostředí když člověk si myslí že trošku něco ví a potom vlastně neví kde tu chybu hledat, resp. proč vznikla. Jsem si jistý, že Vaše pomoc pomůže.

P.S. vážím si Vaší nabídky co se týče možného následného dovysvětlení a přiznám se že bych jí i rád využil :-) nechci přespříliš obtěžovat ale tu a tam se objeví nějaký rádoby "problém" a je potom fajn to mít s kým eventuelně pořešit.

Platí pochopitelně oboustranně v případě zájmu a možností. Je na Vás nějaký přímý kontakt? Rád bych event. s Vámi zůstal v občasném kontaktu, ...pokud by to šlo.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,

nemáte za co děkovat.

Když vím, rád pomůžu. :-)

Budete-li chtít, můžete mne kontaktovat nejlépe emailem: [email protected].

Přeji hezký den.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback