How to reset a Variant? Problem

0
I'm working on a modscript with a subroutine where I'm pulling in a field value a variant. I'm reusing this variant later for another call to the subroutine, but it seems to be holding on to the original value. How would I go about "resetting" this variant?

Accepted Answer

Friday, March 01 2019, 01:29 PM - #Permalink
0
After working with modscript a bit more I do see how being able to specify the submit transition to use would be very helpful. I think it's just a matter that functionality not existing. I would imagine it could be implemented as an optional parameter by MicroFocus on the the StartSubmitToProject() or QuickSubmitToProject() methods.

I opted to head down that route for creating my subtasks it's definitely making things work a bit better; except I'm unable to figure out how to get back the ID of the newly created subtask so that I can create the link between the parent and subtask. Any thoughts?
  • Curtis LaPrise
    more than a month ago
    Nevermind figured it out. I can just do a .GetId() on the same object I ran the .QuickSubmitToProject() on :)
  • Paul Thompson
    more than a month ago
    Here's another idea .... create a dummy "Create Subtask" or "Post" transition for the parent item. Don't show the button on the form, then have ModScript use that transition to create the child item. It may use the mapping defined in the transition to relate the parent to the child. I already see one challenge -- how to specify additional fields in the child that aren't explicitly mapped from the parent. And what happens if the parent's Post/Subtask or the child's SUBMIT transitions aren't "quick"?
The reply is currently minimized Show
Responses (7)
  • Accepted Answer

    Wednesday, February 27 2019, 02:58 PM - #Permalink
    0
    Is the variant a param to the sub, a local var within the sub or a global?

    When you say "holding on to", does that mean you can't change it on subsequent passes?
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, February 27 2019, 06:12 PM - #Permalink
    0
    Hello Paul,

    It's a global Variant that is called within the multiple subroutines. What I'm finding is that when using GetFieldValue(FIELDNAME,Variant) that instead of replacing the existing value on that variant it appends the new value to it. In this case I'm using it to handle the data inside of multi-relational fields... I've attached my script(s) below.

    Note they're still a Work In Progress.
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, February 27 2019, 06:12 PM - #Permalink
    0
    duplicate
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, February 27 2019, 06:16 PM - #Permalink
    0
    Apparently .tscm and .txt are unsupported formats for attachments :/



    /* Name: MasterUpdateSubtask.tscm
    Function: When a Parent item is updated, check to see if a subtasks exists.
    If the Subtasks exists and is active, update the Subtask Item.
    If no Active Subtask exists, then create a new subtask.
    Date: 02/26/2019
    */

    //Include Utility scripts
    include("SubtaskUpdateUtilities");



    // Set Global Constants for Parent Item information
    add_global_const("ELCM_REQUEST", "PARENT_SUBTASK_FLD");
    add_global_const("USR_ELCM", "PARENT_TABLE_NAME");


    // Set Global constant for subtask table
    add_global_const("USR_DEPARTMENTAL_TASK", "SUBTASK_TABLE_NAME");

    //Variables used to retrieve info from parent item
    global nParent_Table_ID = Variant();
    global nSubtask_Table_ID = Variant();
    global objItem = Variant();
    global objFlds = Variant();
    global objFld = Variant();
    global strSubtaskIds = Variant();
    global nStart = Variant();
    global nEnd = Variant();
    global nLength = Variant();
    global objSub = Variant();
    global nSum = Variant();
    global nId = Variant();
    global nActiveInactive = Variant();
    global strNewIds = Variant();
    global strTitle = Variant();
    global strDepartment = Variant();
    global strPositionTitle = Variant();
    global strLocation = Variant();
    global dHireDate = Variant();
    global strRehire = Variant();
    global bOK = false;
    global bExists = false;
    global DEBUG = true;

    global taskCheck = Variant();

    global strChildValue1 = Variant();
    global strChildValue2 = Variant();
    global strChildValue3 = Variant();
    global strChildValue4 = Variant();
    global strChildValue5 = Variant();
    global strChildValue6 = Variant();
    global strChildValue7 = Variant();
    global strChildValue8 = Variant();
    global strChildValue9 = Variant();
    global strChildValue10 = Variant();
    global strChildValue11 = Variant();
    global strChildValue12 = Variant();
    global strChildValue13 = Variant();
    global strChildValue14 = Variant();
    global strChildValue15 = Variant();
    global strChildValue16 = Variant();
    global strChildValue17 = Variant();
    global strChildValue18 = Variant();
    global strChildValue19 = Variant();
    global strChildValue20 = Variant();
    global strChildValue21 = Variant();
    global strChildValue22 = Variant();
    global strChildValue23 = Variant();
    global strChildValue24 = Variant();
    global strChildValue25 = Variant();
    global strChildValue26 = Variant();
    global strChildValue27 = Variant();
    global strChildValue28 = Variant();
    global strChildValue29 = Variant();
    global strChildValue30 = Variant();
    global strChildValue31 = Variant();
    global strChildValue32 = Variant();


    objItem = Shell.Item();


    //Get Standard Parent info
    bOK = objItem.GetFieldValue("TITLE",strTitle);
    bOK = objItem.GetFieldValue("MDT_DEPARTMENT",strDepartment);
    bOK = objItem.GetFieldValue("POSITION_TITLE2",strPositionTitle);
    bOK = objItem.GetFieldValue("PRIMARY_EMPLOYEE_LOCATION",strLocation);
    bOK = objItem.GetFieldValue("HIRE_DATE",dHireDate);
    bOK = objItem.GetFieldValue("REHIRE",strRehire);

    //Set Stanard Subtask Fields
    global SUBTASK_DEPARTMENT = Variant("DEPARTMENT");
    global SUBTASK_POSITION_TITLE = Variant("POSITION_TITLE");
    global SUBTASK_LOCATION = Variant("PRIMARY_EMPLOYEE_LOCATION");
    global SUBTASK_HIREDATE = Variant("HIRE_DATE");
    global SUBTASK_REHIRE = Variant("REHIRE");


    objItem.GetFieldValue("CREATE_APP_SUPPORT_TSK", taskCheck);
    if ( taskCheck == 1){
    //Begin Application Support Subtasking
    if(DEBUG){Ext.LogInfoMsg("Starting Application Support Subtasking");}
    application_support_subroutine(DEBUG);
    }

    objItem.GetFieldValue("CREATE_AUDIT_COMP_TSK", taskCheck);
    if ( taskCheck == 1){
    //Begin Internal Audit & Compliance Subtasking
    if(DEBUG){Ext.LogInfoMsg("Starting Internal Audit & Compliance Subtasking");}
    audit_compliance_subroutine(DEBUG);
    }




    and the utility script:

    def check_for_subtasks(DEBUG, CHILD_SUBTASK_FLD, nSubtask_Table_ID){
    //subroutine to check for existing subtasks
    //reset strSubtaskIDs
    // strSubtaskIDs = ",,";

    // Read the comma separated unique id list of subtask items
    bOK = objItem.GetFieldValue(CHILD_SUBTASK_FLD,strSubtaskIds);
    // Parse the list of sub-task items so we can look them up individually and determine if they are active
    nLength = Len(strSubtaskIds);
    nStart = 2;
    nEnd = nStart;

    // Create the object to hold a subtask item

    objSub = Ext.CreateVarRecord(nSubtask_Table_ID);

    // Loop through the Parent's list of subtasks and process each child
    while ( nStart < nLength ) {
    // The child record IDs reside between pairs of commas
    nEnd = InStr(nStart,strSubtaskIds, ",");
    nId = Mid(strSubtaskIds,nStart, nEnd - nStart);


    // DEBUG - Write the value of the record to the event log.
    if (DEBUG) { Ext.LogInfoMsg("The Table Name is: " &&& SUBTASK_TABLE_NAME &&& "\n The Table number is: " &&& nSubtask_Table_ID &&& "\nThe list of subtasks are: " &&& strSubtaskIds&&&"\n The Record Number is: "&&&nId);}

    // Retrieve the child item and determine if it is an active item
    objSub.Read(nId);
    objSub.GetFieldValue("ACTIVEINACTIVE",nActiveInactive);

    // If the Subtask is active, then update the record
    if (DEBUG) { Ext.LogInfoMsg("The value of ACTIVEINACTIVE is:" &&& nActiveInactive);}

    if (nActiveInactive == 0) {return true;}

    // Position for the next child ID
    nStart = nEnd + 1;
    }
    return false;
    }

    def application_support_subroutine(DEBUG){
    //Main Application Support Subroutine

    // Sub-task project ID, table Name. Project ID is required if a new subtask needs to be created.
    // The project ID can only be found after the initial deployment of the departmental application.
    global CHILD_SUBTASK_FLD = Variant( "APPLICATION_SUPPORT_TASK_R" );
    global ITEM_TYPE_FLD = Variant( "ISSUETYPE" );
    global TASK_TYPE = Variant( 2309 );
    // Sub-task project ID, table ID, and initial state ID
    global PROJECT_ID = Variant( 188 );
    global NEWSTATEID = Variant( 249 );
    //Group ID for the default secondary owner:
    global nGID = Variant( 31 );

    global SUBTASK_FIELD1 = Variant( "FEDLINE_ADVANTAGE_COMAND_P" );
    global SUBTASK_FIELD2 = Variant( "FTA_MONITORING" );
    global SUBTASK_FIELD3 = Variant( "VAULT_ACCESS" );
    global SUBTASK_FIELD4 = Variant( "ENTERPRISE_MANAGER" );
    global SUBTASK_FIELD5 = Variant( "SMA_OPCON" );
    global SUBTASK_FIELD6 = Variant( "JSW_ACCESS" );
    global SUBTASK_FIELD7 = Variant( "SYM_MANAGER_ACCESS" );

    nSubtask_Table_ID = Ext.TableId(SUBTASK_TABLE_NAME);

    //Read in Parent Item values
    bOK = objItem.GetFieldValue(SUBTASK_FIELD1, strChildValue1);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD2, strChildValue2);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD3, strChildValue3);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD4, strChildValue4);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD5, strChildValue5);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD6, strChildValue6);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD7, strChildValue7);



    if (check_for_subtasks(DEBUG, CHILD_SUBTASK_FLD, nSubtask_Table_ID)){
    //Active Subtask Exists!
    //Update Subtask Item Fields
    bOK = objSub.SetFieldValue(SUBTASK_DEPARTMENT,strDepartment);
    bOK = objSub.SetFieldValue(SUBTASK_POSITION_TITLE, strPositionTitle);
    bOK = objSub.SetFieldValue(SUBTASK_LOCATION, strLocation);
    bOK = objSub.SetFieldValue(SUBTASK_HIREDATE, dHireDate);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD1, strChildValue1);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD2, strChildValue2);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD3, strChildValue3);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD4, strChildValue4);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD5, strChildValue5);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD6, strChildValue6);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD7, strChildValue7);

    //Lock > Update > Unlock subtask item.
    bOK = objSub.Lock();
    bOK = objSub.Update();
    bOK = objSub.Unlock();

    }



    if (DEBUG) {Ext.LogInfoMsg("Starting Subtask creation");}
    var CreateSubtask = Variant();
    var objNew = Variant();
    objNew = Ext.CreateVarRecord(nSubtask_Table_ID);

    //Set Standard Field values
    objNew.SetFieldValue("TITLE",strTitle);
    objNew.SetFieldValue(SUBTASK_DEPARTMENT,strDepartment);
    objNew.SetFieldValue(SUBTASK_POSITION_TITLE,strPositionTitle);
    objNew.SetFieldValue(SUBTASK_LOCATION,strLocation);
    objNew.SetFieldValue(SUBTASK_HIREDATE,dHireDate);
    objNew.SetFieldValue(SUBTASK_REHIRE,strRehire);
    objNew.SetFieldValue(ITEM_TYPE_FLD,TASK_TYPE);
    objNew.SetFieldValue("SECONDARY_OWNER",nGID);
    objNew.SetFieldValue(PARENT_SUBTASK_FLD,objItem.GetId());

    // Copy the value of the parent record to the Subtask Record
    objNew.SetFieldValue(SUBTASK_FIELD1, strChildValue1);
    objNew.SetFieldValue(SUBTASK_FIELD2, strChildValue2);
    objNew.SetFieldValue(SUBTASK_FIELD3, strChildValue3);
    objNew.SetFieldValue(SUBTASK_FIELD4, strChildValue4);
    objNew.SetFieldValue(SUBTASK_FIELD5, strChildValue5);
    objNew.SetFieldValue(SUBTASK_FIELD6, strChildValue6);
    objNew.SetFieldValue(SUBTASK_FIELD7, strChildValue7);

    // Set the system fields
    objNew.SetFieldValue("SUBMITDATE", Ext.DateToDbLong(Now()));
    objNew.SetFieldValue("SUBMITTER", Shell.User().GetId());
    objNew.SetFieldValue("LASTSTATECHANGER",Shell.User().GetId());
    objNew.SetFieldValue("LASTSTATECHANGEDATE", Ext.DateToDbLong(Now()));
    objNew.SetFieldValue("LASTMODIFIER", Shell.User().GetId());
    objNew.SetFieldValue("LASTMODIFIEDDATE", Ext.DateToDbLong(Now()));
    objNew.SetFieldValue("PROJECTID", PROJECT_ID);
    objNew.SetFieldValue("STATE", NEWSTATEID);

    // Create (add) the new record in the database.
    CreateSubtask = objNew.Add();

    if (DEBUG) {Ext.LogInfoMsg("Subtask has been created. \n The return is: "&&& CreateSubtask&&&"\n The subtask parent record is: "&&&strSubtaskIds);}

    // update the current record with the newly created subtask

    if ( strSubtaskIds == ",," ){
    strSubtaskIds = ",";
    }

    //Update the Subtask Relational Field Value (Empty field is ',,' otherwise comma separated with IDs of related records ',39,20,48,'
    strSubtaskIds = strSubtaskIds &&& CreateSubtask &&& ",";

    //Set the Updated Relational field values in the Parent Table
    bOK = objItem.SetFieldValue(CHILD_SUBTASK_FLD , strSubtaskIds);
    }


    def audit_compliance_subroutine(DEBUG){
    //Main Audit & Compliance Subroutine

    // Sub-task project ID, table Name. Project ID is required if a new subtask needs to be created.
    // The project ID can only be found after the initial deployment of the departmental application.
    global CHILD_SUBTASK_FLD = Variant( "INT_AUDIT_COMPLIANCE_REQ" );
    global ITEM_TYPE_FLD = Variant( "ISSUETYPE" );
    global TASK_TYPE = Variant( 2312 );
    // Sub-task project ID, table ID, and initial state ID
    global PROJECT_ID = Variant( 194 );
    global NEWSTATEID = Variant( 273 );
    //Group ID for the default secondary owner:
    global nGID = Variant( 32 );

    global SUBTASK_FIELD1 = Variant( "SECRET_SERVER_ACCESS_2" );
    global SUBTASK_FIELD2 = Variant( "KNOWBE4_KCM_ACCESS" );

    nSubtask_Table_ID = Ext.TableId(SUBTASK_TABLE_NAME);

    if(DEBUG){Ext.LogInfoMsg("CHILD_SUBTASK_FLD is set to " &&& CHILD_SUBTASK_FLD);}

    //Read in Parent Item values
    bOK = objItem.GetFieldValue(SUBTASK_FIELD1, strChildValue1);
    bOK = objItem.GetFieldValue(SUBTASK_FIELD2, strChildValue2);


    if (check_for_subtasks(DEBUG, CHILD_SUBTASK_FLD, nSubtask_Table_ID)){
    //Active Subtask Exists!
    //Update Subtask Item Fields
    bOK = objSub.SetFieldValue(SUBTASK_DEPARTMENT,strDepartment);
    bOK = objSub.SetFieldValue(SUBTASK_POSITION_TITLE, strPositionTitle);
    bOK = objSub.SetFieldValue(SUBTASK_LOCATION, strLocation);
    bOK = objSub.SetFieldValue(SUBTASK_HIREDATE, dHireDate);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD1, strChildValue1);
    bOK = objSub.SetFieldValue(SUBTASK_FIELD2, strChildValue2);

    //Lock > Update > Unlock subtask item.
    bOK = objSub.Lock();
    bOK = objSub.Update();
    bOK = objSub.Unlock();

    }



    if (DEBUG) {Ext.LogInfoMsg("Starting Subtask creation");}
    var CreateSubtask = Variant();
    var objNew = Variant();
    objNew = Ext.CreateVarRecord(nSubtask_Table_ID);

    //Set Standard Field values
    objNew.SetFieldValue("TITLE",strTitle);
    objNew.SetFieldValue(SUBTASK_DEPARTMENT,strDepartment);
    objNew.SetFieldValue(SUBTASK_POSITION_TITLE,strPositionTitle);
    objNew.SetFieldValue(SUBTASK_LOCATION,strLocation);
    objNew.SetFieldValue(SUBTASK_HIREDATE,dHireDate);
    objNew.SetFieldValue(SUBTASK_REHIRE,strRehire);
    objNew.SetFieldValue(ITEM_TYPE_FLD,TASK_TYPE);
    objNew.SetFieldValue("SECONDARY_OWNER",nGID);
    objNew.SetFieldValue(PARENT_SUBTASK_FLD,objItem.GetId());

    // Copy the value of the parent record to the Subtask Record
    objNew.SetFieldValue(SUBTASK_FIELD1, strChildValue1);
    objNew.SetFieldValue(SUBTASK_FIELD2, strChildValue2);


    // Set the system fields
    objNew.SetFieldValue("SUBMITDATE", Ext.DateToDbLong(Now()));
    objNew.SetFieldValue("SUBMITTER", Shell.User().GetId());
    objNew.SetFieldValue("LASTSTATECHANGER",Shell.User().GetId());
    objNew.SetFieldValue("LASTSTATECHANGEDATE", Ext.DateToDbLong(Now()));
    objNew.SetFieldValue("LASTMODIFIER", Shell.User().GetId());
    objNew.SetFieldValue("LASTMODIFIEDDATE", Ext.DateToDbLong(Now()));
    objNew.SetFieldValue("PROJECTID", PROJECT_ID);
    objNew.SetFieldValue("STATE", NEWSTATEID);

    // Create (add) the new record in the database.
    CreateSubtask = objNew.Add();

    if (DEBUG) {Ext.LogInfoMsg("Subtask has been created. \n The return is: "&&& CreateSubtask&&&"\n The subtask parent record is: "&&&strSubtaskIds);}

    // update the current record with the newly created subtask

    if ( strSubtaskIds == ",," ){
    strSubtaskIds = ",";
    }

    //Update the Subtask Relational Field Value (Empty field is ',,' otherwise comma separated with IDs of related records ',39,20,48,'
    strSubtaskIds = strSubtaskIds &&& CreateSubtask &&& ",";

    //Set the Updated Relational field values in the Parent Table
    bOK = objItem.SetFieldValue(CHILD_SUBTASK_FLD , strSubtaskIds);
    }
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, February 27 2019, 11:08 PM - #Permalink
    1
    That may be a bug in ModScript. See if you can distill the problem down to as few
    lines as possible and submit a Case to SBM Tech support. The best way to get any
    response is to create a minimal Process App that just demonstrates the behavior
    and send that to Tech Support. The front-line techs don't have much experience
    with scripting. The easier you can make it for the Tech Support team to show
    something to the developers, the more likely you are to get an answer.

    Outside of the possibility of a defect, I did notice some other things. It may
    be have something to do with the problem, but I'm not sure ....

    In "application_support_subroutine" you are defining some global vars like:
    global PROJECT_ID = Variant( 188 );
    that are subsequently re-defined in "audit_compliance_subroutine":
    global PROJECT_ID = Variant( 194 );
    I'm surprised that doesn't generate a run-time error. In any case, it could lead to unexpected behavior.

    The global var "strSubtaskIds" is being read in 1 function and set in another. That just make me nervous.

    In the code, you're creating a subtask, but not creating the appropriate records in TS_ATTACHMENTS, TS_SUBTASKS, TS_MULTIUSERUSAGES or TS_USAGES.

    -------------------------------------------

    Suggestions -- definitely not cast in stone. More like cast in yogurt. as I'm just learning ModScript myself.
    Some of these are carried over from AppScript. They may not be appropriate in the super-duper ModScript world.

    * Global vars are evil. They can lead to all sorts of weird side-effects.
    Use local vars wherever possible.
    * However, Global constants are good. Use And Enjoy.

    * I like to use "add_global_const" to declare Field & Table DB Names, Internal Names of
    Workflows, States, Transitions and Projects and UUIDs of other elements.
    add_global_const("DEPARTMENT","SUBTASK_DEPARTMENT");
    instead of
    global SUBTASK_DEPARTMENT = Variant("DEPARTMENT");

    * I'm using ProjectBasedRecord instead of AppRecord or VarRecord whenever I'm dealing with items with a Primary table and Workflow.
    If I need to query and iterate over a bunch of items I can still use an AppRecordList:

    var pbr_New = Ext.CreateProjectBasedRecord( Ext.TableId(SUBTASK_TABLE_NAME) ) ;
    var arl_NewList = Ext.CreateAppRecordList( pbr_New.GetRecTableId() ) ;

    arl_NewList.ReadWithWhere( ... where clause ...);
    for ( pbr_New : arl_NewList) {
    // Inside the loop "pbr_New" is a Project Based Record.
    }

    * I like to pass an AppRecord, VarRecord or ProjectBasedRecord object into functions when I need to
    get or set field data of an item within the funcion. Just avoid calling the ".Update()" method on the
    Current Item.


    * I'm really (really!) liking the "Submit" capability of ModScript instead of the .Add method.
    It generates the correct change history record and relieves me of the burdon of setting every single field.
    Submitter, SubmitDate, Owner, State, Project, LastModifiedXXX, LastStateChangeXXX are all taken care of automatically.
    All the applicable Table, Workflow, Project and Transition over-rides get applied.
    An added bonus is that, in the future, if the client wants to change the default value of a field
    that is set by an over-ride, I don't need to modify the script and re-deploy. Just change
    the over-ride.
    The one drawback is that I can't (AFAIK) specify the "SUBMIT" transition to use.

    add_global_const("01234567-89ab-cdef-fedc-ba9876543210","PROJECT_UUID");

    pbr_New.StartSubmitToProject(PROJECT_UUID);
    pbr_New.SetFieldValue( ... any fields a user would enter ...) ;
    pbr_New.FinishSubmitToProject(PROJECT_UUID); // Return value is "success" boolean; NOT new item's ID.
    var n_newItemId = pbr_New.GetId ; // This is how to get ID of newly created item.
    Like
    The reply is currently minimized Show
  • Accepted Answer

    Thursday, February 28 2019, 11:45 AM - #Permalink
    0
    I'm actually working on figuring out how I can update the TS_SUBTASKS table to update with the appropriate data, but I can't quite figure it out. I did catch and fix the global vars inside of the the subroutines after I posted my reply last night that's been fixed.

    I'm not sure what the apporpriate links would be for TS_USAGES or TS_MULTIUSERUSAGES fields would be. As for the TS_ATTACHMENTS table I'm not terribly concerned as I'm linking them using a multi-relational field on each app.

    Also I did catch it late last night but I apparently had a typo in my reset of the var. And unlike I originally thought the field is in fact getting overwritten when using GetFieldValue();
    • Paul Thompson
      more than a month ago
      RE: Subtasks & Usages tables : Try using the Modscript "Start/Finish Transition" calls. Let the tools do all the work.
    The reply is currently minimized Show
  • Accepted Answer

    Thursday, February 28 2019, 11:45 AM - #Permalink
    0
    duplicate
    The reply is currently minimized Show
Your Reply

Recent Tweets