Ładny brzuch
Mam problem z zapisem rekordu do pliku. Oto procedura zapisujca:
procedure TAddForm.Button1Click(Sender: TObject); var F : TPlikKsiazek; Rec : TKsiazka; begin try AssignFile(F, 'ksiazki.dat'); if FileExists('ksiazki.dat') then Reset(F) else Rewrite(F); Seek(F, FileSize(F)); Rec.Tytul := Edit1.Text; Rec.Autor := Edit2.Text; Rec.DataWyd := Edit3.Text; Rec.DataPorzyczenia := Edit4.Text; Rec.Porzyczono := Edit5.Text; Rec.Kolumna := PChar(Edit6.Text); Rec.Polka := StrToInt(Edit7.Text); Write(F, Rec); MainForm.ReadCatalog; finally CloseFile(F); end; AddForm.Close; end;
Rekord TKsiazka :
TKsiazka = record Tytul : String[30]; Autor : String[20]; DataWyd : String[9]; DataPorzyczenia : String[9]; Porzyczono : String[20]; Kolumna : PChar; Polka : Integer; Komentarze : ShortString; end; TPlikKsiazek = file of TKsiazka;
Skompilowaem program no i wypeniam pola rekordu no i naciskam przycisk Button1 ktory powoduje otwarcie lub utworzenie pliku "ksiazki.dat" w zalenoci czy plik istnieje. Sprawdzam katalog gdzie jest zapisany program i nie ma tam pliku "ksiazki.dat". Utworzylem go samodzielnie i program wywala bld AccesViolation podczas wywoywania procedury ReadCatalog :
procedure TMainForm.ReadCatalog; var F : TPlikKsiazek; I : Integer; Rec : TKsiazka; ListItem : TListItem; begin ListaKsiazek.Clear; if not FileExists('ksiazki.dat') then exit; AssignFile(F, 'ksiazki.dat'); try Reset(F); for I := 0 to FileSize(F) -1 do begin Read(F, Rec); ListItem := ListaKsiazek.Items.Add; ListItem.Caption := Rec.Tytul; ListItem.SubItems.Add(Rec.Autor); ListItem.SubItems.Add(Rec.DataWyd); ListItem.SubItems.Add(Rec.DataPorzyczenia); ListItem.SubItems.Add(Rec.Porzyczono); ListItem.SubItems.Add(Rec.Kolumna); ListItem.SubItems.Add(IntToStr(Rec.Polka)); ListItem.SubItems.Add(Rec.Komentarze); end; finally CloseFile(F); end; end;
I nie wiem co zrobi eby program zacz dodawa rekordy do pliku.
Primo: Odwoujesz si do tego samego pliku w 2 procedurach, podczas gdy jest on wci otwarty w pierwszej... Skoro i tak za kadym razem czycisz ListView'a to procedur ReadCatalog wywouj po zakoczeniu operacji na pliku w produrze zapsiujcej.
Secundo: plikw typowanych, do ktrych co bdziemy zapisywa nie tworzymy za pomoc ReWrite(); - nawet jak plik nie istnieje moemy uy Reset();
Po trzecie bezpieczniej tworzy pliki - te, ktre maj by w katalogu aplikacji - za pomoc np: ExtractFilePath(application.Exename) + 'ksiazki.dat'; gdy samo 'ksizki.dat' nie zadziaa jeli program zostanie uruchomony, np ze skrtu na pulpicie.
AD2: pomyliem sie :P :frusty:
Uytkownik p1101 edytowa ten post 22 lipiec 2005, 07:32
Pozmieniaem kod tak jak mwie, ale nadal program nie zapisuje rekordu do pliku :( :( :( .
procedure TAddForm.Button1Click(Sender: TObject); var F : file of TKsiazka; Rec : TKsiazka; begin try AssignFile(F, 'ksiazki.dat'); if FileExists('ksiazki.dat') then Reset(F) else Rewrite(F); Seek(F, FileSize(F)); Rec.Tytul := Edit1.Text; Rec.Autor := Edit2.Text; Rec.DataWyd := Edit3.Text; Rec.DataPorzyczenia := Edit4.Text; Rec.Porzyczono := Edit5.Text; Rec.Kolumna := PChar(Edit6.Text); Rec.Polka := StrToInt(Edit7.Text); Write(F, Rec); finally CloseFile(F); end; MainForm.ReadCatalog; AddForm.Close; end;
nie ma bata. zapisa do pliku musi.
Moe po closefile daj showmessage(getcurrentdir); to zobaczysz gdzie ten plik zapisa.
Innych pomysw nie mam... <_<
Uytkownik johans edytowa ten post 22 lipiec 2005, 00:09
Poka kod, gdy sprawdzaem swj sposb u siebie i dziaa. Moliwe, e bd tkwi cakiem gdzie indziej...
Pierwsza Forma :
unit biblioteka; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, addbookform; type TMainForm = class(TForm) ListaKsiazek: TListView; StatusBar1: TStatusBar; Menu: TMainMenu; Ksiki1: TMenuItem; DodajKsikdokatalogu1: TMenuItem; Usuksikzkatalogu1: TMenuItem; Edytujksik1: TMenuItem; N1: TMenuItem; Zamknij1: TMenuItem; procedure MainFormCreate(Sender: TObject); procedure DodajKsikdokatalogu1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure ReadCatalog; end; TKsiazka = record Tytul : String[30]; Autor : String[20]; DataWyd : String[9]; DataPorzyczenia : String[9]; Porzyczono : String[20]; Kolumna : PChar; Polka : Integer; Komentarze : ShortString; end; TPlikKsiazek = file of TKsiazka; var MainForm: TMainForm; implementation {$R *.dfm} procedure TMainForm.ReadCatalog; var F : TPlikKsiazek; I : Integer; Rec : TKsiazka; ListItem : TListItem; begin ListaKsiazek.Clear; if not FileExists(ExtractFilePath(Application.ExeName) + 'ksiazki.dat') then exit; AssignFile(F, ExtractFilePath(Application.ExeName) + 'ksiazki.dat'); try Reset(F); for I := 0 to FileSize(F) -1 do begin Read(F, Rec); ListItem := ListaKsiazek.Items.Add; ListItem.Caption := Rec.Tytul; ListItem.SubItems.Add(Rec.Autor); ListItem.SubItems.Add(Rec.DataWyd); ListItem.SubItems.Add(Rec.DataPorzyczenia); ListItem.SubItems.Add(Rec.Porzyczono); ListItem.SubItems.Add(Rec.Kolumna); ListItem.SubItems.Add(IntToStr(Rec.Polka)); ListItem.SubItems.Add(Rec.Komentarze); end; finally CloseFile(F); end; end; procedure TMainForm.MainFormCreate(Sender: TObject); begin ReadCatalog; end; procedure TMainForm.DodajKsikdokatalogu1Click(Sender: TObject); begin AddForm.ShowModal; end; end.
Druga forma :
unit addbookform; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TAddForm = class(TForm) GroupBox1: TGroupBox; Edit1: TEdit; GroupBox2: TGroupBox; Edit2: TEdit; GroupBox3: TGroupBox; Edit3: TEdit; GroupBox4: TGroupBox; Edit4: TEdit; GroupBox5: TGroupBox; Edit5: TEdit; GroupBox6: TGroupBox; Edit6: TEdit; GroupBox7: TGroupBox; Edit7: TEdit; Button1: TButton; Button2: TButton; GroupBox8: TGroupBox; Edit8: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var AddForm: TAddForm; implementation {$R *.dfm} uses biblioteka; procedure TAddForm.Button1Click(Sender: TObject); var F : TPlikKsiazek; Rec : TKsiazka; begin try AssignFile(F, ExtractFilePath(Application.ExeName) + 'ksiazki.dat'); if FileExists( ExtractFilePath(Application.ExeName) + 'ksiazki.dat') then Reset(F) else ReWrite(F); Seek(F, FileSize(F)); Rec.Tytul := Edit1.Text; Rec.Autor := Edit2.Text; Rec.DataWyd := Edit3.Text; Rec.DataPorzyczenia := Edit4.Text; Rec.Porzyczono := Edit5.Text; Rec.Kolumna := PChar(Edit6.Text); Rec.Polka := StrToInt(Edit7.Text); Write(F, Rec); finally CloseFile(F); end; MainForm.ReadCatalog; AddForm.Close; end; end.
P.S. Jak narazie adne zmiany nic nie day.
Uytkownik damc edytowa ten post 22 lipiec 2005, 19:20
Do plikw typowanych najlepiej uywa BlockRead i BlockWrite. Poza tym w rekordzie masz PChar, wic zostanie zapisane z tego tylko wskazanie na acuch. Rekord musi mie z gry okrelon wielko, a PChar nie jest stae (tzn. nie jest stay cig na kty wskazuje, bo wskanik oczywicie jest znanej, staej wielkoci, dlatego zapisze tylko wskanik). Sprbuj zamieni PChar na co o staj wielkoci tak jak masz w innych polach np. String[20].
Nic to nie daje :(. Program nawet nie tworzy pliku. :(
Nie zaloze sie, ale wystarczy dac przy reset i rewrite 2 parametr 1 i powinno smigac...
// Edit: sproboj zrobic na zwyklym File a nie TPlikKsiazek, a rekord zrob taki:
TKsiazka = record Tytul : String[30]; Autor : String[20]; DataWyd : String[9]; DataPorzyczenia : String[9]; Porzyczono : String[20]; Kolumna : String[128]; Polka : Integer; Komentarze : ShortString; end;
Nie sprawdzalem bo nie mam delphi zainstalowanego.
Uytkownik Ali240 edytowa ten post 23 lipiec 2005, 13:55
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
procedure TAddForm.Button1Click(Sender: TObject); var F : TPlikKsiazek; Rec : TKsiazka; begin try AssignFile(F, 'ksiazki.dat'); if FileExists('ksiazki.dat') then Reset(F) else Rewrite(F); Seek(F, FileSize(F)); Rec.Tytul := Edit1.Text; Rec.Autor := Edit2.Text; Rec.DataWyd := Edit3.Text; Rec.DataPorzyczenia := Edit4.Text; Rec.Porzyczono := Edit5.Text; Rec.Kolumna := PChar(Edit6.Text); Rec.Polka := StrToInt(Edit7.Text); Write(F, Rec); MainForm.ReadCatalog; finally CloseFile(F); end; AddForm.Close; end;
Rekord TKsiazka :
TKsiazka = record Tytul : String[30]; Autor : String[20]; DataWyd : String[9]; DataPorzyczenia : String[9]; Porzyczono : String[20]; Kolumna : PChar; Polka : Integer; Komentarze : ShortString; end; TPlikKsiazek = file of TKsiazka;
Skompilowaem program no i wypeniam pola rekordu no i naciskam przycisk Button1 ktory powoduje otwarcie lub utworzenie pliku "ksiazki.dat" w zalenoci czy plik istnieje. Sprawdzam katalog gdzie jest zapisany program i nie ma tam pliku "ksiazki.dat". Utworzylem go samodzielnie i program wywala bld AccesViolation podczas wywoywania procedury ReadCatalog :
procedure TMainForm.ReadCatalog; var F : TPlikKsiazek; I : Integer; Rec : TKsiazka; ListItem : TListItem; begin ListaKsiazek.Clear; if not FileExists('ksiazki.dat') then exit; AssignFile(F, 'ksiazki.dat'); try Reset(F); for I := 0 to FileSize(F) -1 do begin Read(F, Rec); ListItem := ListaKsiazek.Items.Add; ListItem.Caption := Rec.Tytul; ListItem.SubItems.Add(Rec.Autor); ListItem.SubItems.Add(Rec.DataWyd); ListItem.SubItems.Add(Rec.DataPorzyczenia); ListItem.SubItems.Add(Rec.Porzyczono); ListItem.SubItems.Add(Rec.Kolumna); ListItem.SubItems.Add(IntToStr(Rec.Polka)); ListItem.SubItems.Add(Rec.Komentarze); end; finally CloseFile(F); end; end;
I nie wiem co zrobi eby program zacz dodawa rekordy do pliku.
Primo: Odwoujesz si do tego samego pliku w 2 procedurach, podczas gdy jest on wci otwarty w pierwszej... Skoro i tak za kadym razem czycisz ListView'a to procedur ReadCatalog wywouj po zakoczeniu operacji na pliku w produrze zapsiujcej.
Secundo: plikw typowanych, do ktrych co bdziemy zapisywa nie tworzymy za pomoc ReWrite(); - nawet jak plik nie istnieje moemy uy Reset();
Po trzecie bezpieczniej tworzy pliki - te, ktre maj by w katalogu aplikacji - za pomoc np: ExtractFilePath(application.Exename) + 'ksiazki.dat'; gdy samo 'ksizki.dat' nie zadziaa jeli program zostanie uruchomony, np ze skrtu na pulpicie.
AD2: pomyliem sie :P :frusty:
Uytkownik p1101 edytowa ten post 22 lipiec 2005, 07:32
Pozmieniaem kod tak jak mwie, ale nadal program nie zapisuje rekordu do pliku :( :( :( .
procedure TAddForm.Button1Click(Sender: TObject); var F : file of TKsiazka; Rec : TKsiazka; begin try AssignFile(F, 'ksiazki.dat'); if FileExists('ksiazki.dat') then Reset(F) else Rewrite(F); Seek(F, FileSize(F)); Rec.Tytul := Edit1.Text; Rec.Autor := Edit2.Text; Rec.DataWyd := Edit3.Text; Rec.DataPorzyczenia := Edit4.Text; Rec.Porzyczono := Edit5.Text; Rec.Kolumna := PChar(Edit6.Text); Rec.Polka := StrToInt(Edit7.Text); Write(F, Rec); finally CloseFile(F); end; MainForm.ReadCatalog; AddForm.Close; end;
nie ma bata. zapisa do pliku musi.
Moe po closefile daj showmessage(getcurrentdir); to zobaczysz gdzie ten plik zapisa.
Innych pomysw nie mam... <_<
Uytkownik johans edytowa ten post 22 lipiec 2005, 00:09
Poka kod, gdy sprawdzaem swj sposb u siebie i dziaa. Moliwe, e bd tkwi cakiem gdzie indziej...
Pierwsza Forma :
unit biblioteka; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, addbookform; type TMainForm = class(TForm) ListaKsiazek: TListView; StatusBar1: TStatusBar; Menu: TMainMenu; Ksiki1: TMenuItem; DodajKsikdokatalogu1: TMenuItem; Usuksikzkatalogu1: TMenuItem; Edytujksik1: TMenuItem; N1: TMenuItem; Zamknij1: TMenuItem; procedure MainFormCreate(Sender: TObject); procedure DodajKsikdokatalogu1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure ReadCatalog; end; TKsiazka = record Tytul : String[30]; Autor : String[20]; DataWyd : String[9]; DataPorzyczenia : String[9]; Porzyczono : String[20]; Kolumna : PChar; Polka : Integer; Komentarze : ShortString; end; TPlikKsiazek = file of TKsiazka; var MainForm: TMainForm; implementation {$R *.dfm} procedure TMainForm.ReadCatalog; var F : TPlikKsiazek; I : Integer; Rec : TKsiazka; ListItem : TListItem; begin ListaKsiazek.Clear; if not FileExists(ExtractFilePath(Application.ExeName) + 'ksiazki.dat') then exit; AssignFile(F, ExtractFilePath(Application.ExeName) + 'ksiazki.dat'); try Reset(F); for I := 0 to FileSize(F) -1 do begin Read(F, Rec); ListItem := ListaKsiazek.Items.Add; ListItem.Caption := Rec.Tytul; ListItem.SubItems.Add(Rec.Autor); ListItem.SubItems.Add(Rec.DataWyd); ListItem.SubItems.Add(Rec.DataPorzyczenia); ListItem.SubItems.Add(Rec.Porzyczono); ListItem.SubItems.Add(Rec.Kolumna); ListItem.SubItems.Add(IntToStr(Rec.Polka)); ListItem.SubItems.Add(Rec.Komentarze); end; finally CloseFile(F); end; end; procedure TMainForm.MainFormCreate(Sender: TObject); begin ReadCatalog; end; procedure TMainForm.DodajKsikdokatalogu1Click(Sender: TObject); begin AddForm.ShowModal; end; end.
Druga forma :
unit addbookform; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TAddForm = class(TForm) GroupBox1: TGroupBox; Edit1: TEdit; GroupBox2: TGroupBox; Edit2: TEdit; GroupBox3: TGroupBox; Edit3: TEdit; GroupBox4: TGroupBox; Edit4: TEdit; GroupBox5: TGroupBox; Edit5: TEdit; GroupBox6: TGroupBox; Edit6: TEdit; GroupBox7: TGroupBox; Edit7: TEdit; Button1: TButton; Button2: TButton; GroupBox8: TGroupBox; Edit8: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var AddForm: TAddForm; implementation {$R *.dfm} uses biblioteka; procedure TAddForm.Button1Click(Sender: TObject); var F : TPlikKsiazek; Rec : TKsiazka; begin try AssignFile(F, ExtractFilePath(Application.ExeName) + 'ksiazki.dat'); if FileExists( ExtractFilePath(Application.ExeName) + 'ksiazki.dat') then Reset(F) else ReWrite(F); Seek(F, FileSize(F)); Rec.Tytul := Edit1.Text; Rec.Autor := Edit2.Text; Rec.DataWyd := Edit3.Text; Rec.DataPorzyczenia := Edit4.Text; Rec.Porzyczono := Edit5.Text; Rec.Kolumna := PChar(Edit6.Text); Rec.Polka := StrToInt(Edit7.Text); Write(F, Rec); finally CloseFile(F); end; MainForm.ReadCatalog; AddForm.Close; end; end.
P.S. Jak narazie adne zmiany nic nie day.
Uytkownik damc edytowa ten post 22 lipiec 2005, 19:20
Do plikw typowanych najlepiej uywa BlockRead i BlockWrite. Poza tym w rekordzie masz PChar, wic zostanie zapisane z tego tylko wskazanie na acuch. Rekord musi mie z gry okrelon wielko, a PChar nie jest stae (tzn. nie jest stay cig na kty wskazuje, bo wskanik oczywicie jest znanej, staej wielkoci, dlatego zapisze tylko wskanik). Sprbuj zamieni PChar na co o staj wielkoci tak jak masz w innych polach np. String[20].
Nic to nie daje :(. Program nawet nie tworzy pliku. :(
Nie zaloze sie, ale wystarczy dac przy reset i rewrite 2 parametr 1 i powinno smigac...
// Edit: sproboj zrobic na zwyklym File a nie TPlikKsiazek, a rekord zrob taki:
TKsiazka = record Tytul : String[30]; Autor : String[20]; DataWyd : String[9]; DataPorzyczenia : String[9]; Porzyczono : String[20]; Kolumna : String[128]; Polka : Integer; Komentarze : ShortString; end;
Nie sprawdzalem bo nie mam delphi zainstalowanego.
Uytkownik Ali240 edytowa ten post 23 lipiec 2005, 13:55