IBM Doors DXL: Object Trigger fires on Object enter and block fields / prevent fields from being edited / Objekt Trigger verhindert Editieren von Attributen vor Texteingabe

Problem

Depending on a selected value of a field, other fields should be editable / not be editable.

In this case the requirements are:

  • The object shall be editable, when no other Attribute with the description „Variant Status“ has the text (or the selection in case of enum) „Proposal“
  • The object shall be not ediablte, when one of Attribute with the description „Variant Status“ is set to „Proposal“
  • Exception: The field, that contains a set „Proposal“ Value, shall be editable in each case, otherwise it would not be possible to leave that state

Approach – Ansatz

The following codes installs an Object-Trigger (not attribute), that is fired every time a user double-clicks our is entering an object, but only when the module is in edit mode;

Solution – Lösung

string DXLCode = "
Trigger    trg = current;           
if (null trg) halt(); 
AttrDef ad  = attrdef(trg); 
if (null ad) halt();  // Error?
Object  obj = object(trg);  
if (null obj) halt();  // Error?
string  Name = ad.name;   

Module mod      = module(trg);
if(!isEdit(mod)) halt();

Object oCurr    = current(mod);	
string thisFieldShouldBeEditable = \"n/a\";
bool hasProposal = false;
int i=0;
for ad in mod do
{
  if(ad.object)
  {
    if(ad.description \"\" == \"Variant Status\")
    {
      string BB_Variant_name=ad.name;
      if(obj.BB_Variant_name \"\" == \"Proposal\")
      {
        hasProposal=true;
        thisFieldShouldBeEditable=BB_Variant_name;
      }
    }
  }
}

bool thisIsTheProposalField=false;
if(Name==thisFieldShouldBeEditable)
{
	thisIsTheProposalField=true;
}

// Wenn kein Attribut auf Proposal steht oder das angeklickte Feld 
// das Proposal Feld ist, brauchen wir nix mehr machen
if(!hasProposal||thisIsTheProposalField) halt();
// Wenn ein Attribut auf Proposal steht soll er blockieren

// Der nachfolgende Text text verhindert dass das Edit-Event zu Ende gebracht wird
set(trigPreConFail);


if (isVisible(mod) and obj == oCurr)                       
{
   infoBox(\"The field \" thisFieldShouldBeEditable \" is set to proposal.");
}
else{} 
"      // End definition of string DXLCode
 
Trigger trg;
bool    TrigOK  = true;
string  ErrMess = checkDXL(DXLCode);
 
if (!null ErrMess)
{
   print ErrMess "\n***********\n" DXLCode "**********\n"
   TrigOK       = false
}
 
string  NameTrig = "TriggerResetValidatedOn"
 
string  Prompt = "Delete trigger '" NameTrig "' ??"
if (!TrigOK) Prompt = "Trigger code has errors.\n" Prompt
if (confirm(Prompt))
{
   ErrMess = delete (NameTrig, module->object, pre, open, 6);
}
 
if (TrigOK && confirm("Deploy trigger '" NameTrig "' ??"))
{
   trg     = trigger(NameTrig, module->object, pre, open, 6, DXLCode)
}

Excel VBA: Create dynamic worksheet from SQL Query / Excel Arbeitsblatt durch SQL Query erstellen

Problem

A new Worksheet should be created, that contains the result of an SQL Query (ADODB) generic (in the way, that no column names have to be adressed in the recordset.

Approach – Ansatz

  • Iteration over the Resultsets field names to get Meta Information / Header names
  • Usage of CopyFromRecordSet method of the Range Object: worksheet.Range(„A2“).CopyFromRecordset Rs

Solution – Lösung

Sub CreateExcelSheetWithQueryResult(ws As Worksheet, sql As String)
    Dim Cn As New ADODB.Connection
    Dim Rs As New ADODB.Recordset
    Dim vaTmp() As String
    
    Cn.Provider = "SQLOLEDB.1"
    
    Cn.ConnectionString = "Password=pass;" & _
    "Persist Security Info=True;" & _
    "User ID=user;" & _
    "Initial Catalog=databaseName;" & _
    "Data Source=ServernameOrIP"
    
    Cn.Open
    
    Rs.CursorType = adOpenKeyset
    Rs.LockType = adLockPessimistic
    Rs.Open sql, Cn, adOpenStatic
   
    ws.Cells.Clear
    
    ' This section fills in the field names from the Orders table.
    ReDim vaTmp(Rs.Fields.Count)
    For x = 0 To Rs.Fields.Count - 1
        vaTmp(x) = Rs.Fields(x).Name
    Next
    ws.Cells(1, 1).Resize(1, Rs.Fields.Count) = vaTmp
   
    ws.Range("A2").CopyFromRecordset Rs
    
    Rs.Close
    Cn.Close
End Sub

And if you want to create a new Excel sheet you can do this with a button that assigned macro contains the following source:

Sub DetailQuery1_KlickenSieAuf()
    Dim ws As Worksheet
    Sheets.Add After:=Sheets(Sheets.Count)
    ' Referenz darauf
    Set ws = Sheets(Sheets.Count)
    CreateExcelSheetWithQueryResult ws, "SELECT TOP 10 * FROM irrsinn"
    
End Sub

MS SQL Server: Concat Strings in Group By Clausel / Group By, Strings gruppieren

Problem

Strings sollen in einer Group By Klausel anhand eines Attributs gruppiert und Komma separiert dargestellt werden.

Beispiel:

ID Name Value
1 A 4
1 B 8
2 C 9

Approach – Ansatz

Durch Verwendung der XPath Funktionen lässt sich etwas kreatives erreichen…

Solution – Lösung

CREATE TABLE #YourTable ([ID] INT, [Name] CHAR(1), [Value] INT)

INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'A',4)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'B',8)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9)

SELECT 
  [ID],
  STUFF((
    SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX)) 
    FROM #YourTable 
    WHERE (ID = Results.ID) 
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
  ,1,2,'') AS NameValues
FROM #YourTable Results
GROUP BY ID

DROP TABLE #YourTable

IBM Doors DXL: Versioned Links – Experimente mit BaselineSets, BaselineSetDefinitions

Intention

Allgemein

Für den Doors-Spezialisten erscheint das Thema der „Versioned Links“ mit Sicherheit trivial, ich hingegen habe desöfteren Probleme zu verstehen, wann sich ein „Versioned Link“ bildet. Daher habe ich mir ein Test-Szenario überlegt, anhand dessen ich das Verhalten von „Versioned Links“ näher analysieren möchte.

Was ist ein „Versioned Link“?

Einfach gesagt ist ein „Versioned Link“ ein Link, der auf eine Baseline eines Moduls ( einen eingefrorenen Stand) und nicht auf die „Current Version“ (die akutelle Arbeitsversion) des Moduls zeigt.

Wo ist also mein Problem?

Wer den Mechanismus des Link-Ziehens kennt, der weiß, dass es keine Möglichkeit gibt einen solchen Link bewusst auf eine Baseline zu ziehen.

zustandAinDoors

Desweiteren beziehen sich die Link-Module, über die man ebenfalls iterieren kann, um Quell- und Ziel-Objekte zu ermitteln, ausschließlich auf current LinkModules. Was passiert wenn ein Link-Modul gelöscht wird? Existiert nach dem Löschen der Satisfy-Beziehung (des Satisfy-Linkmoduls) in den alten Baselines immer noch?

Der folgende Code gibt die Baselines von Link-Modulen aus. Bei mir handelt es sich um hohe Versionszahlen größer als 200, die nicht mit den formellen/herkömmlichen Modul-Baselines in Verbindung gebracht werden können. Es ist also nicht ganz korrekt, das Link-Module keine Baselines haben, sie sind nur leider für den Endanwender unbrauchbar… oder kennt jemand einen Anwendungsfall wo er sie bisher nutzten konnte?

string nSatisfiesLinkModule = "/NDS/90 Administration/Satisfies"; 
Module SatisfiesLinkModule = read(nSatisfiesLinkModule, false); 
Baseline b = null;
int i = 0;

for b in SatisfiesLinkModule do 
{ 
    print i ") ";
    print(major b)"."(minor b)(suffix b)" "(annotation b)"\n" 
    i++;
} 

Wann entstehen „Versioned Links“?

„Versioned Links“ entstehen dann, wenn ein current Quell-Modul, welches noch nicht ins letzte  BaselineSet gestellt wurde, einen Outgoing-Link auf ein Ziel-Modul, welches gerade ins BaselineSet gestellt wurde, hat.

versioned_links1

(Zustand A: Quellmodul noch nicht im Baseline Set)

Dies bedeutet, dass der Auslöser für die Duplikation eine Modul-Baseline des Source-Moduls ist und nicht etwas auf Objekt-Ebene ausgelöst wird.

Wird anschließend eine Baseline für das Quell-Modul erstellt, wandern die Links in das gebaselinte Quell-Modul und die Duplikation im „Current Module“ verschwindet wieder.

versioned_links2

(Zustand B: Quellmodul wandert mit duplizierten Links ins BS)

Anmerkung: Den Zustand A sieht man i.d.R. nur in current Modules, die noch nicht ins letzte BaselineSet aufgenommen wurden.

Warum existieren „Versioned Links“?

Ich glaube fast, dass die Existenz von „Versioned Links“ vorwiegend der Tatsache geschuldet ist, dass die Links im Quell-Modul gespeichert werden und anschließend durch eine Art „Verschieben“ dem Baseline-Modul/der Snapshot-Kopie zugewiesen werden. Wenn das so ist, wäre der Zweck dieser Funktion nicht die Erfüllung von Nutzer-Anforderungen oder User-Stories, sondern lediglich einem technischem Zweck geschuldet.

Oder ist es für das Vorstellungsvermögen des Nutzers einfacher sich vorzustellen, wie eine Kopie des Quellmoduls (nämlich die Baseline) langsam mit den duplizierten, verankerten Links ins Baseline Set wandert?

Sorgen „Versioned Links“ im Zustand A für die Korrektheit/Versionssicherheit von Daten?

Wenn nun das Quellmodul, was z.B. eine Design Spezifikaton ist, Links auf die Current-Version und die gebaselinte Version hat, würde durch Veränderung in der Current-Version (also in den Requirements) nicht sichergestellt sein dass das Design noch stimmt. Die Aufgabe könnten Suspect Links erfüllen.

Daher lautet meine Antwort:

Nein (OXI)! „Versioned Links“ im Zustand A können nicht für die Korrektheit der verlinkten Daten sorgen. Meines Erachtens wäre es sinnvoller, wenn dass Source-Modul nur dann auf die Baseline zeigt, wenn das Source-Module seit der Target-Baseline nicht verändert wurde.
–> Wenn sich das „Current Ziel-Modul“ (z.B. die Software Requirements) seitdem geändert hat, so dass sich das Design ändern würde, stellt sich die Frage wieso das „Current Quell-Modul“ (z.B. das Software Design) auf geänderte Requirements zeigt.
Falls es geändert wurde, kann es auf die Current-Version des Ziel-Moduls zeigen… oder auch nicht, da ja noch nicht das ganze Modul geändert wurde…

Test Szenario

Test Beschreibung

Es soll nun getestet werden, wie der Zustand A (Link-Duplikation) bei Modulen, die ausschließlich Quellen, Modulen die ausschließlich Senken und Zwischenmodulen beim Verfolgen von Links darstellt.

Test Aufbau

Ich habe 11 Module auf 4 verschiedenen Ebenen erstellt, die ich mit willkürlichen Link-Typen miteinander verlinkt habe.

Anschließend habe ich eine Baseline Set Definition erstellt, die alle 11 Module beinhaltet und 4 Module (E1I1, E2I3, E3I1, E4I1) bereits in das BaselineSet gestellt (in der Grafik unten rot umrahmt).

TraceabilityTest

Das Baseline Set existiert in der Version 2.0:

tool_baselines

Test Durchführung

Die untenstehende Tabelle geht von current Quell-Modulen bei Outgoing-Links, und current Ziel-Modulen bei Incoming-Links aus.

D.h. bei Incoming-Links ist die Spalte Ziel-Modul das geöffnete Modul, bei dem das Phänomen der gespaltenen Links im Zustand A auftritt, bei Outgoing-Links ist das Quell-Modul der Ort, in dem das Phänomen der gespaltenen Links auftritt.

Auswertung1

Es ergibt sich darauf die folgende Wahrheitstabelle:

Auswertung2

Ergebnis

Der Zustand A von „Versioned Links“ tritt bei Outgoing Links im current Quellmodul auf, wenn das Quellmodul nicht im Baseline Set ist und das Zielmodul im Baseline Set ist.
Der Zustand A von „Versioned Links“ tritt bei Incoming Links im current Zielmodul auf, wenn das Quellmodul im Baseline Set ist, aber das Zielmodul nicht im Baseline Set.
Der Zustand A von „Versioned Links“ tritt auch in Baseline Modulen auf, wenn diese durch die Duplikation auf current Module zeigt.

Navigation mit DXL durch Versioned Links

Um ALLE Links eines Moduls, auch die Current- und Baseline-Versionen für ein Objekt zu bekommen, nutzt man den „ALL“ Quantor in der For-Schleife

Module m=current;
Link lnk;
Object o;
int numLinks=0;

for o in m do
{
  for lnk in all(o->"*") do
  {
    numLinks++;
  }
}  
print "There are " numLinks " outgoing links from this module.";