Seek(); w plikach typowanych - błąd

0

Siemano.
Mam poniższy kod:

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
if FilePos(plik)>0 then
 Seek(plik,FilePos(plik)-1);
RecordDisplay(FilePos(plik));
end;

Czemu to nie działą jak należy? :/
Gdy sobie wyświetliłem FilePos(plik); na Canvasie głównej formy to wyskoczyło mi 2 (mam 3 przykłądowe rekordy w plik), a jak od tej 2 odejmuję 1 to nie wyświetla się rekord numer 1 tylko nadal 2!!!!!!! [glowa]

0

Może nie

 Seek(plik,FilePos(plik)-1); 

tylko

Seek(plik,FilePos(plik)-sizeof(TwujRecord));
0
 Seek(plik,FilePos(plik)-SizeOf(TSerwis));

I/O error #131 :-/
Gdzie mogę obadać jaki to błąd?? Bo wyskakuje podczas działania programu, a nie przy kompilacji :/ :/

0

function SysErrorMessage(ErrorCode: Integer): string; I dowiesz się jaki to błąd.

A co do samego pliku... Co to za plik? Textfile? File? File of something? Jak otwierasz ten plik - reset/rewrite(f), czy reset/rewrite(f,x)?

Wybacz, ale to co podałes jest jak najbardziej poprawne, poza tym że filepos() może zwracać również wartość 0. Seek() ustawia znacznik czytania/pisania nie na konkretny bajt, tylko na rekord, więc jest w porządku. Tak samo działają filepos i filesize, zwracają wartości względem rozmiaru rekordu lub drugiego parametru reset/rewrite.

0

Więc tak:

Mam rekord TSerwis i plik TSerwisFile (chyba zawartość rekordu nie jest ważna?). W części zmiennych globalnych zadeklarowałem jedną zmienną dotyczącą naszgo pliku o nazwie 'plik' (;p)

var
  Form1: TForm1;
  plik: TSerwisFile;

na razie tworzę obsługę formularza i plików więc dla potrzeb edycji tworzę (czyszczę zawartość) plik w metodzie:

procedure TForm1.FormCreate(Sender: TObject);
var
dane:TSerwis;
begin
assignfile(plik,'c:\dane.dat');
<b>rewrite(plik);</b>

//tu wstawiam 3 rekordy za pomocą WRITE();

RecordDisplay(0); //ta procedura wyświetla zawartość rekordu podanego w parametrze na formularzu

Tak więc jak widać na listingu plik otwieram za pomocą REWRITE.
A sama procedura wywołująca błąd ma postać:

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
if FilePos(plik)>0 then
 Seek(plik,FilePos(plik) - SizeOf(TSerwis));
RecordDisplay(FilePos(plik));
end;

Jej poprzednia wersja, która nie działała poprawnie bo nie wyświetlałą dobrego rekordu na formularzu (choć błedó kompilatora nie było) miała postać:

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
if FilePos(plik)>0 then
 Seek(plik,FilePos(plik) - 1);
RecordDisplay(FilePos(plik));
end;

Oparłęm się w niej na przykład w "Delphi 4.0 - vademecum profesjonalisty" więc zdziwiłem się, że stwierdziliscie, że jest zła.. Ale nawet w Helionie znalazłem jakiś bląd :-P AKurat w artykule o plikach typowanych... ;p

0

Poprzednia (Helionowska) wersja jest poprawna. I jeżeli wrócisz do niej to wszystko będzie poprawne. Może po zapisaniu powinieneś zamknąc i potem powtórnie otworzyć plik...

closefile(plik);
reset(plik); // już bez assignfile, bo nazwa jest cały czas przypisana.
seek(plik,filesize(plik));

A jeśli to nie pomoże (i raczej nie powinno), to błąd jest w recorddisplay().

0
  1. Może po zapisaniu powinieneś zamknąc i potem powtórnie otworzyć plik...
    (...)
  2. A jeśli to nie pomoże (i raczej nie powinno), to błąd jest w recorddisplay().

Hhhmmm...
Ad 1) wróciłem do mojej procedurki i nadal mam ten sam problem :-/
Ad 2) RecordDisplay jest poprawne bo w obsłudze BitButton2 dałem po prostu Seek(plik,1); i elegancko działalo. Więc to raczej nie to.

Ale wrzuciłem sobie Labela na formę i coś dziwnego zauważyłem....
Otóż FileSize(plik) zwraca wartość 3. Czyli mamy 3 rekordy w pliku o odpowiednich wskaźnikach/numerach: 0,1,2 prawda? :>
Otóż przy poniższej komendzie:

lblRec.Caption := 'Serwis:' + inttostr(filepos(plik)) + '/' + inttostr(filesize(plik));

na labelu wyskakują mi wartości:
"Seriwis: 1/3"
"Serwis: 2/3"
lub
"Serwis: 3/3",
a z mojej powyższej instrukcji powinny być odpowiednio: "0/3","1/3",2"3".... :-/ Tak przynajmniej sądzę. Skoro tu jest jakiś bug, to może on ma pwływ na działanie całego prograamu? :-/

0

A jednak!!!!
Miałeś rację Flabra. Błąd tkwil w DisplayRecord();
Zamieszczam poniżej procedurkę:

procedure TForm1.RecordDisplay(record_nmbr: integer);
var
dane: TSerwis;
begin
seek(plik,record_nmbr); 
read(plik,dane);
//TU TKWIŁ BŁĄD!!!!!!!!! Otóż po wyświelteniu danych licznik FILEPOS jest zwiększany o 1. Więc aby powrócić do poprzedniego stanu trzeba na końcu dodać linijkę...
with Form1.GroupBox2 do
begin
// (...) - wyświetlanie odpowiednich informacji w Editach...
end;
//seek(plik,FilePos(plik)-1); <---- to ta linijka :-)
end;

Po tym zabiegu znikł również problem z Labelem i wszystko wyświetla się dobrze. ;p ;p ;p

Thx wszystkim za zwrócenie uwagi na ten post (Flabra :-))

Pozdro. :-)

0

Może jeszcze się komuś w przyszłości przyda:
http://www.pwsz.nysa.pl/%7Eportalis/index.php?load=showArt&id=12

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