Trigger Change to Attribute if Object Text Edited

Hello,
Can anyone help with suggesting how I would trigger a change to an attribute if the Object text was edited? We have a requirements review process whereby the reviewer sets an attribute to show when the requirement has been validated. What I would like to do is have that attribute reset to the default value if the object text is subsequently changed. This would force the requirement to be flagged up as needing review. I've searched the forum but found nothing obvious.
Thanks
Peterb4134 - Mon Jan 31 06:47:33 EST 2011

Re: Trigger Change to Attribute if Object Text Edited
llandale - Mon Jan 31 15:17:29 EST 2011

Since you have no intention of preventing the text change, a post-attr-save trigger will do. When the attribute is "Object Text" then the trigger erases another particular attribute. Here's the code of the trigger that may get you started:

Trigger    trg = current;           if (null trg)       halt()  // Error?
AttrDef ad  = attrdef(trg); if (null ad)        halt()  // Error?
Object  obj = object(trg);  if (null obj)       halt()  // Error?
string  Name = ad.name;     if (Name != "Object Text") halt()
 
noError()
obj."ValidatedOn" = ""
lastError()


Now comes the hard part, writing a DXL that gracefully deploys and undeploys this trigger. In this case we might as well hard code the above into a string attribute remembering to escape all the double quotes, in which case the DXL would look like this:

 

string DXLCode = "
Trigger    trg = current;           if (null trg)       halt()  // Error?
AttrDef ad  = attrdef(trg); if (null ad)        halt()  // Error?
Object  obj = object(trg);  if (null obj)       halt()  // Error?
string  Name = ad.name;     if (Name != \"Object Text\") halt()
 
noError()
obj.\"ValidatedOn\" = \"\"
lastError()
"      // End definition of string DXLCode
 
Trigger trg
bool    TrigOK  = true
string  ErrMess = checkDXL(DXLCode)
 
if (!null ErrMess)
{  print ErrMess "\n***********\n" DXLCode "**********\n"
   TrigOK       = false
}
 
string  NameTrig = "TriggerResetValidatedOn"
 
string  Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
   ErrMess = delete (NameTrig, module->attribute, post, save, 6)
 
if (TrigOK              and
    confirm("Deploy trigger '" NameTrig "' ??"))
   trg     = trigger(NameTrig, module->attribute, post, save, 6, DXLCode)

 

 

 

  • Louie

 

 

Re: Trigger Change to Attribute if Object Text Edited
llandale - Mon Jan 31 15:23:16 EST 2011

llandale - Mon Jan 31 15:17:29 EST 2011

Since you have no intention of preventing the text change, a post-attr-save trigger will do. When the attribute is "Object Text" then the trigger erases another particular attribute. Here's the code of the trigger that may get you started:

Trigger    trg = current;           if (null trg)       halt()  // Error?
AttrDef ad  = attrdef(trg); if (null ad)        halt()  // Error?
Object  obj = object(trg);  if (null obj)       halt()  // Error?
string  Name = ad.name;     if (Name != "Object Text") halt()
 
noError()
obj."ValidatedOn" = ""
lastError()


Now comes the hard part, writing a DXL that gracefully deploys and undeploys this trigger. In this case we might as well hard code the above into a string attribute remembering to escape all the double quotes, in which case the DXL would look like this:

 

string DXLCode = "
Trigger    trg = current;           if (null trg)       halt()  // Error?
AttrDef ad  = attrdef(trg); if (null ad)        halt()  // Error?
Object  obj = object(trg);  if (null obj)       halt()  // Error?
string  Name = ad.name;     if (Name != \"Object Text\") halt()
 
noError()
obj.\"ValidatedOn\" = \"\"
lastError()
"      // End definition of string DXLCode
 
Trigger trg
bool    TrigOK  = true
string  ErrMess = checkDXL(DXLCode)
 
if (!null ErrMess)
{  print ErrMess "\n***********\n" DXLCode "**********\n"
   TrigOK       = false
}
 
string  NameTrig = "TriggerResetValidatedOn"
 
string  Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
   ErrMess = delete (NameTrig, module->attribute, post, save, 6)
 
if (TrigOK              and
    confirm("Deploy trigger '" NameTrig "' ??"))
   trg     = trigger(NameTrig, module->attribute, post, save, 6, DXLCode)

 

 

 

  • Louie

 

 

Now that I think about it, you could change "module->attribute" to "project->module->formal->attribute" in two places, in which case your trigger is deployed in the project and applies to all modules. Those modules that lack your target attribute "ValidatedOn" will just cause a trapped error that's not displayed, and end. I would, of course, add code to check for the existence of the attribute that applies to objects, but I don't know if that would make it run any faster or not.

You may notice I'm ignoring any write errors, I've found no graceful way of dealing with trigger/layout/attrDXL errors consistently; lets not "ack" them since when somebody is runing a DXL that makes changes, you may get 1000 acks in a row, hate it when that happens.

  • Louie

Re: Trigger Change to Attribute if Object Text Edited
Peterb4134 - Tue Feb 01 06:42:48 EST 2011

llandale - Mon Jan 31 15:23:16 EST 2011
Now that I think about it, you could change "module->attribute" to "project->module->formal->attribute" in two places, in which case your trigger is deployed in the project and applies to all modules. Those modules that lack your target attribute "ValidatedOn" will just cause a trapped error that's not displayed, and end. I would, of course, add code to check for the existence of the attribute that applies to objects, but I don't know if that would make it run any faster or not.

You may notice I'm ignoring any write errors, I've found no graceful way of dealing with trigger/layout/attrDXL errors consistently; lets not "ack" them since when somebody is runing a DXL that makes changes, you may get 1000 acks in a row, hate it when that happens.

  • Louie

Louie,

Thanks for the advice. I'll take a look at what you suggest and let you how I get on.

Pete

Re: Trigger Change to Attribute if Object Text Edited
Peterb4134 - Wed Feb 02 03:41:58 EST 2011

Peterb4134 - Tue Feb 01 06:42:48 EST 2011
Louie,

Thanks for the advice. I'll take a look at what you suggest and let you how I get on.

Pete

Louie,

Your code worked a treat. Thank You.

I have gone on to modify it further to add some additional functionality. I'm not a DXL expert so would appreciate any feedback on the code below in case I have done something which isn't considered good practice.

For each requirement that is edited the code obtains the value from the "Validation Owner" attribute, it then looks for an object which has the same object text and resets an attribute in the found object.

string DXLCode = "
Module m = current
Object o = current
Trigger trg = current; if (null trg) halt() // Error?
AttrDef ad = attrdef(trg); if (null ad) halt() // Error?
Object obj = object(trg); if (null obj) halt() // Error?
string Name = ad.name; if (Name != \"Object Text\") halt()

AttrDef adValO = find (current, \"Validation Status\"); if (null ad) halt() // Error?
string sub
int offset
int lie
noError()
obj.\"Validation Status\" = \"Pending\"
obj.\"Verification Status\" = \"Pending\"
string sValO = o.\"Validation Owner\"

for o in m do{
string sObjectText = o.\"Object Text\"
if (sObjectText == sValO){
o.\"Validation Ratification Status\" = \"\"
}

}
lastError()
" // End definition of string DXLCode

Trigger trg
bool TrigOK = true
string ErrMess = checkDXL(DXLCode)

if (!null ErrMess)
{ print ErrMess "\n***********\n" DXLCode "**********\n"
TrigOK = false
}

string NameTrig = "TriggerResetValidatedOn"

string Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
ErrMess = delete (NameTrig, project->module->formal->attribute, post, save, 6)

if (TrigOK and
confirm("Deploy trigger '" NameTrig "' ??"))
trg = trigger(NameTrig, project->module->formal->attribute, post, save, 6, DXLCode)
Pete

Re: Trigger Change to Attribute if Object Text Edited
llandale - Wed Feb 02 12:02:09 EST 2011

Peterb4134 - Wed Feb 02 03:41:58 EST 2011
Louie,

Your code worked a treat. Thank You.

I have gone on to modify it further to add some additional functionality. I'm not a DXL expert so would appreciate any feedback on the code below in case I have done something which isn't considered good practice.

For each requirement that is edited the code obtains the value from the "Validation Owner" attribute, it then looks for an object which has the same object text and resets an attribute in the found object.

string DXLCode = "
Module m = current
Object o = current
Trigger trg = current; if (null trg) halt() // Error?
AttrDef ad = attrdef(trg); if (null ad) halt() // Error?
Object obj = object(trg); if (null obj) halt() // Error?
string Name = ad.name; if (Name != \"Object Text\") halt()

AttrDef adValO = find (current, \"Validation Status\"); if (null ad) halt() // Error?
string sub
int offset
int lie
noError()
obj.\"Validation Status\" = \"Pending\"
obj.\"Verification Status\" = \"Pending\"
string sValO = o.\"Validation Owner\"

for o in m do{
string sObjectText = o.\"Object Text\"
if (sObjectText == sValO){
o.\"Validation Ratification Status\" = \"\"
}

}
lastError()
" // End definition of string DXLCode

Trigger trg
bool TrigOK = true
string ErrMess = checkDXL(DXLCode)

if (!null ErrMess)
{ print ErrMess "\n***********\n" DXLCode "**********\n"
TrigOK = false
}

string NameTrig = "TriggerResetValidatedOn"

string Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
ErrMess = delete (NameTrig, project->module->formal->attribute, post, save, 6)

if (TrigOK and
confirm("Deploy trigger '" NameTrig "' ??"))
trg = trigger(NameTrig, project->module->formal->attribute, post, save, 6, DXLCode)
Pete

Keep in mind that my notions of "bad form" or "good practice" are certainly more ADHD than the vast majority of folks.

It is certainly "bad form" to have a trigger that fires when a particular attribute changes to plow through all objects in the module. That would be like having an Outlook rule that fires when you send a message to offer to clear out your entire Sent folder; no it should just ask to save THIS message or not. So I would check your Ratifacation Status just for the current "obj", not "for o in m do".

Your Ratification Status check looks odd; you seem to be clearing attribute "Validation Ratification Status" when Object Text has the same value as the "Validation Owner"; would someone really set Object Text to "Joe"? Perhaps you are trying to clear ratification when the "Validation Owner" is the current person making the the change to Object Text. If so, then something like this may work

string NameOwner  = probeAttr_(obj, \"Validation Owner\")
if (doorsname() == NameOwner)
   o.\"Validation Ratification Status\" = \"\"


That presumes that Validation Owner contains your DOORs login name. If it contains your options Name, then this may work:

 

User   uCurr = find()
string NameCurr = uCurr.fullName
string NameOwner  = probeAttr_(obj, \"Validation Owner\")
if (NameCurr == NameOwner)
   o.\"Validation Ratification Status\" = \"\"


I don't use 'User Name' attributes so maybe someone else can jump in here.

 

 

 

  • Louie

 

 

Re: Trigger Change to Attribute if Object Text Edited
Peterb4134 - Thu Feb 03 05:17:32 EST 2011

llandale - Wed Feb 02 12:02:09 EST 2011

Keep in mind that my notions of "bad form" or "good practice" are certainly more ADHD than the vast majority of folks.

It is certainly "bad form" to have a trigger that fires when a particular attribute changes to plow through all objects in the module. That would be like having an Outlook rule that fires when you send a message to offer to clear out your entire Sent folder; no it should just ask to save THIS message or not. So I would check your Ratifacation Status just for the current "obj", not "for o in m do".

Your Ratification Status check looks odd; you seem to be clearing attribute "Validation Ratification Status" when Object Text has the same value as the "Validation Owner"; would someone really set Object Text to "Joe"? Perhaps you are trying to clear ratification when the "Validation Owner" is the current person making the the change to Object Text. If so, then something like this may work

string NameOwner  = probeAttr_(obj, \"Validation Owner\")
if (doorsname() == NameOwner)
   o.\"Validation Ratification Status\" = \"\"


That presumes that Validation Owner contains your DOORs login name. If it contains your options Name, then this may work:

 

User   uCurr = find()
string NameCurr = uCurr.fullName
string NameOwner  = probeAttr_(obj, \"Validation Owner\")
if (NameCurr == NameOwner)
   o.\"Validation Ratification Status\" = \"\"


I don't use 'User Name' attributes so maybe someone else can jump in here.

 

 

 

  • Louie

 

 

I guess I should have explain a bit better what I was trying to do. Each requirement is assigned a validation owner as indicated by the Validation Owner attribute. When the requirement has been reviewed by the owner and considered to be a good requirement the owner sets the validation status to "Validated". The Validation Owner is defined as business disciplines rather than peoples names e.g. Quality, Stress, Manufaturing

In addition, when a validation owner is happy with the contents of the module he has a "sign off" object in which he sets an attribute to indicate Acceptable, Acceptable subject to comments or Not Acceptable. There is a "sign off" object per validation owner in the module and the object text is used to identify which object belongs to which validtion owner. This is equivalent to a hardcopy sign off sheet that we used to use.

What I wanted the DXL code to do was 2 things:
1 - when an object is edited, force the validation status attribute back to "Pending" to make sure the Validation Owner reviews the changed requirement.
2 - when an object is edited, force the "sign off" object back to a pending status to show that the module has changed since sign off and so needs to be re-reviewed.

The for (o in m) do was associated with finding the "sign off" object for that particular validation owner so that it could be reset to pending. I didn't know how else to find a particular object within the module which was associated with the Valdation Owner of the object which caused the trigger.

Pete

Re: Trigger Change to Attribute if Object Text Edited
DXLUser - Tue Aug 02 11:37:59 EDT 2011

llandale - Wed Feb 02 12:02:09 EST 2011

Keep in mind that my notions of "bad form" or "good practice" are certainly more ADHD than the vast majority of folks.

It is certainly "bad form" to have a trigger that fires when a particular attribute changes to plow through all objects in the module. That would be like having an Outlook rule that fires when you send a message to offer to clear out your entire Sent folder; no it should just ask to save THIS message or not. So I would check your Ratifacation Status just for the current "obj", not "for o in m do".

Your Ratification Status check looks odd; you seem to be clearing attribute "Validation Ratification Status" when Object Text has the same value as the "Validation Owner"; would someone really set Object Text to "Joe"? Perhaps you are trying to clear ratification when the "Validation Owner" is the current person making the the change to Object Text. If so, then something like this may work

string NameOwner  = probeAttr_(obj, \"Validation Owner\")
if (doorsname() == NameOwner)
   o.\"Validation Ratification Status\" = \"\"


That presumes that Validation Owner contains your DOORs login name. If it contains your options Name, then this may work:

 

User   uCurr = find()
string NameCurr = uCurr.fullName
string NameOwner  = probeAttr_(obj, \"Validation Owner\")
if (NameCurr == NameOwner)
   o.\"Validation Ratification Status\" = \"\"


I don't use 'User Name' attributes so maybe someone else can jump in here.

 

 

 

  • Louie

 

 

Hi,

I need to do something similar to this but the Attribute that needs to be flagged is an attribute at the level of the Object Header.

Example if the children of the Object header was edited the attribute = Yes but at the level of the Object Heading.

Re: Trigger Change to Attribute if Object Text Edited
llandale - Tue Aug 02 13:07:29 EDT 2011

DXLUser - Tue Aug 02 11:37:59 EDT 2011
Hi,

I need to do something similar to this but the Attribute that needs to be flagged is an attribute at the level of the Object Header.

Example if the children of the Object header was edited the attribute = Yes but at the level of the Object Heading.

Your trigger could easily get the parent of the object being modified, and modify that parent object's flag. You will need to have a recursive "parent" lookup stopping when you find one with non-null Object Heading.

I'd be tempted to have two attributes <1> Date "Validated On" which is cleared by your trigger but is set manually when folks validate the change. <2> A string attribute DXL "Needs Validation" that browses its own and all subordinate object's "Validated On" value, and if any are blank sets this value to "Not Validated", but if all are validated sets it to blank. Perhaps it needs to consider only subordinate "requirement" objects, presuming that other objects won't have any "Validated On" value. Boolean would work if you don't mind looking for the occational "true" amongst all the "false" displays.

Perhaps trigger <1> would erase the value of "Needs Validation" recursively for all its parent objects; forcing them to be recalculated.

  • Louie

Re: Trigger Change to Attribute if Object Text Edited
DXLUser - Tue Aug 02 15:33:46 EDT 2011

llandale - Tue Aug 02 13:07:29 EDT 2011
Your trigger could easily get the parent of the object being modified, and modify that parent object's flag. You will need to have a recursive "parent" lookup stopping when you find one with non-null Object Heading.

I'd be tempted to have two attributes <1> Date "Validated On" which is cleared by your trigger but is set manually when folks validate the change. <2> A string attribute DXL "Needs Validation" that browses its own and all subordinate object's "Validated On" value, and if any are blank sets this value to "Not Validated", but if all are validated sets it to blank. Perhaps it needs to consider only subordinate "requirement" objects, presuming that other objects won't have any "Validated On" value. Boolean would work if you don't mind looking for the occational "true" amongst all the "false" displays.

Perhaps trigger <1> would erase the value of "Needs Validation" recursively for all its parent objects; forcing them to be recalculated.

  • Louie

How would I go about finding the parent of the object being modified. I only need a trigger that would flag to Yes an attribute at the parent level when something in the children object changes.

So if child object changed, Find Parent and Attribute X = Yes

Thanks for your help!!

Re: Trigger Change to Attribute if Object Text Edited
llandale - Tue Aug 02 16:30:52 EDT 2011

DXLUser - Tue Aug 02 15:33:46 EDT 2011
How would I go about finding the parent of the object being modified. I only need a trigger that would flag to Yes an attribute at the parent level when something in the children object changes.

So if child object changed, Find Parent and Attribute X = Yes

Thanks for your help!!

noError()
Trigger    trg = current
Object  obj = object(trg)
Module  mod = module(obj)
AttrDef ad = find(mod, "Object Heading")
Object  oParent = parent(obj)
                 // Find nearest ancestor that has Object Heading:
while (!null oParent and !hasSpecificValue(oParent, ad))
{  oParent = parent(oParent)
}
oParent."Flag" = true
lastError()


I wonder if you want all parent ancestors with Heading to have Flag set to true:

 

while (!null oParent)
{  if (hasSpecificValue(oParent, ad)) oParent."Flag" = true
   oParent = parent(oParent)
}
lastError()

 

 

  • Louie

 

Re: Trigger Change to Attribute if Object Text Edited
DXLUser - Thu Aug 11 10:59:03 EDT 2011

llandale - Tue Aug 02 16:30:52 EDT 2011

noError()
Trigger    trg = current
Object  obj = object(trg)
Module  mod = module(obj)
AttrDef ad = find(mod, "Object Heading")
Object  oParent = parent(obj)
                 // Find nearest ancestor that has Object Heading:
while (!null oParent and !hasSpecificValue(oParent, ad))
{  oParent = parent(oParent)
}
oParent."Flag" = true
lastError()


I wonder if you want all parent ancestors with Heading to have Flag set to true:

 

while (!null oParent)
{  if (hasSpecificValue(oParent, ad)) oParent."Flag" = true
   oParent = parent(oParent)
}
lastError()

 

 

  • Louie

 

I am sooo new to all of this, I don't know what I'm doing wrong I keep running the code you you provided below, but it doesn't trigger the attribute "flag" when I edit an object text below the object heading.

What can I be doing wrong?

Re: Trigger Change to Attribute if Object Text Edited
llandale - Sun Aug 14 19:31:56 EDT 2011

DXLUser - Thu Aug 11 10:59:03 EDT 2011
I am sooo new to all of this, I don't know what I'm doing wrong I keep running the code you you provided below, but it doesn't trigger the attribute "flag" when I edit an object text below the object heading.

What can I be doing wrong?

That was my suggested trigger code, you still need to wrap it in some on-demand script that removes and deploys the trigger; examples are further up.

Re: Trigger Change to Attribute if Object Text Edited
DXLUser - Mon Aug 15 11:29:44 EDT 2011

llandale - Sun Aug 14 19:31:56 EDT 2011
That was my suggested trigger code, you still need to wrap it in some on-demand script that removes and deploys the trigger; examples are further up.

Oh, yes I know, I'm sorry I should've given you the example, I'm just getting a syntax error message on the following line:

AttrDef ad = find(mod, "Object Heading")

This is the code:

string DXLCode = "
Module mod = module (obj)
Object obj = object(trg)
Trigger trg = current; if (null trg) halt() // Error?
Object oParent = parent(obj)

AttrDef ad = find(mod, "Object Heading")

noError()

// Find nearest ancestor that has Object Heading:
while (!null oParent and !hasSpecificValue(oParent, ad))
{ oParent = parent(oParent)
}
oParent.\"Suspect Link\" = \"true\"

lastError()
" // End definition of string DXLCode

Trigger trg
bool TrigOK = true
string ErrMess = checkDXL(DXLCode)

if (!null ErrMess)
{ print ErrMess "\n***********\n" DXLCode "**********\n"
TrigOK = false
}

string NameTrig = "TriggerReset"

string Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
ErrMess = delete (NameTrig, project->module->formal->attribute, post, save, 6)

if (TrigOK and
confirm("Deploy trigger '" NameTrig "' ??"))
trg = trigger(NameTrig, project->module->formal->attribute, post, save, 6, DXLCode)

Re: Trigger Change to Attribute if Object Text Edited
llandale - Mon Aug 15 17:43:27 EDT 2011

DXLUser - Mon Aug 15 11:29:44 EDT 2011
Oh, yes I know, I'm sorry I should've given you the example, I'm just getting a syntax error message on the following line:

AttrDef ad = find(mod, "Object Heading")

This is the code:

string DXLCode = "
Module mod = module (obj)
Object obj = object(trg)
Trigger trg = current; if (null trg) halt() // Error?
Object oParent = parent(obj)

AttrDef ad = find(mod, "Object Heading")

noError()

// Find nearest ancestor that has Object Heading:
while (!null oParent and !hasSpecificValue(oParent, ad))
{ oParent = parent(oParent)
}
oParent.\"Suspect Link\" = \"true\"

lastError()
" // End definition of string DXLCode

Trigger trg
bool TrigOK = true
string ErrMess = checkDXL(DXLCode)

if (!null ErrMess)
{ print ErrMess "\n***********\n" DXLCode "**********\n"
TrigOK = false
}

string NameTrig = "TriggerReset"

string Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
ErrMess = delete (NameTrig, project->module->formal->attribute, post, save, 6)

if (TrigOK and
confirm("Deploy trigger '" NameTrig "' ??"))
trg = trigger(NameTrig, project->module->formal->attribute, post, save, 6, DXLCode)

AttrDef ad = find(mod, \"Object Heading\")

Re: Trigger Change to Attribute if Object Text Edited
DXLUser - Tue Aug 16 07:38:03 EDT 2011

llandale - Mon Aug 15 17:43:27 EDT 2011
AttrDef ad = find(mod, \"Object Heading\")

Hi,

I fixed it, but now I'm getting a :"null Object parameter was passed into argument position 1" I tried fixing it but I keep getting the same error :-(

Mary

Re: Trigger Change to Attribute if Object Text Edited
DXLUser - Tue Aug 16 08:57:35 EDT 2011

DXLUser - Tue Aug 16 07:38:03 EDT 2011
Hi,

I fixed it, but now I'm getting a :"null Object parameter was passed into argument position 1" I tried fixing it but I keep getting the same error :-(

Mary

Ok, It's working now! Thank you soooo much for your help!! I'm hoping the more I use DXL I'll get to learn it.