DXL column for Object History

The code in the layout dxl column was generated by a script from this forum.  It works and it returns the history with redline markup from oldest to newest.  I want to reverse the order so the most recent changes is at the top of the list.  How can I do this?

I also notice something odd in DOORS(v9.5).  When I first entered new object text(i used the MS Word export to DOORS addin) it lists two history records.  The first one is expected showing 'from' being blank and 'to' being the object text i wanted.  The second entry shows 'from' and 'to' being the same text with no redlines.  Just looks like theres a font/alignment change if that and the date/timestamp for both is exact.y the same.  How can I set a condition so the bogus duplicate date/timestamp doesnt show up?

Is there a way If I select multiple attributes the output is grouped/sorted by date rather than grouped by attribute?  Thanks.

Thanks for the help.

//int dateNumber = 1385269200; Date afterDate = dateOf dateNumber //this int dateNumber was created when I selected 24nov2013 as the date.

Date afterDate = "11/24/2013"//used this hardcoded date rather than the date number.  There will be no DOORS history prior to this date.
//every time the date is pasted to DOORS the quotes need to be retyped.

void defaultDescribeEvent(Object o, string sAttribute, History h, Buffer b)
{
                Buffer v = create()
                Buffer old = create(); old = h.plainOldValue;
                Buffer new = create(); new = h.plainNewValue;

                diff (v, old,new, "\\cf1\\strike ", "\\cf3\\ul ")

//string sRequestedBy = probeRichAttr_(obj, "Requested By", false)

                b += "{\\b On }"
                Date d = h.date
                b += d ""
                b += " {\\b "
                b += h.author ""//change this to sRequestedBy…its not bolding the text though
                b += "} "
                // object modification has old and new values
                b += " modified {\\b "
                b += h.attrName "} "
                b += " \\par "
                b += v
                b += " \\par "

                delete old
                delete new
                delete v
}
string getHistoryForAttributes(Object o, string sAtt, void describeEvent(Object, string, History, Buffer))
{
                History h = null
                HistoryType ht = null
                Buffer b = create()
                for h in o do
                {
                                if(h.readlocked)
                                                continue
                                Date x = h.date

                                if (x < afterDate) continue
                                ht = h.type
                                if (ht == modifyObject)
                                {
                                               string sAttribute = h.attrName
                                               if (sAtt == sAttribute)
                                               describeEvent(o, sAttribute, h, b)
                                }
                }
                string sHistory = stringOf(b)
                delete b
                return sHistory
}
//I added two lines and changed the attribute names and the code pulled those attributes too
displayRichWithColour getHistoryForAttributes(obj, "Object Text", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "VerificationSectionText", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "AdminComments", defaultDescribeEvent)

 


bmohamed - Mon Oct 27 02:53:43 EDT 2014

Re: DXL column for Object History
Wolfgang Uhr - Mon Oct 27 08:43:14 EDT 2014

> I want to reverse the order so the most recent changes is at the top of the list. How can I do this?

The older-newer-order is a naturally result of the order of the history entries "for h in o". If you want to reverse this you have to reverse the order of this search.

Skip skpHistory = create();
int iCnt = 0;
for h in o do {
    put (skpHistory, h, --iCnt);
}

for h in skpHistory do {
 ...
}

 

Best regards

Wolfgang

 

Re: DXL column for Object History
bmohamed - Mon Oct 27 10:17:19 EDT 2014

Wolfgang Uhr - Mon Oct 27 08:43:14 EDT 2014

> I want to reverse the order so the most recent changes is at the top of the list. How can I do this?

The older-newer-order is a naturally result of the order of the history entries "for h in o". If you want to reverse this you have to reverse the order of this search.

Skip skpHistory = create();
int iCnt = 0;
for h in o do {
    put (skpHistory, h, --iCnt);
}

for h in skpHistory do {
 ...
}

 

Best regards

Wolfgang

 

Thanks for the help.

I updated my code and got runtime errors.

-R-E- DXL: <Line:47> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 0023:0047C2B2
 
Backtrace:
<Line:65> 
-R-F- DXL: <Line:47> internal error, please submit a bug report
Backtrace:
<Line:65> 
-I- DXL: execution halted

here is the updated code:

//int dateNumber = 1385269200; Date afterDate = dateOf dateNumber //this int dateNumber was created when I selected 24nov2013 as the date.

Date afterDate = "11/24/2013"//used this hardcoded date rather than the date number.  There will be no DOORS history prior to this date.
//every time the date is pasted to DOORS the quotes need to be retyped.

void defaultDescribeEvent(Object o, string sAttribute, History h, Buffer b)
{
                Buffer v = create()
                Buffer old = create(); old = h.plainOldValue;
                Buffer new = create(); new = h.plainNewValue;

                diff (v, old,new, "\\cf1\\strike ", "\\cf3\\ul ")

//string sRequestedBy = probeRichAttr_(obj, "Requested By", false)

                b += "{\\b On }"
                Date d = h.date
                b += d ""
                b += " {\\b "
                b += h.author ""//change this to sRequestedBy…its not bolding the text though
                b += "} "
                // object modification has old and new values
                b += " modified {\\b "
                b += h.attrName "} "
                b += " \\par "
                b += v
                b += " \\par "

                delete old
                delete new
                delete v
}
string getHistoryForAttributes(Object o, string sAtt, void describeEvent(Object, string, History, Buffer))
{
                History h = null
                HistoryType ht = null
                Buffer b = create()
                
Skip skpHistory = create();
int iCnt = 0;
for h in o do {
    put (skpHistory, --iCnt, h);//I changed the order of --iCnt and h per Mathias below, and this works now. You can change this to iCnt++ to reverse the order of the output
}

for h in skpHistory do 
                {
            if(h.readlocked)
                            continue
            Date x = h.date

            if (x < afterDate) continue
            ht = h.type
            if (ht == modifyObject)
            {
                           string sAttribute = h.attrName
                           if (sAtt == sAttribute)
                           describeEvent(o, sAttribute, h, b)
            }
                }
                string sHistory = stringOf(b)
                delete b
                return sHistory
}
//I added two lines and changed the attribute names and the code pulled those attributes too
displayRichWithColour getHistoryForAttributes(obj, "Object Text", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "VerificationSectionText", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "AdminComments", defaultDescribeEvent)

 

Re: DXL column for Object History
Wolfgang Uhr - Mon Oct 27 11:33:35 EDT 2014

bmohamed - Mon Oct 27 10:17:19 EDT 2014

Thanks for the help.

I updated my code and got runtime errors.

-R-E- DXL: <Line:47> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 0023:0047C2B2
 
Backtrace:
<Line:65> 
-R-F- DXL: <Line:47> internal error, please submit a bug report
Backtrace:
<Line:65> 
-I- DXL: execution halted

here is the updated code:

//int dateNumber = 1385269200; Date afterDate = dateOf dateNumber //this int dateNumber was created when I selected 24nov2013 as the date.

Date afterDate = "11/24/2013"//used this hardcoded date rather than the date number.  There will be no DOORS history prior to this date.
//every time the date is pasted to DOORS the quotes need to be retyped.

void defaultDescribeEvent(Object o, string sAttribute, History h, Buffer b)
{
                Buffer v = create()
                Buffer old = create(); old = h.plainOldValue;
                Buffer new = create(); new = h.plainNewValue;

                diff (v, old,new, "\\cf1\\strike ", "\\cf3\\ul ")

//string sRequestedBy = probeRichAttr_(obj, "Requested By", false)

                b += "{\\b On }"
                Date d = h.date
                b += d ""
                b += " {\\b "
                b += h.author ""//change this to sRequestedBy…its not bolding the text though
                b += "} "
                // object modification has old and new values
                b += " modified {\\b "
                b += h.attrName "} "
                b += " \\par "
                b += v
                b += " \\par "

                delete old
                delete new
                delete v
}
string getHistoryForAttributes(Object o, string sAtt, void describeEvent(Object, string, History, Buffer))
{
                History h = null
                HistoryType ht = null
                Buffer b = create()
                
Skip skpHistory = create();
int iCnt = 0;
for h in o do {
    put (skpHistory, --iCnt, h);//I changed the order of --iCnt and h per Mathias below, and this works now. You can change this to iCnt++ to reverse the order of the output
}

for h in skpHistory do 
                {
            if(h.readlocked)
                            continue
            Date x = h.date

            if (x < afterDate) continue
            ht = h.type
            if (ht == modifyObject)
            {
                           string sAttribute = h.attrName
                           if (sAtt == sAttribute)
                           describeEvent(o, sAttribute, h, b)
            }
                }
                string sHistory = stringOf(b)
                delete b
                return sHistory
}
//I added two lines and changed the attribute names and the code pulled those attributes too
displayRichWithColour getHistoryForAttributes(obj, "Object Text", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "VerificationSectionText", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "AdminComments", defaultDescribeEvent)

 

I don't know. I assume, that it is better not to include the readlocked entries into the skiplist.

Re: DXL column for Object History
Mathias Mamsch - Tue Oct 28 07:22:45 EDT 2014

bmohamed - Mon Oct 27 10:17:19 EDT 2014

Thanks for the help.

I updated my code and got runtime errors.

-R-E- DXL: <Line:47> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 0023:0047C2B2
 
Backtrace:
<Line:65> 
-R-F- DXL: <Line:47> internal error, please submit a bug report
Backtrace:
<Line:65> 
-I- DXL: execution halted

here is the updated code:

//int dateNumber = 1385269200; Date afterDate = dateOf dateNumber //this int dateNumber was created when I selected 24nov2013 as the date.

Date afterDate = "11/24/2013"//used this hardcoded date rather than the date number.  There will be no DOORS history prior to this date.
//every time the date is pasted to DOORS the quotes need to be retyped.

void defaultDescribeEvent(Object o, string sAttribute, History h, Buffer b)
{
                Buffer v = create()
                Buffer old = create(); old = h.plainOldValue;
                Buffer new = create(); new = h.plainNewValue;

                diff (v, old,new, "\\cf1\\strike ", "\\cf3\\ul ")

//string sRequestedBy = probeRichAttr_(obj, "Requested By", false)

                b += "{\\b On }"
                Date d = h.date
                b += d ""
                b += " {\\b "
                b += h.author ""//change this to sRequestedBy…its not bolding the text though
                b += "} "
                // object modification has old and new values
                b += " modified {\\b "
                b += h.attrName "} "
                b += " \\par "
                b += v
                b += " \\par "

                delete old
                delete new
                delete v
}
string getHistoryForAttributes(Object o, string sAtt, void describeEvent(Object, string, History, Buffer))
{
                History h = null
                HistoryType ht = null
                Buffer b = create()
                
Skip skpHistory = create();
int iCnt = 0;
for h in o do {
    put (skpHistory, --iCnt, h);//I changed the order of --iCnt and h per Mathias below, and this works now. You can change this to iCnt++ to reverse the order of the output
}

for h in skpHistory do 
                {
            if(h.readlocked)
                            continue
            Date x = h.date

            if (x < afterDate) continue
            ht = h.type
            if (ht == modifyObject)
            {
                           string sAttribute = h.attrName
                           if (sAtt == sAttribute)
                           describeEvent(o, sAttribute, h, b)
            }
                }
                string sHistory = stringOf(b)
                delete b
                return sHistory
}
//I added two lines and changed the attribute names and the code pulled those attributes too
displayRichWithColour getHistoryForAttributes(obj, "Object Text", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "VerificationSectionText", defaultDescribeEvent)
//displayRichWithColour getHistoryForAttributes(obj, "AdminComments", defaultDescribeEvent)

 

And of course changing the order of key and value might help ;-)

for h in o do {
    put (skpHistory, h, --iCnt);  // change the order of key and value!
}

Because here you are iterating over the values!

for h in skpHistory do { ... }

 

For your problem of getting rid of the formatting changes, you could compare the non-richtext strings with each other, but that will get rid of ALL formatting changes, like adding a bullet, etc. Also what you might want is to reduce multiple changes in the same session to the same object/attribute to one change by taking only the first "from" value and the last "to" value ...

Regards, Mathias

Re: DXL column for Object History
bmohamed - Tue Oct 28 10:01:01 EDT 2014

Mathias Mamsch - Tue Oct 28 07:22:45 EDT 2014

And of course changing the order of key and value might help ;-)

for h in o do {
    put (skpHistory, h, --iCnt);  // change the order of key and value!
}

Because here you are iterating over the values!

for h in skpHistory do { ... }

 

For your problem of getting rid of the formatting changes, you could compare the non-richtext strings with each other, but that will get rid of ALL formatting changes, like adding a bullet, etc. Also what you might want is to reduce multiple changes in the same session to the same object/attribute to one change by taking only the first "from" value and the last "to" value ...

Regards, Mathias

Thanks it worked.  I updated my code above to reflect the change.

I'm not sure how to address your idea regarding session comparison and its a good one.  If its something you could do on the fly in a couple minutes I'd appreciate it otherwise I'll keep experimenting.

Thanks for the help.

Re: DXL column for Object History
Wolfgang Uhr - Tue Oct 28 11:48:02 EDT 2014

bmohamed - Tue Oct 28 10:01:01 EDT 2014

Thanks it worked.  I updated my code above to reflect the change.

I'm not sure how to address your idea regarding session comparison and its a good one.  If its something you could do on the fly in a couple minutes I'd appreciate it otherwise I'll keep experimenting.

Thanks for the help.

Hello

The history has the property "sessionNo" which is an absolute number increased by doors in each session. The sesssions itself are stored in the module.

HistorySession histSess;

for histSess in mdlWork do {
  int iSessionID = number(histSess);
  ...
}

If you run through this loop, you get the last session id.

If you are looking for a good example: http://www.smartdxl.com/content/?p=418

Best regards
Wolfgang

Re: DXL column for Object History
bmohamed - Tue Oct 28 18:45:56 EDT 2014

Wolfgang Uhr - Tue Oct 28 11:48:02 EDT 2014

Hello

The history has the property "sessionNo" which is an absolute number increased by doors in each session. The sesssions itself are stored in the module.

HistorySession histSess;

for histSess in mdlWork do {
  int iSessionID = number(histSess);
  ...
}

If you run through this loop, you get the last session id.

If you are looking for a good example: http://www.smartdxl.com/content/?p=418

Best regards
Wolfgang

Thanks.  Ill put that in my dxl.

Can that be used to sort the output by session and date?

When I enable all three lines of code at once, it shows all the history for Object Text then shows history of VerificationSectionText and so on.  Would it be possible to avoid that grouping and display the history in order of date and skip any attributes that arent listed below?

displayRichWithColour getHistoryForAttributes(obj, "Object Text", defaultDescribeEvent)
displayRichWithColour getHistoryForAttributes(obj, "VerificationSectionText", defaultDescribeEvent)
displayRichWithColour getHistoryForAttributes(obj, "AdminComments", defaultDescribeEvent)

 

Re: DXL column for Object History
bmohamed - Thu Oct 30 11:14:55 EDT 2014

Mathias Mamsch - Tue Oct 28 07:22:45 EDT 2014

And of course changing the order of key and value might help ;-)

for h in o do {
    put (skpHistory, h, --iCnt);  // change the order of key and value!
}

Because here you are iterating over the values!

for h in skpHistory do { ... }

 

For your problem of getting rid of the formatting changes, you could compare the non-richtext strings with each other, but that will get rid of ALL formatting changes, like adding a bullet, etc. Also what you might want is to reduce multiple changes in the same session to the same object/attribute to one change by taking only the first "from" value and the last "to" value ...

Regards, Mathias

The reason for all is that I want a revision history column containing Date, Change, Reason, Requested By.

I have 3 of those values captured in the DOORS history but 'reason' is a text attribute for comments on why the change was made and I want the 'reason' put with the change/date/requested by info it corresponds too.  Since its a separate attribute, the dxl will put after all the object text history is displayed so it wont align how i want.  I'm assuming I'll get a spreadsheet with a column for new object text and column for 'reason' and i'll import that based on absolute number so they should both update within seconds of each other.  I'm open to suggestions on how else to keep track of 'reason' for changes.  Thanks.

Re: DXL column for Object History
Wolfgang Uhr - Thu Oct 30 11:34:51 EDT 2014

bmohamed - Tue Oct 28 18:45:56 EDT 2014

Thanks.  Ill put that in my dxl.

Can that be used to sort the output by session and date?

When I enable all three lines of code at once, it shows all the history for Object Text then shows history of VerificationSectionText and so on.  Would it be possible to avoid that grouping and display the history in order of date and skip any attributes that arent listed below?

displayRichWithColour getHistoryForAttributes(obj, "Object Text", defaultDescribeEvent)
displayRichWithColour getHistoryForAttributes(obj, "VerificationSectionText", defaultDescribeEvent)
displayRichWithColour getHistoryForAttributes(obj, "AdminComments", defaultDescribeEvent)

 

> Can that be used to sort the output by session and date?

Sorting can be done in dxl using skip lists. The key can be an integer (create()) or a string (createString()). If you want to sort by date, you can use intOf(date) and sort the integer. If you want to reverse the directtion, you can build up a skip list bei -intOf(date). If you want to sort by two values or more you have to define something like a sort string. If you want to sort by session first and then by date, you can fill up the integers using zeros.

For example

int sessionID = 12345;

int iDate = intOf(someDay)

-> string sortString = "0000012345:11799034354563234" or else

If you put this in a skip list

put (someSkipList, sortString, someObject);

then you only need to run through the skip loop to get the orderd objects

Object someObject

for someObjects in someSkipList do {

  string sortString= (string key(someSkipList));

  // here the Objects are sorted ...

}

Best regards

Wolfgang

Re: DXL column for Object History
Wolfgang Uhr - Thu Oct 30 11:38:32 EDT 2014

bmohamed - Thu Oct 30 11:14:55 EDT 2014

The reason for all is that I want a revision history column containing Date, Change, Reason, Requested By.

I have 3 of those values captured in the DOORS history but 'reason' is a text attribute for comments on why the change was made and I want the 'reason' put with the change/date/requested by info it corresponds too.  Since its a separate attribute, the dxl will put after all the object text history is displayed so it wont align how i want.  I'm assuming I'll get a spreadsheet with a column for new object text and column for 'reason' and i'll import that based on absolute number so they should both update within seconds of each other.  I'm open to suggestions on how else to keep track of 'reason' for changes.  Thanks.

>  I'm open to suggestions on how else to keep track of 'reason' for changes.

You cannot track "reasons" for changes unless you do not insert this into the database. Date, Change (I think you mean the date of change) are attributes in dxl but not Reason or Requested by.

Re: DXL column for Object History
bmohamed - Thu Oct 30 12:30:29 EDT 2014

Wolfgang Uhr - Thu Oct 30 11:38:32 EDT 2014

>  I'm open to suggestions on how else to keep track of 'reason' for changes.

You cannot track "reasons" for changes unless you do not insert this into the database. Date, Change (I think you mean the date of change) are attributes in dxl but not Reason or Requested by.

Sorry, 'change' means the revision to object text or any attribute.

I'm a single(node locked) doors user but created different accounts for the rest of team so when someone sends me changes, i sign in under their name and make the changes.  That takes care of date, change, and requested by but Im stuck without a reason.  My idea was to keep 'reason' as a text attribute that will be filled in when a change is made as to why they made the change.  I dont know how to get that info displayed right after the Object text change its associated with.  thats why I thought sorting the output of multiple attributes by date would group them right.  Right now the code groups each attribute together in blocks THEN sorts them by date.

Re: DXL column for Object History
llandale - Thu Nov 13 16:23:29 EST 2014

Wolfgang Uhr - Tue Oct 28 11:48:02 EDT 2014

Hello

The history has the property "sessionNo" which is an absolute number increased by doors in each session. The sesssions itself are stored in the module.

HistorySession histSess;

for histSess in mdlWork do {
  int iSessionID = number(histSess);
  ...
}

If you run through this loop, you get the last session id.

If you are looking for a good example: http://www.smartdxl.com/content/?p=418

Best regards
Wolfgang

Be advised that if two folks have the module open shared then it is possible for a History record of Session=n+1 to come before a History record of Session=n.  In fact, I think it is possible to get a History with Date=d+1 to come before a History with Date = d.  At one point in the past I had this figured out but have forgotten.  The upshot of this is that the last History found for an obj-attr value may not be the last de-facto History.

-Louie