[Delphi]ListView - ukládání změn

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod dyžon 1. 6. 2018 08:12

zdravím,
opět bych Vás chtěl poprosit o radu.

mám ListView / report, do kterýho pro jednoduchost ukládám:
1. sloupec ... datum
2. sloupec ... string
3. sloupec ... integer

pomocí tlačítek vkládám a mažu Items z ListView.
dál mám kombobox, ve kterým je výběr podle roku.
to znamená, že ve form.create načtu hodnoty listview, a do comboboxu vložím všechny nalezeny roky.
Combobox obsahuje např: všechno, 2016, 2017, 2018 a podobně.

podle volby Comboboxu se do ListView vypíší buď všechny položky, nebo jen položky z vybranýho roku.

každou změnu (přidej/smaž) hned ukládám do .txt a to tak, že z ListView načtu všechny hodnoty do StringListu a ten potom uložím.

problém je, že když vyberu jen určitej rok a něco do ListView vložím, nebo smažu, tak se txt přepíše jen položkama z toho roku.

říkal jsem si, že budu mít dva listViewy, jeden bude non visible, kde bude všechno, a do druhýho se budou vypisovat vybrany roky, ale stejně mě nenapadá, jak potom zjistím, když třeba někdo smaže 6. položku z vybranyho roku 2017 kolikátou položku mám smazat před uložením z hlavního ListView .. žádná položka není jedinečná.

nevím, jestli to píšu dost srozumitelně, dneska mi to moc nemyslí, ale věřím, že na to nějakej systém určitě existuje ...

napadají mě i další hovadiny jako pro každej rok vytvořit vlastní StringList a před uložením je spojit a podobně, ale radši je sem psát všechny ani nebudu.

prosím o nějaký nápad ...
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod JanFiala 1. 6. 2018 09:13

Tohle je spíš práce pro nějakou byť jednoduchou databázi. DBF tabulka, SQL Lite - něco, co má k dispozici nativní komponenty.


Pokud trváš na texťáku, tak při ukládání postupuj následovně:
- pokud máš zobrazena všechna data, tak můžeš obsah přepsat
- pokud máš zobrazen jen rok, tak v texťáku vymaž jen konkrétní rok a pak tam ulož data z ListView.

Pokud bys pracoval s tabulkou, pak bys zobrazoval data z tabulky, která bys rovnou opravoval, mohl bys filtrovat konkrétní rok apod.
Co můžeš udělat dnes, odlož na včerejšek
JanFiala
Expert
Uživatelský avatar

Odeslat příspěvekod dyžon 1. 6. 2018 11:04

good idea ..
tohle by šlo a nemusím toho ani moc překopávat ..
přidám hlavní StringList a při výběru roku (nebo možná až při změně u vybranýho roku) rovnou smažu všechny záznamy v roce a uložím do SL ty nové ...

chápu, že databáze je nejlepší, ale právě tady jsem se jí chtěl vyhnout .. ten texťák je ideální ...

díky moc ...
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Nargon 1. 6. 2018 12:20

Jak tak na to koukám, tak za mě je tam jeden zásadní problém návrhu. Chybí ti tam nějaký "datový model" tj nějaké centrální uložiště dat, kde s nimi děláš nějaké operace (přidat záznam, odebrat záznam, změnit záznam, načíst ze souboru, uložit do souboru, vyfiltrovat a zobrazit v listview). Lze k tomu použít i tu malou databázi, ale podle mě ta databáze je zbytečně velký kanón. Jde to udělat i nějakým jednoduchým "polem" a vlastní třídou. Ale podle toho co tu vidím tak tvůj datový model je obsah ListView a to je ten kámen úrazu, protože to co tam není zobrazeno tak se nezapíše do souboru.
Osobně doporučuji snažit se dodržovat MVC vzor: https://en.wikipedia.org/wiki/Model%E2% ... controller dost to pomůže. Na některé opravdu primitivní věci model není potřeba a lze data udržovat jen v rámci prvků toho formuláře, ale u něčeho jen o ždibec většího už sám vidíš že to není praktické.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod Stoura 1 4. 6. 2018 08:37

Nápad:
Pokud to není moc velké (položek je dohromady hodně desítek nebo málo stovek), dá se použít inifile.
Nevýhodou inifile je rychlost při větším počtu položek.
Inifile se dá rozdělit do sekcí podle roku.
v Inifile lze modifikovat jednotlivé položky.

Zhruba takto (psáno v c++, pro pascal si upravte):

Kód: Vybrat vše

#include <vcl/inifiles.hpp> // vlozeni definice tridy pro praci s inisouborem

TIniFile *ini;   // ukazatel na komponentu inisouboru

ini = new TIniFile( ChangeFileExt( Application->ExeName, ".mydb" ) );   // vyrobi komponentu, pojmenuje soubor stejne jako program, jen s jinou koncovkou  a nacte data

AnsiString sekce="1997"; // jmeno sekce, ktera se ma nacist
AnsiString jmeno_polozky="prvni polozka"; // polozka z dane sekce
AnsiString data = ini-> ReadString(sekce,jmeno_polozky,"nejaka nahradni hodnota kdyz v souboru nic neni") ; // nacteni dat

//--------
// modifikace:

ini->WriteString( sekce,jmeno_polozky, "uplne nova hodnota" );
ini->UpdateFile(); // update souboru - tim se ulozi vsechny zmeny
delete ini; // uvolneni pameti po nepotrebne komponente



Jen jste jednou upozornuji, ze se to da pouzit jen na maly pocet polozek .
Vyse uvedeny kod lze pouzit vickrat - napriklad poprve jen s nactenim a podruhe jen s modifikaci dat
Stoura 1
Junior
Uživatelský avatar

Odeslat příspěvekod JanFiala 4. 6. 2018 09:10

Poku ini soubor, pak TMemIniFile.
Jednak je MemIniFile v paměti, druhak se inifile po načtení naindexuje, takže vyhledávání je mnohem rychlejší.
Co můžeš udělat dnes, odlož na včerejšek
JanFiala
Expert
Uživatelský avatar

Odeslat příspěvekod dyžon 6. 6. 2018 06:49

díky všem,
vyřešil jsem to prozatím texťákem, kde mažu vždy při editaci celej rok ..
položek v roce je max zhruba kolem 100, takže rychlost je v pohodě.
jak píše Nargon, s tím naprosto souhlasím, ale většinou se během psaní objeví spousta nových věcí, požadavků a pak je potřeba všechno předělat od začátku.
to Stoura 1: IniFile jsem právě nechtěl, .. výhoda .txt je, že to celý načtu do StringListu a pracuji už jen s ním ..
ještě jednou díky.
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků