I had the need that a lot of us have had with ALM, preventing historically entered Comments from being modified. HP ALM is one of the few systems I have seen that allow this, as usually once a Comment is entered it is forever preserved and read-only.
A lot of posts I found here dealt with adding a new History Comments Memo Field, and using that solely for retention of all Comments. While only using the original Dev_Comments field as a purely input mechanism only. In our company we synchronize HP ALM with our TeamForge Development System. This is a two-way sync. And even though, through a lot of work in both systems, i could have implemented the Forum's History Comments functionality, i really wanted to preserve the original Dev_Comments field, but provide only Appending Comments while preventing modifications of existing Comment entries.
After weeks of trial and error, and constanlty reading all the Forums posts dealing with Comments, i finally came up with a solution i really like. I wanted to share my solution with the Forum. The example code refers to Defects, but I also implemented in Requirements too.
Here is what I have done and the instructions on how to use -
- Modified System Field Comments Project Entity field to Sanitization Type = None. This is necessary due to HP ALM always wanting to constantly modify certain HTML tags whenever it sees them, every single update. This constantly affects existing historically entered Comments and I needed to stop any and all modifications of existing Comments 100% of the time. This prevents that from happening anymore.
- Created new Memo field RQ_USER_25 and field BG_USER_25 Label = "Add New Comments". The Memo Field creates a new tab in Defects and Requirements areas where we logically make the tab Visible.
- Logically have made all of the original Comments Fields Read Only, no one can enter anything in them anymore. Only view.
- To enter/add comments now -
When on a list of items, the flat Grid of items -
- Go to Comments tab and click the Add Comments button.
- The "Add New Comments" tab will now be visible at the end of the other tabs along the bottom of the browser window.
- Enter whatever you want in the "Add New Comments" tab. Everything and anything is acceptable. As the original Comments worked, images and attachments are automatically created as Attachments, not embedded in text area.
- When you navigate away from the item you entered text for on the "Add New Comments" tab the text will now be APPENDED to the existing Comments field, with an automatically generated header line consisting of Full Name, User Name, Current Item Status, Date, and Time, then the contents of the "Add New Comments" tab will be cleared, and the "Add New Comments" tab will be removed.
When in the Detail Dialog -
- Go to the Comments tab and press the Add Comments button.
- The "Add New Comments" tab will now be visible next to the Detail tab at the top of the browser window.
- Enter whatever you want in the "Add New Comments" tab. Everything and anything is now acceptable. As the original Comments worked, images and attachments are automatically created as Attachments, not embedded in text area.
- When you when you press Submit/OK the item you entered text for on the "Add New Comments" tab text will now be APPENDED to the existing Comments field, with an automatically generated header line consisting of Full Name, User Name, Current Item Status, Date, and Time, then the contents of the "Add New Comments" tab will be cleared, and the "Add New Comments" tab will be removed and no longer available on any subsequent Detail Dialog.
- TF Comments will continue be appended as they always have.
The only thing I do not like about this new functionality is that when the Add Comments button is pressed that I cannot get the application to automatically navigate to the new Add New Comments tab. But still, all in all, I think this is a very good solution.
Workflow Code Examples:
Function ActionCanExecute(ActionName)
......
if ActionName = "ReqAddDevCommentsAction1" then
Req_Fields.Field("RQ_USER_25").IsVisible = true
Req_Fields.Field("RQ_USER_25").IsReadOnly = false
Bug_Fields.Field("BG_USER_25").IsVisible = true
Bug_Fields.Field("BG_USER_25").IsReadOnly = false
end if
......
Sub Bug_New
…..
Bug_Fields.Field("BG_DEV_COMMENTS").IsReadOnly = True
Bug_Fields.Field("BG_USER_25").IsVisible = false
Bug_Fields.Field("BG_USER_25").IsReadOnly = true
…..
Sub Bug_MoveTo
…..
Bug_Fields.Field("BG_DEV_COMMENTS").IsReadOnly = True
Bug_Fields.Field("BG_USER_25").IsVisible = false
Bug_Fields.Field("BG_USER_25").IsReadOnly = true
…..
Sub Bug_CanPost
…..
If Bug_Fields.Field("BG_User_25").Value <> "" then
Bug_AddToComments
end if
…..
Sub Bug_AddToComments
newComment = Bug_Fields.Field("BG_USER_25").Value
origComment = Bug_Fields.Field("BG_DEV_COMMENTS").Value
' Remove ending </body>... from new comment
lngPos = instr(newComment,"</body>") - 1
if lngPos > 0 then
newComment = left(newComment,lngPos)
end if
lngPos = instr(newComment,"<body>")
if lngPos > 0 then
newComment = mid(newComment,lngPos + 6 )
end if
' Append Comment Separator, Name, Date, and Status to new Comments
if origComment = "" then
newLeadIn = "<html><body><div align=""left"" style=""min-height: 9pt; "">"
else
newLeadIn = Chr(10) & "<div align=""left"" style=""min-height: 9pt; "">" & _
"<font face=""Arial""><span style=""font-size:8pt""><br /></span></font>" & _
"<font face=""Arial"" color=""#000080""><span style=""font-size:8pt"">" & _
"<b>________________________________________</b></span></font>"
end if
newComment = newLeadIn & _
"<font face=""Arial""><span style=""font-size:8pt""><br /></span></font>" & _
"<font face=""Arial"" color=""#000080""><span style=""font-size:8pt"">" & _
"<b>" & fullname & " <" & username & ">, Status-" & _
Bug_Fields.Field("BG_USER_02").Value & _
", " & now & ":</b>" & _
"</span></font>" & _
newComment & _
"</div>"
lngPos = instr(origComment,"<body>")
if lngPos > 0 then
' Resume Next
else
origComment = "<html>" & Chr(10) & "<body>"
end if
lngPos = instr(origComment,"</body>") - 1
if lngPos > 0 then
origComment = left(origComment,lngPos)
end if
Bug_Fields.Field("BG_DEV_COMMENTS").IsReadOnly = false
Bug_Fields.Field("BG_DEV_COMMENTS").Value = origComment & newComment & _
"</body></html>"
Bug_Fields.Field("BG_DEV_COMMENTS").IsReadOnly = true
Bug_Fields.Field("BG_USER_25").Value = "reset"
Bug_Fields.Field("BG_USER_25").Value = ""
Bug_Fields.Field("BG_USER_25").IsReadOnly = true
Bug_Fields.Field("BG_USER_25").IsVisible = false
End Sub