Link module not found Error

Hello all,

 

May I please seek some work around solution for the "Link module NOT found" error please.  This is in reference to this error that has been resolved by IBM as shown at the following IBM's web page:

http://www-01.ibm.com/support/docview.wss?uid=swg1PM76619

 

IBM's Website gave the following reason and solution for the "Link module NOT found" error, please:


We have created an attribute DXL column for the traceability
using a Layout DXL column generated by the Analysis Wizard.
We sent the project's archive file (.dpa) to our customer.
Then, customer restored the .dpa in their database
and when the customer opened the module, they get '??Link module not found??'.

 

Following is the reason for the above link module error and solution by IBM's web page:

 

The basic problem is that the generated attribute DXL code
refers to the link module by it's unique internal ID.
However, once you import the project into a new database,
all of the IDs are changed, so this code can never find the
link module.

 

According to above web page of IBM,

This problem was fixed in DOORS 9.5.0.1.

We have DOORS 9.5.2.0 version.

However, our customer has DOORS 9.3 version.

Our customer, due to other technical reason's can not upgrade, their DOORS to latest version.

 

One work around to this problem, is for our customer to manually recreate the layout DXL columns and covert to attribute columns.

This is a very tedious and time consuming task since there are many modules and many attribute DXL columns in each module.

 

Is there any other relatively easy solution for the customer to see our attribute DXL columns, without customer's upgrading to the latest DOORS version please?

Thanks and best regards,

Mike

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


MikeMelon - Sun Jun 28 21:37:48 EDT 2015

Re: Link module not found Error
MikeMelon - Sun Jun 28 21:47:27 EDT 2015

Or is there any tasks we can do the to the formal modules or our link modules  or the attribute DXL columns, prior to archiving the project so that our customer cans see our attribute DXL columns without upgrading to the latest DOORS version please?

 

Best regards,

Mike

Re: Link module not found Error
woodpryan - Mon Jun 29 12:55:38 EDT 2015

So, the deal is that the LayoutDXL in your Views (and in any DXL Attributes) that you have uses the function itemFromId. This function retrieves an Item (in this case a Link Module) as the DXL type Item using the id that is passed to the function. Problem is, when you archive those Projects and give them to your customer, who is on another database, the IDs do not remain the same. So, although the names and paths of the Link Modules doesn't change, they cannot get the Link Modules in the Views.

The solution is to change every instance of the function itemFromId in your layoutDXL to be the function item(fullName) instead. The only problem with this solution is that when names or paths of Link Modules change, the code will need to be updated. You might want to write yourself a program for changing Module Names that goes through all the other Modules LayoutDXL and DXL Attributes to find references to the Module to change.

Anyway, as for the itemFromId problem, I wrote a program that will actually change the function from the itemFromId function to the item function. The limitation here is that if your Layout DXL uses arrays of IDs instead of flat IDs. This happens if you select "all open Modules" while specifying the source/target Modules in the Wizard.

 

#include <standard/miniExplorer/inc/miniExplorer.inc>

//#include </DXL/include/DXLCommon.dxl>

Module  curMod     = null;
Project curProj    = null;
Folder  curFold    = null;
AttrDef ad         = null;
string  sLayoutDXL = null;
bool    bModified  = false;

void logError(string err)
{
    print("Error: " err "\n");
}

void logMessage(string msg)
{
    print(msg "\n");
}

/*  Function:   getLayoutDXL(Column)
    Purpose:    gets Layout DXL out of the specified column if
                there is Layout DXL present
    Parameters: the column
    Return:     the LayoutDXL as a string
*/
string getLayoutDXL(Column col)
{
    string s = null;
    
    if(null != col)
        s = dxl(col);
    
    return s;
}

/*  Function:   getLayoutDXL(AttrDef)
    Purpose:    retrieves the LayoutDXL of an Attribute Definition
                if the Attribute is a DXL Attribute.
    Parameters: the Definition of the Attribute
    Return:     the LayoutDXL as a string
*/
string getLayoutDXL(AttrDef at)
{
    string s = null;
    
    if(null != at)
        s = at.dxl;
    
    return s;
}

/*  Function:   findAndReplaceItemId()
    Purpose:    searches for unique Identifiers in the global sLayoutDXL
                string, and replaces the Ids with the full names of the Items
                to which the Ids correspond. Also finds calls to function
                itemFromID and replaces them with calls to function item.
    Return:     Returns any error that is returned by function checkDXL
*/
string findAndReplaceItemId()
{
    string itemId     = null;
    string iFullName  = null;
    string strError   = null;
    int    lastOffset = 0;
    int    offset     = 0;
    int    len        = 0;
    Item   i;
    
    if(null == sLayoutDXL)
        return strError;
        
    /*There are three possible ways the itemFromID function may be generated by DOORS in Layout DXL*/
    
    //The first is with an open parenthasis after the function call, followed by a string
    while(findPlainText(sLayoutDXL, "itemFromID(\"", offset, len, false, false))
    {
        if(offset <= lastOffset)
            break;

        lastOffset = offset;
        logMessage("Original sLayoutDXL = " sLayoutDXL "\n");
        itemId = sLayoutDXL[(offset+len):length(sLayoutDXL)];
        
        //what we need is between the quotes
        if(findPlainText(itemId, "\"", offset, len, false, false))
        {
            itemId = itemId[0:offset-1];
            logMessage("itemId = " itemId "\n");
        }
        i = itemFromID(itemId);
        if(null == i)
        {
            logError("Could not get an item from ID " itemId);
            continue;
        }
        
        iFullName = fullName(i);
        if(null == iFullName)
            continue;
        logMessage("Full name of Item = " iFullName);
        if(findPlainText(sLayoutDXL, "itemFromID(\"" itemId "\")", offset, len, false, false))
        {
            sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, "item(\"" iFullName "\")");
            bModified = true;
        }
    }
    lastOffset = 0;
    
    //The second is with a space followed by a string
    while(findPlainText(sLayoutDXL, "itemFromID \"", offset, len, false, false))
    {
        if(offset <= lastOffset)
            break;
        lastOffset = offset;
        
        logMessage("sLayoutDXL = " sLayoutDXL "\n");
        itemId = sLayoutDXL[(offset+len):length(sLayoutDXL)];
        
        //what we need is between the quotes
        if(findPlainText(itemId, "\"", offset, len, false, false))
        {
            itemId = itemId[0:offset-1];
            logMessage("itemId = " itemId "\n");
        }
        i = itemFromID(itemId);
        if(null == i)
        {
            logError("Could not get an item from ID " itemId);
            continue;
        }
            
        iFullName = fullName(i);
        if(null == iFullName)
            continue;
        if(findPlainText(sLayoutDXL, "itemFromID( \"" itemId "\")", offset, len, false, false))
        {
            sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, "item(\"" iFullName "\")");
            bModified = true;
        }
    }
    lastOffset = 0;
    
    //The third is with a space followed by the name of an array
    //The array is expected to be of size 1. recursive LayoutDXL not currently supported
    while(findPlainText(sLayoutDXL, "{\"", offset, len, false, false))
    {
        if(offset <= lastOffset)
            break;
        itemId = sLayoutDXL[(offset+len):length(sLayoutDXL)];
        lastOffset = offset;
        
        if(findPlainText(itemId, "\"}", offset, len, false, false))
        {
            itemId = itemId[0:offset-1];
            if(null == itemId)
                continue;
                
            i = itemFromID(itemId);
            if(null == i)
                continue;
            iFullName = fullName(i);
                
            if(findPlainText(sLayoutDXL, itemId, offset, len, false, false))
            {
                sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, iFullName);
                bModified = true;
            }
        }
    }
    //now that we replaced the Id with the full name, replace the function call that passes the array
    while(findPlainText(sLayoutDXL, "itemFromID", offset, len, false, false))
        sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, "item");
    
    strError = checkDXL(sLayoutDXL);//Make sure the DXL is without errors
    if(null == strError && bModified)
        logMessage("New sLayoutDXL = " sLayoutDXL "\n");
    
    return strError;
}

/*  Function:   findAndReplaceItemId(Column&)
    Purpose:    Calls function findAndReplaceItemId() and puts the modified
                LayoutDXL in the specified column if the function does not
                return an error.
    Parameters: a reference to the column
*/
void findAndReplaceItemId(Column &col)
{
    string strError = null;
    
    strError = findAndReplaceItemId();
    
    if(null == strError)
    {
        if(bModified)
            dxl(col, sLayoutDXL);
        else
            logMessage("Did not modify the Layout DXL of the column.");
        return;
    }
    logError("Could not replace DXL in column " title(col) " because the code included the following error: \n" strError);
}

/*  Function:   findAndReplaceItemId(AttrDef&)
    Purpose:    calls function findAndReplaceItemId() and replaces the Attribute
                Definition's LayoutDXL with the modified sLayoutDXL string if
                findAndReplaceItemId does not return an error.
    Parameters: a reference to the definition of the Attribute
*/
void findAndReplaceItemId(AttrDef &ad)
{
    string strError = null;
    
    bModified = false;
    strError = findAndReplaceItemId();
    if(null == strError)
    {
        if(bModified)
        {
            if(canModify(curMod, ad.name))
                ad = modify(ad, setDXL, sLayoutDXL);
            else
                logError("Could not modify Attribute " ad.name " because access is denied.");
        }
            
        return;
    }
    logError("Could not set DXL for Attribute " ad.name "because the DXL contained the following error:\n" strError);

}

/*  Function:   searchModuleForLayoutDXL()
    Purpose:    searches the global curMod variable for columns in Views
                that are built on LayoutDXL code. Searches for Attribute
                Definitions that are DXL Attributes. Calls appropriate
                findAndReplaceItemId functions when it finds LayoutDXL.
*/
void searchModuleForLayoutDXL()
{
    View     vView     = null;
    string   sViewName = null;
    string   sError    = null;
    Column   col       = null;
    ModName_ modName   = null;
    
    for sViewName in views(curMod) do
    {
        vView = view(sViewName);
        load(curMod, vView);
        logMessage("Loaded view " sViewName);
        for col in curMod do
        {
            bModified = false;
            sLayoutDXL = getLayoutDXL(col);
            if(null != sLayoutDXL)
            {
                if(!isEdit(curMod))
                {
                        logError("Module is not open for edit. Internal error.");
                        return;
                }
                findAndReplaceItemId(col);
                if(bModified)
                {
                    modName = module(curMod);
                    noError();
                    if(canModify(modName, vView))
                        save(vView);
                    else
                        logError("Could not modifiy view named " sViewName " because access was denied.");
                    sError = lastError();
                    if(null != sError)
                        logError("Could not save the view because of the following error:\n" sError);
                }
            }
        }
    }
    for ad in curMod do
    {
        sLayoutDXL = getLayoutDXL(ad);
        if(null != sLayoutDXL)
        {
            if(!isEdit(curMod))
            {
                logError("Internal error. Module is not open for edit.\n");
                return;
            }
            findAndReplaceItemId(ad);
        }
    }
    
    if(unsaved(curMod))
        save(curMod);
        
    close(curMod);
}

/*  Function:   searchFolderForLayoutDXL()
    Purpose:    Searches the global curFold variable for
                Items. If the Item is a Formal Module, it opens it,
                sets global var curMod to it, and calls searchModuleForLayoutDXL.
                If the Item is a folder, function recursively calls itself until
                it has drilled down to each of the lowest level Folders and 
                searched them for Modules.
*/
void searchFolderForLayoutDXL()
{
    Item   i;
    Folder fold = curFold;
    
    for i in fold do
    {
        if(type(i) == "Formal")
        {
            curMod = edit(fullName(i), true);
            searchModuleForLayoutDXL();
        }
        else if(type(i) == "Folder")
        {
            /*The for Item in Folder loop only returns items within the single Folder.
              It doesn't drill down into the sub-folders. So, if we come accross another
              Folder, we need to recursively call this function until we have gotten every
              Item inside of this Folder.*/
            curFold = folder(i);
            searchFolderForLayoutDXL();
        }
    }
}

/*  Function:   searchModulesForLayoutDXL()
    Purpsoe:    searches the global curProj variable for Formal
                Modules and calls searchModuleForLayoutDXL on each
                of them.
*/
void searchModulesForLayoutDXL()
{
    Item   i;
    
    if(null == curProj)
    {
        logError("Could not loop through a null Project.");
        return;
    }
    for i in curProj do
    {
        if(type(i) != "Formal")
            continue;
        curMod = edit(fullName(i), true);
        searchModuleForLayoutDXL();
    }
}

int Main()
{
    Item   i;
    User   u            = null;
    string searchLevel  = null;
    string userType     = null;
    string selectedItem = null;
    
    //Check for proper access rights
    u = find();
    UserClass uClass = u.class;
    userType = stringOf(uClass);
    if(userType != "Administrator")
    {
        ack("Only the Database Administrator may execute this program.");
        return -1;
    }
    
    //get the item on which the user wishes to execute the program
    selectedItem = fnMiniExplorer(null, folder "/", MINI_EXP_FORMAL_MODS, "Browse", "DOORS Database");
    
    i = item(selectedItem);
    if(null == i)
        return -1;
        
    searchLevel = type(i);
        
    //can't run this on the full database. It would take too long
    if(name(i) == "Root Folder")
    {
        ack("This program may not be executed on the full database.");
        return -1;
    }
    if(searchLevel == "Folder")
    {
        curFold = folder(i);
        searchFolderForLayoutDXL()
    }
    else if(searchLevel == "Project")
    {
        curProj = project(i);
        searchModulesForLayoutDXL()
    }
    else if(searchLevel == "Formal")
    {
        curMod = edit(fullName(i), true);
        searchModuleForLayoutDXL();
    }
    
    return 0;
}

Main();

 

Re: Link module not found Error
MikeMelon - Mon Jun 29 22:22:32 EDT 2015

woodpryan - Mon Jun 29 12:55:38 EDT 2015

So, the deal is that the LayoutDXL in your Views (and in any DXL Attributes) that you have uses the function itemFromId. This function retrieves an Item (in this case a Link Module) as the DXL type Item using the id that is passed to the function. Problem is, when you archive those Projects and give them to your customer, who is on another database, the IDs do not remain the same. So, although the names and paths of the Link Modules doesn't change, they cannot get the Link Modules in the Views.

The solution is to change every instance of the function itemFromId in your layoutDXL to be the function item(fullName) instead. The only problem with this solution is that when names or paths of Link Modules change, the code will need to be updated. You might want to write yourself a program for changing Module Names that goes through all the other Modules LayoutDXL and DXL Attributes to find references to the Module to change.

Anyway, as for the itemFromId problem, I wrote a program that will actually change the function from the itemFromId function to the item function. The limitation here is that if your Layout DXL uses arrays of IDs instead of flat IDs. This happens if you select "all open Modules" while specifying the source/target Modules in the Wizard.

 

#include <standard/miniExplorer/inc/miniExplorer.inc>

//#include </DXL/include/DXLCommon.dxl>

Module  curMod     = null;
Project curProj    = null;
Folder  curFold    = null;
AttrDef ad         = null;
string  sLayoutDXL = null;
bool    bModified  = false;

void logError(string err)
{
    print("Error: " err "\n");
}

void logMessage(string msg)
{
    print(msg "\n");
}

/*  Function:   getLayoutDXL(Column)
    Purpose:    gets Layout DXL out of the specified column if
                there is Layout DXL present
    Parameters: the column
    Return:     the LayoutDXL as a string
*/
string getLayoutDXL(Column col)
{
    string s = null;
    
    if(null != col)
        s = dxl(col);
    
    return s;
}

/*  Function:   getLayoutDXL(AttrDef)
    Purpose:    retrieves the LayoutDXL of an Attribute Definition
                if the Attribute is a DXL Attribute.
    Parameters: the Definition of the Attribute
    Return:     the LayoutDXL as a string
*/
string getLayoutDXL(AttrDef at)
{
    string s = null;
    
    if(null != at)
        s = at.dxl;
    
    return s;
}

/*  Function:   findAndReplaceItemId()
    Purpose:    searches for unique Identifiers in the global sLayoutDXL
                string, and replaces the Ids with the full names of the Items
                to which the Ids correspond. Also finds calls to function
                itemFromID and replaces them with calls to function item.
    Return:     Returns any error that is returned by function checkDXL
*/
string findAndReplaceItemId()
{
    string itemId     = null;
    string iFullName  = null;
    string strError   = null;
    int    lastOffset = 0;
    int    offset     = 0;
    int    len        = 0;
    Item   i;
    
    if(null == sLayoutDXL)
        return strError;
        
    /*There are three possible ways the itemFromID function may be generated by DOORS in Layout DXL*/
    
    //The first is with an open parenthasis after the function call, followed by a string
    while(findPlainText(sLayoutDXL, "itemFromID(\"", offset, len, false, false))
    {
        if(offset <= lastOffset)
            break;

        lastOffset = offset;
        logMessage("Original sLayoutDXL = " sLayoutDXL "\n");
        itemId = sLayoutDXL[(offset+len):length(sLayoutDXL)];
        
        //what we need is between the quotes
        if(findPlainText(itemId, "\"", offset, len, false, false))
        {
            itemId = itemId[0:offset-1];
            logMessage("itemId = " itemId "\n");
        }
        i = itemFromID(itemId);
        if(null == i)
        {
            logError("Could not get an item from ID " itemId);
            continue;
        }
        
        iFullName = fullName(i);
        if(null == iFullName)
            continue;
        logMessage("Full name of Item = " iFullName);
        if(findPlainText(sLayoutDXL, "itemFromID(\"" itemId "\")", offset, len, false, false))
        {
            sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, "item(\"" iFullName "\")");
            bModified = true;
        }
    }
    lastOffset = 0;
    
    //The second is with a space followed by a string
    while(findPlainText(sLayoutDXL, "itemFromID \"", offset, len, false, false))
    {
        if(offset <= lastOffset)
            break;
        lastOffset = offset;
        
        logMessage("sLayoutDXL = " sLayoutDXL "\n");
        itemId = sLayoutDXL[(offset+len):length(sLayoutDXL)];
        
        //what we need is between the quotes
        if(findPlainText(itemId, "\"", offset, len, false, false))
        {
            itemId = itemId[0:offset-1];
            logMessage("itemId = " itemId "\n");
        }
        i = itemFromID(itemId);
        if(null == i)
        {
            logError("Could not get an item from ID " itemId);
            continue;
        }
            
        iFullName = fullName(i);
        if(null == iFullName)
            continue;
        if(findPlainText(sLayoutDXL, "itemFromID( \"" itemId "\")", offset, len, false, false))
        {
            sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, "item(\"" iFullName "\")");
            bModified = true;
        }
    }
    lastOffset = 0;
    
    //The third is with a space followed by the name of an array
    //The array is expected to be of size 1. recursive LayoutDXL not currently supported
    while(findPlainText(sLayoutDXL, "{\"", offset, len, false, false))
    {
        if(offset <= lastOffset)
            break;
        itemId = sLayoutDXL[(offset+len):length(sLayoutDXL)];
        lastOffset = offset;
        
        if(findPlainText(itemId, "\"}", offset, len, false, false))
        {
            itemId = itemId[0:offset-1];
            if(null == itemId)
                continue;
                
            i = itemFromID(itemId);
            if(null == i)
                continue;
            iFullName = fullName(i);
                
            if(findPlainText(sLayoutDXL, itemId, offset, len, false, false))
            {
                sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, iFullName);
                bModified = true;
            }
        }
    }
    //now that we replaced the Id with the full name, replace the function call that passes the array
    while(findPlainText(sLayoutDXL, "itemFromID", offset, len, false, false))
        sLayoutDXL = replaceRichText(sLayoutDXL, offset, len, "item");
    
    strError = checkDXL(sLayoutDXL);//Make sure the DXL is without errors
    if(null == strError && bModified)
        logMessage("New sLayoutDXL = " sLayoutDXL "\n");
    
    return strError;
}

/*  Function:   findAndReplaceItemId(Column&)
    Purpose:    Calls function findAndReplaceItemId() and puts the modified
                LayoutDXL in the specified column if the function does not
                return an error.
    Parameters: a reference to the column
*/
void findAndReplaceItemId(Column &col)
{
    string strError = null;
    
    strError = findAndReplaceItemId();
    
    if(null == strError)
    {
        if(bModified)
            dxl(col, sLayoutDXL);
        else
            logMessage("Did not modify the Layout DXL of the column.");
        return;
    }
    logError("Could not replace DXL in column " title(col) " because the code included the following error: \n" strError);
}

/*  Function:   findAndReplaceItemId(AttrDef&)
    Purpose:    calls function findAndReplaceItemId() and replaces the Attribute
                Definition's LayoutDXL with the modified sLayoutDXL string if
                findAndReplaceItemId does not return an error.
    Parameters: a reference to the definition of the Attribute
*/
void findAndReplaceItemId(AttrDef &ad)
{
    string strError = null;
    
    bModified = false;
    strError = findAndReplaceItemId();
    if(null == strError)
    {
        if(bModified)
        {
            if(canModify(curMod, ad.name))
                ad = modify(ad, setDXL, sLayoutDXL);
            else
                logError("Could not modify Attribute " ad.name " because access is denied.");
        }
            
        return;
    }
    logError("Could not set DXL for Attribute " ad.name "because the DXL contained the following error:\n" strError);

}

/*  Function:   searchModuleForLayoutDXL()
    Purpose:    searches the global curMod variable for columns in Views
                that are built on LayoutDXL code. Searches for Attribute
                Definitions that are DXL Attributes. Calls appropriate
                findAndReplaceItemId functions when it finds LayoutDXL.
*/
void searchModuleForLayoutDXL()
{
    View     vView     = null;
    string   sViewName = null;
    string   sError    = null;
    Column   col       = null;
    ModName_ modName   = null;
    
    for sViewName in views(curMod) do
    {
        vView = view(sViewName);
        load(curMod, vView);
        logMessage("Loaded view " sViewName);
        for col in curMod do
        {
            bModified = false;
            sLayoutDXL = getLayoutDXL(col);
            if(null != sLayoutDXL)
            {
                if(!isEdit(curMod))
                {
                        logError("Module is not open for edit. Internal error.");
                        return;
                }
                findAndReplaceItemId(col);
                if(bModified)
                {
                    modName = module(curMod);
                    noError();
                    if(canModify(modName, vView))
                        save(vView);
                    else
                        logError("Could not modifiy view named " sViewName " because access was denied.");
                    sError = lastError();
                    if(null != sError)
                        logError("Could not save the view because of the following error:\n" sError);
                }
            }
        }
    }
    for ad in curMod do
    {
        sLayoutDXL = getLayoutDXL(ad);
        if(null != sLayoutDXL)
        {
            if(!isEdit(curMod))
            {
                logError("Internal error. Module is not open for edit.\n");
                return;
            }
            findAndReplaceItemId(ad);
        }
    }
    
    if(unsaved(curMod))
        save(curMod);
        
    close(curMod);
}

/*  Function:   searchFolderForLayoutDXL()
    Purpose:    Searches the global curFold variable for
                Items. If the Item is a Formal Module, it opens it,
                sets global var curMod to it, and calls searchModuleForLayoutDXL.
                If the Item is a folder, function recursively calls itself until
                it has drilled down to each of the lowest level Folders and 
                searched them for Modules.
*/
void searchFolderForLayoutDXL()
{
    Item   i;
    Folder fold = curFold;
    
    for i in fold do
    {
        if(type(i) == "Formal")
        {
            curMod = edit(fullName(i), true);
            searchModuleForLayoutDXL();
        }
        else if(type(i) == "Folder")
        {
            /*The for Item in Folder loop only returns items within the single Folder.
              It doesn't drill down into the sub-folders. So, if we come accross another
              Folder, we need to recursively call this function until we have gotten every
              Item inside of this Folder.*/
            curFold = folder(i);
            searchFolderForLayoutDXL();
        }
    }
}

/*  Function:   searchModulesForLayoutDXL()
    Purpsoe:    searches the global curProj variable for Formal
                Modules and calls searchModuleForLayoutDXL on each
                of them.
*/
void searchModulesForLayoutDXL()
{
    Item   i;
    
    if(null == curProj)
    {
        logError("Could not loop through a null Project.");
        return;
    }
    for i in curProj do
    {
        if(type(i) != "Formal")
            continue;
        curMod = edit(fullName(i), true);
        searchModuleForLayoutDXL();
    }
}

int Main()
{
    Item   i;
    User   u            = null;
    string searchLevel  = null;
    string userType     = null;
    string selectedItem = null;
    
    //Check for proper access rights
    u = find();
    UserClass uClass = u.class;
    userType = stringOf(uClass);
    if(userType != "Administrator")
    {
        ack("Only the Database Administrator may execute this program.");
        return -1;
    }
    
    //get the item on which the user wishes to execute the program
    selectedItem = fnMiniExplorer(null, folder "/", MINI_EXP_FORMAL_MODS, "Browse", "DOORS Database");
    
    i = item(selectedItem);
    if(null == i)
        return -1;
        
    searchLevel = type(i);
        
    //can't run this on the full database. It would take too long
    if(name(i) == "Root Folder")
    {
        ack("This program may not be executed on the full database.");
        return -1;
    }
    if(searchLevel == "Folder")
    {
        curFold = folder(i);
        searchFolderForLayoutDXL()
    }
    else if(searchLevel == "Project")
    {
        curProj = project(i);
        searchModulesForLayoutDXL()
    }
    else if(searchLevel == "Formal")
    {
        curMod = edit(fullName(i), true);
        searchModuleForLayoutDXL();
    }
    
    return 0;
}

Main();

 

Hi Ryan,

Thanks so much for your fast reply. I will test this program by creating simple DOORS project. Can you please clarify couple features of this DXL program?

Your program runs only if the user is a DOORS administrator.  I am running the DOORS client on my computer as a Database Manager access rights. However, I do not have Administrator login credentials.

If I absolutely needed, I may be able to get DOORS Administrator password from our IT dept.

 

Is it safe to run this DXL program by commenting out the if statement that checks for DOORS administrator please?

 

Best regards,

Mike

 

 

Re: Link module not found Error
Wolfgang Uhr - Tue Jun 30 04:37:12 EDT 2015

MikeMelon - Sun Jun 28 21:47:27 EDT 2015

Or is there any tasks we can do the to the formal modules or our link modules  or the attribute DXL columns, prior to archiving the project so that our customer cans see our attribute DXL columns without upgrading to the latest DOORS version please?

 

Best regards,

Mike

Hi

I think the following code will solve the problem:

 

string sLinkModuleID_Home = "12345678";

string sLinkModuleID_Customer = "01234567";

Item itmWork = itemFromID(sLinkModuleID_Home);

If (itmWork == null) {

    itmWork = itemFromID(sLinkModuleID_Customer);

} else {

  sFullName = fullName(itmWork );

  if (sFullName == ""\My\Well\Known\Module\Name") {

    itmWork = itemFromID(sLinkModuleID_Customer);

  }

}

 

This code snippet shall run on both sides correct and itmWork will point to the link module.

Best regards

Wolfgang

Re: Link module not found Error
woodpryan - Tue Jun 30 12:00:21 EDT 2015

MikeMelon - Mon Jun 29 22:22:32 EDT 2015

Hi Ryan,

Thanks so much for your fast reply. I will test this program by creating simple DOORS project. Can you please clarify couple features of this DXL program?

Your program runs only if the user is a DOORS administrator.  I am running the DOORS client on my computer as a Database Manager access rights. However, I do not have Administrator login credentials.

If I absolutely needed, I may be able to get DOORS Administrator password from our IT dept.

 

Is it safe to run this DXL program by commenting out the if statement that checks for DOORS administrator please?

 

Best regards,

Mike

 

 

You can comment that out, yes. I did that for a couple reasons. 1. protection of the Database from Joe User. 2. Administrator can see ALL Views, including User's Views with the privacy set to 'private' or 'protected.' Other users can't see all of the Views. Anyway, I hope it works out for you.