You are here:

FoxPro/Browse tracking help

Advertisement


Question
I have written these to programs :
1.Track.prg

set talk off
clos all
sele a
use xx && just change the file name (except track.dbf) here and you done!
** here we can use set field to and fields name in which we generally need tracking!
scat memv
set safe off
copy stru exte to yy
sele b
use yy
browcmd='brow fiel '
do whil not eof()
browcmd=browcmd+allt(field_name)+':v=a(),'
skip
endd
inde on field_name to xx
set safe on
sele c
use track
set rela to uppe(field_name) into b
sele a
browcmd=stuff(browcmd,rat(',',browcmd),1,'')
browcmd=browcmd+' when b()'
set proc to track1
&browcmd
set proc to

2.Track1.prg
*** it is part of track.prg

func a
xx=varread()
oldvar="m."+xx
newval=&xx
do case
case type(xx)='C'
if &oldvar # &xx
*** This is the place where you can track the changes!"
*wait wind "Old Value was:"+&oldvar nowa
_fn=alia()
_recno=recno()
sele c
appe blan
repl filename with _fn
repl recno with _recno
repl field_name with xx
repl field_type with b.field_type
repl field_len with b.field_len
repl field_dec with b.field_dec
repl oldvalue with &oldvar
repl newvalue with newval
repl corrdate with date()
repl corrtime with time()
sele a
endi

case type(xx)='N'
if &oldvar # &xx
*** This is the place where you can track the changes!"
*wait wind "Old Value was:"+allt(str(&oldvar)) nowa
_fn=alia()
_recno=recno()
sele c
appe blan
repl filename with _fn
repl recno with _recno
repl field_name with xx
repl field_type with b.field_type
repl field_len with b.field_len
repl field_dec with b.field_dec
_kk=''
_jj=b.field_len-(b.field_dec+iif(!empty(b.field_dec),1,0))
for i=1 to _jj
_kk=_kk+'9'
next
if !empty(b.field_dec)
_kk=_kk+'.'
for i=1 to b.field_dec
_kk=_kk+'9'
next
endi
repl oldvalue with tran(&oldvar,_kk)
repl newvalue with tran(newval,_kk)
repl corrdate with date()
repl corrtime with time()
sele a
endi
endc

func b
sele a
scat memv

With the help of above two .prgs, I am able to track the changes in track.dbf.  My questions are :

(A)It supports only those .dbfs which have fewer fields, otherwise it returns line too long error.  So, is it possible to work for more columns or any other good way to handle tracking.
(B)I want to track the deletion of records too.  So, how to incorporate that also.

Thanks and Regards
Girish Sharma

Answer
Sir:

  First - you apparently missed the part in the instructions which asked for the version of FoxPro you are using.  As a result, my answer has to be generic enough that it won't matter.

  As you may already know, the "line too long" error is caused by the length of BROWCMD when you attempt its execution.  Since, there is an inherent limit on the length of a command line, that can't be overcome.  If you continue performing file edits within a browse window, I don't see any way around this.  

  That being said... If you perform editing using memory variables and a data entry screen, you would be able to compare the existing table contents to the memory variables at the end of the editing session.  So, create a data entry screen/form based on memory variables, then use a simple browse command inside of a do...enddo loop to select the record to edit - similar to:

  USE xx
  USE track IN 0  && can be opened here or in TrackIt.PRG
  DO WHILE .T.
     SELECT xx
     ON KEY LABEL ENTER KEYBOARD(CHR(23)) && this is Ctrl+W
     BROWSE
     ON KEY LABEL ENTER
     IF LASTKEY() = 27  && user pressed escape, end process
        EXIT
     ENDIF
     ** if you get here, the user pressed Ctrl+W or ENTER
     SCATTER MEMVAR MEMO
     SaveThisData = .f.
     ** run the data entry screen here (how to create one and run it is version dependent)
     **    in the data entry screen, set SaveThisData = .t. if you want to save the changes.
     **    leave it set to .f. if the user wants to cancel the changes.
     **          generally done with "SAVE" and "CANCEL" buttons
     ** once the screen is gone (released when the user clicks SAVE or CANCEL)
     IF SaveThisData    && user selected SAVE
        DO TrackIt.PRG
        ** Within the program, you can:
        ** compare the fields (m.fldname versus fldname) using field names in yy
        ** if/when a change is found, store the information in TRACK.DBF
        **    [you already have a good grasp of how to do the comparison and save the data]
        ** the TrackIt program can also check for IF DELETED() [answers second question]
        
        ** after you're finished with updating TRACK.DBF
        SELECT xx          && go back to the main table
        GATHER MEMVAR MEMO   && make the updates
     ENDIF
  ENDDO
  CLOSE DATA

Good Luck,

Fred

P.S.
Feel free to ask a follow-up if needed.
Please use the comments field in the rating system to let me know if it works out.

FoxPro

All Answers


Answers by Expert:


Ask Experts

Volunteer


Fred Frase

Expertise

Questions about development only. No installation or hardware specific questions, please. Your first step in requesting assistance should be to identify the version of FoxPro you are using. I can write short functions but, PLEASE do not ask me to write programs for you.

Experience

Nearly 30 years professional programming experience using FoxPro (FoxBase through VFP 9) or other xbase language, primarily in Windows environments.

Education/Credentials
Completed a 1,000 hour diploma course in programming at International Academy of Ohio (subsequently merged with Southern Ohio College).

©2016 About.com. All rights reserved.