Diskuze: Vícenásobné filtrování dat v dataGrideView za pomoci ComboBoxů (z Excel souboru, ne SQL)
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


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
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>
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, unikatniHodnotySloupce(table, 0)) // spatne
selectOptions(0, unikatniHodnotySloupce(table2, 0))
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;
}
}
}
//_______________________________________________________//
}
}
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)
];
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.
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);
Zobrazeno 8 zpráv z 8.