Skip to content

Release 3 Agents

Chapter 8-4
Release 3 Agents

Introduction

Agents in Domino and Notes were preceeded by macros in Notes Release 3. As of Release 4, macros have been replaced by agents. For backward compatibility, Domino still supports macro notes and refers to them as Release 3 agents. This chapter explains how to create, read, and run Notes Release 3 agents from a C API program. It describes different types of Release 3 agents and how you can use the C API to manipulate them, identifies the components of Release 3 agent notes, and describes how to interpret these items.


Sample Programs

This chapter refers to the two sample programs ADDMACRO and RUNMACRO. The source code files for ADDMACRO reside in the directory samples\dbdesign\addmacro. The source code files for RUNMACRO reside in the directory samples\dbdesign\runmacro.


Release 3 Agent Notes

Release 3 agent notes are notes of class NOTE_CLASS_FILTER. Like form and view notes, agent notes are design notes that reside in Domino databases. Domino application developers design agents to perform custom operations on documents in a database.

Release 3 agent notes contain formulas and control information. The formulas select documents to process and calculate values to store in the documents. The control information tells Domino or Notes when to execute the agent, which documents to consider for selection, and what operation to perform.

Some Release 3 agents -- for example, Button and SmartIcon agents -- do not reside in agent notes. This chapter focuses on Release 3 agents that do reside in agent notes.


Types of Release 3 Agents

Domino and Notes supports a wide variety of agents. This section identifies different types of Release 3 agents and discusses how you can use the C API to manipulate each type.

Release 3 Agents that C API Programs Can Create

A C API program can create any type of agent except SmartIcons.

Release 3 Agents that C API Programs Can Run

A C API program can execute any agent that does not depend on Notes user interface functionality. The following functions depend on Notes user interface functionality. Any Release 3 agent that uses one of these functions has no effect when run from a C API program:

      @DbLookup
      @DbColumn
      @Command
      @MailSend
      @DDEInitiate
      @DDETerminate
      @DDEExecute
      @DDEPoke


Release 3 Filter Agents

Filter agents normally update a series of documents in a database automatically. You can execute most filter agents from a C API program.

There are three types of filter agents, based on when the agent is executed: menu agents, background agents, and mail/paste agents.

Menu Agents

A menu agent runs when a Notes user selects it from the Actions menu or when a C API program runs it. Menu agents do not run automatically. C API programs can run most menu agents.

Background Agents

Background agents run at predetermined intervals or when a Notes user selects the View, Agents and selects Run from the Actions menu. C API programs can run most background agents.

The Domino or Notes background program automatically runs background agents at the predetermined interval specified in the agent. The control information in the agent note specifies the frequency -- hourly, daily, weekly, or never. For details, see the description of the $Period item below.

Mail/Paste Agents

Mail/paste agents run whenever the router delivers a document to the database or a user pastes the document into the database from the clipboard.

C API programs cannot intercept documents delivered to a database by the router or pasted into a database by a Notes user. Therefore, C API programs cannot run mail/paste agents when Notes would. However, C API programs can run mail/paste agents on documents in a database just as they can run menu and background agents.

Release 3 Search Agents

Search agents operate on the set of documents selected by a full-text search query. Search agents can be activated from the full text search bar or run in the background at predetermined intervals. C API programs can execute most search agents.

Release 3 Execute-Once Agents

Execute-once agents perform a single operation and then stop. The operation may process a single document or a set of documents. It does not repeat the operation for each document. C API programs can execute most execute-once agents.

Buttons

Buttons are agents that reside in forms (like fields) or in documents. They operate on the current document. When a Notes user clicks a button, it evaluates a formula and performs actions just like other agents. However, buttons do not reside in agent notes.

Since most buttons perform functions that depend on Notes user interface functionality, (for example, they use the @Command function) C API programs cannot execute most button agents. For more information about buttons, see the "Hotspots" chapter in this guide.

SmartIcons

SmartIcons are agents associated with the icons on the SmartIcons palette. SmartIcons reside in a smarticons file (.smi). The C API does not expose the format of .smi files, so C API programs can not access SmartIcons.


Components of Release 3 Agent Notes

This sections describes the items stored in a Release 3 agent note and how to interpret these items.

A Release 3 agent note must contain the following fields:

Field Name Symbolic Constant Data Type Description
$TITLE FIELD_TITLE TYPE_TEXT Name of the agent
$Type FILTER_TYPE_ITEM TYPE_TEXT Agent run options
$Operation FILTER_OPERATION_ITEM TYPE_TEXT Operation setting
$Scan FILTER_SCAN_ITEM TYPE_TEXT Run agent on setting
$Flags DESIGN_FLAGS TYPE_TEXT Design flags

Certain types of agents require additional fields. Most agents (except full-text search queries) require a field named $Formula that contains the compiled formula. Background agents must have a field named $Period that specifies how frequently Domino or Notes should run the agent. Background agents also have a field named $MachineName that identifies what machine an agent should run on. Search agents must have either a field named $SimpleQuery or a field named $BuilderQuery.

Use the symbolic constants defined in the C API header file stdnames.h when referring to the field names of agent note items. stdnames.h also defines symbolic constants for many of the standard values normally stored in these items.

Generally, $Type encodes the "When should this agent run" options, $Operation encodes the operation settings (on the lower right of the dialog if the "Formula" radio button is selected), and $Scan encodes the "Which documents should it act on" settings. These three fields represent the settings specified in the Create - Design - Agent dialog box at agent design time.


$TITLE

The $TITLE field is required in all Release 3 agent notes. The data type is TYPE_TEXT. The value of the $TITLE field is the agent name.

When you create an agent with the Notes user interface, you specify the name in the Create - Design - Agent dialog box. Notes needs the name to list the agent in menus and dialog boxes. C API programs need the name so that end users can specify the agent by name.

When you use the C API to create an agent, the agent name must not exceed DESIGN_LEVEL_MAX bytes unless it is a cascading agent name.


$Type

The $Type field is required in all Release 3 agent notes. The data type is TYPE_TEXT. The value is a character digit -- '0', '1', '2', or '3' -- corresponding to one of the filter types defined in stdnames.h.

The value stored in the $Type field encodes the "When should this agent run" options. When you create an agent with the Notes user interface, you specify the "When should this agent run" options in the Create - Design - Agent dialog box. The following table maps the filter type symbolic constants to the run options in the dialog box:

Filter Type Symbol Run Option
FILTER_TYPE_MENU Run manually from Actions menu
FILTER_TYPE_BACKGROUND Run periodically in the background
FILTER_TYPE_MAIL Run when documents are pasted/mailed into database
FILTER_TYPE_ONCE Run once

The symbolic constants are defined as numbers between 0 and 3, but the value stored in the item is a character. The code fragment below shows how to translate the symbolic filter type constant to the corresponding character before setting the $Type field.

addmacro.c - Setting the $Type Field

/ wType must be one of FILTER_TYPE_MENU, FILTER_TYPE_BACKGROUD,
   FILTER_TYPE_MAIL, or FILTER_TYPE_ONCE.
/

STATUS  LNPUBLIC  SetMacroType( NOTEHANDLE hMacro, WORD wType )
{
   STATUS      error;
   CHAR        cType;


    cType = (CHAR)('0' + wType);
   if (error = NSFItemSetText(hMacro,
               FILTER_TYPE_ITEM, / "$Type" /
               &cType, 1))
   {
       printf ("Error: unable to set Type field in macro note.\n");
   }
   return(error);    
}



$Operation

The $Operation field is required in all Release 3 agent notes. The data type is TYPE_TEXT. The value is a character digit -- '0', '1', or '2' -- corresponding to one of the filter operations defined in stdnames.h.

The value stored in the $Operation field encodes the agent operation setting. When you create an agent with the Notes user interface, you specify the operation setting in the Create - Design - Agent dialog box. The following table maps the filter operation symbolic constants to the operation settings in the dialog box:

Filter Operation Symbol Operation Setting
FILTER_OP_UPDATE Update existing document when run
FILTER_OP_SELECT Select document when run
FILTER_OP_NEW_COPY Create new document when run

The symbolic constants are defined as numbers between 0 and 2, but the value stored in the item is a character. The code fragment below shows how to translates the filter operation symbolic constant to the corresponding character before setting the $Operation field.

addmacro.c - Setting the $Operation Field

/  wOperation must be one of FILTER_OP_UPDATE,
    FILTER_OP_SELECT, or FILTER_OP_NEW_COPY.
/

STATUS  LNPUBLIC  SetMacroOperation( NOTEHANDLE hMacro, WORD wOperation )
{
   STATUS      error;
   CHAR        cOperation;
                   
   cOperation = (CHAR)('0' + wOperation);
   if (error = NSFItemSetText(hMacro,
               FILTER_OPERATION_ITEM,  / "$Operation" /
               &cOperation, 1))
   {
       printf ("Error: unable to set Operation field in macro note.\n");
   }


    return(error);
}



$Scan

The $Scan field is required in all Release 3 agent notes. The data type is TYPE_TEXT. The value is a character digit -- '0', '1', '2', '3', '4', or '5' -- corresponding to one of the filter operations defined in stdnames.h.

The value stored in the $Scan field encodes the "Which document(s) should it act on" setting. When you create an agent with the Notes user interface, you specify this setting in the Create - Design - Agent dialog box. The following table maps the filter scan option symbolic constants in stdnames.h to the "Which document(s) should it act on" settings in the dialog box:

Filter Scan Option Symbol "Which document(s)" Setting
FILTER_SCAN_ALL Run on all documents in database
FILTER_SCAN_UNREAD Run on documents not yet marked read by you
FILTER_SCAN_VIEW Run on all documents in view
FILTER_SCAN_SELECTED Run on selected documents in view
FILTER_SCAN_MAIL Not used

The symbolic constants are defined as numbers between 0 and 5, but the value stored in the item is a character. The code fragment below shows how to translate the filter scan option symbolic constant to the corresponding character before setting the $Scan field.

addmacro.c - Setting the $Scan Field

/  wScan must be one of FILTER_SCAN_ALL, FILTER_SCAN_UNREAD,
   FILTER_SCAN_VIEW, FILTER_SCAN_SELECTED, FILTER_SCAN_MAIL,

    or FILTER_SCAN_NEW.
/

STATUS  LNPUBLIC  SetMacroScan( NOTEHANDLE hMacro, WORD wScan )
{
   STATUS      error;
   CHAR        cScan;
   
   cScan = (CHAR)('0' + wScan);
   if (error = NSFItemSetText(hMacro,
               FILTER_SCAN_ITEM, / "$Scan" /
               &cScan, 1))
   {
       printf ("Error: unable to set Scan field in macro note.\n");
   }
   return(error);
}


Domino and Notes requires all Background and Mail agents to have the "Which document(s) should it act on" setting set to "Run on all new and modified documents since last run." At the C API level, this means that all agents whose $Type items are set to FILTER_TYPE_BACKGROUND or FILTER_TYPE_MAIL must have their $Scan items set to FILTER_SCAN_NEW.


$Formula and $Formula2

All Release 3 agents except full-text search queries require a field named $Formula (FILTER_FORMULA_ITEM) that contains the compiled agent formula. Some agents also contain a field named $Formula2 (FILTER_FORMULA2_ITEM) that contains an extended agent formula.

The $Formula and $Formula2 fields have data type TYPE_FORMULA. Create these fields by expressing the formula as a character string and then using NSFFormulaCompile to compile the string. This yields a formula handle and the length of the compiled formula. Append this data to the note by locking the handle to obtain a pointer, then calling NSFItemAppend to append the compiled formula -- as specified by the pointer -- to an open note.

The code fragment below shows how to compile a character string into a formula, then append the formula as the $Formula field to an open agent note.

addmacro.c - Setting the $Formula Field

STATUS far  PASCAL  SetMacroFormula( NOTEHANDLE hMacro, PCHAR szFormula )
{
   STATUS          error;
   FORMULAHANDLE   hFormula;
   WORD            wFormulaLen;
   WORD            wdc;


    if (error = NSFFormulaCompile(  NULL, 0, szFormula, strlen(szFormula),
                                   &hFormula, &wFormulaLen, &wdc, &wdc,
                                   &wdc, &wdc, &wdc))
   {
       printf ("Error compiling formula.\n");
       return(error);
   }


    error = NSFItemAppend(
               hMacro,                 / handle to note to append to /
               ITEM_SUMMARY,           / item flags /
               FILTER_FORMULA_ITEM,    / item name: "$Formula" /
               strlen(FILTER_FORMULA_ITEM),
               TYPE_FORMULA,           / item type /
               OSLockObject(hFormula), / item value /
               wFormulaLen);           / value length /


    OSUnlockObject(hFormula);
   OSMemFree(hFormula);


    if (error)
   {
       printf ("Error: unable to append formula item to macro note.\n");
   }
   return (error);
}



$Query

Full Text Search agents are distinguished by the presence of the field named $Query (FILTER_QUERY_ITEM). The $Query field has data type TYPE_TEXT. The value of the $Query field is the text of the query. When performing a full-text search from the Notes user interface, you specify the query text in the query text box in the upper left corner of the search bar.


$LeftToDo

The $LeftToDo field (FILTER_LEFTTODO_ITEM) is a required field in certain types of Release 3 agents, including those that run only on new documents or documents that have been modified since the last time the agent ran. At the Notes user interface level, this includes all agents with "Which document(s) should it act on" set to "All new and modified documents since last run." At the C API level, this includes all agents whose $Scan item is set to FILTER_SCAN_NEW.

The $LeftToDo item has data type TYPE_OBJECT. It contains a table of note IDs that identifies all the documents that the agent has not yet processed. Domino or Notes maintains this ID table each time it runs an agent containing this field.

Before running an agent containing a $LeftToDo object, Domino or Notes retrieves the ID table from the object and updates the table with the IDs of all documents that have been updated or modified since the last time the agent ran. The resulting ID table identifies the set of documents that the agent needs to process this time.

After running the agent, the ID table is updated by deleting the IDs of all documents processed, then it is stamped with the time and date it was updated, and then it is saved in the $LeftToDo object in the agent note.

This mechanism lets the agent itself store the list of documents it has processed so that Domino, Notes or C API programs that run agents can avoid processing documents unnecessarily.

The $LeftToDo object consists of an ID table followed by theTIMEDATE the agent was last modified and the DBID of the database in which the agent resided when it last ran. The Time field of the ID table records when the table was last updated. Domino and Notes uses this information to evaluate the relevance of the ID table. The agent should discard the ID table and reprocess all notes in the database if:

  • The agent was modified (that is, the formula was changed) since the last time it ran
  • The agent was in a different database the last time it ran (that is, the agent note was copied from one database and pasted into the current database)


Because $LeftToDo is an item of type TYPE_OBJECT, you must use the NSFDbReadObject and NSFDbWriteObject functions to access the ID Table.

The code fragment below shows how to read the $LeftToDo object and return a handle to the ID table, the TIMEDATE the agent was last modified, and the DBID of the database in which the agent resided when it last ran.

runmacro.c - Reading the $LeftToDo Object


/  pObject         gets the OBJECT_DESCRIPTOR structure
    phLeftToDo      gets the handle to the $LeftToDo ID Table
   
ptdLeftToDoTime gets the Time member of the ID Table
   pwLeftToDoFlags gets the Flags member of the ID Table

/

STATUS  LNPUBLIC  ReadLeftToDoObject( DBHANDLE    hDb,
                        NOTEHANDLE          hMacro,
                        OBJECT_DESCRIPTOR  pObject,
                        HANDLE            
phLeftToDo,
                        TIMEDATE           ptdLeftToDoTime,
                        WORD              
pwLeftToDoFlags )
{
    STATUS      error;
    WORD        wDataType;
    BLOCKID     bidValue;
    DWORD       dwValueLength;
    void        ptable;
OBJECT_DESCRIPTOR  tempObjectPtr;
OBJECT_DESCRIPTOR
tempPtr;

    error = NSFItemInfo(hMacro, FILTER_LEFTTODO_ITEM,
                        sizeof(FILTER_LEFTTODO_ITEM)-1,
                        NULL, &wDataType, &bidValue, &dwValueLength);

    if ( ERR(error) == ERR_ITEM_NOT_FOUND )
    {
        return (error);
    }
    else if (error)
    {
        printf("Error: unable get '%s' from Macro.\n", FILTER_LEFTTODO_ITEM);
        return(error);
    }
    if (wDataType != TYPE_OBJECT)
    {
        printf ("Error: item '%s' not TYPE_OBJECT.\n", FILTER_LEFTTODO_ITEM);
        return(error);
    }
       
    pObject = ((OBJECT_DESCRIPTOR)(OSLockBlock(char,bidValue)+sizeof(WORD)));

tempPtr = pObject;

    ODSReadMemory( &tempPtr, _OBJECT_DESCRIPTOR, &tempObjectPtr, 1 );

    memcpy(pObject,&tempObjectPtr, ODSLength(_OBJECT_DESCRIPTOR));

    if (pObject->ObjectType != OBJECT_FILTER_LEFTTODO)
    {                                                
        printf ("Error: object '%s' unknown type.\n",FILTER_LEFTTODO_ITEM);
        OSUnlockBlock(bidValue);
        return (ERR_RUNMACRO_BADOBJECTTYPE);
    }

    error = NSFDbReadObject(hDb, pObject->RRV, 0, MAXDWORD, phLeftToDo);
    OSUnlockBlock(bidValue);
    if (error)
    {
        printf ("Error: unable to read object '%s'.\n",FILTER_LEFTTODO_ITEM);
        return (error);
    }

    ptable = OSLock(void,
phLeftToDo);
    ptdLeftToDoTime = IDTableTime(ptable);
   
pwLeftToDoFlags = IDTableFlags(ptable);
    OSUnlock(phLeftToDo);              / unlock handle we are done with */

    return NOERROR;
}

$Period

The $Period field (FILTER_PERIOD_ITEM) is required in all Release 3 Background agents. The data type is TYPE_TEXT. The value is a character digit -- '0', '1', '2', or '3' -- corresponding to one of the filter periods defined in stdnames.h.

The value stored in the $Period field encodes one of the schedule settings in the "When should this agent run" setting. When you create an agent with the Notes user interface, you specify this setting in the Create - Design - Agent dialog box. The following table maps the filter period symbolic constants in stdnames.h to this setting in the dialog box:

Filter Period Symbol Frequency Setting
PERIOD_HOURLY hourly
PERIOD_DAILY daily
PERIOD_WEEKLY weekly
FILTER_DISABLED Never

The symbolic constants are defined as numbers between 0 and 3, but the value stored in the item is a character. The code fragment below translates the filter period symbolic constant to the corresponding character before setting the $Period field.

addmacro.c - Setting the $Period Field
/* wPeriod must be PERIOD_HOURLY, PERIOD_DAILY,
   PERIOD_WEEKLY, or PERIOD_DISABLED
*/

STATUS  LNPUBLIC  SetMacroPeriod( NOTEHANDLE hMacro, WORD wPeriod )
{
   STATUS      error;
   CHAR        cPeriod;
   
   cPeriod = (CHAR)('0' + wPeriod);
   if (error = NSFItemSetText(hMacro,
               FILTER_PERIOD_ITEM,     /* "$Period" */
               &cPeriod, 1))
   {
       printf ("Error: unable to set Scan field in macro note.\n");
   }


    return(error);
}



$Flags

The $Flags field is required in all Release 3 agent notes. The data type is TYPE_TEXT. The value is a string consisting of from one to four characters corresponding to the design flags defined in stdnames.h.The $Flags field is used to manage design components of databases.

The table below indicates the set of design flags to set for various types of agents:

Agent Type Design Flags
Menu DESIGN_FLAG_PRESERVE
Background DESIGN_FLAG_PRESERVE and
DESIGN_FLAG_BACKGROUND_FILTER
Execute Once DESIGN_FLAG_PRESERVE
Paste/mail DESIGN_FLAG_PRESERVE and DESIGN_FLAG_MAIL_FILTER
Search DESIGN_FLAG_QUERY_MACRO_FILTER
Lotus Script Data DESIGN_FLAG_V4AGENT_DATA


Other Components of Release 3 Agent Notes

The $Comment field is an optional TYPE_TEXT field in any Release 3 agent note. The $Comment field contains the text of the comment in the agent. Database designers can provide comments to help others understand or maintain their agents.

Full text search agents can contain fields with the names $SimpleQuery, $BuilderQuery, and $FormulaAction. These items contain values derived from settings in the search bar or the query builder dialog box.


Running Release 3 Agents

This section outlines the steps required to use the C API to run a Release 3 agent on a database. The exact functionality required depends on the agent itself and the context of the C API program.

Generally, a C API program runs an agent on a database by implementing the following algorithm:
  1. Read the agent note.
  2. Determine the documents to process.
  3. For each document:
    - Open the document.
    - Evaluate the agent formula.
    - Perform the agent operation (update or copy).
    - Close the document.
  4. If necessary, update the agent note.


Access the Agent Note

Any C API program attempting to run an agent in a database must open the database, open the agent note, and read the required fields -- &Type, $Operation, and $Scan.

Most C API programs obtain the name of the agent as input from the user or from a parameter. Given the agent name, use NIFFindDesignNote (specifying NOTE_CLASS_FILTER) to obtain the note ID of the agent note.

Given the note ID of the agent note, use NSFNoteOpen to open the agent note. Read the required fields &Type, $Operation, and $Scan as shown in the code fragments in this chapter. Use the values of these fields to verify that the program can run the agent.

All agents except full-text search queries contain a field named $Formula. They may also contain a field named $Formula2. If the agent is not a full-text search query, read the $Formula field and the $Formula2 field if it is available.

Determine the Documents to Process

Determine the set of documents to process -- the set of documents the agent should examine, not the set that matches the SELECT portion of the formula. Later, your program will evaluate the agent formula for each document in this set. Evaluating the formula determines whether a given document matches the SELECT criteria or not.

This step normally yields an ID table containing the note IDs of all notes the agent should process.

Use the value of the $Type item, the $Scan item, and other information to build this ID table. For example, if $Type is FILTER_TYPE_ONCE, your C API program must normally obtain a single note for the agent to process.

If $Scan is FILTER_SCAN_ALL, the set of documents should include all documents in the database. If $Scan is FILTER_SCAN_VIEW, then your C API program must select -- or be given -- a particular view in the database. Build an ID table containing the IDs of all entries in this view.

If $Scan is FILTER_SCAN_NEW, your program must determine what documents have been added to the database, modified, or removed from the database since the last time the agent ran. Start with the ID table stored in the $LeftToDo object. Evaluate whether this ID table applies in the context of the current database and agent note, then update the table as necessary. The sample program runmacro.c uses the function GetIDsOfAllNewDocs to demonstrate how to build an ID table of all the documents that need to be processed if $Scan is FILTER_SCAN_NEW.

If the agent contains a $Query item, your C API program will need to perform a full-text query to determine the documents to process.

Evaluate the Formulas

Process all the documents in the set determined by the preceding step. However, before starting this process, call the C API function NSFComputeStart for the compiled agent formulas $Formula and -- if available -- $Formula2. Each call to NSFComputeStart yields an HCOMPUTE structure used later in NSFComputeEvaluate.

Loop through the note IDs in the table of IDs to process. For each ID in the table, open the document and evaluate the agent formula. Call the C API function NSFComputeEvaluate to evaluate a formula on one document. This may change fields in the document or take other actions. It yields three pieces of information:
  • Whether the document matches the SELECT criteria
  • Whether the document should be deleted
  • Whether the document has been modified as result of evaluating the formula

Call NSFComputeEvaluate to evaluate the second formula on the document if:
  • The optional secondary formula $Formula2 was given in the agent note
  • The document matches the SELECT criteria
  • The document is not to be deleted

The code fragment below shows how to evaluate the two formulas for each document being processed.
runmacro.c - Evaluating the Formulas
/* Compute the first formula on the document. */
   if (fCompute1Started)
   {
       if (error = NSFComputeEvaluate(
                   hCompute1,          /* returned from NSFComputeStart */
                   hDoc,               /* This note provides any additional
                                          variable used by the formula. It
                                          also gets FIELD variables assigned
                                          during the evaluation. */
                   NULLHANDLE,         /* don't need the ComputeResult */
                   NULL,               /* don't need Compute Result Len */
                  &fDocMatchesFormula1,/* gets TRUE if note matches the
                                          SELECT portion of the formula */
                  &fDocShouldBeDeleted1,/* gets TRUE if formula
                                          indicates note should be deleted*/
                  &fDocModified1 ))    /* gets TRUE if any of the fields
                                          of hDoc were modified as result

                                           of the formulat evaluation. */
       {
           printf ("Error: unable to compute forumula on document.\n");
           goto Exit1;
       }
   }
  /*
   * Proceed to compute the second (optional) formula on the note if
   * there is a second formula and the note matched the SELECT portion
   * of the first formula and the first formula does not indicate that
   * the note should be deleted.
   */
   if (fCompute2Started && fDocMatchesFormula1 && !fDocShouldBeDeleted1)
   {
       if (error = NSFComputeEvaluate( hCompute2, hDoc, NULLHANDLE, NULL,
                  &fDocMatchesFormula2,
                  &fDocShouldBeDeleted2,
                  &fDocModified2 ))
       {
           printf ("Error: unable to compute formula 2 on document.\n");
           goto Exit1;
       }
   }


Perform the Operation

After evaluating the formulas on the document, update the document as a new document or as the original, depending on the value of the $Operation field.

If the $Operation field specifies FILTER_OP_NEW_COPY, zero out the NOTEID and generate a new OID in the header data of the document note. This causes NSFNoteUpdate to leave the original document unchanged and write the changed document in memory to disk as a new note.

Update and close the modified document.


Maintain the $LeftToDo Object

If $Scan is FILTER_SCAN_NEW, your program must maintain the $LeftToDo object in the agent note.

To properly update the $LeftToDo object, your program must retrieve the original object from the agent note, update the ID table with any documents that were added to or deleted from the database while the agent was running, and remove from the table the IDs of all documents processed by the agent.

The sample program RUNMACRO.C uses the function UpdateLeftToDo to demonstrate how to update the ID table in the $LeftToDo object and save the object back to disk after running an agent. ---