"DJ" <
ddjames@tampabay.rr.com>wrote
Quote
I work with text files that contain messages passed between POS systems and
financial institutions. The messages are text strings that vary in length,
up to 400 characters, with each string being composed of variable length
fields. Here's an example of one of the message strings:
EFQC000855050413180103ACME004200031403 05041300000000SWTH
780000000000 01010356001234567890123456=14121104485478004008PB09901
05044123 Main Street Home Town RI40008
41020091004663 42020840901000325542
47024002480010990001000000000810100000000000830260101000000009900200606663299
The messages themselves are requests sent from the POS terminal to the
financial institution, and replies from the institution back to the POS
terminal. Reply messages are matched to their corresponding request message
when certain fields within the messages (message number, transaction
sequence id, etc.) are identical between the two messages.
I'm trying to write a vb app that will scan the text file, parse the
messages and match request messages to reply messages.
<...>
Any suggestions would be appreciated.
If I read your message correctly, you have a large text file where each line is
a recorded transaction (either request, or reply) and you want to match up
replies with their requests using a few fields to identify the request/reply.
Can it be safe to assume that the request will always be ahead of the reply?
(Going on that assumtion....)
Use the file pointer to identify and locate the different lines in the file. Build
a fixed length identifier that will match the replies with the requests (using
the message number, transaction ID, etc). Finally, use 2 collections to sort
the file into replies, and requests. As you read each line in the file, first note
where the file pointer points to, then read the line, then determine if it is a
request, or reply. Build the transaction ID and add the file pointer value
to either the Requests collection, or the Replies collection, using the transaction
ID as its key. If that line was a reply, check for a matching key in the Requests
collection. If it is found there, you have enough info to make a status report on
that transaction.
In pseudo code, it might look similar to:
Open file
Do While Not EOF
Get File Pointer (Seek)
Input line (Line Input)
Decide Transaction type
If Request type Then
Build ID
Add to request collection
If Reply type Then
Build ID
Check for matching request
If Request found Then
Add status to status report
(Remove Request ???)
For a short example (minus any file activity) paste the following
into a new form:
'------------------
Option Explicit
Private ReQ As Collection
Private ReP As Collection
Private Sub Form_Load()
Dim msg As String, ID As String
Set ReQ = New Collection ' Requests
Set ReP = New Collection ' Replies
' Reading file adds to collections
ReQ.Add 1, BuildID("9", "1000")
ReQ.Add 101, BuildID("10", "1001")
ReP.Add 201, BuildID("9", "1002")
ReQ.Add 301, BuildID("10", "1014")
ReQ.Add 401, BuildID("11", "1016")
ReP.Add 501, BuildID("10", "1001")
' Test current reply (10, 1001)
ID = BuildID("10", "1001")
If IsPresent(ID) Then
msg = "STATUS:" & vbCrLf & vbCrLf
msg = msg & "The Request that begins at file position "
msg = msg & CStr(ReQ(ID)) & vbCrLf
msg = msg & "is followed by a reply that begins at file position "
msg = msg & CStr(ReP(ID)) & vbCrLf
MsgBox msg, vbInformation, "Match Found"
End If
End Sub
Function BuildID(MsgNum As String, TransID As String) As String
BuildID = Space$(24)
Mid(BuildID, 1) = MsgNum
Mid(BuildID, 12) = TransID
End Function
Function IsPresent(ID As String) As Boolean
On Error Resume Next
IsPresent = (ReQ(ID)>0)
Err.Clear
End Function
'----------------------------------
Note that keeping the functions separate helps in re-use. Also, once
you know the positions in the file where the data is at, you can, at your
next convenience, go back and re-read those lines if needed. (Read
Seek Function and Seek Statement in VB Help) Leaving the data in the
file means you won't be using up computer memory as much as storing
each line would require. Chances are, the file pointer is all you need....
If there is only one reply per request, then you could remove any matches
found (from both collections) so that at the end, you'd know how many
were not matched in the two collections, and if needed, where they are
in the file.
HTH
LFS
-