Brno? Vypsali jsme pro vás nové termíny školení Základů programování a OOP v Brně!
Avatar
Petr Havel
Člen
Avatar
Petr Havel:28. května 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. května 11:36
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. května 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. května 12:55
 
Nahoru Odpovědět  -1 28. května 12:54
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. května 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. května 13:12
 
Nahoru Odpovědět 28. května 13:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. května 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. května 13:15
 
Nahoru Odpovědět 28. května 13:15
Avatar
Petr Havel
Člen
Avatar
Odpovídá na Peter Mlich
Petr Havel:28. května 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. května 14:12
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:29. května 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. května 7:41
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:29. května 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. května 8:26
 
Nahoru Odpovědět 29. května 8:24
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:29. května 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. května 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.