SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00010 RECORD RELATED ROUTINES 1 05-28-9313:55ALL SWAG SUPPORT TEAM BLOCKRW1.PAS IMPORT 14 {πDoes anyone have any examples of how to Write Text to a File usingπblockWrite?π}πProgram DemoBlockWrite;ππConstπ { Carriage-return + Line-feed Constant. }π co_CrLf = #13#10;ππVarπ st_Temp : String;π fi_Temp : File;π wo_BytesWritten : Word;ππbeginπ { Assign 5 lines of Text to temp String. }π st_Temp := 'Line 1 of Text File' + co_CrLf + 'Line 2 of Text File'π + co_CrLf + co_CrLf + 'Line 4 of Text File' + co_CrLf +π ' My name is MUD ' + co_CrLf;ππ assign(fi_Temp, 'TEST.TXT');π {$I-}π reWrite(fi_Temp, 1);π {$I+}π if (ioresult <> 0) thenπ beginπ Writeln('Error creating TEST.TXT File');π Haltπ end;π { Write 5 lines of Text to File. }π BlockWrite(fi_Temp, st_Temp[1], length(st_Temp), wo_BytesWritten);π { Check For errors writing Text to File. }π if (wo_BytesWritten <> length(st_Temp)) thenπ beginπ Writeln('Error writing Text to File!');π Haltπ end;π { Close File. }π Close(fi_Temp);π { Attempt to open Text File again. }π Assign(fi_Temp, 'TEST.TXT');π {$I-}π Reset(fi_Temp, 1);π {$I+}π if (IOResult <> 0) thenπ beginπ Writeln('Error opening TEST.TXT File');π Haltπ end;π st_Temp := 'Guy';π { Position File-Pointer just before the 'MUD' in Text. }π seek(fi_Temp, 77);π { Correct my name by overwriting old Text With new. }π blockWrite(fi_Temp, st_Temp[1], length(st_Temp), wo_BytesWritten);π { Check For errors writing Text to File. }π if (wo_BytesWritten <> length(st_Temp)) thenπ beginπ Writeln('Error writing Text to File!');π Haltπ end;π Close(fi_Temp)πend.π 2 05-28-9313:55ALL SWAG SUPPORT TEAM BLOCKRW2.PAS IMPORT 51 (* Program to demonstrate BlockRead and BlockWrite *)π(* routines. *)πProgram BlockReadWriteDemo;πUsesπ Crt;πTypeπ st20 = String[20];π st40 = String[40];π st80 = String[80];ππ rcPersonInfo = Recordπ stFirst : st20;π stLast : st20;π byAge : Byteπ end;πConstπ coRecSize = sizeof(rcPersonInfo);ππVarπ wototalRecs : Word;π rcTemp : rcPersonInfo;π fiData : File;ππ (***** Initialize Program Variables. *)π Procedure Init;π beginπ ClrScr;π wototalRecs := 0;π fillChar(rcTemp, coRecSize, 0);π fillChar(fiData, sizeof(fiData), 0)π end; (* Init. *)ππ (***** Handle Program errors. *)π Procedure ErrorHandler(byErrorNumber : Byte; boHalt : Boolean);π beginπ Case byErrorNumber ofπ 1 : Writeln('Error creating new data-File.');π 2 : Writeln('Error writing Record to data-File.');π 3 : Writeln('Record does not exist.');π 4 : Writeln('Error reading Record from data-File.');π 5 : Writeln('Error erasing Record in data-File.')π end; (* Case byErrorNumber of *)π if boHalt thenπ halt(byErrorNumber)π end; (* ErrorHandler. *)ππ (***** Create new data-File to hold Record data. *)π Function CreateDataFile(Var fiData : File) : Boolean;π beginπ {$I-}π reWrite(fiData, 1);π {$I+}π if (ioresult = 0) thenπ CreateDataFile := Trueπ elseπ CreateDataFile := Falseπ end; (* CreateDataFile. *)ππ (***** Open data-File. *)π Procedure OpenDataFile(Var fiData : File; stFileName : st80);π beginπ assign(fiData, stFileName);π {$I-}π reset(fiData, 1);π {$I+}π if (ioresult <> 0) thenπ beginπ if (CreateDataFile(fiData) = False) thenπ ErrorHandler(1, True)π elseπ Writeln('New data-File ', stFileName, ' created.')π endπ elseπ Writeln('Data-File ', stFileName, ' opened.');π wototalRecs := Filesize(fiData) div coRecSizeπ end; (* OpenDataFile. *)ππ (***** Add a Record to the data-File. *)π Procedure AddRecord(woRecNum : Word; Var rcTemp : rcPersonInfo);π Varπ woBytesWritten : Word;π beginπ if (woRecNum > succ(wototalRecs)) thenπ woRecNum := succ(wototalRecs);π seek(fiData, (pred(woRecNum) * coRecSize));π blockWrite(fiData, rcTemp, coRecSize, woBytesWritten);π if (woBytesWritten = coRecSize) thenπ inc(wototalRecs)π elseπ ErrorHandler(2, True)π end; (* AddRecord. *)πππ(*** PART 2 *****)ππ (***** Get a Record from the data-File. *)π Procedure GetRecord(woRecNum : Word; Var rcTemp : rcPersonInfo);π Varπ woBytesRead : Word;π beginπ if (woRecNum > wototalRecs)π or (woRecNum < 1) thenπ beginπ ErrorHandler(3, False);π Exitπ end;π seek(fiData, (pred(woRecNum) * coRecSize));π blockread(fiData, rcTemp, coRecSize, woBytesRead);π if (woBytesRead <> coRecSize) thenπ ErrorHandler(4, True)π end; (* GetRecord. *)ππ (***** Erase the contents of a data-File Record. *)π Procedure EraseRecord(woRecNum : Word);π Varπ woBytesWritten : Word;π rcEmpty : rcPersonInfo;π beginπ if (woRecNum > wototalRecs)π or (woRecNum < 1) thenπ beginπ ErrorHandler(3, False);π Exitπ end;π fillChar(rcEmpty, coRecSize, 0);π seek(fiData, (pred(woRecNum) * coRecSize));π blockWrite(fiData, rcEmpty, coRecSize, woBytesWritten);π if (woBytesWritten <> coRecSize) thenπ ErrorHandler(5, True)π end; (* EraseRecord. *)ππ (***** Display a Record's fields. *)π Procedure DisplayRecord(Var rcTemp : rcPersonInfo);π beginπ With rcTemp doπ beginπ Writeln;π Writeln(' Firstname = ', stFirst);π Writeln(' Lastname = ', stLast);π Writeln(' Age = ', byAge);π Writelnπ endπ end; (* DisplayRecord. *)ππ (***** Enter data into a Record. *)π Procedure EnterRecData(Var rcTemp : rcPersonInfo);π beginπ Writeln;π With rcTemp doπ beginπ Write('Enter First-name : ');π readln(stFirst);π Write('Enter Last-name : ');π readln(stLast);π Write('Enter Age : ');π readln(byAge)π end;π Writelnπ end; (* EnterRecData. *)ππ (***** Obtain user response to Yes/No question. *)π Function YesNo(stMessage : st40) : Boolean;π Varπ chTemp : Char;π beginπ Writeln;π Write(stMessage, ' (Y/N) [ ]', #8#8);π While KeyPressed doπ chTemp := ReadKey;π Repeatπ chTemp := upCase(ReadKey)π Until (chTemp in ['Y','N']);π Writeln(chTemp);π if (chTemp = 'Y') thenπ YesNo := Trueπ elseπ YesNo := Falseπ end; (* YesNo. *)ππ (***** Compact data-File by removing empty Records. *)π Procedure PackDataFile(Var fiData : File);π beginπ (* This one I'm leaving For you to Complete. *)π end; (* PackDataFile. *)ππ(***** PART 3 *****)π (* Main Program execution block. *)πbeginπ Init;π OpenDataFile(fiData, 'TEST.DAT');π rcTemp.stFirst := 'Bill';π rcTemp.stLast := 'Gates';π rcTemp.byAge := 36;π DisplayRecord(rcTemp);π AddRecord(1, rcTemp);π rcTemp.stFirst := 'Phillipe';π rcTemp.stLast := 'Khan ';π rcTemp.byAge := 39;π DisplayRecord(rcTemp);π AddRecord(2, rcTemp);π GetRecord(1, rcTemp);π DisplayRecord(rcTemp);π EraseRecord(1);π GetRecord(1, rcTemp);π DisplayRecord(rcTemp);π EnterRecData(rcTemp);π AddRecord(1, rcTemp);π DisplayRecord(rcTemp);π close(fiData);π if YesNo('Erase the Record data-File ?') thenπ erase(fiData)πend.πππ 3 05-28-9313:55ALL SWAG SUPPORT TEAM MANYRECS.PAS IMPORT 13 {π>Okay, I've got the need to load about 3000 Records, at 73 Bytes a piece,π>into active memory. It'd be preferred to have it as an Array ofπ>Records, which is what I'm using now (only at 1000 Records though).ππ>When I do this I get Structure too Large. Is there any way that I canπ>load all of these Records into memory, For sorting, editing, deletingπ>and adding new entries (which is easy With an Array).ππ}πConstπ MaxItems = 3000 ;ππType TItem =π Recordπ { 73 Bytes Record }π Dum : Array[1..73] of Byte ;π end ;π PItem = ^TItem ;ππ TItemArray = Array[1..MaxItems] of PItem ;ππVar i : Integer ;π Arr : TItemArray ;ππbeginπ For i:=1 to MaxItems Do New(Arr[i]) ;ππ { Now, can use all those items in memory }ππ For i:=1 to MaxItems Do Dispose(Arr[i]) ;πend.ππ{ππnote that the set of data will occupy :ππ3000*4 Bytes in DS 12000 Bytesπ3000*80 Bytes in the heap 240000 Bytesπ ------π 252000 Bytes of memory...ππThe '80' in the second line is due to the fact that TP 6's heap managerπallocates heap space by multiples of 8 Bytes, thus 73 Bytes result inπ80 Bytes allocs. Reducing it to 72 Bytes would save 8*3000=24000 Bytes.ππAnyway, this is not Real safe Programming, and you should prefer using aπFile, unleast you are Really sure that :π- you won't have more than 3000 Records,π- any machine your Program will run onto has enough memory.π} 4 05-28-9313:55ALL SWAG SUPPORT TEAM RECINFO1.PAS IMPORT 64 >Can anyone tell me how I can delete a Record from a File?ππTwo ways.ππ1) Mark the Record With a value that tells your Program thatπ Record is classified as deleted. (Most DB Programs work thisπ way)ππ2) Read the WHOLE File in, one Record at a time. Copy theseπ Records into the new File. While you are copying, ignore anyπ Record(s) you want to delete.ππ Once the copy is Complete, delete the old File and rename theπ new to the old Filename...ππYou could also open the File as unTyped :-), and use blockRead to read bigπchunks Until you've read (recSize * number of Records beFore bad one) Bytes,πand blockWrite to Write them out to the temp File. This might be faster,πdepending on the number of Records and how big they are.ππ> How would I pack a File of Records to save space?ππ if you have seen other posts by me about packing Database TypeπFiles, you will see I normally recommend against it.ππI usually go With a "Deleted" indicator and Records marked asπdeleted are re-used. It is my personnal experience that such Filesπnormally grow in size Until they reach a balanced state. A state inπwhich the File does not grow anymore and where balance is reachedπbetween Additions and Deletions.ππif you Really want to pack it then,ππ 1- Build a list of deleted Recordsπ 2- take the last Record in the Fileπ 3- Keep a note that that Record is now emptyπ 4- OverWrite the FIRST DELETED Record's space With itπ 5- Repeat steps 2-4 Until all deleted Records have been filled.π 6- Seek to the first Record marked empty, this should be the lastπ one you moved.π or you could simply seek to Record_COunt since the File shouldπ now contain no empty space all valid Records should be at theπ head of the File and thus seeking to Record_Count ensures youπ of being positionned at the very end.π 7- Truncate the File there by using the Truncate command.π 8- Be sure to close and re-open the File beFore any more processingπ so that Directory and FAT are updated.πππ> Could someone please give me an example of a good way (the best way?) toπ> delete Records from a Typed File? My only guess, after looking at allπ> of the TP documentation, and my one TP book, is that I will have to readπ> the File, and Write a new File, excluding the "deleted" Record. Thisπ> will require another (identical) Type statment, and File Variable, etc.,π> and will require me to then rename the smaller File...π>π> Isn't there a more efficient way????ππYES THERE IS!!!ππModify your Record to this:ππTypeπ My_Record = Recordπ Deleted : Boolean;π < Rest of your usual stuff >π end;ππ Now if you use index Files, create an index File With the DELETEDπfield as the key to that index.ππPseudo code ahead:ππ Adding a Record:π 1- Set index to DELETEDπ 2- Go to first Recordπ 3- Is it deletedπ 4- Yes, use it as our new Recordπ 4a Change the Deleted field to False;π 4b Write our new Record to this one overwriting it.π 5- No, Add a new phisical Record to the File,π 5a Remember to Set Deleted to False on this oneπ 5b Write our Record to the new Record.ππ Deleting a Record:π 1- Go to Record,π 2- Read it inπ 3- Set the deleted field to True.π { This allows UnDeleting a Record With it's original data}ππ Listing Records:π Remember to skip deleted Records.ππyou will soon find that using this management method your applicationsπwill perForm at speeds vastly faster than others. Simply because theπFile is never moved, truncated etc.. Eliminating fragentation on theπdisk. You will also find that as you open new databases, they willπquickly grow and then attain a stable size where new Records are mostlyπreusing deleted Records.ππ This is how my dBase applications are handled. Our last projectπWhile I was at the Justice Departement was re-written to use thisπprinciple of management instead of using dBase's Pack and deleteπroutines. The efficiency was greatly augmented both in speed and in diskπoccupation. We no longer needed to perForm unfragmentation routinesπperiodically and we also could reverse any error our users might haveπcommited.ππ By adding additionnal info such as deletion date, user ID thatπrequested the delete etc... we were able to offer options that were notπavailable beFore. An added benefit was that we didn't need to reindexπthe whole database. Affected Index Files were open during operations andπwere thus opdated on the fly. So our Deleted index was allways uptodate.πGenerating a message when physical space was added to the database, weπwere able to perForm defragementation only when Really needed. and thoseπoperations were greatly shortened in time because 98% of the databaseπwas allready defragmentated.ππIt's the sensible way to do it, and it can be done in any language.ππ{------------------------------------------------------------------------}ππ> Can someone tell me how to search through a Typed File.π> Example:π> Type Dummy = Recordπ> Name : Stringπ> Age : Integerπ> end;π> DummyFile = File of Dummy;ππ> How could I find a Record that has AGE = 20 ?ππDo something like this:ππVarπ PersonRecord : Dummy;ππProcedure searchForAge(PersonsAge: Integer);πbeginπ ... Open the File ...π Seek(DummyFile, 0); {start at beginning of File}π PersonRecord.Age:= 1000; {Init to unused value}π While not(Eof) and (PersonRecord.Age <> PersonsAge) doπ beginπ Read(DummyFile, PersonRecord);π end;π ... Close the File ...πend;πππThis might work:π Typeπ rec = Recordπ age: Integer;π etc...π end;π Varπ f: File of rec;π r: rec;π beginπ assign(f, 'FileNAME.EXT');π reset(f, sizeof(rec)); (* have to indicate Record size *)ππ While not eof(f) do beginπ blockread(f, r, 1); (* read one rec from f into r *)π if r.age = 20 thenπ (* do something interesting *)π end;π close(f);π end.ππThe trick is to inForm the runtime library of the size of each Record in theπFile; you do this in the call to reset. Blockread takes a File, an unTypedπbuffer, and the number of Records to read.ππππππ>I know that this is probably as common as the "I want to Write a BBS",π>and "*.MSG structures" :) but haven't seen anything lately (and I'veπ>been reading this For quite some time) about tips on searching Recordsπ>in a File. Any tips/routines on fast searching, or ways to set up theπ>Record For fast searching? Thanks.ππ Well, you're kinda restricting yourself by saying, "in a File". That meansπyou have a File of some Type, and you're pretty-much confined to the waysπappropriate For that File Type. However, there are some things you can doπwhich will make processing the data faster and more efficient:π 1. For Text Files:π a. use large buffers (SetTextBuf Procedure)π b. establish an Index For the Records on the File, and use random i/o toπaccess specific Records. Thgis does not imply reading all the Records eachπtime you "search it", but you must have some "key" or order in that File fromπwhich you can assign and index key. This is a large subject, and to goπfurther, I'd have to know more about your File.π c. have the File (be of) fixed Records, sort on some key field, and use aπbinary search/random read scheme to search For Records. Also prettyπComplicated in Implementation...π 2. Random Files:π There are many options here, and are mostly dependant on the File order andπdata content/Record size.ππ Finally, suggest you read the entire File into memory (using Heap, Pointerπaccess, etc.), and do all your work in memory. The above ideas are appropriateπFor very large Files, but anything under 450K can be stored in you systemπmemory and used there, I'll bet. Once in memory, you can even sort the data inπsome fashion and use some fancy searching techniques, too.πππππ 5 05-28-9313:55ALL SWAG SUPPORT TEAM RECSORT.PAS IMPORT 18 {π ... would anyone know how-to sort a Record With 5 thing in it one ofπ which is "NAME"...I want to sort each Record in the Array by name andπ can't figure it out....my Array name is LabelS and my Record name isπ SofT...π}ππProgram sort_Records;ππTypeπ index_Type = 1..100;π soft_Type = Recordπ name,π street,π city: String[20];π state: String[2];π zip: Integerπ end; { Record }π Labels_Type = Array[index_Type] of soft_Type;ππVarπ Labels: Labels_Type; { an Array of Records }π index,π count: index_Type;π f: Text; { a File on disk holding your Records, we assume 100 }ππ{ ******************************************** }πProcedure get_Records(Var f: Text;π Var Labels: Labels_Type); Varπ counter: index_Type;ππbegin { get_Records }π For counter := 1 to 100 doπ beginπ With Labels[counter] doπ readln(f, name, street, city, state, zip);π end;πend; { get_Records }ππ{ ******************************************** }πProcedure sort_em(Var Labels: Labels_Type);ππVarπ temp: soft_Type; { a Single Record }π counter,π counter2,π min_index: Integer;ππbegin { sort_em }π For counter := 1 to 99 do { 99 not 100 }π beginπ min_index := counter;π For counter2 := counter + 1 to 100 doπ if Labels[counter2].name < Labels[counter].nameπ thenπ min_index := counter;π temp := Labels[min_index];π Labels[min_index] := Labels[counter];π Labels[counter] := tempπ end;πend; { sort_em }ππ{ ******************************************** }ππProcedure Write_Labels(Var Labels: Labels_Type;π Var f: Text);πVarπ counter: index_Type;ππbegin { Write_Labels }π For counter := 1 to 100 doπ beginπ With Labels[counter] doπ Writeln(f, name, street, city, state, zip);π end;πend; { Write_Labels }ππ{ ******************************************** }ππbegin { main }π assign(f, 'DATAFile.DAT'); { or whatever it is on your disk }π reset(f);π get_Records(f, Labels);π sort_em(Labels);π reWrite(f);π Write_Labels(Labels, f);π close(f)πend. { main }π 6 05-28-9313:55ALL SWAG SUPPORT TEAM RECSRCH.PAS IMPORT 22 {πHAGEN LEHMANNπ> Can someone help me make a search Procedure that will readπ> from a Record format, from the disk!!!ππThe easiest way to search a Record in a File is to read the Records from Fileπand compare them With the Record that is to be searched.ππif you simply want to search For a String then I've got something For you. ;-)πLook at this Function:π}πFunction Search(SearchFor : String; FileName : String) : LongInt;πVarπ F : File;π Pos,Dummy : LongInt;π BufSize,ReadNum : Word;π Buffer : ^Byte;π Found : Boolean;ππ Function SearchString(Var Data; Size : Word; Str : String) : LongInt;π Varπ S : String;π Loop : LongInt;π Found : Boolean;π L : Byte Absolute Str;π beginπ Loop := -1;π Found := False;π if L > 0 Then { I don't search For empty Strings, I'm not crazy }π Repeatπ Inc(Loop);π { convert buffer into String }π Move(Mem[Seg(Data) : Loop], Mem[Seg(S) : Ofs(S) + 1], L + 1);π S[0] := Char(L);π if S = Str Thenπ Found := True; { search For String }π Until Found Or (Loop = Size - L);π if Found Thenπ SearchString := Loop { that's the File position }π elseπ SearchString := -1; { I couldn't find anything }π end;ππbeginπ Search := -1;π if MaxAvail > 65535 Thenπ BufSize := 65535 { check available heap }π elseπ BufSize := MaxAvail;π if (BufSize > 0) And (BufSize > Length(SearchFor)) Thenπ beginπ GetMem(Buffer, BufSize); { reserve heap For buffer }π Assign(F, FileName);π Reset(F, 1); { open File }π if IOResult = 0 Thenπ beginπ Pos := 0;π Found := False;π Repeatπ BlockRead(F, Buffer^, BufSize, ReadNum); { read buffer }π if ReadNum > 0 Then { anything ok? }π beginπ Dummy := SearchString(Buffer^, ReadNum, SearchFor);π if Dummy <> -1 Then { String has been found }π beginπ Found := True; { set found flag }π Inc(Pos, Dummy);π endπ elseπ beginπ Inc(Pos, ReadNum - Length(SearchFor));π Seek(F, Pos); { set new File position }π end;π end;π Until Found Or (ReadNum <> BufSize);π if Found Thenπ Search := Pos { String has been found }π elseπ Search := -1; { String hasn't been found }π Close(F);π end;π Release(Buffer); { release reserved heap }π end;πend;ππ 7 05-28-9313:55ALL SWAG SUPPORT TEAM VARIANT.PAS IMPORT 15 {* Program that works!π** Shows use of Variant Records.π** roleplaying Type implemented.π*}πUses Crt;πTypeπ CharType = (Warrior, Wizard);π CharacterType = Recordπ Name: String[16];π Health, MaxHealth: Integer;π Char: CharType;π Case CharType ofπ Warrior: ( DamagetoHit: Integer);π Wizard : ( Spell, MaxSpell: Integer);π end;ππVarπ Character: CharacterType;π S: String;ππbeginππ { select Character Type }π Writeln;π Writeln('Select Character Type:');π Writeln(' [ 1 ] Warrior');π Writeln(' [ 2 ] Wizard');π Readln(S);ππ With Character doπ beginπ if S = '1' then Character.Char := Warrior elseπ Character.Char := Wizard;ππ { set fixed Variables }π Write('Enter Character name: ');π Readln(Name);π Write('Enter Character health value: ');π Readln(MaxHealth);π Health := MaxHealth;π { set Variant Variables }π Case Char ofπ Warrior: beginπ Write('Enter ', Name, '''s hit value: ');π Readln(Character.DamagetoHit);π end;π Wizard: beginπ Write('Enter ', Name, '''s spell value: ');π Readln(MaxSpell);π Spell := MaxSpell;π end;π end;π end;ππ With Character do { display Character info }π beginπ { fixed Variables }π Writeln;π Writeln('*** Your Character:');π Writeln(' Name: ', Name);π Writeln(' Health: ', Health,'/',MaxHealth);π { Variant Variables }π Case Char ofπ Warrior: Writeln(' Hit: ', DamagetoHit);π Wizard: Writeln(' Spell: ', Spell, '/', MaxSpell);π end;π end;πend.π 8 05-31-9307:13ALL SWAG SUPPORT TEAM Fast Delete Typed RecordsIMPORT 9 BG>JB>A method that I have successfully used to delete records in place isπBG>JB>to...ππ 'Scuse me for butting in, but I have another approach which willπ preserve your record order. I will present it for a file of recordsπ the total size of which is less than 64K. The routine may easily beπ adapted for large files:ππprocedure del_rec(fname : string;target : longint;rec_size : longint);πtypeπ t_buf=array[1..65520] of byte;ππvarπ f : file;π buf : t_buf;π n : word;ππbeginπ new(buf);π assign(f,fname); { open your file }π reset(f,1);π blockread(f,buf,sizeof(buf),n);π close(f);ππ move(bufsucc(target)*rec_size],buftarget*rec_size],n-(target*rec_size));π dec(n,rec_size);π rewrite(f,1);π blockwrite(f,buf,n);π close(f);π dispose(buf);πend;π---π * The Right Place (tm) BBS/Atlanta - 404/476-2607 SuperRegional Hubπ * PostLink(tm) v1.05 TRP (#564) : RelayNet(tm)π---π ■ OLX 2.1 TD ■ I just steal 'em, I don't explain 'em.π 9 08-27-9321:14ALL DANIEL HEFLEY Delete Record Routine IMPORT 13 6ü {πDANIEL HEFLEYππ> according to all references I've read, the only way to delete Recordsπ> in ANY File is to copy the good Records to a new File, skipping overπ> the ones you want deleted, delete the original File, and rename the newπ> one to the original name. A long way of doing it, but I don't know ofπ> any other.ππ No.....You could:π}ππProcedure DelRec(RecIdx : LongInt);πVarπ Count,π RecNo : LongInt;π IFile : File of ItemRec;π Item : ItemRec;ππbeginπ Assign(IFile,'Tmp.Dat'); Reset(f); { assuming it exists }π Seek(IFile,idx); { assuming recidx exists }π RecNo := FileSize(f) - idx - 1;π For Count := idx to RecNo doπ beginπ Seek(IFile,Count+1);π Read(IFile,Item); { read next rec }π Seek(IFile,Count);π Write(IFile,Item); { overide prev rec }π end;π Seek(IFile,RecNo); { seek to last Record }π Truncate(IFile); { truncate rest of File }π Close(IFile);πend;ππ{π> Of course, you could cheat like I do...when I create a File Withπ> Records, every one of them has one Boolean field called ACTIVE_REC,π> which is forced to True when the Record is created. if the user wantsπ> to delete the Record, ACTIVE_REC becomes False and the Program ignoresπ> the Record. Eventually, you'll have to use the aboveπ> copy-delete-rename Procedure, but it sure saves time if you're justπ> deleting one Record!ππWhen you initialize new Variables....find the Non Active Record and assignπyour File index Variable to that record!π} 10 08-27-9321:14ALL STEVE ROGERS Another Delete Routine IMPORT 8 6ü {πSTEVE ROGERSππ>A method that I have successfully used to delete Records in place is to...ππ 'Scuse me For butting in, but I have another approach which willπ preserve your Record order. I will present it For a File of Recordsπ the total size of which is less than 64K. The routine may easily beπ adapted For large Files:π}ππProcedure del_rec(fname : String; target : LongInt; rec_size : LongInt);πTypeπ t_buf = Array[1..65520] of Byte;πVarπ f : File;π buf : ^t_buf;π n : Word;πbeginπ new(buf);π assign(f, fname); { open your File }π reset(f, 1);π blockread(f, buf^, sizeof(buf^), n);π close(f);ππ move(buf^[succ(target) * rec_size],π buf^[target * rec_size], n - (target * rec_size));π dec(n, rec_size);π reWrite(f, 1);π blockWrite(f, buf^, n);π close(f);π dispose(buf);πend;π