Welcome to Telelogic Product Support
  Home Downloads Knowledgebase Case Tracking Licensing Help Telelogic Passport
Telelogic DOORS (steve huntington)
Decrease font size
Increase font size
Topic Title: Exporting Object History
Topic Summary: I need to generate a readable output of change history for review purposes
Created On: 16-Nov-2004 19:35
Status: Post and Reply
Linear : Threading : Single : Branch
Search Topic Search Topic
Topic Tools Topic Tools
Quick Reply Quick Reply
Subscribe to this topic Subscribe to this topic
E-mail this topic to someone. E-mail this topic
Bookmark this topic Bookmark this topic
View similar topics View similar topics
View topic in raw text format. Print this topic.
 16-Nov-2004 19:35
User is offline View Users Profile Print this message


Tom Roman

Posts: 4
Joined: 16-Nov-2004

I would like to generate reports from DOORs that capture changes that occured between two specified dates. This would be used in lieue of the CPS, mainly as a way to notify people of changes rather than get approval.

I can export a file from "Module History" and filter that based on dates, but the file appears to be raw text with spaces separating predefined fields. I would have to write some sort of script to parse that to make it useful, and I'd like to have some flexibility to define fields.

Is there any easy way to generate such a report? With fields like Type of Change (create, modify, delete etc), date, time, user, Attribute name, Changed From, and Changed To:?   

I know I could write a DXL script, but I'd have to learn DXL and I'm not extremely SW-oriented. Maybe someone out there has a DXL script? Or a way to post-process the standard DOORs history export file?

Thanks,
Tom



Edited: 16-Nov-2004 at 19:36 by Tom Roman
Report this to a Moderator Report this to a Moderator
 17-Nov-2004 08:02
User is offline View Users Profile Print this message


Roy Bond

Posts: 39
Joined: 25-Mar-2003

Try this one.......




// Export Module History to File.dxl

/*

DXL Utility to extract Formal Module History into Temporary Text File.


Note :

Text File Name and Path are defined as :

C:\Temp\TempFile.txt

*/

// **********************************************************************************************
// Constant and Variable declarations


Module current_module = current

History h

string TempFile = "C:\\Temp\\TempFile.txt"

Stream out = write TempFile

RichText rt


// **********************************************************************************************
// Functions and Procedures


void print(History h) {

HistoryType ht = h.type

out << "User : " h.author "\nDate : " h.date "\nAction : " goodStringOf(ht) " "

if (ht == createType || ht == modifyType || ht == deleteType) { // attribute type

out << h.typeName


} else {

if (ht == createAttr || ht == modifyAttr || ht == deleteAttr) { // attribute definition

out << "\"" h.attrName "\""


} else {

if (ht == createObject || ht == copyObject || ht == modifyObject) { // object

out << h.absNo ""

if (ht==modifyObject) { // modify means an attribute

out << " Attribute \"" h.attrName "\""

string oldV = "Before : " h.oldValue

out << "\n\n"

for rt in oldV do {
out << rt.text
}

out << " \n\n"

string newV = "After : " h.newValue

for rt in newV do {
out << rt.text
}

out << "\n"

}
}
}
}

out << "\n----------------------------------------------------------------------------------------------\n\n"
}


// **********************************************************************************************
// Main Body of DXL Script

string modname = current_module."Name"
string modver = version(current_module)
Date now = dateOf intOf today

out << "Formal Module : " modname "\n"

out << "Version : " modver "\n"

out << "\nFile Created : " now "\nBy User : " doorsname "\n\n"

out << "==============================================================================================\n"

out << "Formal Module History (since last Baseline) : \n\n\n"

for h in current_module do print h

out << "End of Formal Module History\n"

out << "----------------------------------------------------------------------------------------------"

close out




Roy Bond
MTU Aero Engines
Munich

roy-david.bond@muc.mtu.de
Report this to a Moderator Report this to a Moderator
 18-Nov-2004 14:01
User is offline View Users Profile Print this message


Tom Roman

Posts: 4
Joined: 16-Nov-2004

Thanks Roy - that worked.

The script exports every change since the baseline. I'd really like to specify a date range. Also, ideally I'd like to export to Excel, so I can sort/filter on fields there.

If anyone can help with that kind of a script I'd greatly appreciate it!


Tom
Report this to a Moderator Report this to a Moderator
 23-Nov-2004 08:18
User is offline View Users Profile Print this message


Kristian Bøe

Posts: 29
Joined: 16-Jun-2003

This should do you. It will also look across baselines if there are any since the specified from date.

// Creates an MS Excel report on all changes spanning over baselines from a certain date to current version
/*
Finds all the changes made in DOORS modules, in the same folder, from a user defined date
and exports this to en MS Excel file document. A choice is given whether to report from the current
module, all open modules in the current project or all similar modules in the same folder.
All attributes generating history are checked, changes to values are reported.
*/

string S_TYPE_1 = type (current Module) // Type of module to export from
string S_PATH_1 = path (current Module) // Folder in which the modules are found
DB progressBox = centered "Change Report Progress"


//
// Handling writing to MS Excel
//

pragma runLim,0
#include
checkPlatform "Microsoft Excel"

//--------------------------------------------------------------

OleAutoObj objExcel = null
OleAutoObj objWorkbooks = null
OleAutoObj objWorkbook = null
OleAutoObj objSheet = null
OleAutoObj objCell = null
OleAutoArgs args = create

//--------------------------------------------------------------


bool excelInit() {
objExcel = connectToApp(cObjExcelApplication, "Excel")
if (null objExcel) return false

makeVisible objExcel

// get workbooks collection
checkRes(oleGet(objExcel,cPropertyWorkbooks,objWorkbooks))
if (null objWorkbooks) {
ack "Unable to get workbooks collection"
return false
}

// add one
checkRes(oleMethod(objWorkbooks, cMethodAdd))

// get active workbook
checkRes(oleGet(objExcel,cPropertyActiveWorkbook,objWorkbook))
if (null objWorkbook) {
ack "Unable to get active workbook"
return false
}
// get active sheet
checkRes(oleGet(objWorkbook,cPropertyActiveSheet,objSheet))
if (null objSheet) {
ack "Unable to get active sheet"
return false
}

return true
}


string intToCol(int i) {
int p
if (i < 26) {
char a = `A'
p = intOf a
p = p + (i-1)
a = charOf p
return a ""
} else {
ack "Too many columns"
halt
}
}

void setCell(int row, int col, string s) {
closeIfNonNull objCell
clear(args)
put(args, (intToCol col) row "")
checkRes(oleGet(objSheet, cMethodRange,args, objCell))

if (null objCell) {
ack "Unable to get cell object"
halt
}

checkRes(olePut(objCell, cPropertyValue, s))
}

bool StartExcel () {
if (!excelInit) {
delete excelTrigger
return false
}

setCell(1, 1, "Module name")
setCell(1, 2, "Object ID")
setCell(1, 3, "Changed by")
setCell(1, 4, "Date of change")
setCell(1, 5, "Type of change")
setCell(1, 6, "Changed attribute")
setCell(1, 7, "Changed from")
setCell(1, 8, "Changed to")

return true
}

string MyTextFix (string value) {
string ttt = ""
RichText rt

if (isRichText (value)) then {
for rt in value do ttt = ttt rt.text
return ttt
}
else return value
}


//
// Returns the exact time of last modification if there is a history record for it!
//

Date MyLastMod (Object o) {
History hhh
Date dHist1 = o."Last Modified On"

for hhh in o do {
if (intOf(hhh.date) > intOf(dHist1)) then dHist1 = hhh.date
}
return dHist1
}



int MyHistoryReport (int row, string sMod, sObj, Object o, Date dBeg) {
History h = null

for h in o do {
// check for correct date
if (h.date < dBeg) then continue
row++
setCell(row, 1, sMod)
setCell(row, 2, sObj)
setCell(row, 3, h.author)
setCell(row, 4, h.date "")
setCell(row, 5, h.type "")
if (h.type == modifyObject) then {
setCell(row, 6, h.attrName)
setCell(row, 7, MyTextFix (h.oldValue))
setCell(row, 8, MyTextFix (h.newValue))
}
}
if (null(h)) then {
row++
setCell(row, 1, sMod)
setCell(row, 2, sObj)
setCell(row, 3, "Unknown")
setCell(row, 4, "Unknown")
setCell(row, 5, "Unknown")
}

return row
}

int ReportChanges (Module cm, Date dBeg, int row) {
Baseline b
Date dBase, dLMO, dPrev, dOldest

Object oo, ob
History hh
Skip skHIST = create
string sKEY, sKEY_2
string sPF
bool bOBJ



int iBASE = 1
dPrev = dBeg
dOldest = today

for b in current Module do if (dateOf(b) > dBeg) iBASE++
string sBASE[iBASE]

i = 0

//
// Look through all of the baselines, check if they occured before the start date (dBeg)
//

for b in current Module do {

dBase = dateOf(b)

if (dBase >= dBeg) then {
sKEY_2 = (major b) "." (minor b) (suffix b) ""
sBASE = sKEY_2
i++

m = load (b, false)
for hh in m do {
if (hh.type == baselineModule && intOf(hh.date) > intOf(dPrev)) then {
dPrev = hh.date
}
}
for oo in m do {
dLMO = MyLastMod(oo)
if ((dBase >= dLMO) && (dLMO > dPrev)) then {
sPF = m."Prefix"
sKEY = sKEY_2 sPF oo."Absolute Number" ""
put (skHIST, sKEY, oo)
}
}
}
}

sBASE = "Current"
m = cm

for hh in m do {
if (hh.type == baselineModule && intOf(hh.date) > intOf(dPrev)) then {
dPrev = hh.date
}
}

for oo in m do {
dLMO = MyLastMod(oo)
if (dLMO > dPrev) then {
sPF = m."Prefix"
sKEY = sBASE sPF oo."Absolute Number" ""
put (skHIST, sKEY, oo)
}
}

sort sBASE

for oo in cm do {
dLMO = oo."Last Modified On"
bOBJ = true
for (i = 0; i < iBASE; i++) {
sPF = cm."Prefix"
sKEY = sBASE sPF oo."Absolute Number" ""
if (find(skHIST, sKEY, ob)) then {
bOBJ = false
row = MyHistoryReport (row, name(cm), sPF oo."Absolute Number" "",ob, dBeg)
}
}
if (dLMO > dPrev) then {
if (bOBJ) then row = MyHistoryReport (row, name(cm), sPF oo."Absolute Number" "", oo, dBeg)
}
}

for hh in cm do {
if (hh.type == deleteObject) {
row++
setCell (row, 1, name(cm))
setCell (row, 2, cm."Prefix" hh.absNo "")
setCell (row, 3, hh.author)
setCell (row, 4, hh.date "")
setCell (row, 5, hh.type "")
}
}

delete (skHIST)
return row
}

void ParsTheModules (Module mCM, Date ddt, int modulesChoice) {
Item it
int ii = 0
int row = 1 // Row in XL that we start on!
int noOfModules
Module m

if (modulesChoice == 0) then { // Current module only
noOfModules = 1
}
elseif (modulesChoice == 1) then { // All open modules in project
string S_TYPE_1 = type (mCM)

noOfModules = 0
for m in current Project do {
if ((type (m)) == S_TYPE_1) then noOfModules++
}
}
elseif (modulesChoice == 2) then { // All similar modules in folder
string S_PATH_1 = path (mCM)
string S_VIEW_1 = currentView (mCM)
string S_TYPE_1 = type (mCM)

noOfModules = 0
for it in current Project do {
if (((type (it)) == S_TYPE_1) && (path(it) == S_PATH_1)) noOfModules++
}
}
elseif (modulesChoice == 3) then { // All similar modules in project
string S_VIEW_1 = currentView (mCM)
string S_TYPE_1 = type (mCM)

noOfModules = 0
for it in current Project do {
if ((type (it)) == S_TYPE_1) noOfModules++
}
}
else return

string modules[noOfModules]


if (modulesChoice == 0) then { // Current module only
modules[ii++] = name current Module
}
elseif (modulesChoice == 1) then { // All open modules in project
for m in current Project do {
if ((type (m)) == S_TYPE_1) then modules[ii++] = name (m)
}
}
elseif (modulesChoice == 2) then { // All similar modules in folder
for it in current Project do {
if (((type (it)) == S_TYPE_1) && (path(it) == S_PATH_1)) modules[ii++] = name it
}
}
elseif (modulesChoice == 3) then { // All similar modules in project
for it in current Project do {
if ((type (it)) == S_TYPE_1) modules[ii++] = name it
}
}

sort modules

if (!StartExcel) then {
print "Could not initiate Excel!\n"
return
}

realize progressBox
progressStart(progressBox, "Change Report Progress", "Checking ", noOfModules)
for (i = 0; i < noOfModules; i++) {
ii = i + 1
progressStep (ii)
progressMessage ("Processing module " ii " of " noOfModules "")
m = read (S_PATH_1 "/" modules, false) // Change to false if default view is OK
if (!null m) then {
current = m
row = ReportChanges (m, ddt, row)
if (mCM != m) close (m)
}
}
progressStop
destroy (progressBox)
}

DB load = create ("Export changes", styleCentered)
DBE sDate = text (load, "Changes after date:", "2003 nov 15", 20, 20, false)
string mods[] = {"Current module", "Open modules", "All modules in folder", "All similar modules in project"}
DBE modulesRadio = radioBox(load, "Which modules? ", mods, 0)

string sFileName
Date dd

void getSelection(DB splitBox) {
string sDD = get sDate
dd = sDD

ParsTheModules (current Module, dd, get modulesRadio)
destroy load
} // getSelection

apply (load, "Do it!", getSelection)
show (load)




-------------------------
Kristian Bøe
Extenda AB
Kristian.Boe@extenda.se
Report this to a Moderator Report this to a Moderator
 24-Nov-2004 21:02
User is offline View Users Profile Print this message


Tom Roman

Posts: 4
Joined: 16-Nov-2004

Thanks Kristian! I've gotten a very fundamental version of your code working. Little by little I plan on implementing the whole thing - it looks very powerful and useful.

Thanks again,
Tom
Report this to a Moderator Report this to a Moderator
 26-Nov-2004 03:28
User is offline View Users Profile Print this message


Tom Roman

Posts: 4
Joined: 16-Nov-2004

One last question to anyone who can help...

If I'm accessing history records with a loop of the form:

History hr;

for hr in current Module do {
    setCell(iRow, 1, hr.absNo"");
    setCell(iRow, 2, hr.author);
    setCell(iRow, 3, hr.date"");

Etc etc.....

where setCell is a function that exports to Excel, what syntax can I use within the loop to export object attributes (versus history records)?

For each history record I have the "absNo" of the object ... can I use that as some sort of index?


Tom

Report this to a Moderator Report this to a Moderator
 7-Apr-2005 16:08
User is offline View Users Profile Print this message


Jobina Johnson

Posts: 55
Joined: 12-Sep-2002

Hi Tom

could you post or send me the portion of Kristian's code that you have working. I've been trying to implement the code and can't get it to work.

Thanks
Jobina

jobina.l.johnson@boeing.com


-------------------------


jobina.l.johnson@boeing.com
Report this to a Moderator Report this to a Moderator
 15-Apr-2005 14:18
User is offline View Users Profile Print this message


Richard Good

Posts: 152
Joined: 22-Mar-2005

Hi Jobina,
I had the same problem, but it only involved a 10 minute fix, heres  Kirsten s code with my mods, it works (but not perfectly) for the current module option, didn't test it for the others.

-------------------------
Regards,

Richard Good
Report this to a Moderator Report this to a Moderator
 15-Apr-2005 19:56
User is offline View Users Profile Print this message


Jobina Johnson

Posts: 55
Joined: 12-Sep-2002

Thanks Richard

It seems to work fine on the others options. Exports all the changes into the same excel spreadsheet one module at a time

-------------------------


jobina.l.johnson@boeing.com
Report this to a Moderator Report this to a Moderator
 7-Sep-2005 23:50
User is offline View Users Profile Print this message


Andre Quillen

Posts: 13
Joined: 10-May-2005

Worked for me as well.  (DOORS 7.1)  Very robust and useful, thank you, all.

Andre Quillen
Raytheon
Report this to a Moderator Report this to a Moderator
 8-Feb-2008 20:01
User is offline View Users Profile Print this message


Ken McNair

Posts: 47
Joined: 12-Sep-2003

Richard,

I get an "array bounds exceeded" error at line 222.
Any idea what the problem might be?

Thanks,
Ken.
Report this to a Moderator Report this to a Moderator
Statistics
20925 users are registered to the Telelogic DOORS forum.
There are currently 1 users logged in.
The most users ever online was 15 on 15-Jan-2009 at 16:36.
There are currently 0 guests browsing this forum, which makes a total of 1 users using this forum.
You have posted 0 messages to this forum. 0 overall.

FuseTalk Standard Edition v3.2 - © 1999-2009 FuseTalk Inc. All rights reserved.