Edytor CSV w pascalu

0

Witam
Dostałem temat projektu edytor plików CSV, za bardzo nie wiem nawet jak się za to zabrać ma ktoś jakiś pomysł? każda pomoc się przyda

1

Najpierw zapoznaj się ze strukturą plików CSV (dokument po polsku - na wszelki wypadek)

Następnie zastanów się nad tym, w jaki sposób przedstawisz zawartość tych plików w programie - jaki komponent będzie odpowiedzialny za wyświetlanie i edycję danych; Tutaj trzeba zauważyć, że każdy wiersz pliku zawiera informacje oddzielone znakiem przecinka, a kilka takich wierszy układa się w tabelkę; Skoro dane można przedstawić w postaci tabelki, to idealnym komponentem do wyświetlania i edycji danych będzie komponent klasy TStringGrid; On zapewni Ci obsługę łańcuchów znaków oraz dwa wymiary (wiersze tabelki jako wiersze pliku oraz kolumny jako kolejne wartości danego wiersza);

A skoro cały edytor opierać się będzie na jednym komponencie, dużo pracy nad tym edytorem mieć nie będziesz; Pozostanie jedynie zapis i odczyt danych do i z plików, dodawanie i usuwanie wierszy i kolumn, a także ewentualne dodatkowe funkcje, np. wygodne dodawanie liczb (różne formaty zapisu), kolorów (konwertowanych na liczby) itd.;

Żeby coś więcej napisać - musisz sam podać pełną docelową funkcjonalność edytora, ale skup się póki co na poznaniu komponentu TStringGrid i pobaw się nim trochę.

0

Jest też opcja użycia TDBGrid, nie wiem jak tam w DELPHI ale w takim Lazarusie jak najbardziej nie ma z tym problemów, pod warunkiem podpięcie TSdfDataset, który to jest stworzony właśnie po to by obsługiwać pliki CSV.

Oczywiście nie ma żadnego problemu z TStringGrid, tylko że to oznacza po prostu więcej zabawy i odpowiedniego oprogramowania tego.

0

@drorat1 - ja nie wiem czy Ty piszesz poważnie, ale użycie komponentów bazodanowych do stworzenia niebazodanowego edytora to jakiś turbo WTF; Nawet jeśli ten TSdfDataset potrafi obsługiwać pliki CSV;

Postawienie komponentu klasy TStringGrid na formularzu to kilka sekund, wyklikanie właściwości to kilka minut; Przeparsowanie linijki pliku CSV to jedna instrukcja ExtractStrings, a połączenie jej z powrotem to użycie metody DelimitedText każdego wiersza, po uprzednim ustawieniu właściwości Delimiter;

Nadal uważasz, że to dużo roboty? Faktycznie dużo roboty było by w przypadku, gdyby pytacz musiał użyć 30-letniego, gołego Pascala; Tak przy okazji - @Jakub94g, podaj informacje na temat środowiska, w którym masz stworzyć ten projekt.

0
furious programming napisał(a):

@drorat1 - ja nie wiem czy Ty piszesz poważnie, ale użycie komponentów bazodanowych do stworzenia niebazodanowego edytora to jakiś turbo WTF; Nawet jeśli ten TSdfDataset potrafi obsługiwać pliki CSV;

Turbo WTF to jest ta Twoja odpowiedź; zapoznaj się z TsdfDataSet a potem krytykuj.
A TsdfDataSet to naprawdę bardzo udatny komponent, który po prostu robi to co ma robić. A ma udostępniać standardowy interfejs bazodanowy dla każdego pliku CSV, co jest mega wygodne.

Postawienie komponentu klasy TStringGrid na formularzu to kilka sekund, wyklikanie właściwości to kilka minut; Przeparsowanie linijki pliku CSV to jedna instrukcja ExtractStrings, a połączenie jej z powrotem to użycie metody DelimitedText każdego wiersza, po uprzednim ustawieniu właściwości Delimiter;

Nadal uważasz, że to dużo roboty? Faktycznie dużo roboty było by w przypadku, gdyby pytacz musiał użyć 30-letniego, gołego Pascala; Tak przy okazji - @Jakub94g, podaj informacje na temat środowiska, w którym masz stworzyć ten projekt.

Tak właśnie uważam, że to całkiem sporo roboty, jeżeli ma to być zrobione dobrze a nie na odwal się.
Zapominasz o kilku sprawach, jak typy danych (tak, wiem - CSV to format tekstowy, ale informacje np. dla liczb rzeczywistych mogą być zapisane z określonym separatorem części ułamkowej, co pozwala je łatwo konwertować na np. typ Currency) i/lub identyfikator tekstu (czyli kiedy średnik nie jest separatorem kolumny a informacją zawartą w kolumnie), wygodna edycja danych z automatyczną wizualizacją zmian (ew końcu to ma być edytor).
I tego nie zrobisz w kilka sekund/minut/godzin (niepotrzebne skreślić).

Poza tym taki TsdfDataSet to de-facto TDataSet, a co za tym idzie pozwala na wyszukiwanie danych, łączenie je w relacje master-detail, filtrowanie, usuwanie i edycję oraz wiele, wiele innych.
I masz to z automatu, Panie turbo-WTF.

0
furious programming napisał(a):

Postawienie komponentu klasy TStringGrid na formularzu to kilka sekund, wyklikanie właściwości to kilka minut; Przeparsowanie linijki pliku CSV to jedna instrukcja ExtractStrings, a połączenie jej z powrotem to użycie metody DelimitedText każdego wiersza, po uprzednim ustawieniu właściwości Delimiter;

To nie jest żaden dobry parser CSV, chyba że do bardzo wąskich zastosowań (z dużymi uproszczeniami i określonymi założeniami). Co do TSdfDataSet, de facto dziedziczy on po komponencie TFixedFormatDataset, jest to wszystko w sdfdata.pas w FPC i TSdfDataset jest to bardzo dobry parser CSV, gdzie Delimiter nie musi być wcale przecinkiem czy tam jakimś średnikiem.

A CSV to tak naprawdę bazy danych. Co do parsowania za pomocą tego co tu zaproponowałeś, weźmy takie coś. Skoro w CSV to przecinek jest separatorem pól a np. ten przecinek ma być czasem w danych w jakimś tam polu, to rzecz jasna całość musi być w cudzysłowie. Kolejna sprawa, pierwsza linia może być jako Schema ale wcale nie musi tak być. TSdfDataset oczywiście to obsługuje i nie ma z tym problemu.

i tak:

 
field1,field2,field3
1,"1,11",2
"8,1",22,"3,11"

Akurat tutaj ta pierwsza linia zawiera nazwy pól (Schema), zaś floaty, które akurat tutaj mają przecinek jako separator miejsc dziesiętnych (a może tak być), to muszą być tutaj w cudzysłowie, inaczej TSdfDataset nie wypluje podczas parsowania poprawnych wyników.

Myślisz że to taka prosta sprawa z jakimś DelimitedText w TStringList czy czymś tam podobnym?

1

Ludzie o czym wy dyskutujecie, "wyplucie" danych do CSV to banalna sprawa. Wczytanie ich odrobinę trudniejsza, ale tylko odrobinę. Z tego co używałem, to żaden z gridów (który obsługuje csv) nie miał jakiś większych problemów.
Dodatkowo w CSV używa się nie tylko przecinka do rozdzielnia pól, często są tez taby albo średniki - te ostatnie chyba najczęściej spotykane, ze względu na lepszą czytelność takiego pliku w edytorze tekstu.
Oczywiście można użyć komponentów bazodanowych, ale to tak jakby uzywac armaty na muchy...

0
kaczus napisał(a):

Ludzie o czym wy dyskutujecie, "wyplucie" danych do CSV to banalna sprawa. Wczytanie ich odrobinę trudniejsza, ale tylko odrobinę. Z tego co używałem, to żaden z gridów (który obsługuje csv) nie miał jakiś większych problemów.

A jaki grid potrafi obsługiwać (czytać, zapisać, edytować) CSV, ciekawość?

Dodatkowo w CSV używa się nie tylko przecinka do rozdzielnia pól, często są tez taby albo średniki - te ostatnie chyba najczęściej spotykane, ze względu na lepszą czytelność takiego pliku w edytorze tekstu.
Oczywiście można użyć komponentów bazodanowych, ale to tak jakby uzywac armaty na muchy...

A to niby dlaczego ów bazodanowy TSDFDataSet jest armatą? Jeśli nawet to armata, to bardzo precyzyjna i dedykowana do takiego zastosowania.
Boisz się komponentów bazodanowych czy po prostu nie rozumiesz jak to działa?
Poza tym OP pisał o edytorze, a dla mnie edytor to nie tylko wczytanie pliku tekstowego do memo, ale pełna i wygodna edycja tych danych. A skoro taki CSV to de-facto tabela to dlaczego nie używać komponentów pochodnych od TDataSet?

0
kaczus napisał(a):

Ludzie o czym wy dyskutujecie, "wyplucie" danych do CSV to banalna sprawa. Wczytanie ich odrobinę trudniejsza, ale tylko odrobinę.

Oczywiście że wczytanie jest trudniejsze. Weź pod uwagę fakt że:

  1. Poprawny format CSV wymaga, żeby jakiekolewiek dane które zawierają ten delimiter, który jak słusznie zauważyłeś nie musi być wcale przecinkiem (można przecież użyć tabulacji, średnika, dwukropka a nawet spacji) były umieszczone w znakach cudzysłów a to przecież podczas parsowania musisz uwzględnić. Dodam tylko tyle, że każde pole może być też w cudzysłowie ale nie musi, jeśli nie zawiera delimitera.
  2. Liczby zmiennoprzecinkowe. Tak jak robiłem coś w JAVA to tam akurat separatorem miejsc dziesiętnych jest kropka, więc jak masz przecinek jako delimiter, znaki cudzysłów są zbędne. Ale co jak separatorem miejsc dziesiętnych jest przecinek? Tutaj chodzi mi przede wszystkim o łatwą konwersję typu FloatToString i vice versa.
  3. Pierwsza linia w CSV może (ale nie musi) zawierać po prostu nazwy tych pól. TSdfDataset umożliwia definicję tych nazw pól, w przypadku gdy pierwsza linia nie jest Schema, więc w TSdfDataset po prostu dodajesz te nazwy do Schema (string lista).
  4. Może być też opcja wykrywania co jest właśnie tym delimiterem w tym CSV, TSdfDataset tego nie obsługuje ale zawsze przecież bez problemu można by próbować coś takiego napisać.
0

@wloochacz najczęściej wykorzystuję nicegrida (ale fakt mocno w niego sobie ingerowałem, poprawiając conieco - poprawki wysłałem autorowi, ale chyba nie był zainteresowany, jedynie podziękował.
@drorat1 zawsze wczytuję całość jako stringi do edycji - co najwyżej daje reguły walidacji przed zapisem.

0

w sumie to sam mogę sobie wybrać środowisko i raczej to będzie lazarus

0

@kaczus

Masz tutaj sdfdata.pp na Githubie, jest to cześć FCL dla FPC. Nie wiem czy tam DELPHI posiada coś podobnego ale obstawiam że tak.

https://github.com/graemeg/freepascal/blob/master/packages/fcl-db/src/sdf/sdfdata.pp

Może dla niektórych to jakiś kombajn ale dla mnie nie. I nie widzę tu żadnych problemów z wykorzystaniem do edycji CSV, jak również Fixed Format (też dane w plikach tekstowych). Tym bardziej chyba nie powinno być problemów jak masz już coś takiego standardowo w DELPHI.

2

@Jakub94g - w takim razie napisz czy chcesz coś popisać, pobawić się i zasłużyć na zaliczenie, czy wolisz kilka razy kliknąć i mieć wszystko gotowe; Jeśli chcesz coś zrobić sam, to zacznij od tego, co opisałem w zaplusowanym przez Ciebie poście; A jeśli wolisz szybkie i bezbolesne rozwiązanie, to użyj jakieś komponentu-kombajnu, który zrobi wszystko za Ciebie.

0
furious programming napisał(a):

@Jakub94g - w takim razie napisz czy chcesz coś popisać, pobawić się i zasłużyć na zaliczenie, czy wolisz kilka razy kliknąć i mieć wszystko gotowe; Jeśli chcesz coś zrobić sam, to zacznij od tego, co opisałem w zaplusowanym przez Ciebie poście; A jeśli wolisz szybkie i bezbolesne rozwiązanie, to użyj jakieś komponentu-kombajnu, który zrobi wszystko za Ciebie.

Myślę ze skorzystam z twojej rady, dzięki wielkie

1

Wiem że temat rozwiązany aczkolwiek robiłem porządki na kompie i znalazłem projekt jeszcze z czasów studenckich gdzie miałem zrobić mniej więcej to co ty teraz. W załączniku zamieszczam cały projekt gdybyś chciał coś podpatrzeć. Od razu mówię, że to były same początki zabawy z Delphi więc za jakość kodu nie odpowiadam :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1