05. august 2003 - 00:00
#3
UHA, det ser grimme grimme ud. Ligner det ikke en goto-label???
Jeg ved godt, at de findes i Pascal, men det er altså kun noget man bruger i assembler, men der hedder det jmp, jne e.l. (og basic, men det er der ingen seriøse programmører, der bruger)
Prøv at smide hele metoden herud, det kan lette opklaringsarbejdet.
- Og forhåbentligt vise, at det er en del af en case-sætning :-)
05. august 2003 - 14:35
#4
recNext må i hvert fald være en label... Men den kan ikke være problemet, for der er jo ingen tilsvarende goto. Desuden burde oversætteren brokke sig, hvis der ikke er lavet en definition af label'en.
Men hvad mener du med, at du skal trykke to gange på knappen? Er minfil det logiske navn på en diskfil, eller har du sat det til at læse fra tastaturet, eller hvad? Jeg kunne godt tænke mig at se noget mere af koden, for umiddelbart kan jeg ikke se noget galt i det, du har vist. Mit indtryk i øjeblikket er, at du læser tegn for tegn fra minfil, og når du har set det læste tegn igennem, så sætter du pos til at pege på næste tegn i filen - hvis der er flere, og ellers laver du Exit. Men det kan den omliggende kode formentlig opklare...
05. august 2003 - 20:07
#5
Jeg kan give jer et eksempel som jeg har hentet den fra.
Det eneste jeg har forandret er jeg har skiftet en edit ud med en memo da der ikke kan laves tekst på flere linjer på en edit.
Den her virker dog fint nok ????
:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls;
{Address Record}
type
TAddressRec = record
First : String[20];
Last : String[20];
Add1 : String[40];
Add2 : String[40];
City : String[30];
ST : String[2];
Zip : String[10];
Phone : String[20];
Fax : String[20];
end;
{Direction Type}
type
TRecMove = (recFirst, recLast, recNext, recPrev);
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
btnNew: TButton;
btnFirst: TButton;
btnLast: TButton;
btnNext: TButton;
btnPrev: TButton;
btnDelete: TButton;
btnUpdate: TButton;
Edit8: TEdit;
Label8: TLabel;
Edit9: TEdit;
Label9: TLabel;
StatusBar1: TStatusBar;
Label10: TLabel;
Edit10: TEdit;
btnFind: TButton;
btnFindNext: TButton;
Bevel1: TBevel;
btnInsert: TButton;
procedure FormCreate(Sender: TObject);
procedure btnNewClick(Sender: TObject);
procedure btnFirstClick(Sender: TObject);
procedure btnLastClick(Sender: TObject);
procedure btnNextClick(Sender: TObject);
procedure btnPrevClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnDeleteClick(Sender: TObject);
procedure btnUpdateClick(Sender: TObject);
procedure btnFindClick(Sender: TObject);
procedure btnFindNextClick(Sender: TObject);
procedure btnInsertClick(Sender: TObject);
private
procedure SetRecVals;
procedure ReadRec;
procedure EnableButtons(EnableIt : Boolean);
procedure MoveToRec(Direction : TRecMove);
procedure LocateRec(Value : String; FromBOF : Boolean);
procedure CreateNewRec;
procedure InsertRec;
procedure UpdateRec;
procedure DeleteRec;
public
{ Public declarations }
NewRec : Boolean;
end;
var
Form1: TForm1;
AddrFile : File of TAddressRec;
AddrRec : TAddressRec;
const
MAXRECS = 2000;
implementation
{$R *.DFM}
{=============Basic Form Methods================}
procedure TForm1.FormCreate(Sender: TObject);
begin
AssignFile(AddrFile, 'Address.DAT');
if FileExists('Address.DAT') then
begin
Reset(AddrFile);
if (FileSize(AddrFile) > 0) then
begin
Seek(AddrFile, 0);
ReadRec;
NewRec := False;
end;
end
else
begin
Rewrite(AddrFile);
NewRec := True;
end;
btnNew.Enabled := True;
btnInsert.Enabled := False;
btnUpdate.Caption := '&Update';
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseFile(AddrFile);
end;
{=============General Purpose Routines===============}
procedure TForm1.SetRecVals;
begin
with AddrRec do begin
First := Edit1.Text;
Last := Edit2.Text;
Add1 := Edit3.Text;
Add2 := Edit4.Text;
City := Edit5.text;
ST := Edit6.Text;
Zip := Edit7.Text;
Phone := Edit8.Text;
Fax := Edit9.Text;
end;
end;
{Merely reads the current record in the file into the
edit fields}
procedure TForm1.ReadRec;
begin
Read(AddrFile, AddrRec);
with AddrRec do begin
Edit1.Text := First;
Edit2.Text := Last ;
Edit3.Text := Add1 ;
Edit4.Text := Add2 ;
Edit5.text := City ;
Edit6.Text := ST ;
Edit7.Text := Zip ;
Edit8.Text := Phone;
Edit9.Text := Fax ;
end;
Seek(AddrFile, FilePos(AddrFile) - 1);
end;
procedure TForm1.EnableButtons(EnableIt : Boolean);
begin
btnNew.Enabled := EnableIt;
btnFirst.Enabled := EnableIt;
btnPrev.Enabled := EnableIt;
btnNext.Enabled := EnableIt;
btnLast.Enabled := EnableIt;
{Only enable the insert button when "New" is pressed}
btnInsert.Enabled := NOT EnableIt;
end;
{=============Data Manipulation Routines==============}
{This merely clears the fields. It does nothing to the
file itself}
procedure TForm1.CreateNewRec;
var
I : Integer;
begin
if NewRec then
LockWindowUpdate(Handle);
{Clear the TEdit values}
for I := 0 to ComponentCount - 1 do
if (Components[I] is TEdit) then
TEdit(Components[I]).Clear;
LockWindowUpdate(0);
NewRec := True;
EnableButtons(False);
btnUpdate.Caption := '&Post to End';
end;
procedure TForm1.InsertRec;
var
curPos,
numRecs,
I : Integer;
RecBuf : Array[0..MAXRECS] of TAddressRec;
begin
{First read the fields into the temporary record structure}
SetRecVals;
{Get the current file position}
curPos := FilePos(AddrFile);
{Get the total number of records to write}
numRecs := FileSize(AddrFile);
{Fill the "Head" portion of the file with records from
beginning of file to one less than the current position.
The file position will end up on curPos after this operation
because Read will increment the pointer. This operation only
applies to records other than the first one; otherwise, just
skip the initial loop}
if FilePos(AddrFile) > 0 then begin
I := 0;
Seek(AddrFile, 0);
while FilePos(AddrFile) < curPos do begin
Read(AddrFile, RecBuf[I]);
Inc(I);
end;
end;
{Write the record to insert into the array}
RecBuf[curPos] := AddrRec;
{Read all the remaining records in the file into the buffer
Make sure that you make the buffer position one greater than
the current file position, otherwise you'll overwrite the
record you've just read in.}
I := curPos + 1;
while NOT EOF(AddrFile) do begin
Read(AddrFile, RecBuf[I]);
Inc(I);
end;
{Now, write the entire buffer back to the file}
I := 0;
Seek(AddrFile, 0);
while (I <= numRecs) do begin
Write(AddrFile, RecBuf[I]);
Inc(I);
end;
{Now go back to the original position and read the
record into the fields.}
Seek(AddrFile, curPos);
ReadRec;
btnUpdate.Caption := '&Update';
EnableButtons(True);
end;
{Writes over/updates the current record or
writes a new record to the end}
procedure TForm1.UpdateRec;
var
curPos : Integer;
begin
curPos := FilePos(AddrFile);
{Copy the TEdit values into the temporary record}
SetRecVals;
{If this is a new record, then seek to the end of the file
so you don't overwrite an existing one}
if NewRec then
begin
Seek(AddrFile, FileSize(AddrFile));
curPos := FileSize(AddrFile) + 1;
end;
Write(AddrFile, AddrRec);
{Write increments position by 1, so return to the
position again to "stick" to it}
if (FileSize(AddrFile) > 0) then
begin
Seek(AddrFile, curPos);
NewRec := False;
end;
EnableButtons(True);
btnUpdate.Caption := '&Update';
end;
{"Deletes" a record. Actually, what this procedure does
is read all records after the one you want to delete
into the array RecBuf, truncates the file from the
current position of the file, then reads the buffered
records back into the file, adding them to the end}
procedure TForm1.DeleteRec;
var
curPos,
numRecs,
I : Integer;
RecBuf : Array[0..MAXRECS] of TAddressRec;
begin
if MessageDlg('Are you sure you want to delete this record?',
mtConfirmation, [mbYes, mbNo], 0) = mrNo then Exit;
{If user wants to cancel the deletion during entry of a new record
then just re-read the current position in the database and leave}
if NewRec then begin
ReadRec;
NewRec := False;
EnableButtons(True);
Exit;
end;
{Get the current file position}
curPos := FilePos(AddrFile);
{get number of recs to copy}
numRecs := FileSize(AddrFile) - curPos - 1;
{Now, if we're not on the last record...}
if (FilePos(AddrFile) < (FileSize(AddrFile) - 1)) then
begin
{...start out by going to the record after the
one we want to delete}
Seek(AddrFile, FilePos(AddrFile) + 1);
I := 0;
{Then copy the remaining records into the
temporary buffer array}
while NOT EOF(AddrFile) do begin
Read(AddrFile, RecBuf[I]);
Inc(I);
end;
{Now, go back to the record we want to delete
and truncate the file at that position}
Seek(AddrFile, curPos);
Truncate(AddrFile);
{Once the file is truncated, write the records
in the buffer back to the new end of the file}
for I := 0 to numRecs - 1 do
Write(AddrFile, RecBuf[I]);
end
else
{...otherwise, just truncate the record that's at the end}
begin
Truncate(AddrFile);
{Since this is at the end of the file, we can't return
to this position, so decrement the position by 1}
Dec(curPos);
end;
{Always return to the original position}
Seek(AddrFile, curPos);
{Read current record into the fields}
ReadRec;
end;
procedure TForm1.btnDeleteClick(Sender: TObject);
begin
DeleteRec;
end;
{=============Data Navigation Routines and Methods==============}
{Locates a record either from beginning of file or from cursor}
procedure TForm1.MoveToRec(Direction : TRecMove);
var
pos : Integer;
begin
{Make sure the appropriate buttons are enabled}
EnableButtons(True);
{Get the current file position}
pos := FilePos(AddrFile);
{If there's nothing in the file, then get out}
if (FileSize(AddrFile) = 0) then
Exit;
case Direction of
recFirst : pos := 0;
recLast : pos := FileSize(AddrFile) - 1;
{With movement to next and previous records, }
recNext : if (FilePos(AddrFile) < (FileSize(AddrFile) - 1)) then
pos := FilePos(AddrFile) + 1
else
Exit;
recPrev : if (FilePos(AddrFile) > 0) then
pos := FilePos(AddrFile) - 1
else
Exit;
end;
Seek(AddrFile, pos);
ReadRec;
NewRec := False;
end;
procedure TForm1.LocateRec(Value : String; FromBOF : Boolean);
var
curPos,
SearchPos : Integer;
Found : Boolean;
begin
{Store the current position of the file}
curPos := FilePos(AddrFile);
{Set the pointer to where you want to search from}
if FromBOF then
SearchPos := 0
else
SearchPos := curPos + 1;
Found := False;
while (SearchPos <= (FileSize(AddrFile) - 1)) AND (NOT Found) do begin
{Move to the search position}
Seek(AddrFile, SearchPos);
Read(AddrFile, AddrRec);
{If the element matches the search value}
if (AddrRec.Last = Value) then
begin
{Set the loop exit flag}
Found := True;
{Give a warning tone}
MessageBeep(MB_OK);
{Since a Read operation increments the file pointer by one,
in order to read the right record into fields, you need
to Seek back to the position first; this is especially important
if you're at the end of the file where failing to seek back
will cause a Read beyond end of file error}
Seek(AddrFile, SearchPos);
{Read the record in to the fields}
ReadRec;
end;
Inc(SearchPos)
end;
if NOT Found then
ShowMessage('Last Name not found in file');
end;
{Creates a new, blank record}
procedure TForm1.btnNewClick(Sender: TObject);
begin
CreateNewRec;
end;
procedure TForm1.btnUpdateClick(Sender: TObject);
begin
UpdateRec;
end;
{Moves the file position to the first record and reads it in}
procedure TForm1.btnFirstClick(Sender: TObject);
begin
MoveToRec(recFirst);
end;
{Moves the file position to the last record and reads it in}
procedure TForm1.btnLastClick(Sender: TObject);
begin
MoveToRec(recLast);
end;
{Moves the file position to the next record and reads it in}
procedure TForm1.btnNextClick(Sender: TObject);
begin
MoveToRec(recNext);
end;
{Moves the file position to the previous record and reads it in}
procedure TForm1.btnPrevClick(Sender: TObject);
begin
MoveToRec(recPrev);
end;
procedure TForm1.btnFindClick(Sender: TObject);
begin
if (Edit10.Text <> '') then begin
if NewRec then
btnUpdateClick(Self);
LocateRec(Edit10.Text, True);
end;
end;
procedure TForm1.btnFindNextClick(Sender: TObject);
begin
LocateRec(Edit10.Text, False);
end;
procedure TForm1.btnInsertClick(Sender: TObject);
begin
InsertRec;
end;
end.