DBGrid - przerysować kolumnę (problem)

0

Mam sobie tabelę DBGrid (Paradox7).
Pierwsza kolumna to jest LP. i wiersze są numerowane automatycznie (+autoincrement).
Nieraz zdarza się że musze usunąć środkowe wiersze i postać LP. wygląda np. tak:
LP.
1
2
5
6
7
czyli wiersz 3 i 4 został usunięty.
Pytanie brzmi: jak odświeżyć lub przerysować tabelę aby LP. miało postać już
1
2
3
4
5
Ma uporządkować numery, aby były po kolei. Dzięki za wskazówki!!! :)

0

OK już sobie z tym poradziłem tylko autoinkrementację musiałem wyłączyć, ale za to zrobiłem swoją :)

Dla ciekawskich kodzik:

var
l:integer;
begin
l:=0;
Table8.First;
  while not Table8.Eof do
     begin
inc(l);
   Table8.Edit;
  Table8.FieldByName('LP.').asString:=IntToStr(l);
        Table8.Next;
   end; end;
0

Brawa za inwencję i twórczy wkład. Proponowałbym jeszcze podpiąć tą procedurę po przycisk USUŃ (pewnie taki masz).

//spróbuj odpalić tą procedurę na przefiltrowanej tabeli :P

0

Tak, dodałem od razu pod przycisk USUŃ i pod przycisk DODAJ REKORD.
Bardzo ładnie przerysowywuje numerację i ani jednego błędzika nie ma :)
Polecam ten kod wsystkim! :)

OK, ale mam teraz inny problem: w innej kolumnie mam liczby:
12
2
25
17
45
1
Oczywiście te liczby są w następnych wierszach jednej kolumny.
I teraz muszę zrobić takie jakby segregowanie bez zmiany pozycji wierszy, aby w Edit przedstawiało komórkę z najbliższą liczbą zera czyli komórkę 1, a potem jak usunę wiersz z tą komórką 1 to potem w Edit ma pokazywać wiersz z komórką 2 itd.

Ja wymyśliłem takie coś aby tą kolumnę przedstawiać w Combobox. Ten komponent segreguje sobie wszystkie stringi, a potem napisać procedurę dla Edita:
Edit1.Text:=Combobox1.Items.Strings[0];
I to pokazywałoby mi wiersz najbliższy zeru. Zrobiłbym jeszcze odświeżanie w przypadku usunięcia wiersza.
Czy taki sposób na to jest dobry, czy macie jakieś inne pomysły???
Dzięki za wskazówki, kodu nie chcę, bo chcę się sam nauczyć. Cześć :)

0

Nie bardzo chwytam dowcip :(
Najczęściej w Editach wyświetla się zawartość bieżącego rekordu a Ty byś chiał dodatkowo wyświetlić najmniejszą wartość danej kolumny, czy dobrze zrozumiałem?

//Ja tam bym poszedł na łatwiznę
Dodałbym kolejną kontrolkę TTable i TDataSource podłączone do tego samego pliku, indeks ustawiony na kolumnie której tam chcesz i DBEdit podłączony do tej tabeli (może to mało efektywne ale powinno działać)
Znowu zero kodu :P

0

No troszkę zamieszałem to fakt.
Bieżący rekord podaje DBEdit a nie Edit :)
Edita trzeba dobrze opisać, a w DBEdit wystarczy ustawić w Properties kolumnę do odczytu :)

OK napiszę prościej:
Mam sobie ListBox, Edit i Button.
W Listbox mam np. 5 wierszy, a one wyglądają tak:

657
2
34
1617
14
I teraz za kliknięciem na Button, w Edit ma mi się wyświetlić String najbliższy liczbie 0. Czyli to będzie drugi wiersz o wartości = 2. Jak skasuję ten wiersz to potem po kliknięciu na Button ma się znów pokazać String najbliższy liczbie 0 czyli teraz 14 itd. itd. :) Kumasz teraz? I tak teraz chcę zrobić, ale nie na Listbox tylko na kolumnie w DBGrid.

0

Może ja czegoś nie rozumiem ale... DBGrid pobiera wartości z tabeli... to co złego jest w sposobie powyżej?
Możesz sobie pokomplikować życie i pod przycisk podpiąć procedurę która odczyta wszystkie wiersze z jednego pola tabeli (sposób znasz) przepiszesz je do tablicy (najlepiej dynamicznej), wyszukasz najmniejszą wartość lub przesortujesz (co na jedno wyjdzie) tablicę i wyświetlisz najmniejszą wartość, tylko po co?

//Po zastanowieniu jeszcze jeden sposób na pokomplikowanie sobie życia.
Dajesz zmienną x typu integer, przechodzisz do pierwszego rekordu tabeli przypisujesz do x wartość pola, przechodzisz do następnego rekordu i sprawdzasz czy x jest wieksze od wartości pola, jeżeli tak przepisujesz wartość pola do x i przechodzisz do następnego rekordu, jeżeli nie po prostu przechodzisz do następnego rekordu, po przejściu całej tabeli x będzie zawierać najmniejszą wartość.
Miało nie być kodu :P

0

Tamte sposoby które wymyśliłem okazały się dobre do czasu gdy nie wykasowałem jakiegoś wiersza ze środka.

Myślałem nad tym twoim ostatnim sposobem i zrozumiałem go, ale kodu nie umiem napisać. Wiem że tu chodzi o porównywanie kolejnych komórek, ale jak napisac to kodowo? Poprosze jednak o kod :) dzięki.

0

Sposob z dodaniem TTable nie działa? Wierzyć mi się nie chce, może dodaj odświeżanie nowej tabeli. Tak czy inaczej.. nie sprawdzałem więc się nie będę mądrował ale teoria wydawała się słuszna.

Oto kodzik:

var
  x : integer; //przy założeniu że w kolumnie są tylko liczby całkowite
begin
  Table.First;
  x := Table.FieldByName('NazwaPola').AsInteger;
  Table.Next;
    while not Table.Eof do
       begin
          if x > Table.FieldByName('NazwaPola').AsInteger then
            x := Table.FieldByName('NazwaPola').AsInteger
               else
                  Table.Next;
       end;
end;

//jeżeli któreś pole będzie puste to x będzie zero, ale to najmniejsza wartość jeżeli nie stosujesz liczb ujemnych :P

0

Teraz działa dobrze :)

Tylko jest teraz jeden mały schodek.
Otóż w kolumnie mogę mieć takie same dwie lub więcej wartości, np. dwa razy wartość 0 lub 2. A te liczby to dokładnie są dni :)
Czyli np. zostało 0 dni lub 2 dni do końca, a następna kolumna to są [GODZINY].

I teraz może sięzdarzyć, że będę miał tak:

[DNI] [GODZINA]
0 14:45
0 13:40

A powiedzmy, że mamy obecnie godzinę 12:30.
Ma wyszukać rekord z godziną (bo już dzień wyszukany wcześniej), która będzie najbliższa godzinie obecnej czyli 12:30. To będzie ten rekord z godziną 13:40.
Teraz mam taki problemik :)

0

To masz problem z odpowiednim podejściem do sprawy.
Zrób to na SQLu, jedno zapytanie i po sprawie.
Na TTable nie da się stosować złożonych zapytań.
Z drugiej strony jak już TAK DALEKO zabrnołeś to można by założyć filtr na DNI o wartości x, i powtórzyć wyszukiwanie w GODZINA (zainteresuj się wbudowaną procedurą DecodeTime) i wynik wrzucić do FindKey (wbudowana procedura) albo ponownie filtrować. (DNI = x and GODZINA = y - jakoś tak)
Trochę to zagmatwane a mi się już nie chce myśleć. [???]
Sugerowałbym jednak zastąpienie TTable - TQuery, SQL daje więcej możliwości.
Powodzenia w zgłębianiu wiedzy.

0

No to musiałbym się uczyć SQL'a, którego oczywiście chcę poznać porządnie.
Filtr może i zrobię, bo w innych tabelach mam zrobiony, ale wtedy będę widział tylko pofiltrowane rekordy (a może to i dobrze?). A chce widzieć wszystkie. Hmm jednak te filtry wstawię.

Zrobiłem jeszcze prockę do usuwania wszystkich rekordów z tabeli, z wcześniejszym zapytaniem o to. na pewno się komuś to przyda:

procedure TForm1.SpeedButton7Click(Sender: TObject);
begin
 if Application.MessageBox('Czy napewno usunąć wszystkie rezerwacje?','Rezerwacje',
MB_IconQuestion or MB_YESNO)=IDYES then begin
   Table8.First;
    while not Table8.Eof do
       begin
         Table8.Delete;
  end;end;end;

Kurde bardzo chcę tego SQL'a się nauczyć, chyba poszukam jakieś kursy i potem chciałbym go wtapiać w Delphi'm, czyli robić jakieś na początku proste bazy.

Mam jeszcze kilka pytań dręczących mnie, ale chyba nie będę Ci już zawracał gitarry, bo nie chce Ci się myśleć ;)

0

DBGrida masz podłączonego do jednego TTable, dodaj drugi TTable podłączony do tego samego pliku i na nim filtruj, wyszukuj itd. nie zapomnij o odświeżaniu -Table.Refresh, dla wizualizacji Twoich poczynań możesz tymczasowo wrzucić drugiego DBGrida. Pierwszy DBGrid będzie cały czas wyświetlał wszystkie rekordy.
Proste jak metr sznurka w kieszeni. ;)

0

No wiem że tak można zrobić, ale nie chcę śmiecić formy sobie, nawet jeśli elementy dodatkowe będą ukryte po kompilacji :)

Ale za to wpadłem na inny pomysł :)
Może dosyć spartański sposób, ale te liczby dni zamieniać na godziny?
Jeśli będzie już 0 dni to coś się już wymyśli :)
Chyba ten pomysł zadowoli moje potrzeby :)

Wiem, oszalałem, ale cóż...

0

Nie bardzo widzę co wniesie zamiana dni na godziny, ale ja ograniczony jestem :/

Widać że wiedzę masz niewielką ale nikt nie rodzi się omnibusem.
Ale z myśleniem też u Ciebie nie najlepiej, bez obrazy.
W jednym z poprzednich postów pytałeś jak porównać czas, więc czemu nie porównywać daty i czasu jako całości? 2005-07-31 20:55
Nawet jeżeli przechowujesz datę w jednej kolumnie a czas w innej to da się je połączyć (np. najpierw konwertując do stringa, łącząc i konwersja do TDateTime) i zapisać w innej kolumnie.
Teraz już tylko operujesz na jednej kolumnie (wyszukuj, porównuj, filtruj itd) kóra przecież nie musi być widoczna w DBGridzie. Tylko trzeba chwilę pomyśleć.

Jak to nie rozwiąże Twojego problemu to ja się poddaję :P

0

Na 100% rozwiąże, bo chodzi o to aby te dwie kolumny skonwertować do jednej i z niej wyszukiwać, filtrować itd. Ja siedzę w Delphi od jakiegoś miesiąca, a w bazach od wtorku więc sie nie dziw, że u mnie z myśleniem nie najlepiej jeszcze.

No cóż, będę musiał teraz czytać gdzieś od tej konwersji.

0

Konwersje:
data do stringa - DateTimeToStr(data) czas chyba taka samo
string do daty - StrToDateTime(string)

I tym prostym sposobem oszczędziłem Ci trzy dni życia :P

PS. Jak łączy się stringi to chyba wiesz?
A jak nie to zapytaj jakiejś dziewczyny, one noszą stringi :P

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