DXL Script to Export DOORS Object Information to Microsoft Word - Randomly Dropping Information - ibm-doors

I have a DXL script that is supposed to go through each object in the selected module and export various object information based on the object data to a Microsoft Word file. It generally works, but I am having a problem where at random points in the module the data doesn't get pasted into the Word document.
There are a few functions to perform the export of data, and they are called depending on the DOORS object:
put_heading_in_word( string s ) - puts heading number and heading text in a larger font
put_plain_text_in_word( string s ) - puts plain text in Word document
put_new_line_in_word() - puts a carriage return in Word
put_object_text_in_word( Object ob ) - copies the text from the passed in DOORS object to Word
Here are the functions:
/****************************************************************************************
* put_new_line_in_word
*****************************************************************************************/
void put_new_line_in_word()
{
clear oleAutoArgs
put(oleAutoArgs, 1) // 0=wdCollapseEnd, 1=wdCollapseStart
oleMethod(objSel, "Collapse", oleAutoArgs)
setRichClip(richText "\n" )
oleMethod(objSel, "Paste")
}//put_new_line_in_word
/****************************************************************************************
* put_plain_text_in_word
*****************************************************************************************/
void put_plain_text_in_word(string s)
{
clear oleAutoArgs
put(oleAutoArgs, 1) // 0=wdCollapseEnd, 1=wdCollapseStart
oleMethod(objSel, "Collapse", oleAutoArgs)
copyToClipboard( s )
oleGet(objSel, "Font", oleFont)
olePut(oleFont, "Size", 11)
oleMethod(objSel, "Paste")
}//put_plain_text_in_word
/****************************************************************************************
* put_heading_in_word
*****************************************************************************************/
void put_heading_in_word( string s )
{
clear oleAutoArgs
put(oleAutoArgs, 1) // 0=wdCollapseEnd, 1=wdCollapseStart
oleMethod(objSel, "Collapse", oleAutoArgs)
copyToClipboard( s )
oleGet(objSel, "Font", oleFont)
olePut(oleFont, "Size", 18)
oleMethod(objSel, "Paste")
}//put_heading_in_word
/****************************************************************************************
* put_object_text_in_word
*****************************************************************************************/
void put_object_text_in_word(Object ob)
{
clear oleAutoArgs
put(oleAutoArgs, 1) // 0=wdCollapseEnd, 1=wdCollapseStart
oleMethod(objSel, "Collapse", oleAutoArgs)
// setRichClip(richText richText(ob."Object Text"))
setRichClip(richText(ob."Object Text"))
oleMethod(objSel, "Paste")
}//put_object_text_in_word
Here is an example of how they are used:
/****************************************************************************************
* Export_object
* This is called for each object
*****************************************************************************************/
void Export_object (Module m, Object obj)
{
// allows the the use of attribute exists
current = m
if ( isValidObject(obj))
{
temp_str = obj."Object Heading"
if(!null temp_str)
{
put_plian_text_in_word("ID: ")
put_plian_text_in_word(identifier(obj))
put_new_line_in_word
temp_str = number(obj)
put_heading_in_word(temp_str)
put_heading_in_word(" ")
temp_str = obj."Object Heading"
put_heading_in_word(temp_str)
put_new_line_in_word
}
else
{
put_plian_text_in_word("ID: ")
put_plian_text_in_word(identifier(obj))
put_new_line_in_word
temp_str = obj."Requirement"
put_plian_text_in_word("Requirement: " temp_str)
put_new_line_in_word
temp_str = obj."Derived"
put_plian_text_in_word("Derived: " temp_str)
put_new_line_in_word
temp_str = obj."DO-178 Level"
put_plian_text_in_word("DO-178 Level: " temp_str)
put_new_line_in_word
temp_str = obj."Safety"
put_plian_text_in_word("Safety: " temp_str)
put_new_line_in_word
put_plian_text_in_word("Object Text: ")
put_new_line_in_word
put_object_text_in_word(obj)
if(oleCopy(obj))
{
oleMethod(objSel, "Paste")
put_new_line_in_word
}
temp_str = obj."Justify"
put_plian_text_in_word("Justify: " temp_str)
put_new_line_in_word
}
}
}
My initial thought was that there were too many accesses to the OLE interface and things were getting dropped, so I created functions that used Buffer variables where I put the individual strings into the buffer and stopped using the "put_new_line_in_word" function and just placed '\n' in the buffer. Now I just lose bigger chunks of data, and it didn't seem to reduce the frequency of losing data.
Any ideas?

As far as I know, this is an unresolved issue with DOORS and Windows 10. The usual way to export to a Word document is using the Windows clipboard. The memory management seems to have changed in Windows 10, which throws OLE-Errors / OLE problems. That's also, why the issue is not reproducible all of the time.
I have no actual solution for you. As a workaround, if you have the possibility to use Windows 7, I would suggest to use it, until IBM or Microsoft are fixing this issue, (in the IBM DOORS Release Notes, I have not seen a fix regarding this issue, until the current release 9.7.2.1).

Related

Is there a way to view the last modified date of the the Object Text in DOORS?

I'm new to using DOORS and am trying to create a column/attribute that has the date of the last modification to the Object Text. I found the below code which uses "Last Modified On", but that that includes all attributes and I'm only concerned about the Object Text. Maybe there's a way to specifiy an attribute for this?
Date dMod
dMod = obj."Last Modified On"
dMod = dateAndTime(dMod)
display dMod ""
There's no such attribute on an attribute.
The only way to determine this is via the object's history. Below is the example script from DXL manual. The idea is to loop through the object's history until the history record's typeis modifyObjectand it's attrName equals 'Object Text'. Keep in mind, though, that the history in a module only goes back to the last baseline. So, you may have to browse through all baselines to find the history record you need. See Tony's "Smart History Viewer" at http://www.smartdxl.com/content/?page_id=125 for details.
// history DXL Example
/*
Example history DXL program.
Generate a report of the current Module's
history.
*/
// print a brief report of the history record
void print(History h) {
HistoryType ht = h.type
print h.author "\t" h.date "\t" ht "\t"
if (ht == createType ||
ht == modifyType ||
ht == deleteType) { // attribute type
print h.typeName
} else if (ht == createAttr ||
ht == modifyAttr ||
ht == deleteAttr) {
// attribute definition
print h.attrName
} else if (ht == createObject ||
ht == clipCopyObject ||
ht == modifyObject) { // object
print h.absNo
if (ht==modifyObject) {
// means an attribute has changed
string oldV = h.oldValue
string newV = h.newValue
print " (" h.attrName ":" oldV " -> " newV ")"
}
}
print "\n"
}
// Main program
History h
print "All history\n\n"
for h in current Module do print h
print "\nHistory for current Object\n\n"
for h in current Object do print h
print "\nNon object history\n\n"
for h in top current Module do print h

DOORS Layout DXL is reporting each link twice

I'm using the Analysis Wizard to create a LayoutDXL column which should list attributes (e.g. AbsoluteNumber) for each existing In-link in my current module. In one particular DOORS module, the resulting DXL code displays each of these attributes twice. This doesn't happen in other modules.
I did notice that the offending module doesn't have a defined set of LinkModules (as seen in File/ModuleProperties). Could that be causing some sort of loopback?
Update:
I've discovered that somehow the DXL code "thinks" there are two versions of a defined LinkModule, i.e. "Current" and "Baseline X" . These each link to different baseline numbers in the target DOORS module. I don't know how to fix that.
For reference, here's the DXL code generated with the Wizard. This is DOORS 9.6.1.11
// DXL generated by DOORS traceability wizard on 12 February 2019.
// Wizard version 2.0, DOORS version 9.6.1.11
pragma runLim, 0
string limitModules[1] = {"[serial number redacted]"}
void showIn(Object o, int depth) {
Link l
LinkRef lr
ModName_ otherMod = null
Module linkMod = null
ModuleVersion otherVersion = null
Object othero
string disp = null
string s = null
string plain, plainDisp
int plainTextLen
int count
bool doneOne = false
string linkModName = "*"
for lr in all(o<-linkModName) do {
otherMod = module (sourceVersion lr)
if (!null otherMod) {
if ((!isDeleted otherMod) && (null data(sourceVersion lr))) {
if (!equal(getItem otherMod, (itemFromID limitModules[depth-1]))) continue
load((sourceVersion lr),false)
}
}
}
for l in all(o<-linkModName) do {
otherVersion = sourceVersion l
otherMod = module(otherVersion)
if (null otherMod || isDeleted otherMod) continue
if (!equal(getItem otherMod, (itemFromID limitModules[depth-1]))) continue
othero = source l
if (null othero) {
load(otherVersion,false)
}
othero = source l
if (null othero) continue
if (isDeleted othero) continue
doneOne = true
if (depth == 1) {
s = probeRichAttr_(othero,"Absolute Number", false)
if (s == "")
displayRich("\\pard " " ")
else
displayRich("\\pard " s)
s = probeRichAttr_(othero,"Object Heading", false)
if (s == "")
displayRich("\\pard " " ")
else
displayRich("\\pard " s)
}
}
}
showIn(obj,1)
I've seen the situation where objects DID have two links between them, this is possible with different link modules (Object 1 of Module A SATISFIES Object 2 of Module B and Object 1 of Module A REFINES Object 2 of Module B). While there may be reasons for such a situation, most often this is caused by a "link move" script that was not used correctly.
You should augment your code by displaying the name of the link module as well (variable linkModName). Perhaps this shows the reason for your observation

can't extract module's Version DXL IBM DOORS

I'm working on a DXL program in Doors which supposed to output to a csv file all of source module, target, linkset and version of each (source/target) modules. I've succeed to output "source module, target, linkset but I couldn't extract the version of modules. Does anyone know how to do it ?
Here is my code bellow:
The following uses an output file which is in C:\Temp, but you can easily change that.
it works by matching modules using a grep string, again which you can change to suit.
I have different module types, and therefore I can just get the results on the prefix 'STR' in this case. I decided to have multiple scripts for different prefix modules, rather than dynamically pass the STR keyword.
You need to enter your folder and subfolders for the "modPathname"
then adjust the Regexp "GrepString" to suit your naming convention
alternatively you can bypass all this by hardcoding the values.
string filename = "C:\\TEMP\\STR_Baseline_Info.txt"
Stream outFile = write filename
string Modtype = "STR"
void PrintAndOutput ( string s)
{
// print (s) // Enable if you want output
outFile << s
}
void DisplayResults( string Modtype )
{
Item modItem
Module mName
Regexp GrepString = regexp2 "^" Modtype "-[0-8][0-9][0-9]"
Folder modPathname = folder "/EnterYourFolderHere/AnySubFolders/" Modtype ""
string fullModuleName , CommentStr , moduleName
Baseline b
PrintAndOutput "------------------------------------------------------------------------------\n"
CommentStr = "This File is automatically produced via the " Modtype " Baseline Info.dxl script. \n" Modtype " Versions as of : " dateAndTime(today) "\n"
PrintAndOutput CommentStr
PrintAndOutput "-------------------------------------------------------------------------------\n\n"
for modItem in modPathname do
{
if (type (modItem ) == "Formal")
{
moduleName = (name modItem)
if (GrepString moduleName)
{
fullModuleName = (fullName(modItem))
mName = read(fullName modItem , false)
b= getMostRecentBaseline (mName)
if (b != null )
{
PrintAndOutput moduleName " -\tBaseline : "(major b)"."(minor b)(suffix b) " \t " (dateOf b) "\n"
}
else
{
PrintAndOutput moduleName " \t### No Baseline Information ### \t" " \n"
}
}
}
}
}
DisplayResults ( Modtype)

Iterating multiple reasoned literals from the same property

The title may be a bit confusing but basically this is the problem: I am using Jena and a Pellet reasoner to produce property literals from a resource called Patient_Doug. The triple looks like this:
Patient_Doug-> hasSuggestion-> Literal inferred suggestion.
The problem is that the Protege Pellet reasoner comes up with three suggestions for Doug, because Doug is in a pretty bad way in hospital. The Protege reasoner suggests that Doug needs a Hi-Lo bed, an RF ID band and a bed closer to the nurse's station. Unfortunatly, in Jena, I can only get Hi-lo bed to print. Only one of 3 literals.
Here is some of the code.
OntModel model = ModelFactory.createOntologyModel( PelletReasonerFactory.THE_SPEC );
String ns = "http://altervista.org/owl/unit.owl#";
String inputFile = "c:\\jena\\acuity.owl";
InputStream in = FileManager.get().open(inputFile);
if (in == null) {
throw new IllegalArgumentException("File: " + inputFile + " not found");
}
model.read(in,"");
model.prepare();
//inf and reasoner wont run unless i use hp libraries!
//asserted data properties
Individual ind = model.getIndividual(ns+"Patient_Doug");
OntProperty abcValue = model.getOntProperty("http://example.org/hasABCValue");
//inferred data properties
OntProperty suggestion = model.getOntProperty(ns+"hasSuggestion");
//print asserted data properties
System.out.println("Properties for patient "+ind.getLocalName().toString());
System.out.println( abcValue.getLocalName()+"= "+ind.getPropertyValue(abcValue).asLiteral().getInt());
//print inferenced data properties
StmtIterator it = ind.listProperties(suggestion);
//this iterator only prints one suggestion in an infinite loop
while (it.hasNext()) {
System.out.println("A posible suggestion= "+ind.getPropertyValue(suggestion).asLiteral().getString());
}
}
The code works fine but the iterator at the end only prints only one subggestion in an infinite loop.
I would be grateful for any suggestions.
Thanks.
This code works to iterate and print the many inferred hasSuggestions. The hasSuggestion SWRL rules are in the OWL ontology
OntModel model = ModelFactory.createOntologyModel( PelletReasonerFactory.THE_SPEC );
String ns = "http://altervista.org/owl/unit.owl#";
String inputFile = "c:\\jena\\acuity.owl";
InputStream in = FileManager.get().open(inputFile);
if (in == null) {
throw new IllegalArgumentException("File: " + inputFile + " not found");
}
model.read(in,"");
model.prepare();
//inf and reasoner wont run unless i use hp libraries!
//asserted data properties
Individual ind = model.getIndividual(ns+"Patient_Doug");
OntProperty abcValue = model.getOntProperty("http://example.org/hasABCValue");
//inferred data properties
OntProperty suggestion = model.getOntProperty(ns+"hasSuggestion");
//print asserted data properties
System.out.println("Properties for patient "+ind.getLocalName().toString());
System.out.println( abcValue.getLocalName()+"= "+ind.getPropertyValue(abcValue).asLiteral().getInt());
for (StmtIterator j = ind.listProperties(suggestion); j.hasNext(); ) {
Statement s = j.next();
//System.out.println( " " + s.getPredicate().getLocalName() + " -> " );
System.out.println( "A possible suggestion... " + s.getLiteral().getLexicalForm());
}

Checking variables exist before building an array

I am generating a string from a number of components (title, authors, journal, year, journal volume, journal pages). The idea is that the string will be a citation as so:
#citation = article_title + " " + authors + ". " + journal + " " + year + ";" + journal_volume + ":" + journal_pages
I am guessing that some components occasionally do not exist. I am getting this error:
no implicit conversion of nil into String
Is this indicating that it is trying to build the string and one of the components is nil? If so, is there a neat way to build a string from an array while checking that each element exists to circumvent this issue?
It's easier to use interpolation
#citation = "#{article_title} #{authors}. #{journal} #{year}; #{journal_volume}:#{journal_pages}"
Nils will be substituted as empty strings
array = [
article_title, authors ,journal,
year, journal_volume, journal_pages
]
#citation = "%s %s. %s %s; %s:%s" % array
Use String#% format string method.
Demo
>> "%s: %s" % [ 'fo', nil ]
=> "fo: "
Considering that you presumably are doing this for more than one article, you might consider doing it like so:
SEPARATORS = [" ", ". ", " ", ";", ":", ""]
article = ["Ruby for Fun and Profit", "Matz", "Cool Tools for Coders",
2004, 417, nil]
article.map(&:to_s).zip(SEPARATORS).map(&:join).join
# => "Ruby for Fun and Profit Matz. Cool Tools for Coders 2004;417:"

Resources