Link to home
Start Free TrialLog in
Avatar of KimberlyMinarik
KimberlyMinarik

asked on

Delete records from a text file

I have a text file that writes records 65 characters across then carriage returns and starts a new record.

I need to read that text file and delete an entire record, if it does not meet a verification check.

How do I do this without rewriting the entire file?

Because these records could be in the middle, I don't want to have to read and recreate every text file excluding the records that don't meet the verification.

Is there a way just to delete that record from the text file without rewriting the whole text file to not include the record?  

Thanks...

Avatar of bobbit31
bobbit31
Flag of United States of America image

you can open it in a richtextbox do your edits there and then save it back.
Avatar of KimberlyMinarik
KimberlyMinarik

ASKER

How do you do that???
try something like this:

put richtextbox control on form and call it richtextbox1

Private Sub Command1_Click()
    Dim records() As String

    RichTextBox1.LoadFile "C:\my documents\test.txt"
   
    records = Split(RichTextBox1.Text, vbCrLf)

    For i = 0 To UBound(records)
        If records(i) <> "Hello World" Then '' you would put your checks here
            RichTextBox1.Find records(i) & vbCrLf, 1, Len(RichTextBox1.Text)
            RichTextBox1.SetFocus
            SendKeys "{DELETE}", True
        End If
    Next

    RichTextBox1.SaveFile "C:\my documents\test.txt", rtfText
End Sub

test.txt looks like this before:
Hello World
name1
name2
Hello World
name3
name4

and after:
Hello World
Hello World

Hi,

Doing the rich text box is writing the whole file back to the disk. There is no way to delete part of a file from the middle. The only thing you can do is rewrite the entire file, using whatever method, or have a flag for each record saying whether it is valid or not.

Zaphod.
You could try creating a text-based file DSN (data source) and then using standard data access techniques to handle the records - that would probably improve your whole code.

See (I know its RDO but the idea, and indeed the code, is virtually identical)
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q187670

You could try creating a text-based file DSN (data source) and then using standard data access techniques to handle the records - that would probably improve your whole code.

See (I know its RDO but the idea, and indeed the code, is virtually identical)
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q187670

ASKER CERTIFIED SOLUTION
Avatar of olx
olx

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Richie_Simonetti
olx, that's a good idea but as records are added, the file size grows up and the performance would suffers.
Besides, you need to rewrite entire file to put the flag, am i right?
No, you don't need to rewrite the entire file to change the value of certain bytes in the middle, you just have to open it in binary mode then write to the appropriate bytes in the file. You just cannot add or remove bytes from the middle without rewriting the entire file, or at least the entire file after that point.

Zaphod.
Overwrite the record with the contents of the last record, and use SetEndOfFile to make your file shorter.
Kimberly:


- my original idea was to make the change (add the flag) in the file structure definition and start capturing "from now on" with the flag.  no to rewrite te whole db each time.

- if the discarded records are less than 5% of the total records you get in a period.. then no problem.

- i was thinking last night that if you do the check while you receive de information then you could discard the record inmediately.  capturing and checking are made by different apps at different times?
if not, thats it, you could receive de record, checkit and if its ok, write it, if not, dont.

*** Other option is to capture in a file, (same structure, just named diferent, acording to date) and when you make the check use that file, good records go to the main file, bad ones get ignored.  and at the end, delete the file.   To avoid receiving in the same file that you are checking, you could capture in files named by the date. 20020418_Buffer.dat

Hope this helps

:)


if you need to capture and check in realtime then you cant use the file buffer.

BUT then what comes next is to mark the record as discarded and when you add other record, doit over the discarded records.  

here is some code.

'put this in a module
type isamB01 as records
   Exist as string *1
   ClientCode as long
   Reference as date
   Amount as currency
   EndOfRecord as string *3
end type

'put this to get a new record

Private Sub cmdNew_Click()

    Dim b01 As isamB01
    Dim r01 As Long
    Open file For Random As #1 Len = Len(b01)
    r01 = 0
    Do
        r01 = r01 + 1
        Get #1, r01, b01
        If b01.Exist <> "1" Then  ' good record
       
        b01.Amount = x
        b01.ClientCode = y
        b01.EndOfRecord = ">" & vbCrLf
        b01.Exist = "1"
        b01.Reference = Now()
       
        Put #1, r01, b01
    Loop
       
    Close 1
   
End Sub


'put this to discard records.
Private Sub cmdDiscard_Click()

    Dim b01 As isamB01
    Dim r01 As Long
    Open file For Random As #1 Len = Len(b01)
    r01 = x 'record# to be discarded
    Get #1, r01, b01
    b01.Exist = "X"
    Put #1, r01, b01
    Close 1
   
End Sub

hope this helps
probably you think that is sooooo slow to re read the whole db each time, but it takes less than a second to read a 10,000 records of 65char lenght.

and at the moment of creating a new record you could start from half the file.

instead of

r01 = 0

use

r01 = (lof(1) / 65) /2
'the filelen, in records, cut in half

this way you assure you could reuse the last discarded records.

:)
Sorry I took so long to add.  I have been away do to family issues.