Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Filip
Člen
Avatar
Filip:29.3.2015 11:49

Zdravim,
pokusam sa vytvorit program, ktory z databazy SQLCe nacita tabulku, a tu zobrazi v DGV. Cez TextBox (searchBox) funguje "zive" vyhladavanie v tabulke podla mena. Jednotlive metody som oddelil do osobitnych tried a tu som narazil na problem s pristupom k premenej typu DataTable.
Nasledujuci kod sice funguje, ale neviem ci som ho napisal spravne, hlavne co sa tyka premennej typu DataTable. Neviem ci je spravne tuto premennu vytvarat vzdy v kazdej triede kde sa pracuje s formatom DataTable.
Diky. (v C# som uplny zaciatocnik)

urivky z kodu:

Form1.cs:

...
public partial class Form1 : Form
    {
        public DataTable tabulka;
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            tabulka = spravcaOsob.NacitajTabulku();
            dataGridView1.DataSource = tabulka;
        }
        private void searchBox_TextChanged(object sender, EventArgs e)
        {
            DataView DV = new DataView(tabulka);
            DV.RowFilter = string.Format("Meno LIKE '%{0}%'",searchBox.Text);
            dataGridView1.DataSource = DV;
        }
}

trieda SpravcaOsob.cs :

public class SpravcaOsob
    {
        private databaza db = new databaza();
        DataTable udaje;

        public DataTable NacitajTabulku()
        {
            using (udaje = db.citajDB("SELECT * FROM osoby"))

                if (!string.IsNullOrEmpty(db.chybaDB)) return null;
                else return udaje;

trieda databaza.cs :

class databaza
     {
        private SqlCeConnection pripojenie ;
        private SqlCeDataAdapter adapter;
        public SqlCeCommand prikaz=null;
        private DataTable vysledok;
        private string connectionString ;
        public string chybaDB=null ;
       ...
public DataTable citajDB(string SQLprikaz)
        {
            VytvorSpojenie();

            try
            {
                adapter = new SqlCeDataAdapter(SQLprikaz, pripojenie);
                vysledok = new DataTable();
                adapter.Fill(vysledok);
            }
            catch (Exception ex)
            {
                vysledok = null;
                chybaDB = ex.Message;
            }
            pripojenie.Close();
            return vysledok;
        }
}
 
Odpovědět
29.3.2015 11:49
Avatar
Odpovídá na Filip
Michal Štěpánek:29.3.2015 11:58

Myslím si, že DataTable bys měl vytvořit ve třídě a ve formu se na ní jen přes tu třídu odkazovat.

Nahoru Odpovědět
29.3.2015 11:58
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Filip
Člen
Avatar
Odpovídá na Michal Štěpánek
Filip:29.3.2015 16:07

OK, spravil som to takto:

Tabulka.cs

public static class Tabulka
    {
        public static DataTable DT;
    }

... potom sa v ostatnych triedach na tuto premennu odkazujem "Tabulka.DT"
Funguje to, ale neviem ci je to optimalne riesenie.

 
Nahoru Odpovědět
29.3.2015 16:07
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na Filip
Jan Vargovský:29.3.2015 16:25

Je to asi jedno z nejhnusnějších :)

 
Nahoru Odpovědět
29.3.2015 16:25
Avatar
Filip
Člen
Avatar
Filip:29.3.2015 16:38

OK.... ide mi o to, ze ked mam SQL tabulku ktora ma cca 1000 riadkov po 20 stlpcov, aby sa ta tabulka nenacitavala do RAMky po 3x (v troch roznych premennych) - aby ten program nezozral celu volnu pamat (sice neviem, ako .NET pracuje s datami za behu programu, ale pre istotu...)

 
Nahoru Odpovědět
29.3.2015 16:38
Avatar
Odpovídá na Filip
Michal Štěpánek:30.3.2015 9:28

Netahej do toho zbytečně statiku. Prostě v té třídě, kde taháš data z databáze udělej

public datatable dt;

, dej do ní data a pak ve formu se na ní odkaž

private void Form1_Load(object sender, EventArgs e)
        {
            spravcaOsob.NacitajTabulku();
            dataGridView1.DataSource = spravcaOsob.dt;
        }
Editováno 30.3.2015 9:28
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
30.3.2015 9:28
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Filip
Člen
Avatar
Filip:16.4.2015 13:06

Ake jednoduche. Dakujem.

 
Nahoru Odpovědět
16.4.2015 13:06
Avatar
Odpovídá na Filip
Michal Štěpánek:16.4.2015 13:15

Jen jsem to napsal špatně, v té třídě to má být

public DataTable dt = new DataTable();

jinak pak bude křičet, že objekt nemá instanci, protože před každým "znovunatažením" dat, bys měl udělat

dt.clear();

aby se ti nezobrazovaly duplicitní záznamy...

Editováno 16.4.2015 13:15
Nahoru Odpovědět
16.4.2015 13:15
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Filip
Člen
Avatar
Filip:22.4.2015 11:55

Zacyklil som sa do dalsej blbosti, ne zeby som to nevedel vyriesit inak, ale kedze som nad tym stravil cely vecer (cca 6 hodin ;() tak ma zaujima preco to nefunguje. Problem je ten, ze v "HlavnyForm" mam povodny obsah dat. zlozky "db.tabulka". Ta premenna sa nechce po pridani noveho zaznamu aktualizovat. Pritom vo forme "PridajOsobuForm" je to OK. Dufam ze z kodu to bude jasne.

public partial class HlavnyForm : Form
    {
        praca_sDB db;

        public HlavnyForm()
        {
            InitializeComponent();
        }
        private void HlavnyForm_Load(object sender, EventArgs e)
        {
         db = new praca_sDB;
         db.NacitajTabulku();  // do "public DataTable tabulka" nacita
tabulku z SQL databazy.

         DataGridView1.DataSource = db.tabulka; // tabulka zobrazena, OK.
        }

private void novyBut_Click(object sender, EventArgs e)
        {

            PridajOsobuForm pridajOsobu = new PridajOsobuForm();
        // zobrazi novy form, v ktorom sa z TextBoxov ulozia udaje do SQL DB.
            if (pridajOsobu.ShowDialog() == DialogResult.OK)
            {
        // v tomto bode zaznam ulozeny a "db.tabulka" je znovu naplnena z SQL DB.
                db.tabulka.AcceptChanges();  // bez vysledku
                DataGridView1.Update();
                DataGridView1.Refresh();
                DataGridView1.DataSource = db.tabulka; // ***tu je problem,
v "db.tabulka" nieje pridany novy riadok. Tabulka sa neaktualizovala.

            }
      }
}
//////////////////////////////

public partial class PridajOsobuForm : Form
    {
       //
     }
        public PridajOsobuForm()
        {
            InitializeComponent();
        }

        private void ulozButton_Click(object sender, EventArgs e)
        {
            praca_sDB db;

            if (!ValidateChildren())
                DialogResult = DialogResult.None;

            else
            {
              // nasleduje ukladanie dat z TextBoxov do SQL DB

                using (db = new praca_sDB())
                {
                db.Uloz_zaznam(objekty ktore ukladam);  // tato metoda
ulozi zaznam do SQL tabulky a zaroven nacita celu SQL tabulku do dat. zlozky "tabulka"

                // v tomto bode je zaznam ulozeny v DB, "db.tabulka" obsahuje aj novy zaznam, vsetko je OK.
                }
                    if (chyba pri ukladani)
                    {
                    // zobraz chybove hlasenie

                    DialogResult = DialogResult.None;
                    }
                    else
                    {
                     DialogResult = DialogResult.OK;
                    }
         // vrati sa do "HlavnyForm", v tomto bode "db.tabulka" je stale OK.

       }
  }
Editováno 22.4.2015 11:58
 
Nahoru Odpovědět
22.4.2015 11:55
Avatar
Gramli
Tvůrce
Avatar
Odpovídá na Filip
Gramli:22.4.2015 12:16

Ta tabulka se nemeni v HlavnyForm ,protoze vytvaris ve PridajOsobuForm novou tridu pro praci s databazi a nikde promenou v HlavnyForm neaktualizujes.

Takhle by to mohlo jit:

public partial class HlavnyForm : Form
    {
        public praca_sDB db; // promena je public

        public HlavnyForm()
        {
            InitializeComponent();
        }
        private void HlavnyForm_Load(object sender, EventArgs e)
        {
         db = new praca_sDB;
         db.NacitajTabulku();  // do "public DataTable tabulka" nacita
tabulku z SQL databazy.

         DataGridView1.DataSource = db.tabulka; // tabulka zobrazena, OK.
        }

private void novyBut_Click(object sender, EventArgs e)
        {

            PridajOsobuForm pridajOsobu = new PridajOsobuForm();
        // zobrazi novy form, v ktorom sa z TextBoxov ulozia udaje do SQL DB.
            if (pridajOsobu.ShowDialog() == DialogResult.OK)
            {
        // v tomto bode zaznam ulozeny a "db.tabulka" je znovu naplnena z SQL DB.
                db.tabulka.AcceptChanges();  // bez vysledku
                DataGridView1.Update();
                DataGridView1.Refresh();
                DataGridView1.DataSource = db.tabulka; // ***tu je problem,
v "db.tabulka" nieje pridany novy riadok. Tabulka sa neaktualizovala.

            }
      }
}

public partial class PridajOsobuForm : Form
    {
       private HlavnyForm hlavnyForm; //vytvoris si promenou HlavnyForm
       //
     }
        public PridajOsobuForm(HlavnyForm form) // do konstruktoru predas HlavnyForm
        {
            hlavnyForm = form; //nastavis HlavnyForm
            InitializeComponent();
        }

        private void ulozButton_Click(object sender, EventArgs e)
        {
            if (!ValidateChildren())
                DialogResult = DialogResult.None;

            else
            {
              // nasleduje ukladanie dat z TextBoxov do SQL DB

                using (hlavnyForm.db) //tady pristupujes k promene z hlavniho Formu
                {
                hlavnyForm.db.Uloz_zaznam(objekty ktore ukladam);  // tato metoda
ulozi zaznam do SQL tabulky a zaroven nacita celu SQL tabulku do dat. zlozky "tabulka"

                // v tomto bode je zaznam ulozeny v DB, "db.tabulka" obsahuje aj novy zaznam, vsetko je OK.
                }
                    if (chyba pri ukladani)
                    {
                    // zobraz chybove hlasenie

                    DialogResult = DialogResult.None;
                    }
                    else
                    {
                     DialogResult = DialogResult.OK;
                    }
         // vrati sa do "HlavnyForm", v tomto bode "db.tabulka" je stale OK.

       }
  }
Editováno 22.4.2015 12:17
Nahoru Odpovědět
22.4.2015 12:16
Kdo to říká ten to je...
Avatar
Odpovídá na Filip
Michal Štěpánek:22.4.2015 23:12

stačí toto

if (pridajOsobu.ShowDialog() == DialogResult.OK)
            {
        // v tomto bode zaznam ulozeny a "db.tabulka" je znovu naplnena z SQL DB.
                db.tabulka.AcceptChanges();  // bez vysledku
                DataGridView1.Update();
                DataGridView1.Refresh();
                DataGridView1.DataSource = db.tabulka; // ***tu je problem,
v "db.tabulka" nieje pridany novy riadok. Tabulka sa neaktualizovala.

            }

změnit takto

if (pridajOsobu.ShowDialog() == DialogResult.OK)
            {
        // v tomto bode zaznam ulozeny a "db.tabulka" je znovu naplnena z SQL DB.
db.NacitajTabulku();     //tím se provede znovunačtení dat do datatable
DataGridView1.DataSource = db.tabulka;

            }
Nahoru Odpovědět
22.4.2015 23:12
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Filip
Člen
Avatar
Odpovídá na Gramli
Filip:23.4.2015 12:06

Diky, funguje to. Ale musel som este doplnit parameter "this" do konstruktora formulara "PridajOsobuForm".

PridajOsobuForm pridajOsobu = new PridajOsobuForm(this);
 
Nahoru Odpovědět
23.4.2015 12:06
Avatar
Filip
Člen
Avatar
Odpovídá na Michal Štěpánek
Filip:23.4.2015 12:31

Ano, staci. Existuje viacero sposobov aby to fungovalo, ale mna zaujimalo, preco ta "db.tabulka" v hlavnomForme sa zobrazuje bez zmeny, ked v skutocnosti obsahuje aj posledny pridany zaznam, teda vsetky data z DB.

btw. takto ako si to navrhol, program by pracoval takto:

Vytvor pripojenie k DB -> Otvor DB -> Uloz zaznam do DB -> Zatvor DB ->
 Zrus pripojenie -> Vytvor pripojenie k DB -> Otvor DB -> Napln tabulku z DB ->
Zatvor DB -> Zrus pripojenie.

Preto som to chcel zoptimalizovat asi takto:

Vytvor pripojenie k DB -> Otvor DB -> Uloz zaznam do DB -> Napln tabulku z DB ->
Zatvor DB -> Zrus pripojenie.

Ja viem, pocitaci to je jedno :-)

Editováno 23.4.2015 12:32
 
Nahoru Odpovědět
23.4.2015 12:31
Avatar
Odpovídá na Filip
Michal Štěpánek:23.4.2015 23:38

Zjednodušit by se to asi dalo, musel by sis naplnit datatable ve stejném kroku, když se ukládá záznam, ale myslím, že je to zbytečné...
Ten krok

db.NacitajTabulku();

bys musel volat přímo v té proceduře ukládání

Nahoru Odpovědět
23.4.2015 23:38
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 14 zpráv z 14.