Program do koniungacji czasowników włoskich

0

Na włoskiej Wikipedii znalazłem taką listę (nie sprawdzałem jeszcze jej poprawności) i ona ma około 700 wpisów. Przekopiowałem kolumny do pliku także z tym nie było problemu.

Edit // Powiem Ci, że ciągle to czytam, ale nie wiem nawet jak zacząć tego używać? Ja mam coś zainstalować? Sciągnąłem jakieś pliki ale tam są pliki .pas? Mam to skompilować? Myślałem, że to będzie jakiś unit i będę tylko w sekcji USES się do tego odnosił.

W internecie znalazłem taki filmik , ale nie wiem czy ja też muszę ściągać tego SQLite Menagera, itd?

0

Okej znalazłem jeszcze takie coś co już dużo bardziej rozjaśnia sprawę ;)
SQLite w Delphi
Tylko wciąż nie wiem jak zrobić żeby taką bazę utworzyć, bo tutaj bardziej opisują program, który ma możliwość dodawania i ładowania tej bazy. Ja chciałbym mięć taką bazę i z niej tylko wczytywać potrzebne informacje. Czy muszę zrobić osobny program, który będzie tworzył taką bazę, a w moim docelowym ją czytał?

0

Tak, przy czym program tworzący bazę to dosłownie kilka linijek. Zakładając, że nie interesuje Cię edycja ani dopisywanie danych, po prostu zakładasz nową bazę, tworzysz tabelę, a następnie przelatujesz linka po linii plik TXT, w którym aktualnie trzymasz listę słów i dodajesz sztuka po sztuce. To oczywiście w odniesieniu do listy słów, które się odmieniają zgodnie z drugim mechanizmem. Taka tabela w sumie to będzie miała dwie kolumny: ID oraz słowo, nic więcej na chwilę obecną mi nie przychodzi do głowy.

Co do pozostałych słów, czyli tych totalnie nieregularnych, które się nie łapią na żaden z dwóch mechanizmów - w tym przypadku bym stworzył drugą tabelę, może być w tej samej bazie. Tutaj dałbym więcej kolumn - coś w stylu ID, słowo, forma1, forma2, forma3 i tak dalej. Oczywiście trzeba będzie tutaj wszystkie wartości wypisać ręcznie, no chyba, że też się dobierzesz do jakiejś gotowej listy/zestawienia.

A potem już samo sprawdzanie jak dane słowo się odmienia jest dość proste. Najpierw sprawdzasz, czy słowo występuje w tabeli 2 (czyli totalny freestyle). Jeśli tam jest, to wczytujesz jego formy wpisane do bazy i je wyświetlasz w aplikacji. Jeżeli słowa tam nie będzie to sprawdzasz, czy jest w pierwszej tabeli (słowa odmieniane zgodnie z "drugim" schematem). Ponieważ wiemy, jak te słowa należy odmieniać, więc nas interesuje jedynie, czy słowo tam występuje. Jeśli jest, to odmieniamy zgodnie z drugim schematem. A jeśli słowa nie będzie także w pierwszej tabeli, to znaczy, że mamy do czynienia z odmieniającym się regularnie, więc dodajemy końcówki zgodnie z tym, co podałeś już wieeele postów wcześniej :)

A co do managera - ja osobiście polecam https://sqlitestudio.pl/index.rvt.

0

Już trochę nie kumam. To potrzebuję tego SQLite Menagera czy nie? Bo w necie znajduję poradniki i oczywiście to co mi poleciłeś czyli dodanie słów do bazy w postaci forma1, forma2 itd. sam już wymyśliłem tylko nie wiem jak mam je dodać, bo w internecie są same przykłady, gdzie ktoś dodaje do formy komponenty i przycuski do zarządzania bazą, a ja chciałbym mieć tylko mój program, bez konieczności tworzenia dodatkowych komponentów.

Wybacz jeżeli te pytania są dziecinne mocno, ale nigdy nie ruszałem tych baz i naprawdę nie wiem jak to ugryźć. A tak btw. to masz może jakiś poradnik tj. komendy do tej bazy? Bo obecnie nawet nie wiem jak "przelecieć" przez nią tak jak mówisz.

// Edit. Ok, widzę, że dałeś już link do managera :)

1

Nie mam czego Ci wybaczać, temat jest dla Ciebie świeży, więc normalne, że możesz czuć się zagubiony.

Nie wiem na ile w ogóle masz pojęcie, czym jest SQL - dlatego kilka słów wprowadzenia ;) Dane można przechowywać na wiele sposobów. Można w plikach tekstowych, można także w plikach, w których zamiast tekstu zapisuje się struktury danych (file of record-type). Stworzono różne systemy działania z bazami danych - chociażby słynne i dawniej bardzo popularne pliki DBF. Ale to było za mało, bo one raczej skupiały się na pojedynczych rekordach, a nie na całości posiadanych danych. Dlatego kolejnym krokiem jest SQL (od razu uprzedzając osoby chcące mnie prostować - wiem, czym jest SQL, a czym sama baza/silnik, ale tutaj piszę w sposób uproszczony, żeby oddać ideę). W przypadku SQL działasz na większych partiach danych. Przykładowo - w "tradycyjnym" modelu, żeby znaleźć jakąś informację, nieraz musisz przeszukać cały plik, odczytać wszystkie rekordy. W wypadku SQL zadajesz pytanie, a resztę wykonuje za Ciebie silnik/baza.

I teraz dochodzimy do tego, dlaczego SQLite jest fajne. Taki tradycyjny silnik (chociażby MySQL, Postgres, MsSQL czy Oracle) musi być zanistalowany, skonfigurowany, musi cały czas działać. Jest to normalne w sytuacji, w której usługa ma być dostępna cały czas. Ale często SQL jest potrzebny tylko czasami i na chwilę, więc nie ma sensu odpalać wielkiego kombajnu, żeby przechować parę rzeczy. Istotna jest także kwestia przenośności - jeśli aplikacja odwołuje się do serwera SQL, to żeby można było mieć dostęp do danych z innych komputerów, musi on być dostępny publicznie.

Żeby zrobić z tym porządek ktoś kiedyś wymyślił SQLite. Z punktu widzenia użytkownika, działa to jak "prawdziwy" SQL, czyli wysyła się zapytania, które nakazują SQL wykonanie pewnych czynności. Ale różnica jest taka, że nie trzeba niczego instalować, nie ma żadnych wielkich systemów, które muszą chodzić w tle. W przypadku Windowsów całość ogranicza się do 1 albo 2 plików DLL, które trzeba umieścić w katalogu aplikacji. A rolę bazy odgrywa jakiś zwykły plik, w którym są zapisane potrzebne dane. Owszem, takie rozwiązanie ma parę minusów, chociażby brak haseł, użytkowników, poziomów dostępu itp, ale coś za coś. Trzeba umieć wybrać narzędzie do potrzeb. W Twoim przypadku, do trzymania listy słów. SQLite jest wystarczający całkiem.

To o co chodzi z tymi managerami i/oraz komponentami?

Zasadniczo różnego rodzaju managery to takie graficzne nakładki. Wszystko można zrobić w SQL ręcznie w konsoli. Chociażby tworzenie tabeli - można w jakimś graficznym kreatorze kliknąć coś w stylu "nowa tabela", potem pojawi się pewnie jakieś okienko, w którym się określi parametry tej tabeli. Ale równie dobrze można sobie ręcznie wywołać polecenie CREATE TABLE xxxxxxx i tam określić, co to ma być za tabela. Tak naprawdę, to manager wykona dokładnie to samo, tylko w sposób niejawny. W każdym razie - tego typu aplikacje są przydatne, bo można w łatwy i graficzny sposób mieć dostęp do danych zawartych w bazie, można także zmieniać ustawienia bazy, tworzyć i kasować tabele, dodawać kolumny itp. ALE żeby była jasność - sama baza/silnik bazy nie ma żadnego związku z managerem. Możesz mieć bazę i nie korzystać z managera. Manager to jedynie takie udogodnienie, edytor danych trzymanych w bazie.

Co do kontrolek/komponentów - tutaj można działać na dwa sposoby. W Lazarusie masz cały zestaw komponentów do pracy z bazami danych. Można z nich korzystać, ale w naszym przypadku nie ma takiej potrzeby, a wręcz przeciwnie, mam wrażenie, że byłoby z tym więcej zamieszania. Dlatego Ty powinieneś postępować zgodnie z tym, co masz napisane w tutorialu na 4P, do którego link wkleiłeś kilka postów wyżej. Po prostu - dodajesz do uses odpowiednie pliki, dorzucasz DLL, a następnie wydajesz stosowne zapytania. Zakładając, że rozumiesz co jest w tutorialu, powinieneś dać sobie radę. Ewentualnie pytaj dalej, w miarę możliwości postaram się coś wyjaśnić.

0

Bardzo pomocne są Twoje wpisy :) Coraz jaśniejsze się to robi dla mnie, no ale jest oczywiście problem, bo jak dodaję

SQLiteBaza: TSQLiteDataBase; //Obiekt odpowiedzialny za połączenie z bazą
SQLiteTabela: TSQLiteTable; //Obiekt odpowiedzialny za zapytania
_PATH: String; //Katalog w którym znajduje się nasza aplikacja

a następnie

procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteBaza := nil;
  _PATH := ExtractFilePath(Application.ExeName);
  if not FileExists(_PATH + 'baza.dat') then  //Sprawdzamy czy w katalogu z programem NIE istnieje baza danych
  begin
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat'); // Łączymy się z bazą
    SQLIteBaza.ExecSQL('CREATE TABLE tabela (id INTEGER PRIMARY KEY, imie VARCHAR, nazwisko VARCHAR)'); //A następnie tworzymy tabelę
  end
  else
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat');
end;

Próbuję to uruchomić i dostaję błąd

No i dalszy problem to jak dodać kolejne dane do bazy, bo w tutorialu jest napisane:

Wrzućmy na formę 3 Edity i Button. W OnClick Buttona piszemy tylko jedno polecenie

A jak ustaliliśmy już chciałbym nie dodawać żądnych innych form/komponentów.
Ten program, który podałeś fajny bardzo, bo przejrzysty i nawet udało mi się taką bazę dodać z pliku


Przy eksportowaniu mam kilka formatów pliku do wyboru i żaden z nich to .db ani .dat (jak w przykładzie na 4P) tylko XML, SQL albo nawet PDF. Z którego najlepiej korzystać?

0

Po pierwsze - jak możesz to wrzuć cały projekt do archiwum i podeślij to jako załącznik do posta - w ten sposób będzie mi łatwiej rzucić okiem, w czym jest problem.

Po drugie - w zakresie rozszrzenia pliku bazy: tak naprawdę nie ma to żadnego znaczenia, czy dasz .dat, .dup, .stefan czy .xyz. Jedynie istotne jest to, żebyś potem dokładnie taką samą nazwę pliku podał w aplikacji podczas otwierania bazy. Równie dobrze możesz nawet nie dawać żadnego rozszerzenia.

Po trzecie - z tego co widzę to masz zrobioną bazę. Z drugiej strony napisałeś, że podczas próby wykonania CREATE TABLE tabela (id INTEGER PRIMARY KEY..... pojawia się błąd. Napisz proszę, co chcesz zrobić, bo ne do końca rozumiem co tu się dzieje. tabelę masz, ale jednocześnie chcesz ją stworzyć jeszcze raz? Wiem, że to nie ma raczej nic wspólnego z podanym przez Ciebie errorem, ale tak zwyczajnie nie rozumiem, co chcesz osiągnąć, więc ciężko mi jakoś pomóc ;)

0

Ah, wybacz. To przez to, że robię 10 rzeczy na raz :P Twoim programem bawię się, ale na razie nie dodaję jej do programu, bo próbowałem utworzyć ją w programie i tam mam błąd. Jednocześnie w archiwum jest jeszcze plik txt IreVerbs, który zostawiłem póki nie działa baza :)

W katalogu mam plik sqlite3.dll

0

Teraz udzielę standardowej odpowiedzi, jakiej się udziela w branży IT: dziwne, u mnie działa ;)

Jakiego masz Windowsa - 32 czy 64 bit?

1

https://sqlite.org/download.html - spróbuj pobrać wersję dll 64-bitowej i zobacz, czy pójdzie.

Ewentualnie, jeśli Twój Lazarus produkuje wersje 64-bit, to może wymuś 32-bit. U mnie na testowym XP (jak łatwo się domyślić - 32bit) poszło za pierwszym razem, natomiast 64-bit Win7 z zainstalowanym 64-bit Lazarus (do celów testowych mam zainstalowane kilkanaście różnych maszyn wirtualnych z różnymi wersjami Windowsa, więc mogę szybko sobie przełączać i sprawdzać) miałem ten sam problem. Wprawdzie podmiana pliku .dll na 64-bit rozwiązała problem, ale mam dla Ciebie inną poradę: wywal Lazarusa 64-bit i zainstaluj 32-bit. Sugeruję to z dwóch powodów. Po pierwsze - mogą się czasem pojawiać kwiatki w stylu opisanego przez Ciebie. Mając 64-bit w takiej prostej aplikacji totalnie niczego nie zyskujesz, ale możesz sobie czasem życie skomplikować. A po drugie - jeśli chcesz, żeby aplikacja była przenośna, to lepiej robić ją 32-bit. Taką wersję odpalisz wszędzie, natomiast do wersji 64-bit musisz mieć 64-bitow system.

0

Dobra to jeszcze jedno zapytam i dziś daję Ci spokój, bo uwierz, że bardzo szanuję Twój czas, który wkładasz w pomoc :)

Czy jak w OnCreate daję:

begin
  SQLiteBaza := nil;
  _PATH := ExtractFilePath(Application.ExeName);
  if not FileExists(_PATH + 'IrregularVerbs.sql') then  //Sprawdzamy czy w katalogu z programem NIE istnieje baza danych
  begin
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat'); // Łączymy się z bazą
    SQLIteBaza.ExecSQL('CREATE TABLE tabela (id INTEGER PRIMARY KEY, imie VARCHAR, nazwisko VARCHAR)'); //A następnie tworzymy tabelę
  end
  else
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'IrregularVerbs.sql');
end;

to nie będzie mi zerować tej bazy przy każdym uruchomieniu programu?

0

Ze spokojem, jak coś chcesz wiedzieć to pytaj.

Odnośnie ostatniej kwestii - przecież sam możesz sprawdzić, co się stanie z bazą, jak odpalisz CREATE TABLE na istniejącej tabeli :P

Porada 1: https://www.sqlite.org/lang_createtable.html: "It is usually an error to attempt to create a new table in a database that already contains a table, index or view of the same name" (czyli mówiąc prościej - wywali jakiś błąd, ale tabeli nie wyczyści).

Porada 2: można zrobić lekką modyfikację i zapisać to w postaci create table if not exists :) http://www.sqlitetutorial.net/sqlite-create-table/

0

Siedzę już długo nad tym i przejrzałem z milion stron, ale nie jestem wstanie dojść jak mam wyszukać zmiennej Verb w tej bazie. Próbowałem jakimiś metodami typu 'SELECT verb_name FROM ireverbs WHERE verb_name LIKE @Verb', ale nic nie działa. Nie wiem jak porównać wartości zmiennej w Delphi i to co szuka w SQLite. W ogóle nie mogę zrozumieć, kiedy coś się wykonuje w tym SQLu, a kiedy nie, bo na razie całkowicie z tym stanąłem w miejscu.

Dobra, mały update: Udało mi się zrobić żeby program szukał w bazie :D Ależ jestem szczęśliwy!

SQLiteTabela := SQLiteBaza.GetTable('SELECT * FROM ireverbs');
  if Verb = SQLiteTabela.FieldByName['verb_name'] then
  Result := true;
  SQLiteTabela.Free;

Mały problem jest tylko taki, że nie wiem jak zrobić żeby program przeleciał przez całą bazę, bo na razie szuka tylko pierwszego rekordu w bazie:P

Próbowałem coś takiego, ale wywala mi błąd

  while not SQLiteTabela.EOF do
  begin
  	SQLiteTabela := SQLiteBaza.GetTable('SELECT * FROM ireverbs');
    if Verb = SQLiteTabela.FieldByName['verb_name'] then
  	begin
  		SQLiteTabela.Next;
  	  Result := true;
  	end;
  		SQLiteTabela.Free;
  end;
end;  

0

Udało się! Po 100 próbach napisałem coś takiego i wychodzi na to, że działa :D

SQLiteTabela := SQLiteBaza.GetTable('SELECT * FROM ireverbs');
 for i := 1 to SQLiteTabela.RowCount do
 begin
   if Verb = SQLiteTabela.FieldByName['verb_name'] then
   Result := true
   else SQLiteTabela.Next;
 end;
 SQLiteTabela.Free;

Nie wiem czy to optymalne rozwiązanie, ale na razie nic nie wymyślę ponad to, a i tak z tego jestem dumny :D

1

w załączniku masz prosty przykład obsługi sqlite w lazarusie.

0

Dzięki! Tutaj widzę jest obsługa z komponentami, a na razie z tego co widzę nie potrzebuję tego, ale dziękuję, bo może przyda się na przyszłość :)

1

SQLiteTabela := SQLiteBaza.GetTable('SELECT * FROM ireverbs'); for i := 1 to SQLiteTabela.RowCount do

Nie wiem czy to optymalne rozwiązanie

To rozwiązanie ma jeden plus - działa. Ale tu jego plusy się kończą :P

To co zrobiłeś praktycznie nie różni się zanadto od działania z plikiem tekstowym. I tu i tam wczytuje się wszystkie dane, a potem w nich grzebie i stara się znaleźć potrzebny element. SQL totalnie nie tak ma działać. W przypadku SQL masz tak zaprojektować zapytanie, żeby silnik SQL sam przeszukał dane i zwrócił Ci to, co jest potrzebne, bez konieczności dalszego przesiewania uzyskanych danych.

Widzę, że 2 posty wyżej @Paweł Dmitruk dał Ci gotowy przykład. Przejrzyj go, postaraj się zrozumieć, jak jego program działa, a potem daj znać, czy wiesz już jak porządnie wysłać zapytanie do SQL'a, czy potrzebna jest pomoc.

Podpowiedź 1 : SELECT * FROM xxx WHERE yyy.
Gwiazdka oznacza że ma pobrać wszystkie kolumny. Jeśli potrzebujesz tylko jedną albo kilka, zamiast gwiazdki możesz wstawić nazwy tych kolumn, na których Ci zależy
Po WHERE dajemy warunek - coś w stylu WHERE rok_urodzenia > 1980. https://www.w3schools.com/sql/sql_where.asp

Podpowiedź 2: skoro odpytujesz bazę ze słówkami nieregularnymi, to niekoniecznie musisz coś z niej pobrać (to dotyczy "drugiego sposobu odmiany"). Wystarczy informacja, że rowCount jest większy od zera - oznacza to, że dane słowo jest w bazie. Nie musimy go pobierać, wystarczy że wiemy, że słowo tam się pojawia. Co innego w przypadku totalnie nieregularnych - w takim przypadku musimy pobrać wartość wszystkich kolumn/wszystkich form danego słowa, żeby je wyświetlić użytkownikowi (bo ponieważ są to słowa totalnie nieregularne, nie da się ich poszczególnych form wytworzyć automatycznie, więc trzeba je wczytać skądś, w naszym przypadku z bazy).

0

And you've burst my bubble aż wypada powiedzieć zostając w nomenklaturze obcojęzycznej :P

A więc tak - w tej bazie jest jedna kolumna to nie wiem czy to jakaś różnica czy dam * czy verb_name, ale powiedzmy, że napiszę SELECT verb_name FROM ireverbs to problem zaczyna się w miejscu, gdzie muszę napisać warunek do WHERE, bo nie mogę znaleźć jak porównać to co wpisałem do zmiennej Verb z tym co jest w bazie. Jedyny sposób jaki zadziałał to ten co widać w poście wyżej :)

Ten program @Paweł Dmitruk trudny do zrozumienia się wydaje, bo masa funkcji, których nie widziałem nigdy i trochę ciężko się połapać.
Próbowałem trochę kombinacji w stylu SELECT verb_name FROM ireverbs WHERE verb_name =' +Verb+, no ale nic z tego. Nie wiem jak mam się odnieść do tej zmiennej.

Co do tej podpowiedzi drugiej to w ogóle nie rozumiem co masz na myśli, że nie musi nic pobierać z bazy. Ta funkcja teraz nic nie pobiera tylko sprawdza czy słowo występuje w bazie dlatego mam for i := 1 to SQLiteTabela.RowCount do

Edit: // Zrobiłem coś takiego teraz
Powiedz czy mniej więcej oto chodziło, czy pudruję trupa? :P
SQLiteTabela := SQLiteBaza.GetTable('SELECT verb_name FROM ireverbs WHERE verb_name = ' + QuotedStr(Verb));

0

No to metodą małych kroczków/drobnych podpowiedzi :D

Zrób jakąś zmienną, nazwijmy ją WordToCheck. Wykonaj na niej serię operacji - czyli wczytanie z jakiegoś pola wypełnionego przez użytkownika, zamiana na małe/wielkie litery, ewentualnie obcięcie końcówek albo dodanie czegoś. W ten sposób będziesz miał w tej zmiennej słowo, które chcesz uzyskać. A następnie dajesz zapytanie SQL w postaci 'SELECT verb_name FROM ireverbs WHERE verb_name = ' + WordToCheck.

W celach testowych zawsze możesz skorzystać z tzw. dupa debuging - w tym przypadku możesz zrobić showmessage pokazujący wartość zapytania SQL. Zobaczysz, czy się ono poprawnie tworzy.

0

No, ale ja właśnie mam taką zmienną i ona się nazywa Verb
Verb := Trim(LowerCase(VerbEdit.Text))

a potem na tej zmiennej mam to
SQLiteTabela := SQLiteBaza.GetTable( 'SELECT verb_name FROM ireverbs WHERE verb_name = ' + QuotedStr(Verb));

Chyba, że znowu nie rozumiem tego co chciałeś mi przekazać :P Nie do końca rozumiem te zapytania itd. Muszę poczytać o tych bazach danych, ale dziś już nie dam rady. Najwcześniej we wtorek dopiero a jest szansa, że ruszę dopiero w czwartek to :(

0

To mam propozycję - wrzuć tu jako załącznik plik z bazą słówek, a ja zrobię kod, który sprawdzi, czy podane przez użytkownika słowo występuje w tej bazie. A Ty będziesz miał możliwość pokombinowania samodzielnie, a jeśli nie dasz rady/będziesz potrzebował podpórki - rzucisz okiem na mój kod. Wydaje mi się, że brzmi uczciwie ;)

0

Szanowny Panie - poniżej wklejam działający kod :)

Chciałem dać to jako załącznik, ale przy tych dosłownie kilku liniach to chyba nie ma sensu ;)


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, sqlitetable3;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;
  Baza: TSQLiteDatabase;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Baza := TSQLiteDatabase.Create('ireverbs.sql');
  if (not Baza.TableExists('IreVerbs')) then
    begin
      Baza.Free;
      ShowMessage ('Nie można wczytac bazy.');
      Application.Terminate;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Odpowiedz: TSQLiteTable;
begin
  Odpowiedz := Baza.GetTable('SELECT verb_name from IreVerbs WHERE verb_name = "' + Form1.Edit1.Text + '"');
  if (Odpowiedz.Count > 0) then
    ShowMessage ('Slowo wystepuje w bazie')
  else
    ShowMessage('Slowa brak');
  Odpowiedz.Free;
end;

end.

0

Dziś nie mam za bardzo czasu więc tylko tak rzuciłem oko na to co napisałeś i nie bardzo rozumiem znowu

Nie rozumiem jak to niby sprawdza czy dane słowo jest w bazie
if (Odpowiedz.Count > 0) then
przecież to tylko wskaże czy wpisów w bazie jest więcej niż 0.
Dodatkowo po przerobieniu tego pod mój program
Odpowiedz := TSQLiteDataBase.GetTable('SELECT verb_name from IreVerbs WHERE verb_name = "' + MainForm.VerbEdit.Text + '"');
dostaję wiadomość, że "Identifier not found "VerbEdit"" mimo, że przecież obiekt VerbEdit istnieje i ma się dobrze :)

Dodatkowo teraz użyłem Twojego kodu na zupełnie nowym projekcie i pomimo, że się kompiluje to nie wyszukuje nic. Po próbie szukania dostaję błąd "Acces Violation".

EDIT:
Na podstawie Twojego kodu napisałem takie coś

 SQLiteTabela := SQLiteBaza.GetTable(
 'SELECT verb_name FROM ireverbs WHERE verb_name = ' + QuotedStr(Verb));
 if SQLiteTabela.Count > 0 then
 Result := true;
 SQLiteTabela.Free;  

i to działa :/ Nie wiem zupełnie dlaczego, ale to działa. Mógłbyś wyjaśnić ten fragment z tym .Count? Nie wiem dlaczego to działa :( Chyba, że to sprawdza ile razy w bazie pojawia się dane słowo, tylko że jeśli tak to czy to też nie przelatuje przez całą bazę?

0

Jeszcze pokażę coś dzisiaj zrobiłem w wolnej chwili. Nie wiem czy to dobrze czy źle, ale pozbyłem się jednej procedury na rzecz funkcji CheckedVerbsFunction.
Wygląda ona tak

function TMainForm.CheckedVerbsFunction(X: Integer): String;
begin
  Result := AnsiRightStr(Verb, X);
end;

Zastąpiłem nią procedurę CheckedVerbsProcedure i tym samym zmiennej globalnej CheckedVerb

procedure TMainForm.CheckedVerbsProcedure(X: Integer);
begin
  CheckedVerb := AnsiRightStr(Verb, X);
end;

Teraz słowo sprawdzam tak

if (CheckedVerbsFunction(4) = 'care') or (CheckedVerbsFunction(4) = 'gare') then

Podzieliłem główną procedurę Conjugation na 3: AreConjugation, EreConjugation i IreConjugation i wywołuję je w procedurze MainConjugation. Nie wiem czy to coś daje, ale przejżyściej to wygląda i łatwiej mogę dopisywać warunki do konkretnych słów o konkretnej końcówce.

Co do tych Case'ów, które polecałeś to za dużo zachodu z tym chyba. Ciągle jakieś błędy, nie wiem jak ogarnąć ORy, a dodatkowo dla mnie to dużo mniej czytelnei wygląda więc chyba zostanę przy IFach :)

1

Jak już pisałem kilka razy - fajnie mi się z Tobą pisze, jesteś samodzielny, kombinujesz we własnym zakresie - dlatego chętnie odpowiem na Twoje pytanie. Zrobię to trochę "inaczej" - ponownie wkleję kod umieszczony 2-3 posty wcześniej (niektóre fragmenty pomijam, bo nic nie wnoszą do sprawy) i skomentuję co każda linia robi. Mam nadzieję, że po tym będziesz już rozumiał, o co chodzi :)

Baza: TSQLiteDatabase; - deklarujemy zmienną, która będzie nam przechowywać odwołanie do bazy. Robię to globalnie - w ten sposób ta baza będzie dostępna ze wszystkich procedur i funkcji

Baza := TSQLiteDatabase.Create('ireverbs.sql'); - otwieramy bazę. Na razie nie wiemy, czy ten plik istnieje (oraz czy zawiera zapisane dane), czy istnieje, ale nie jest bazą, a może w ogóle go nie ma. Dlatego musimy to sprawdzić

if (not Baza.TableExists('IreVerbs')) then - poleceniem TableExists sprawdzamy, czy w otwartej przed chwilą bazie jest tabela o nazwie "IreVerbs". Funkcja TableExists zwraca TRUE jeśli tabela istnieje, natomiast jeśli jej brak to otrzymujemy FALSE. Ponieważ przy if mamy NOT, jeśli tabeli nie ma to zostaną wykonane następujące instrukcje: skasowanie obiektu bazy, wyświetlenie komunikatu o braku bazy oraz zakończenie aplikacji.

Skoro/jeśli aplikacja nie została zamknięta, to znaczy, że udało się bazę wczytać i możemy działać. Po wpisaniu jakiegoś słowa do sprawdzenia i wciśnięciu przycisku zostaje wywołana procedura Button1Click.

var Odpowiedz: TSQLiteTable; - deklarujemy obiekt, do którego zostaną wsadzone dane uzyskane jako odpowiedź po wykonaniu zapytania SQL.

Odpowiedz := Baza.GetTable('SELECT verb_name from IreVerbs WHERE verb_name = "' + Form1.Edit1.Text + '"'); - do zmiennej zadeklarowanej w poprzednim akapicie przypisujemy wynik zwrócony przez zapytanie SQL.

  • SELECT verb_name - informujemy SQL, że interesuje nas kolumna o nazwie "verb_name" i chcemy otrzymać jedynie dane w niej przechowywane. W tym przypadku nie ma innych kolumn, ale wyobraź sobie np. tabelę z danymi pracowników (wiek, wykształcenie, płeć, imię, data urodzenia, stanowisko, staż pracy, czy jest niepełnosprawny, czy może pracować w weekendy itp.). Jakbyśmy dali SELECT * to zapytanie by nam zwróciło wszystkie informacje, ale czasami szukamy tylko określonych danych - np. wykształcenia. Dlatego wskazujemy SQL'owi, jakie dane ma nam zwrócić
  • from IreVerbs - wskazujemy, w której tabeli te dane są przechowywane. Jedna baza może zawierać wiele tabel, więc trzeba wskazać, która nas interesuje
  • WHERE verb_name="accutio" - jakbyśmy nie dali WHERE, to w odpowiedzi byśmy dostali wszstkie dane zawarte w tabeli. O ile pamiętam, to wcześniej właśnie w ten sposób pobierałeś dane z bazy. Nie po to bawimy się SQL'em, żeby się potem ręcznie jeszcze babrać w przeszukiwanie danych uzyskanych w odpowiedzi. Dlatego podany zapis oznacza, że ma zwrócić jedynie takie wyniki, które mają w kolumnie verb_name wpisaną wartość "accutio".

Wracając do przykładu z pracownikami - jakbyśmy chcieli np. sprawdzić, jakie wykształcenie mają ludzie urodzeni w roku 1975, to moglibyśmy dać zapytanie SELECT wyksztalcenie FROM pracownicy WHERE rok_urodzenia = 1975. To polecenie oznacza, że ma znaleźć pracowników, którzy mają rok urodzenia 1975, a następnie zwrócić nam wykształcenie każdego znalezionego pracownika.

Mam nadzieję, że już rozumiesz, jak działa to zapytanie. Ważna sprawa - zwróć uwagę, że słowo którego szukamy podałem w cudzysłowie. Wbrew pozorom te dwa poniższe zapisy oznaczają coś zupełnie innego:
'SELECT verb_name from IreVerbs WHERE verb_name = "accutio"
ORAZ
'SELECT verb_name from IreVerbs WHERE verb_name = accutio.
W pierwszym przykładzie podajemy, że interesują nas pozycje, które jako słowo (verb_name) mają wartość "accutio". A co w takim razie oznacza drugi zapis? W przypadku SQL możemy tworzyć o wiele bardziej skomplikowane warunki. Powiedzmy, że mamy tabelę pracowników, która posiada także kolumny "rok_zatrudnienia" oraz "rok_zwolnienia". Jeśli chcemy znaleźć pracowników zatrudnionych w 2010 to wpisujemy WERE rok zatrudnienia = 2010. A co jakbyśmy chcieli znaleźć pracowników, którzy zostali zatrudnieni oraz zwolnieni w tym samym roku (niezależnie, jaki by to rok nie był)? Wtedy byśmy dali zapytanie WHERE rok_zatrudnienia = rok_zwolnienia. Taki zapis oznacza, iż interesują nas jedynie takie pozycje, w których pracownik w tym samym roku został przyjęty oraz zwolniony. A wracając do naszego przykładu - zapis WHERE verb_name = accutio SQL rozumie jako "podaj mi wyniki, w których wartość kolumny verb_name jest taka sama jak wartość kolumny accutio". No ale przecież nie mamy kolumny accutio, prawda? Dlatego SQL wywali błąd i niczego sensownego nie zwróci. To jest powód, dla którego wartość string do zapytania podajemy w cudzysłowie.

No i ostatni fragment. Jeśli zrozumiałeś jak działa samo zapytanie SQL, to masz świadomość, że po zadaniu zapytania dostajemy wynik zawierający interesujące nas dane. Fragment if (Odpowiedz.Count > 0) then sprawdza, ile razy poszukiwane słowo występowało w bazie. Jeśli count zwróci zero, oznacza to, że słowo nie występuje w bazie. Natomiast jakikolwiek wynik dodatni (przecież może być więcej niż 1 wystąpienie, ktoś mógł się pomylić i kilka razy to słowo dodać do tabeli) oznacza, że słowo występuje/znajduje się w bazie.

0

Dziękuję bardzo (który to już raz?). Wszystko wydaje się dużo bardziej przejrzyste teraz :D Nie mogłem wcześniej zrozumiec trochę jak działa ta "opcja" WHERE, bo rozumiałem, że zapis np. WHERE = "accutio" oznacza, że program i tak musi przelecieć całą bazę i dopiero potem zwrócić, że taki rekord się znajduje.

Obecnie tak wygląda moja funkcja i na razie niech taka zostanie

function TMainForm.IreVerbsChecker: Boolean;
begin
	SQLiteTabela := SQLiteBaza.GetTable(
	'SELECT verb_name FROM ireverbs WHERE verb_name = ' + QuotedStr(Verb));
	if SQLiteTabela.Count > 0 then result := true;
	SQLiteTabela.Free;
end;

Mam nadzieję tylko, że bardzo nie skrytykujesz tych zmian, bo chciałem się w środę wziąć za czasowniki zwrotne ;p

0

No nie rób ze mnie jakiegoś dupka/psychola, który się tylko czepia :P

Co do QuotedStr - jest to jak najbardziej OK, można też zrobić jak ja, czyli dodać ręcznie cudzysłów, ale z dwóch opcji Twoja jest bardzie professional ;)

W sumie to jedynie bym zrobił lekką modyfikację przy if. Obecnie masz podane, że result ma być TRUE jeśli znaleziono słowo w bazie, ale nie podajesz, co ma się stać w sytuacji, kiedy słowa nie będzie. Owszem, można wyjść z założenia, że w pewnych sytuacjach pewne zmienne są inicjowane określoną wartością, ale ja osobiście zawsze wolę jawnie przypisać pożądaną wartość.

Zresztą rzuć okiem na ten wątek - https://4programmers.net/Forum/Delphi_Pascal/321598-wskazniki_incompatible_types. Są tam opisane dwa przykłady, w których inaczej się zachowuje Delphi, a inaczej Lazarus. Moim zdaniem nie powinno się polegać na "automagicznych" działaniach, bo nie masz gwarancji, że w innym środowisku albo w kolejnej wersji kompilatora to się nie zmieni. Później taki błąd będzie ciężko wyłapać. A jak jawnie dodasz else Result := FALSE to możesz czuć się bezpieczny, a ponadto cała funkcja robi się trochę bardziej czytelna.

0

Zupełnie nie to miałem na myśli :P Po prostu sam często robię proste błędy i wychodzę z założenia, że jak coś działa to znaczy, że jest dobrze, a sam mi pokazujesz, że wiele rzeczy można usprawnić :)

Co do tych If'ów to nie wiem czy dobrze zrozumiałem, ale wydaje mi się, że w moim kodzie jest już co się ma stać jak słowa nie znajdzie w bazie, mianowicie

    If IreVerbsChecker then
    ChangeCaptions('isco', 'isci', 'isce', 'iamo', 'ite', 'iscono')
    else
    ChangeCaptions('o', 'i', 'e', 'iamo', 'ite', 'ono');

czyli jeśli funkcja IreVerbsChecker jest true to dodaj końcówki 'isco', 'isci', 'isce', 'iamo', 'ite', 'iscono', w przeciwnym wypadku odmień regularnie czyli dodaj końcówki 'o', 'i', 'e', 'iamo', 'ite', 'ono'

0

Z tymi ifami zupełnie się nie zrozumieliśmy.
Chodziło mi o fragment if SQLiteTabela.Count > 0 then result := true;. Masz tu sprawdzenie warunku oraz wskazanie co zrobić, jeśli wynik będzie pozytywny (wtedy dajesz Result := TRUE). Ja bym jeszcze dodał else Result := FALSE, żeby wprost określić, jaki ma być wynik zwrócony przez funkcję jeśli nie znajdzie danego słowa. Rozumiemy się? :D

0

o parametrach zapytań słyszeli czy nie?

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