Highlighted
curtiplas Frequent Contributor.
Frequent Contributor.
1278 views

How to reset a Variant?

Jump to solution
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?
Tags (3)
0 Likes
1 Solution

Accepted Solutions
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
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?

View solution in original post

0 Likes
15 Replies
PM Thompson Outstanding Contributor.
Outstanding Contributor.

Re: How to reset a Variant?

Jump to solution
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?
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
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.
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
duplicate
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
duplicate
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
duplicate
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
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);
}
0 Likes
PM Thompson Outstanding Contributor.
Outstanding Contributor.

Re: How to reset a Variant?

Jump to solution
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.
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
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();
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
duplicate
0 Likes
curtiplas Frequent Contributor.
Frequent Contributor.

Re: How to reset a Variant?

Jump to solution
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?

View solution in original post

0 Likes
PM Thompson Outstanding Contributor.
Outstanding Contributor.

Re: How to reset a Variant?

Jump to solution
😉 I frequently get the same thing with "duplicate" posts when I click a button to post something or answer a question. I can't spot any pattern ... it seems random.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.