I am trying to create a text log file to record when the Add Change and Delete buttons are used on a browse.
There are two issues I have not been able to resolve.
The first is to do with inserting a “Header” line to the log when the file is created or recreated. The code included below creates the header for each entry, where my intention is to put 1 header line at the top of the file.
The second is in regard to recognising when the delete button is selected. Both the Insert(Add in my example) and Change (Edsit in my example) work fine, but the Delete button does not trigger any output to the log file.
Can anyone offer suggestions to what I need to do to correct these two issues?
This is the code I have created:
! Add to Log file
!----------------
SHARE(PaySched)
IF ERRORCODE()
CREATE(PaySched)
SHARE(PaySched)
END
IF RECORDS(PaySched) = 0 ! Insert a header
GET(PaySched,0)
CLEAR(PaySched)
ACCESS:PaySched.Insert
LOG:LogEntry = 'Activity|Date|Time|Description|BankSysID|PayeeSysID|TaskSysID|TransactionSysID|UserCode'
END
APPEND(PaySched)
IF SELF:Request = InsertRecord
LOG:LogEntry = 'TASKS - Add Entry - |'&FORMAT(TODAY(),@D017)&'|'&FORMAT(CLOCK(),@t3)&'|'&CLIP(TSK:PaymentTask)&'|BankID:'&FORMAT(TSK:BNKSysID,@N04)&'|PayeeID:'&FORMAT(TSK:PAYSysID,@N04)&'|TaskID:'&FORMAT(TSK:TSKSysID,@N04)&'|TransID:N/A|User:'&CLIP(GLO:UserCode)
ELSIF SELF:Request = ChangeRecord
LOG:LogEntry = 'TASKS - Edit Entry - |'&FORMAT(TODAY(),@D017)&'|'&FORMAT(CLOCK(),@t3)&'|'&CLIP(TSK:PaymentTask)&'|BankID:'&FORMAT(TSK:BNKSysID,@N04)&'|PayeeID:'&FORMAT(TSK:PAYSysID,@N04)&'|TaskID:'&FORMAT(TSK:TSKSysID,@N04)&'|TransID:N/A|User:'&CLIP(GLO:UserCode)
ELSIF SELF:Request = DeleteRecord
LOG:LogEntry = 'TASKS - Delete Entry - |'&FORMAT(TODAY(),@D017)&'|'&FORMAT(CLOCK(),@t3)&'|'&CLIP(TSK:PaymentTask)&'|BankID:'&FORMAT(TSK:BNKSysID,@N04)&'|PayeeID:'&FORMAT(TSK:PAYSysID,@N04)&'|TaskID:'&FORMAT(TSK:TSKSysID,@N04)&'|TransID:N/A|User:'&CLIP(GLO:UserCode)
ELSE
MessageResult#=Message('If this message appears there is a problem|as this message should not be reached!','NO ACTIVITY NOMINATED',Icon:Cross,'Abort',0,)
END
APPEND(PaySched)
CLOSE(PaySched)
Looks like CW20/Clarion rather than ABC being used?
In ABC when deleting a record, if the form is not displayed which requires the user to click OK to exit the update form, the record will be deleted by the browse window. That could explain why you are not seeing anything when a record is deleted.
With this in mind, I would use the global embeds (Dct Trigger’s) section to write a log message when ever a record is CRUD’ed on a file/table. That way you log the action thats occurred by the app which is initiated by the user, but it will also log changes made by processes and reports.
What are you trying to achive with the log?
I had something similar built into an app so we could see who had touched tables, but as always, records removed using means outside the app typically wont show up in the log file.
Likewise, I never deleted records, they had a marker to say they were deleted so didnt display in normal windows. I didnt like to see Record ID gaps in the raw data. It was more work to implement that, but I needed to and liked to account for and explain everything that occurred with my app’s and the data captured.
I would guess you are using the ASCII or DOS Driver in which case RECORDS() is not supported and always returns zero so you get the header every time.
You could change to BYTES(PaySched)=0, but I don’t like Bytes() because it works two ways. I would code:
IF PaySched{PROP:FileSize}=0 THEN ! Insert a header
You really want to check for the specific Error Code 2 “File not found” as there can be other reasons the Open fails, which you may want to handle.
E.g. If you are not doing a CLOSE() then you’ll get an error 52 “File Already Open”. You’ll try to CREATE the file again, which will fail so your file remains. The BYTES() would not return file size but instead the last ADD size
Add mentioned your mixing in the ABC .Insert is likely not working, not probably needed.
I thought the OP was using the ASCII Driver so I only checked that Supported Commands Help which said NO for RECORDS().
I just checked the DOS Supported Commands and it does say YES for RECORDS(). There’s no description of what it returned or how it works. I assume it works like BYTES?
It returns the number of records in the file.
Records = filesize / recordsize ! rounded up.
In other words, if the record size is say 4k, and the file size is 24k, then Records(dosfile) returns 6.
if the file size is 25k it returns 7.
Thank you, everyone for your responses. It really how much I really don’t know about the beast.
Carl, I changed my code as per your suggestion and that worked a treat.
Sean, I took your advice about DB Auditing that does fit the bill, but with one problem, how to locate the log files so that they are accessible to network users. I noticed that when setting up the User Name logging, I could use a global variable successfully, but when I tried to do that with a filename and path, that did not work. Are there any suggestions on how to use a variable to name and locate the log file?
By the way, I am using the ASCII driver for the log file in my example.
I am also now re-reading the “Making the Transition to the ABC Templates” to try getting a better understanding of ABC.
Thanks again,
Kenn Sharples
LOG:LogEntry = '|'&FORMAT(TODAY(),@D017)&'|'&FORMAT(CLOCK(),@t3)&'|'&CLIP(TSK:PaymentTask)&'|BankID:'&FORMAT(TSK:BNKSysID,@N04)&'|PayeeID:'&FORMAT(TSK:PAYSysID,@N04)&'|TaskID:'&FORMAT(TSK:TSKSysID,@N04)&'|TransID:N/A|User:'&CLIP(GLO:UserCode)
CASE SELF.Request
OF InsertRecord
LOG:LogEntry = 'TASKS - Add Entry - '& LOG:LogEntry
OF ChangeRecord
LOG:LogEntry = 'TASKS - Edit Entry - '& LOG:LogEntry
Of DeleteRecord
LOG:LogEntry = 'TASKS - Delete Entry - '& LOG:LogEntry
ELSE
LOG:LogEntry = 'TASKS - Request ?'& SELF.Request &' - '& LOG:LogEntry
MessageResult#=Message('If this message appears there is a problem|as this message should not be reached!','NO ACTIVITY NOMINATED',Icon:Cross,'Abort',0,)
END
I think you had the same Log Entry string code 3 times. I think you could have it 1 time as done above before the CASE. This makes it easier to change the code.
Gold Start for the ELSE that takes the unexpected. Your message 'If this message appears there is a problem|as this message should not be reached!'
gives no context or details about the problem. Two years from now when it appears you may be scratching your head. I’ve been there… Suggest
Message('Failed Log of PaySched with Unknown Request # '& SELF.Request ||'& LOG:LogEntry ...
There is a ViewRecord request you would not need to log. That should close the Form as Cancelled, so probably will not hit your code.