IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
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í.

Diskuze: Vícenásobné filtrování dat v dataGrideView za pomoci ComboBoxů (z Excel souboru, ne SQL)

Aktivity
Avatar
Petr Havel
Člen
Avatar
Petr Havel:28.5.2019 11:36

Zdravím,
pracuji na ročníkové práci, kde jsem si jako téma zvolil - Dovolená-filtrování. Narazil jsem ale na problém, že pokud chci filtrovat více, jak jedny data (stát, destinace, strava...) tak si nevím rady, jak to zprovoznit.
Filtrování mi funguje pro jednu volbu - stát, ale jak k tomu připojit i další filtry, aby to filtrovalo podle všech vybraných kategorií najednou?

 
Odpovědět
28.5.2019 11:36
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28.5.2019 12:54

Zadani je nejasne. Co je vstup, co ma byt vystup a co je mezi tim. Podle kodu mi prijde, ze jsi ani nic nezkousel a ze to dela uplne neco jineho, asi kopie uplne jineho prikladu.
Zkusim ti popsat v JS par variant, prepis si to pak do c#:

(1)
<script>
function zobraz(table)
{
var i;
for (i=0; i<table.length; i++)
  document.write(i + ': ' + table[i].join(', ') + '<br>');
document.write('<br><br>');
}

var i, j, table, table2, filter, col, text, bool;

table = [
// jmeno, stat, mesto
['Tomas', 'Cesko', 'Zlin'],
['Petr', 'Cesko', 'Ostrava'],
['Libor', 'Slovensko', 'Kosice']
];
zobraz(table);

filter = [
[1, 'ce'], // filtruj podle sloupce id=1 (stat)
[0, '']    // id=0 (mesto)
];

table2 = [];
for(i=0; i<table.length; i++)
    {
    bool = true;
    for(j=0; j<filter.length; j++)
        {
        text = filter[j][1].toUpperCase(); // aby ignoroval mala velka pismena
        if (text=='') {continue;} // hledany text je prazdny, pokracuj dalsim filtrem
        col  = table[i][filter[j][0]].toUpperCase();
//alert([col, text])
//      if (table[i][col]!=text) {bool=false; break;} // hledany text se shoduje s textem sloupce (to obvykle nepotrebujes)
//      pozn.: take muzes pouzit misto indexOf regularni vyraz
        if (col.indexOf(text)==-1) {bool=false; break;} // hledany text nenalezen
        if (col.indexOf(text)!==0 ) {bool=false; break;} // hledany text neni na zacatku sloupce
        }
    if (bool===true) table2[table2.length] = table[i] // pokud je bool stale true, zkopiruj radek do table 2
    }
//alert(table2.toSource())
zobraz(table2);

</script>

Vypise to
0: Tomas, Cesko, Zlin
1: Petr, Cesko, Ostrava
2: Libor, Slovensko, Kosice

0: Tomas, Cesko, Zlin
1: Petr, Cesko, Ostrava

Editováno 28.5.2019 12:55
 
Nahoru Odpovědět
28.5.2019 12:54
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28.5.2019 13:11

K tomu kodu, jako, dival jsem se fakt usilovne a nedava to smysl. To nikdy nic nemohlo delat. Spousta promenych tam neexistuje. CSV reader je uplne spatne, naprosto ignoruje pravidla csv. Kdybych tam dal tohle do sloupce, tak tvuj program selze.

a"h;o
j
--- ulozi se do csv jako
sloupec;"a""h";o
j";sloupec

Nevim, mozna chces mit propojene comboboxy. To muzes udelat podobnym zpusobem jako ja tu tabulku

// pseudokod
(2)
<select onchange="filtruj()">
  <option>
  <option>
<select onchange="filtruj()">
  <option>
  <option>
<select onchange="filtruj()">
  <option>
  <option>

<script>
function filtruj()
{
filtry = [
[0, select0.selected.value],
[1, select1.selected.value],
[2, select2.selected.value]
]
table2 = filtrujTabulku(table, filtry)
selectOptions(0, unikatniHodnotySloupce(table, 0)) // ze sloupce 0 vyber unikatni hodnoty a prepis select 0
selectOptions(1, unikatniHodnotySloupce(table, 1))
selectOptions(2, unikatniHodnotySloupce(table, 2))
}
</script>
Editováno 28.5.2019 13:12
 
Nahoru Odpovědět
28.5.2019 13:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28.5.2019 13:15

ups, tady melo bys samozrejme table2, ta vyfiltrovana :) Jo, a nejsou to js funkce, muzel by sis je napsat. ale to je jednoduchy cyklus.
selectOptions(0, unikatniHodno­tySloupce(table, 0)) // spatne
selectOptions(0, unikatniHodno­tySloupce(table2, 0))

Editováno 28.5.2019 13:15
 
Nahoru Odpovědět
28.5.2019 13:15
Avatar
Petr Havel
Člen
Avatar
Odpovídá na Peter Mlich
Petr Havel:28.5.2019 14:12

No, tak tohle je ten kód, se kterým pracuji úplně, snažil jsem se vypsat jen to s čím pracuji.
A k tomu, že není jasné, co potřebuji - za pomoci comboBoxů filtruji data, která jsou nahraná v dataGridView. Toto mi funguje, ale pouze tehdy, pokud filtruji jedny data např. Stát. Já si ale nevím rady s tím, jak k tomu přidat ještě to, aby to zároveň se státem, mohlo filtrovat i data, která jsou zapsána jako letoviska.
Př: Vyberu si stát Egypt, letovisko Hurghada a potřebuji, aby to vyhodilo všechny dovolené, co jsou ve státě Egypt a zároveň v letovisku Hurghada.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Ročníková_práce
{
    public partial class Filtr : Form
    {
        private List<String> filterConstraints;
        private List<Filtr> data;
        private DataTable dt;
        private DataView dv;

        public Filtr()
        {
            InitializeComponent();

            dt = new DataTable();
            dt.Columns.Add("Stát");
            dt.Columns.Add("Letovisko");
            dt.Columns.Add("Doprava");
            dt.Columns.Add("Strava");
            dt.Columns.Add("Úroveň hotelu");

            fillDataTable(generateData());
            dv = new DataView(dt);

            dgvNabídky.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dgvNabídky.DataSource = dv;

            filtrDoprava();
            filtrLetovisko();
            filtrHotel();
            filtrStrava();
            filtrStát();
        }


        private void Filtr_Load(object sender, EventArgs e)
        {
        }

        //_______________________________________________________________________________________//

        //ukončení celé aplikcae
        private void btUkončení_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        //--NAHRÁNÍ DAT ZE SOUBORU EXCEL DO APLIKACE A NÁSLEDNÉ ZOBRAZENÍ DAT V DATAGRIDVIEW--//

        private List<Filtr> generateData()
        {
            data = new List<Filtr>();
            StreamReader soubor = new StreamReader(@"Sešit.csv", Encoding.Default);
            string hlavickaDokumentu = soubor.ReadLine();
            string lajna;
            while ((lajna = soubor.ReadLine()) != null)
            {
                string[] split = lajna.Split(';');
                data.Add(new Filtr(split[0], split[1], split[2], split[3], split[4]));
            }
            return data;

        }

        private void fillDataTable(List<Filtr> podmínky)
        {
            foreach (Filtr podmínka in podmínky)
            {
                dt.Rows.Add(podmínka.Stát, podmínka.Letovisko, podmínka.Doprava, podmínka.Strava, podmínka.Úroveň);
            }
        }

        private void dgvNabídky_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            //dgvNabídky.Rows.Clear();

            foreach (string[] item in řádek("Pokusný_sešit.csv"))
            {
                dgvNabídky.Rows.Add(item);
            }
        }

        private IEnumerable<string[]> řádek(string v)
        {
            throw new NotImplementedException();
        }

        //--FILTROVÁNÍ NAHRANÝCH DAT--//

        private string Stát, Letovisko, Doprava, Strava, Úroveň;

        public Filtr(string stát, string letovisko, string doprava, string strava, string úroveň)
        {
            this.Stát = stát;
            this.Letovisko = letovisko;
            this.Doprava = doprava;
            this.Strava = strava;
            this.Úroveň = úroveň;
        }
        public string stát
        {
            get { return Stát; }
        }
        public string letovisko
        {
            get { return Letovisko; }
        }
        public string doprava
        {
            get { return Doprava; }
        }
        public string strava
        {
            get { return Strava; }
        }
        public string úroveň
        {
            get { return Úroveň; }
        }

        private void filtrStát()
        {
            filterConstraints = new List<String>
            {
                "Nerozhoduje",
                "Egypt",
                "Chorvatsko",
                "Řecko",
                "Tunisko",
                "Turecko"
            };
            comBoxStát.DataSource = filterConstraints;
        }

        private void filtrLetovisko()
        {
            filterConstraints = new List<String>
            {
                "Nerozhoduje",
                "Hurghada",
                "Marsa Alam",
                "Vis",
                "Korčula",
                "Split",
                "Pag",
                "Karphatos",
                "Kos",
                "Korfu",
                "Samos",
                "Kréta",
                "Rhodos",
                "Djerba",
                "Monastir",
                "La Marsa",
                "Gammarth",
                "Hammamet",
                "Monastir",
                "Ordu",
                "Trabzon",
                "Mersin",
                "Ordu",
                "Didim"
            };
            comBoxLetovisko.DataSource = filterConstraints;
        }

        private void filtrDoprava()
        {
            filterConstraints = new List<String>
            {
                "Nerozhoduje",
                "Vlastní",
                "Autobusem",
                "Letecky"
            };
            comBoxDoprava.DataSource = filterConstraints;
        }

        private void filtrStrava()
        {
            filterConstraints = new List<String>
            {
                "Nerozhoduje",
                "Snídaně",
                "Večeře",
                "Polopenze",
                "All Inclusive",
                "Ultra All Inclusive"
            };
            comBoxStrava.DataSource = filterConstraints;
        }
        private void filtrHotel()
        {
            filterConstraints = new List<String>
            {
                "Nerozhoduje",
                "Jedna hvězda",
                "Dvě hvězdy",
                "Tři hvězdy",
                "Čtyři hvězdy",
                "Pět hvězd"
            };
            comBoxStát.DataSource = filterConstraints;
        }

        //___________________________________________________________//

        private void comBoxStát_SelectedIndexChanged(object sender, EventArgs e)
        {
            String vybrané = comBoxStát.SelectedItem.ToString();
            if (dv != null)
            {
                if (vybrané == "Nerozhoduje")
                {
                    dv.RowFilter = "";
                    dgvNabídky.DataSource = dv;
                }
                else if (vybrané == "Egypt")
                {
                    dv.RowFilter = "Stát = 'Egypt'";
                    dgvNabídky.DataSource = dv;
                }
                else if (vybrané == "Chorvatsko")
                {
                    dv.RowFilter = "Stát = 'Chorvatsko'";
                    dgvNabídky.DataSource = dv;
                }
                else if (vybrané == "Řecko")
                {
                    dv.RowFilter = "Stát = 'Řecko'";
                    dgvNabídky.DataSource = dv;
                }
                else if (vybrané == "Tunisko")
                {
                    dv.RowFilter = "Stát = 'Tunisko'";
                    dgvNabídky.DataSource = dv;
                }
                else if (vybrané == "Turecko")
                {
                    dv.RowFilter = "Stát = 'Turecko'";
                    dgvNabídky.DataSource = dv;
                }
                else
                {
                    dgvNabídky.DataSource = dt;
                }
            }
        }
        //_______________________________________________________//
    }
}
 
Nahoru Odpovědět
28.5.2019 14:12
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:29.5.2019 7:41

Aha, tak to jsem ti prave napsal. Musis pracovat s celou tabulkou. Ulozit data do jine. Vyradit radky, ktere neodpovidaji zadani. A pak z te tabulky vygenerovat ty comboboxy.
Kdezto, jestli chapu ten kod, tak ty mas comboboxy predpripravene, bez souvislosti na tabulku. A CSV reader mas spatne, znacne zjednoduseny.

Ty resis filtr takhle

private void filtrStát()
{
    filterConstraints = new List<String>
    {
        "Nerozhoduje",
        "Egypt",
        "Chorvatsko",
        "Řecko",
        "Tunisko",
        "Turecko"
    };
    comBoxStát.DataSource = filterConstraints;
}

Ale spravne bys ho mel resit nejak takhle

private void filtrStát(table_filtered, column = 3)
{
    list = new List<String>;
    for (i=0; i<delka(table_filtered); i++)
       {
       value = table.filtered[i][column];
       (if value not in list) // resi unique value in list
            {
            list.add()
            }
       }
    comBoxStát.DataSource = filterConstraints;
}

Cili, filtr je zavisly na tom, jak jsi vyfiltroval tabulku.
Samozrejme ty listy muses skladat uz pri filtrovani tabulky.
Si zkus ten javascript nahore udelat copy-paste do nejake html stranky a prepis si filtry

filter = [
[1, 'ce'], // filtruj podle sloupce id=1 (stat)
[0, '']    // id=0 (mesto)
filter = [
[1, 'ce'], // filtruj podle sloupce id=1 (stat)
[0, 'to']    // id=0 (mesto)
];
 
Nahoru Odpovědět
29.5.2019 7:41
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:29.5.2019 8:24

Pridal jsem tam i inputy pro filtrovani a uzavrel to do class a pridal kod na generovani selectu.
https://jsfiddle.net/7a38ou40/
Jo, klikni na te strance Run, jestli neznas jsfiddle (ale mozna se to spusti samo). A pak si smaz z inputu CE, mel by se jeden cselect opticky natahnout a uvnitr vsech se maji zmenit data.

Editováno 29.5.2019 8:26
 
Nahoru Odpovědět
29.5.2019 8:24
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:29.5.2019 8:35

A mozna to chces jinak, aby se postupne menili filtry.

//      table2 = root.func.tableFilter(table, filter);
//      root.func.select(table2, 0);
//      root.func.select(table2, 1);
//      root.func.select(table2, 2);

        root.func.select(table, 0); // nula nefiltrovana
        table2 = root.func.tableFilter(table, [filter[1]]); // filtrovana podle sloupce 0 (filter[1] = [sloupec=0, text=''], proste to mam v tabulce/poli filter na radku 1)
        root.func.select(table2, 1);
        table2 = root.func.tableFilter(table2, [filter[0]]);
        root.func.select(table2, 2);
 
Nahoru Odpovědět
29.5.2019 8:35
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 8 zpráv z 8.