Here's my current version of an Undelete UDF (User-Defined Function). It is shown below and as an attached zip file.
Note that it exits early if all records have been undeleted or if there are no records to undelete. Also there are optional filters and record # ranges, and an option to mark or not the undeleted records.
Regards,
Ira J. Perlow
Computer Systems Design & Associates
[email protected]
Note that it exits early if all records have been undeleted or if there are no records to undelete. Also there are optional filters and record # ranges, and an option to mark or not the undeleted records.
Regards,
Ira J. Perlow
Computer Systems Design & Associates
[email protected]
Code:
function UndeleteRecords as N(TableName as C,Options as C,Filter as C) ' Created by Computer Systems Design & Associates ' Copyright 2001 Computer Systems Design & Associates, All Rights Reserved ' Last Update: June 15, 2001 ' Input: TableName = Table (dbf) name to delete. ' If Null, it then prompts you for tables in the current database ' If blank (but not null), it uses the current table ' If "*", It prompts you for any table ' Options = "I" - Display information before running with choice to cancel ' "M" - Mark records that were undeleted ' "R" - Prompt for record range ' "F" - Prompt for filter ' if null, then IRM options are selected ' Filter = Filter (in context of table) expression to process undelete for ' If blank or null, all records will be processed ' The filter expression may not be able to access the table fields unless ' the current form's table is used ' Output: Number of records that were undeleted ' Negative number indicates error ' Errors: -1 = Cancelled operation ' -2 = Table name not found ' -3 = Table not available ' -4 = Other errors ' Typical Usage: ' Place a button on table to delete records with a function call like the example in it's code ' Examples: ' UndeleteRecords("tablename","IRM","") ' Notes: ' The filter expression may not be able to access the table fields unless ' the current form's table is used ' Set default error return UndeleteRecords=-4 If Options=="" Opt="IRM" ELSE Opt=trim(Options) End If ' If not blank and not asterisk, use the supplied tablename IF .NOT.(TRIM(TableName)=="").AND..NOT.(ALLTRIM(TableName)=="*") ' If file does not exist, then return IF .not.:File.Exists(TableName) UndeleteRecords=-2 END END IF ' Use the supplied Tablename TabNam=TableName else if TableName=="" dim tlist[100] as C tname=:A5.table_enum("") IF .NOT.(trim(tname)=="") ' While the table_enum method returns ' nonblank names, get next name i=1 WHILE .not.(trim(tname)=="") tlist[i]=tname i=i+1 tname=:A5.table_enum(tname) END WHILE ' sort the array otherwise names will be in ' order in which operations were created. sort_array("tlist") ' Show the user a list of names choice=ui_get_list_array("Select Table to Undelete",1,"tlist") ' If the user selects a table, then do it IF TRIM(choice)=="" UndeleteRecords=-1 END END IF getpath=IF(trim(:A5.Get_Master_Path())=="",:A5.Get_Path(),:A5.Get_Master_Path()) IF .NOT.:File.Exists(getpath+chr(92)+choice+".dbf") UndeleteRecords=-2 END END IF TabNam=getpath+chr(92)+choice+".dbf" END IF ELSE IF TRIM(TableName)=="" TabNam=table.current().Name_Get()+".dbf" ELSE choice=ui_get_file("Table to Undelete Records:","Table(*.dbf)",table.current().Name_Get()+".dbf","X") IF TRIM(choice)=="" UndeleteRecords=-1 END END IF TabNam=choice END IF 'trace.writeln("Table selected="+TabNam) ' Save status of table being opened IF :Table.IsOpen(TabNam) opened=1 ELSE opened=0 END IF ' Set Flag to trap errors ErrFlag=0 ON ERROR GOTO error_handler tbl=table.open(TabNam) ON ERROR GOTO 0 ' If error in opening file, then exit with error IF ErrFlag=1 UndeleteRecords=-3 END END IF ' Counts of Regular and deleted records reccnt=tbl.records_get() recdel=tbl.records_deleted() IF "I" $ UPPER(Opt) txt="Table: "+tabnam+CHR(10)+CHR(13) txt=txt+" Total Records: "+STR(reccnt+recdel,7,0)+CHR(10)+CHR(13) txt=txt+"Deleted Records: "+STR(recdel,7,0) choicen=ui_msg_box("Undelete Records?",txt,UI_OK_CANCEL+UI_QUESTION_SYMBOL+UI_SECOND_BUTTON_DEFAULT) IF .not.(UI_OK_SELECTED=choicen) UndeleteRecords=-1 ' If the table was previously closed, close it now IF opened=0 tbl.close() END IF END END IF END IF ' Exit if nothing to do IF recdel=0 UndeleteRecords=0 END END IF IF "F" $ UPPER(Opt) IF trim(filter)=="" dflt=".T." ELSE dflt=alltrim(filter) END IF choice=ui_get_expr("Enter Filter Expression","Filter:",dflt) IF TRIM(choice)=="" UndeleteRecords=-1 ' If the table was previously closed, close it now IF opened=0 tbl.close() END IF END END IF filtexp=alltrim(choice) ELSE IF trim(filter)=="" dflt=".T." ELSE dflt=alltrim(filter) END IF filtexp=dflt END IF IF "R" $ UPPER(Opt) choice=ui_get_number("Record Range for Undelete","Max Record="+LTRIM(STR(reccnt+recdel))+" Begin Record #:","1") IF (0>=VAL(choice)).or.(VAL(choice)>reccnt+recdel) UndeleteRecords=-1 ' If the table was previously closed, close it now IF opened=0 tbl.close() END IF END END IF rangebeg=VAL(choice) choice=ui_get_number("Record Range for Undelete","Max Record="+LTRIM(STR(reccnt+recdel))+" End Record #:",LTRIM(STR(reccnt+recdel))) IF (0>=VAL(choice)).or.(VAL(choice)>reccnt+recdel).or.(rangebeg>VAL(choice)) UndeleteRecords=-1 ' If the table was previously closed, close it now IF opened=0 tbl.close() END IF END END IF rangeend=VAL(choice) ELSE rangebeg=1 rangeend=reccnt+recdel END IF Undeleted=0 i=1 ' Get pointer to delete/mark field ' Field contains "-" (Dash) for Marked, "*" (Asterick) for Deleted, ' " " (space) for regular record fld=tbl.field_get(0) i=rangebeg ON ERROR GOTO error_handler nxt: tbl.fetch_goto(i) IF tbl.is_deleted() tbl.change_begin() ErrFlag=0 fil=eval(filtexp) IF ErrFlag=1 fil=.T. 'trace.writeln("rec #="+LTRIM(STR(i))+"default") ELSE 'trace.writeln("rec #="+LTRIM(STR(i))+" filter="+IF(fil,".T.",".F.")) END IF IF eval(filtexp) IF "M" $ UPPER(Opt) ' Mark record tbl.mark() ' Alternative way to do the mark 'fld.value_put("-") ELSE ' Undelete record fld.value_put(" ") END IF Undeleted=Undeleted+1 END IF tbl.change_end(.t.) END IF i=i+1 ' If some records still deleted and range has not yet been reached, repeat IF rangeend>=i.and.recdel>Undeleted GOTO nxt END IF ON ERROR GOTO 0 ' New counts of Regular and deleted records newcnt=tbl.records_get() newdel=tbl.records_deleted() ' If the table was previously closed, close it now IF opened=0 tbl.close() END IF UndeleteRecords=Undeleted ui_msg_box("Undelete Results","Undeleted "+LTRIM(STR(Undeleted))+" records in table"+CHR(10)+CHR(13)+tabnam,UI_OK+UI_INFORMATION_SYMBOL) END ' Error handler error_handler: ErrFlag=1 'errcode=error_code_get() 'errmsg=error_text_get(err) RESUME NEXT END end function
Comment