Search code examples
ibm-doors

How to populate a DXL attribute with the history from a specific attribute?


Hi I'm trying to return the date that the last edit was made to the attribute titled "VVT Status", into the attribute titled "VVT Status Update". It is currently returning all of the updates to the object since the last baseline rather than just the latest edit to the "VVT Status" attribute. Code is below and adapted from similar questions in SO. Thanks in advance.

Module m = current

string getHistoryContent (History h)
{ \\attrName is only in sReturnValue so I can check it came from correct attribute
 HistoryType ht = h.type
 string sReturnValue = h.attrName "\t" h.date "\t" 
 return sReturnValue
}
string sHistoryAttributeName = "VVT Status Update"
string attributName

Object o
for o in entire m do
{
  History h
  for h in o do
   {
     attributName = h.attrName
  
     if isDeleted(o) then continue
     if (!canModify o.sHistoryAttributeName) then {warn "cannot modify history entry for object " (identifier o) "\n"; continue}
     if((attributeName=="VVT Status"))
     {
       Buffer bContentOfVVT = create
       
       for h in o do
         {
          bContentOfVVT += getHistoryContent(h) "\n"
         }
       o.sHistoryAttributeName = bContentOfVVT
       delete bContentOfVVT
     }
   }
}
save m

Hoped to get date "VVT Status" last modified into "VVT Status Update"


Solution

  • From my long history with DXL, there are a number of different approaches to this, but to stick as closely as possible to the design intent apparent in your code, I have changed it as follows:

    if (null current Module)
    { errorBox("This script must run inside a Formal Module opened in Exclusive Edit mode.") }
    
    Module modThis = current
    Object objThis = null
    
    if (!isEdit modThis)
    { errorBox("This script must run inside a Formal Module opened in Exclusive Edit mode.") }
    
    const string sHistoryAttributeName = "Object Text Update"
    const string sAttributeName        = "Object Text"
    
    string getHistoryContent (string sAttrName)
    {
      History     hRec       = null
      HistoryType hType      = null
      string      sHAttrName = null
      Date        dtLastMod  = null
    
      for hRec in objThis do
      {
          hType      = hRec.type
          sHAttrName = hRec.attrName
    
        if ((hType == modifyObject) && (sHAttrName == sAttributeName))
        { dtLastMod = hRec.date }
      }
    
      if (!null dtLastMod)
      { return stringOf(dtLastMod) }
      return ""
    }
    
    for objThis in entire modThis do
    {
      if isDeleted(objThis) then continue
      if (!canModify objThis.sHistoryAttributeName) then {warn "cannot modify history entry for object " (identifier objThis) "\n"; continue}
    
      objThis.sHistoryAttributeName = getHistoryContent(sAttributeName)
    }
    
    save modThis
    refresh modThis
    

    I hope this is helpful - please feel free to ask questions about my proposed solution. Main feature is that the (optimised) heavy-lifting of searching the history is now in the function rather than the main program loop.

    Kind regards,

    Richard