Shall we play a game? Tic-Tac-Toe mal anders

Für die einen ist es nichts weiter als Drei Gewinnt. Den anderen zaubert es ein nostalgisches Schmunzeln ins Gesicht, während sie an Joshua, die einsichtige KI aus dem Klassiker War Games denken. Für mich ist Tic-Tac-Toe ein schönes Beispiel dafür, wie unterschiedlich Softwareentwickler Strategien zur Lösung eines Problems entwickeln.

Für Tic-Tac-Toe gibt es 255.169 verschiedene Spielverläufe, von denen 131.185 mit einem Sieg des ersten Spielers enden, 77.904 mit einem Sieg des zweiten Spielers und 46.080 mit einem Unentschieden. (Quelle: Wikipedia)

Während die Anzahl an Spielverläufen somit übersichtlich ist, gestaltet sich die Entwicklung eines Tic-Tac-Toes in z.B. C# sogar noch einfacher, wenn es nur als Zweispieler (ohne selbst-lernende KI) gedacht ist. Doch während sich die meisten gleich als erstes die Frage danach stellen, wie sie das Spielbrett visualisieren und die Interaktion mit dem Spieler gestalten sollen (Windows Forms, HTML, WPF,…) ist dieses Spiel aus meiner Sicht einfach zu gut dafür geeignet, um sich über TDD Gedanken zu machen, als dass man es ignorieren könnte.

Klar. Ein Gameboard ist schnell entworfen und nach der Überlegung, dass es nicht mehr als neun Felder gibt, sind auch die ersten Tests schnell geschrieben.

GameBoardTests.cs

[TestClass]
public class GameBoardTests
{
  private GameBoard board = null;

  [TestInitialize]
  public void TestInitialize()
  {
    this.board = new GameBoard(null);
  }

  [TestMethod]
  [TestCategory("GameBoard")]      
  public void Fail_If_Greater_Than_Max()
  {
    Action action = () => board.Set(9);
    action.ShouldThrow<ArgumentOutOfRangeException>();
  }

  [TestMethod]
  [TestCategory("GameBoard")]
  public void Fail_If_Less_Than_Min()
  {
    Action action = () => board.Set(-1);
    action.ShouldThrow<ArgumentOutOfRangeException>();
  }
}
  

 

(Für die Prüfung erwarteter Exceptions kommt hier übrigens das Paket FluentAssertions zum Einsatz.)

GameBoard.cs

public class GameBoard
{
  public void Set(int pos)
  {
    if (pos < 0 || pos > 8) throw new ArgumentOutOfRangeException("The gameboard only consists of nine fields. Please set a new coin only on positions from zero to eight.");
  }
}       
  

 

Doch nun kommt schon die Frage: Angenommen, ein Spieler entscheidet sich für ein gültiges Feld. Wie genau soll das gespeichert werden? Und dann gleich die nächste Frage: Wie genau soll der Code ermitteln, ob jemand gewonnen hat?

Während nahezu jede Beispielimplementierung von Tic-Tac-Toe an dieser Stelle mit einem zweidimensionalen Array arbeitet und für die Gewinnermittlung verschachtelte If-Then-Else Abfragen nutzt, schlage ich einfach mal folgende Datentypen für die Verwaltung des Spielbrettes und der Gewinner-Kombinationen vor:

GameBoard.cs

private int board = 0;
private int[] winningCombinations = { 448, 56, 7, 292, 146, 73, 273, 84 };
  

 

Mehr braucht es eigentlich nicht. Genial, oder?

Die Idee ist im Prinzip recht simpel: Das Tic-Tac-Toe Spielfeld besteht aus 9 Feldern. Es ist also problemlos möglich, die Felder binär zu repräsentieren (000 000 000). Damit ließen sich auch die Gewinnerkombinationen einfach festlegen:

  • Horizontal: 111 000 000, 000 111 000, 000 000 111
  • Vertikal: 100 100 100, 010 010 010, 001 001 001
  • Diagonal: 100 010 001, 001 010 100

Mehr gibt es nicht. Umgerechnet in Dezimalwerte ergibt sich daraus die Liste von Zahlen wie oben im Array winningCombinations dargestellt.

Das ist in sofern pfiffig, als dass sich mit nur einer Schleife herausfinden lässt, ob ein Gewinner vorliegt. Dazu muss einfach nur über das obige Array iteriert und der jeweilige Wert mit dem Spielbrett bitverknüpft werden. Fertig.

Wer mitgedacht hat, wird spätestens jetzt sagen: Ja, aber! Es gibt zwei Spieler. Daraus ergeben sich drei Zustände und ein Bit kann nur zwei Zustände haben:

  • Feld unbesetzt
  • Feld von Spieler 1 besetzt
  • Feld von Spieler 2 besetzt

Ich sage: Richtig. Also speichern wir einfach für jeden Spieler in dem Integer ein separates Spielbrett. Das ergibt somit 18 Bit und ist problemlos abbildbar (Dezimal 262.143). Worauf nun lediglich geachtet werden muss, ist beim abwechselnden Setzen von X und O durch Spieler 1 und Spieler 2 a) das korrekte Spielbrett innerhalb des Integers zu erwischen und b) darin wiederum das korrekte Feld. Das ermöglichen Bit-Shift Operationen:

GameBoard.cs

public enum Player
{
  Player1,
  Player2
};

private int GetPosition(int pos, Player player){
  return (1 << (int)player * 9) << pos;
}
  

 

Die Frage von oben, wie sich denn nun die gewählten Felder der jeweiligen Spieler in der Integer Variablen festhalten lassen, ist damit leicht beantwortet:

GameBoard.cs

public void Set(int pos)
{  
  if (pos < 0 || pos > 8) throw new ArgumentOutOfRangeException("The gameboard only consists of nine fields. Please set a new coin only on positions from zero to eight.");

  this.board |= this.GetPosition(pos, this.ActivePlayer);
}
  

 

Da dieser Artikel mehr auf die etwas ungewöhnliche Art, ein Tic-Tac-Toe Spielbrett in C# abzubilden abzielt und weniger auf den testgetriebenen Ansatz, kommt an dieser Stelle der Hinweis: Bevor es zu dieser Implementierung gekommen ist, wurden zunächst Tests für das Setzen von Feldern, der Prüfung, ob ein Feld bereits belegt wurde und dann irgendwann das Prüfen verschiedener Gewinner-Konstellationen implementiert. Abschließend wurde der Spielverlauf selbst mittels Strategie-Muster entworfen und getestet.

Wichtig hierbei war natürlich die Entkopplung von Abhängigkeiten (wie z.B. Benutzereingabe und Bildschirmausgabe).

Um aber noch kurz zu zeigen, wie einfach basierend auf der hier vorgestellten Methode das Prüfen auf einen Gewinner ist, der Vollständigkeit halber noch der dazugehörige Code:

GameBoard.cs

public bool CheckWinner()
{
  foreach (int winningCombination in this.winningCombinations)
  {
    if (this.IsMatch(winningCombination))
    {
      return true;
    }
  }
  return false;
}

private bool IsMatch(int combination)
{
  return (this.board & combination << 9) == combination << 9 || // Check if player 2 won
    (this.board & combination ) == combination; // Check if player 1 won
}
  

 

Spannend, oder? Falls sich jemand für die Solution interessiert, lohnt sich ein entsprechender Kommentar. Auch der TDD Ansatz lässt sich hier ganz gut demonstrieren: In der ersten Iteration gab es noch zwei Integer-Variablen für die Repräsentation der Spielfelder für beide Spieler (und natürlich eine Menge Unit-Tests). Im Anschluss wurde der Game Code refaktorisiert, so dass nur noch eine Integer Variable wie oben gezeigt notwendig war. Die bestehenden Unit Tests konnten zeigen, dass die Logik (von außen betrachtet) dadurch keinen Schaden genommen hat.

Und so soll es schließlich ja auch sein.

Smile 

Bugfix: Glossar Beschreibung im OIA anzeigen

Mit diesem Artikel folgt ein weiteres Deep Dive in die Welt des OIA (Oracle Identity Analytics). Dieses Mal vor dem Hintergrund eines Bugs, dessen Lösung im Folgenden beschrieben wird.

Im letzten Artikel haben wir gezeigt, wie eine Zertifizierung auf der Grundlage lokaler Konten konfiguriert und durchgeführt werden kann. Da es dabei erforderlich ist, Primärschlüssel zusammenzusetzen, entstehen für die Attribute relativ lange Namen. Das macht die Darstellung für den Zertifizierer unübersichtlich.

Zu sehen war deswegen in dem Artikel, wie beispielsweise die Gruppenmitgliedschaft zwar als Kombination zwischen Server, Account und Gruppe importiert wurde (“SRV01 > A000002 > Users”), die Anzeige sich aber während der Zertifizierung auf die Darstellung der Gruppe beschränkt:

image

 

Klickt nun der Zertifizierer auf die Gruppe, können Glossarinformationen angezeigt werden, die in diesem Beispiel im Feld Description eine Beschreibung des Servers mitführt. Das kann dem Zertifizierer dabei helfen, den Kontext besser zu verstehen. Damit das funktioniert, müssen ressourcenabhängig Glossarinformationen importiert werden.

Import Glossary

Datei: …\import\schema\Betriebssystem_glossary.rbx

# @iam:namespace name="Betriebssystem" shortName="OPS"
attributeName,atributeValueValue,endpointName,definition,shortDescription

Datei: …\import\in\Betriebssystem_01_glossary.csv

"groups","SRV01 > D000001 > Users","Windows","Users","Zentraler Entwicklungsserver"
"groups","SRV01 > D000001 > Developers","Windows","Developers","Zentraler Entwicklungsserver"
"groups","SRV01 > A000002 > Administrators","Windows","Administrators","Zentraler Entwicklungsserver"
"groups","SRV01 > A000002 > Users","Windows","Users","Zentraler Entwicklungsserver"

Das Ergebnis des Imports kann nun im Identity Warehouse im Bereich Data Management der jeweiligen Ressource eingesehen werden:

image

Wenn der Zertifizierer während der Zertifizierung nun wie oben dargestellt auf einen Glossareintrag klickt, erhält er aber folgendes Popup:
image

 

Was fehlt, ist die Description. Und der Grund hierfür ist der oben erwähnte Bug in OIA.

Analyse

Bei der Analyse des Datenstroms zwischen Server und Browser mit Hilfe der Internet Explorer Developer Toolbar hat sich gezeigt, dass die Daten für das Popup über den Service dwrIDCService mit der Methode loadBatchUserAccounts gezogen werden. Der Blick in den Quellcode hat zutage gefördert, dass am Ende die Abfrage getIDCAccountAttributesFlatByUser ursächlich für das Problem verantwortlich ist. Da allerdings im OIA das (inzwischen abgemeldete) Produkt iBATIS zum Einsatz kommt, lässt sich die Abfrage leicht einsehen. Sie befindet sich in der Datei IDCAccount.xml im Verzeichnis …\WEB-INF\classes\com\vaau\rbacx\idc\dao\ibatis\maps.

Zunächst wird in der Abfrage ein Defaultdatensatz erzeugt:

<select id="getIDCAccountAttributesFlatByUser" resultMap="account-attribute-wrapper">
  select
  null as attribute_value_id,
  null as attribute_id,
  null as attribute_value,
  null as glossary_def,
  null as short_description,
  null as attribute_name,
  ,
  

 

Einige Zeilen später findet ein Union statt mit einer Abfrage, die die tatsächlichen Daten aus der Datenbank bezieht. Hier zeigt sich das Problem:

select 
   
  idc_account_attributes.short_description as short_description, 
    
from 
  idc_account_attributes, attributes, idc_user_acct_attrs, idc_accounts, namespaces 
  
  

 

Der Blick in die Datenbank zeigt, dass sich hier schlicht keine Daten befinden. Die Glossarinformationen wurden beim Import nämlich in die Tabelle attribute_value_metadata eingelesen.

Lösung

Die Abfrage muss angepasst werden, so dass die Tabelle attribute_value_metadata mit einbezogen wird. Dabei ist darauf zu achten, über die Where-Klausel die Verknüpfung korrekt zu definieren.

select 
   
  attribute_value_metadata.short_description as short_description, 
   
from 
  idc_account_attributes,attribute_value_metadata, attributes,  
where 
  attributes.attributekey = idc_account_attributes.attribute_id and 
  attribute_value_metadata.attribute_value_id=idc_account_attributes.iam_attr_val_id and 
  attribute_value_metadata.endpoint_id=idc_accounts.endpoint_id and 
  idc_account_attributes.id = idc_user_acct_attrs.account_attribute_id and
   
  

Das war es auch schon.

An dieser Stelle ein leider notwendiger Hinweis: Soweit wir es sagen können, hat diese Änderung keine Auswirkungen auf das restliche Produkt. Da wir den OIA aber nicht entwickelt haben, können wir dafür keine Gewährleistung übernehmen. Sollten Sie daher ebenfalls Änderungen an Ihrem System vornehmen, geschieht das auf eigene Gefahr.

Fazit

Leider zeigt sich beim OIA, dass durch den turbulenten Lebenslauf (entwickelt von vaau, übernommen von Sun, gekauft von Oracle) die eine oder andere Unstimmigkeit entstanden ist. Von außen lässt sich natürlich schwer nachvollziehen, welches Unternehmen nun ursächlich für solche Probleme verantwortlich ist. Das ist aber auch unerheblich. Wichtiger ist, dass man sie lösen kann.

Wir konnten dieses Problem durch den Einsatz verschiedener Analysewerkzeuge inkl. Einsicht in den Quellcode identifizieren und nachhaltig beheben. Da von einem Unternehmen, das den OIA zum Zweck der Zertifizierung von Benutzern, Rollen und Konten einsetzt, natürlich kaum erwartet werden kann, so tief in die Technik einzusteigen wenn etwas nicht funktioniert wie erwartet, gibt es für Kunden i.d.R. nur eine Option: Bei Oracle einen Spezialisten einkaufen.

Oder aber Sie fragen uns. :)

Wie man wirklich (!) eine manuelle Korrekturverfolgung im OIA konfiguriert

Das Produkt Oracle Identity Analytics ist eine wirklich umfangreiche Anwendung zur Analyse von Rollen und Berechtigungen. Im Zusammenspiel mit dem Oracle Identity Manager (OIM) gelingt es zudem, sogar automatisiert Konsequenzen aus der Analyse zu ziehen: Sobald ein Manager bspw. einem Konto Berechtigungen entzogen oder eine Rollenzugehörigkeit aufgehoben hat, kann der OIA diese Information an den OIM weitergeben, der dann wiederum die Umsetzung erforderlicher Maßnahmen in der Infrastruktur auslöst (Deprovisioning). Gleichzeitig fungiert er auch als Provisioning Server und kann somit den OIA mit entsprechenden Daten beliefern, auf Grundlage derer die Manager den Status der Benutzer und deren Berechtigungen analysieren und letztendlich zertifizieren können. Diesen Prozess nennt Oracle Closed Loop Remediation und das dazugehörige Modul im OIA, welches diesen Prozess visualisiert, nennt sich Remediation Tracking, oder auf deutsch: Korrekturverfolgung.

Was aber, wenn es keinen OIM gibt? Dann spricht man von einer Open Loop Remediation, oder alternativ von einer erforderlichen manuellen Korrektur. Dieser Artikel beschreibt, was für Schritte erforderlich sind, damit der OIA in etwa das tut, was man von ihm erwarten würde.

Ausgangslage

  • Es wurden Resourcen-Typen angelegt und konfiguriert (in diesem Beispiel: Ein Ressourcen-Typ mit dem Namen Betriebssystem, dem Kurznamen OPS und einem Multivalue-Attribut groups in der Attributkategorie General)
  • Es existieren Global User (wird weiter unten erläutert)
  • Es wurden Accounts importiert, den Global Users zugeordnet und auf Ressourcen verteilt (wird weiter unten erläutert)

Auf dieser Grundlage ließen sich nun Zertifizierungen erstellen. Aber bevor es soweit ist, zunächst die Einstellungen für die Wartung von Konten und den OIA Prozess der Korrekturverfolgung.

Grundeinstellungen

Damit bei der Korrekturverfolgung auch erkannt werden kann, ob eine zu entziehende Berechtigung auch entzogen wurde, muss der OIA in der Lage sein, die zuvor importierten Daten zu einem Benutzer verändern zu können. In der IT wurde beispielsweise ein Konto von einem Server gelöscht oder eine Gruppenmitgliedschaft aufgehoben. Diese Information muss nun auch der OIA erhalten. Dazu gibt es zwei Möglichkeiten.

Explicit Revoke

Bei der expliziten Methode werden die Daten einfach erneut importiert. Im Falle eines Accounts wird zusätzlich der Parameter suspended übergeben. Der Wert 0 bedeutet, dass der Account aktiv ist (nicht suspended) und der Wert 1 deaktiviert ihn (suspend). Dazu muss natürlich der Parameter in der entsprechenden Schema-Datei (.rbx) angegeben sein.

Im Falle eines Attributes wie z.B. einer Gruppenzugehörigkeit, geht das natürlich nicht. Denn diese werden allenfalls in Form eines Multivalue-Feldes linear aufgelistet; man kann nicht zu jedem Attribut ein zusätzliches Feld wie z.B. suspended übergeben. Was aber geht: Weglassen. Sprich: Sobald ein Account erneut importiert wird, ohne dass die in Frage kommende Gruppenmitgliedschaft aufgelistet wird, erkennt der OIA sie als entfernt (revoked)

Implicit Revoke

Implizit bedeutet, dass der OIA die Korrektur selbst erkennt. Das geschieht auf Basis des letzten Update-Timestamps. Sobald mehr Tage seit dem letzten Import vergangen sind, als angegeben, kann der OIA den existierenden Datensatz selbst aktualisieren.

Schritt 1

In der Datei …\conf\iam.properties muss dazu die Account Maintenance konfiguriert werden (~Zeile 49):

# Account Maintenance parameters
# options { delete | suspend }
com.vaau.rbacx.maintenance.accounts.maintenanceAction=suspend
com.vaau.rbacx.maintenance.accounts.maxStaleDays=30
com.vaau.rbacx.maintenance.accounts.resources=All

Hier sind zwei Dinge zu beachten. Zum einen führt ein Löschen (delete) dazu, dass der Account in dem Fall tatsächlich gelöscht wird. In der Korrekturverfolgung (auf die ich später noch eingehe) gilt die Maßnahme damit zwar als umgesetzt. Allerdings kann sie den Account dann auch nicht mehr anzeigen und somit kann man auch die Historie nicht mehr einsehen. Die Einstellung suspend wiederum hat den Vorteil, dass man weiterhin Einblick in die Historie hat. Optisch führt das dazu, dass in der Account-Auflistung unterhalb der Global User der jeweilige Account ausgegraut wird.

image

 

Zum anderen ist hier der Wert maxStaleDays zu beachten. I.d.R. wird die Maintenance regelmäßig durchgeführt (z.B. einmal am Tag). Wenn nun die Accountdaten bspw. alle 10 Tage importiert werden und maxStaleDays auf einem niedrigeren Wert steht, dann werden regelmäßig alle Konten im OIA gelöscht, bzw. suspended. Insofern gilt es, den Wert auf die Import-Prozesse abzustimmen.

Schritt 2

Für sowohl die automatische Wartung von Accounts wie auch die Verarbeitung der Korrekturinformationen sind im OIA zwei Jobs zuständig. Diese werden ausgelöst von dazugehörigen Triggern. Beides muss aktiviert und konfiguriert werden.

In der Datei …\WEB-INF\scheduling-context.xml im Property jobDetails (~Zeile 157) sind die Jobs per Default auskommentiert. Sie müssen aktiviert werden:

<ref bean="accountsMaintenanceJob"/>

<ref bean="certificationRemediationJob"/>

In der gleichen Datei im Property triggers (~Zeile 195) sind die dazugehörigen Trigger per Default auskommentiert. Sie müssen ebenfalls aktiviert werden:

<ref bean="accountsMaintenanceTrigger"/>

<ref bean="certificationRemediationTrigger"/>

Schritt 3

Die soeben aktivierten Trigger müssen konfiguriert werden. Dabei dient ein Cron-Ausdruck dazu, anzugeben, wann die Jobs automatisch ausgeführt werden sollen.

In der Datei …\WEB-INF\jobs.xml wird die Bean accountsMaintenanceTrigger (~Zeile 516) konfiguriert:

<bean id="accountsMaintenanceTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
 
<property name="jobDetail">
    <ref bean="accountsMaintenanceJob"/>
   </property>
  < property name="cronExpression">          
    < value>0 0 0 ? * SUN-THU</value>
  </property>
</bean>

Die cronExpression kann bspw. mit Hilfe von http://www.cronmaker.com/ erzeugt werden.

In der gleichen Datei wird die Bean remediationCertificationTrigger (~Zeile 938) konfiguriert:

<bean id="certificationRemediationTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
  < property name="jobDetail">
    < ref bean="certificationRemediationJob"/>
  </property>
  < property name="cronExpression">
    <value>0 0/2 * * * ?</value>
  </property>
< /bean>

Auch hier ist die cronExpression zu beachten. Für Testzwecke kann es sinnvoll sein, beide Trigger auf z.B. 2 Minuten zu setzen, um schnell Ergebnisse beobachten zu können. Für die In-Produktivnahme sollten die Werte aufeinander abgestimmt sein.

Schritt 4

Sobald die Konfiguration durchgeführt wurde, muss der OIA neu gestartet werden, um die Änderungen zu übernehmen. Im Anschluss gilt es beim Erstellen einer Zertifizierung auf das Thema Korrekturverfolgung zu achten.

Unter Administration > Settings im Tab Identity Certification im Abschnitt Revoke and Remediation:

image

Hier sind gleich zwei Einstellungen bemerkenswert. Erstens hat die Checkbox Display Remediation Instructions keinerlei Auswirkungen. Unsere Annahme war, dass nach Abschluss einer Zertifizierung ein Manager die Instruktionen angezeigt bekommt, die wir später noch konfigurieren werden. Dem ist aber nicht so. Statt dessen sieht man diese ausschließlich an zwei Stellen: Zum einen, wenn man in einer Zertifizierung auf einen Resourcen-Namen klickt und zum anderen in verschiedenen Reports. Aber dazu später mehr.

Wir haben uns mit einem Decompiler den Code angeschaut und in der Tat: Dieses Setting wird nirgends genutzt.

Zweitens ist die Checkbox Perform Closed Loop Remediation (und die dazugehörige Einstellung Certification Completion Date) wichtig. Denn selbst wenn der Certification Remediation Job durch den entsprechenden Trigger, den wir bereits konfiguriert haben, ausgeführt wird: Wenn diese Checkbox nicht gesetzt wird, tut der Job nichts. Und das hat nichts mit der Closed Loop Remediation im Sinne einer Integration in den OIM zu tun. Sondern in jedem Fall mit der Korrekturverfolgung. Auch der “manuellen”.

Schritt 5

Wir sprachen eben von den Remediation Instructions. Diese werden in den Resourcen konfiguriert. Und auch hier gibt es Einiges zu beachten.

Unter Identity Warehouse > Resources klickt man auf eine Resource und wechselt in den Tab Remediation:

image

 

Für eine manuelle Korrektur wird entsprechend der Wert Manual ausgewählt. Zusätzlich gibt es die Möglichkeit, sich zwischen einem Plain Text und einem Rich Text Editor zu entscheiden. Hierzu ein Hinweis: Sollte man versuchen wollen, sich auf die mitgelieferten Reports zu beschränken, dann empfehlen wir den Plain Text Editor und hier lediglich auf z.B. ein internes Handbuch o.ä. zu verweisen, in dem die notwendigen Schritte für die Deprovisionierung beschrieben werden. Denn die Reports übernehmen für jede einzelne erforderliche Korrektur diesen Text und sind leider nicht in der Lage HTML zu erkennen. Sprich: Wenn man den Rich Text Editor nutzt und viel Text eingibt (mit jeder Menge Formatierungen), erscheinen diese inkl. HTML-Tags im Report. In jedem Datensatz. Soviel dazu.

Datenimport

Ausgehend davon, dass z.B. User- und Accountdaten wie folgt mittels CSV-Dateien importiert wurden, kann nun eine Zertifizierung erstellt werden. Doch zunächst die Daten:

Import Global User

Datei: …\import\schema\users.rbx (Schema)

userName,firstName,lastName,primaryEmail

Datei: …\import\in\users_01.csv

"D000001","Timo","Tempel","Timo.Tempel@domain.com"

"A000002","Yasmin","Markmann","Yasmin.Markmann@domain.com"

Import Accounts

Datei: …\import\schema\Betriebssystem_accounts.rbx

# @iam:namespace name="Betriebssystem" shortName="OPS"
userName<CorrelationKey>,name,endpoint,groups,suspended

Datei: …\import\in\Betriebssystem_01_accounts.csv

"D000001","SRV01 > D000001","Windows","SRV01 > D000001 > Users,SRV01 > D000001 > Developers","0"
"A000002","SRV01 > A000002","Windows","SRV01 > A000002 > Administrators,SRV01 > A000002 > Users","0"

Wem die seltsame Nomenklatur aufgefallen ist, sei folgender Hinweis mitgegeben: Für dieses Szenario zwar unerheblich, orientiere ich mich aber dennoch an einem Kundenprojekt, in dem wir es mit der Zertifizierung lokaler Benutzerkonten zu tun haben. Da hier ein Kontoname (z.B. D000001) auf mehreren Servern vorkommen kann und dabei nicht zwangläufig identisch ist (da nicht zentral verwaltet mittels bspw. dem Active Directory), benötigen wir zusammengesetzte Primärschlüssel. Gleiches gilt für z.B. Gruppenmitgliedschaften, die wir als Multivalue-Felder konfiguriert haben. Wie man trotzdem eine halbwegs annehmbare User Experience während der Zertifizierung hinbekommt, erkläre ich evtl. ein andern Mal.

Zertifizierung

Nachdem eine Zertifizierung erstellt wurde, stellt sich diese für den Manager wie folgt dar:

image

 

image

 

Der Manager entzieht nun Timo Tempel den Account auf SRV01 und Yasmin Markmann wird die Mitgliedschaft in der Gruppe Administrators entzogen.

Inder Korrekturverfolgung unter Identity Certification > Remediation Tracking zeigt sich nun, dass der OIA das Delta zwischen SOLL und IST verstanden hat:

image


In den Details zeigt sich z.B., dass Yasmin aus der Gruppe Administrators entfernt werden soll:

image

 

Zu Timo zeigt der OIA an, dass er aus sowohl der Developers als auch der Users Gruppe entfernt werden muss. Soweit alles OK.

Zur Demonstration wird nun eine neue Betriebssystem_01_accounts.csv Datei importiert:

"D000001","SRV01 > D000001","Windows","","1"
"A000002","SRV01 > A000002","Windows","SRV01 > A000002 > Users","0"

Hier zu erkennen: In Timos Datensatz wurden die Gruppen entfernt; außerdem wird sein Account suspended. Yasmin wurde einfach nur aus der Gruppe Administrators entfernt.

Im Remediation Tracking schaut das dann so aus:

image

 

Klickt man nun im Remediation Tracking bei Yasmin bspw. auf den Attributwert Administrators, lässt sich im Akkordeon Certification History auch die Historie anzeigen:

image

 

Auch ohne das Neu-Importieren der Datensätze wie oben beschrieben hätte der OIA die Korrektur erfolgreich erkannt, sobald eine entsprechend maxStaleDays Anzahl an Tagen verstrichen wäre.

Im Prinzip ist es nicht kompliziert, den OIA für eine manuelle Korrekturverfolgung zu konfigurieren. Allerdings verlangt es an einigem Know-How und unglücklicherweise schweigt sich die Dokumentation vom Hersteller zu diesem Thema gänzlich aus. Darüber hinaus gibt es noch einige weitere Themen in diesem Zusammenhang, auf die ich nicht im Detail eingegangen bin. Hoffentlich wurden trotzdem einige wesentliche Punkte etwas klarer!

Falls dennoch Fragen offen sind, stehen wir wie immer gerne zur Verfügung. Dazu freuen wir uns über eine Email über unser Kontaktformular auf http://www.toptechnologies.de.

Project Spark 4.5 unter Visual Studio 2015

Nein, mit Projekt Spark ist nicht der kürzlich eingestellte Microsoft Spielebaukasten für selbst ernannte Game Designer gemeint, sondern ein simples, leichtgewichtiges ORM Framework der data & objects Factory. Während zwar eine Version 5.0 analog zur kommenden Version vom .NET Framework bereits in Arbeit ist, kann bis zum Erscheinen natürlich die Version 4.5 weiterhin genutzt werden.

Allerdings hat sich seit Visual Studio 2013 einiges geändert. Beispielsweise wird inzwischen die LocalDB in der Version 13 eingesetzt; Spark setzt auf Version 11 auf. Dieser Artikel soll die Schritte beschreiben, die notwendig sind, um die Referenzapplikation Art Shop (“A fully functional, real-world e-commerce Web App”) unter Visual Studio 2015 zum Laufen zu kommen.

Los geht’s.

;tldr

  1. Solution in Visual Studio 2015 öffnen
  2. Datenbank von (LocalDB)\v11.0 nach (LocalDB)\MSSQLLocalDB migrieren
  3. Mittels NuGet das Paket AspNetWebApi im Projekt Art.Rest.v1 installieren

Schritt 1

Als erstes kann die Solution Spark 4.5.sln aus dem Verzeichnis Spark wie gewohnt im Visual Studio 2015 geöffnet werden. Möglicherweise erscheint an dieser Stelle bereits eine Meldung, die einen darauf hinweist, dass die eingesetzte Datenbank nicht mit der aktuellen Installation der LocalDB kompatibel ist. Diese Meldung behauptet, es reiche aus, auf die Datei Art.mdf doppelt zu klicken, um die Migration anzustoßen. Das funktioniert aber leider nicht.

Schritt 2

Mittels View –> Service Explorer den Service Explorer öffnen und mittels Rechtsklick auf Data Connections –> Add Connection… den Verbindungsassistent öffnen. Als Server Name (LocalDB)\MSSQLLocalDB eingeben und mittels <Test Connection> die Verbindung prüfen. Wenn das geklappt hat, über die Auswahl Attach a database file die Datei …\Spark\Art.Web\App_Data\Art.mdf auswählen und den Assistenten mit <OK> schließen. Die Meldung, die daraufhin erscheint mit <Ja> quittieren; nun wird die Datenbank migriert.

Schritt 3

Wenn man an dieser Stelle versucht, das Projekt zu kompilieren (nur zu…), dann gibt es dutzende Fehler. Diese gründen im Wesentlichen darauf, dass die Referenz zu System.Web.Http im Projekt Art.Rest.v1 kaputt ist. Das Problem kann einfach wie folgt behoben werden:  Mittels Tools –> NuGet Package Manager –> Package Manager Console die NuGet Package Manager Console öffnen und zunächst unter Default Project das Projekt Art.Rest.v1 auswählen. Dann mittels Install-Package AspNetWebApi die ASP.NET WebApi Bibliotheken im Projekt Art.Rest.v1 installieren. Anschließend kann das Projekt kompiliert und ausgeführt werden.

image 

Webseiten, Produkte und Tools, die jeder VBA-Entwickler kennen sollte

VBA steht für Visual Basic for Applications. Im Grunde genommen kennt nahezu jeder Softwareentwickler diese Programmiersprache, die ihren Ursprung in den Office-Produkten hat. Denn hier kommt sie i.d.R. zum Einsatz: Outlook, Word und Excel. Hier wird am meisten automatisiert, bis der Arzt kommt.

Während unserer Meinung nach VBA eine große Flexibilität bietet, sehen wir uns aber oft einer eher negativen Einstellung gegenüber VBA ausgesetzt.

Die Gründe lassen sich einfach auflisten:

  • Kein besonders intelligentes IntelliSense
  • Keine Anbindung an eine Quellcode-Verwaltung*
  • Kein Refactoring
  • Kein Exception-Handling
  • ...

Die Liste ist noch viel länger, aber eines wird schnell klar: VBA ist kein C# und VBE (Visual Basic Editor) ist kein Visual Studio. Allerdings ergeben sich so auch Vorteile: Fachabteilungen können zumeist eigene Herausforderungen schnell und flexibel lösen (ohne von der IT oder der Entwicklungsabteilung abhängig zu sein). Es werden keine zusätzlichen Lizenzen für Entwicklungsumgebungen benötigt, da alles, was man braucht, in Office integriert ist (inkl. der Laufzeitumgebung). Installationssysteme sind nicht notwendig, da der Code Bestandteil der jeweiligen Dokumente ist. Natürlich empfinden wir die Nachteile (siehe oben) aber auch als problematisch.

Um sie im Vergleich zu modernen Programmiersprachen und Entwicklungsumgebungen ein wenig auszugleichen, hat der an Qualität interessierte VBA-Entwickler nichts desto trotz Zugriff auf einen reichhaltigen Fundus an Know-How und Erweiterungen.

Dieser Artikel listet einige davon auf (und erfüllt natürlich nicht den Anspruch auf Vollständigkeit; Ergänzungen werden gerne gesehen > Ab damit in die Kommentare!).  

MZ-Tools

MZ-Tools ist der Platzhirsch unter den Anbietern von (u.a.) VBA-Erweiterungen. Der Anbieter selbst spricht von Funktionen, die einen schneller Ergebnisse erzielen lassen, besser Code wiederzufinden, besser Oberflächen zu gestalten, einfach Dokumentationen zu generieren, u.v.m.

Link zur Website

Rubber Duck

Hierbei handelt es sich um ein ambitioniertes Open Source Projekt, das sich anschickt, den Visual Basic Editor ins 21. Jahrhundert zu katapultieren. Auch in dieser Erweiterung finden sich Funktionen wie z.B. ein integriertes Refactoring und eine regelbasierte Überprüfung der Code Qualität. Die Besonderheit von Rubber Duck: Ab Version 2.0 ist eine Anbindung von Git als Quellcode Verwaltung vorgesehen! Übrigens: Rubber Duck beinhaltet auch einen Testrunner für VBA Unit-Tests. Kein Witz!

Link zur Website

Tipps und Tricks von Pearson Software Consulting

CPearson bietet eine unfassbar umfangreiche Liste an Tipps und Tricks im Umgang mit u.a. VBA an. Auch nur Ansatzweise darzustellen, was man hier alles lernen kann, würde den Artikel sprengen. Hier (für mich) zwei Perlen: "Implementing Interfaces in Class Modules" (ja, es geht noch immer um VBA!) und "Introduction to Classes".

Link zur Website

Excel Tips von J-Walk & Associates

Auch hier gibt es eine lange Liste von Tipps für Entwickler, kategorisiert nach VBA Functions, UserForms, CommandBars & Menus und General VBA. Auch für Benutzer finden sich hier zahlreiche Hinweise, die einem das Leben in zumindest Excel deutlich erleichtern.

Link zur Website

Excel-Formeln übersetzt

Zugegeben, hier geht es weniger um VBA direkt, als denn mehr um Excel. Da allerdings auch oft von VBA aus Excel-Dokumente automatisiert werden, kann es manchmal hilfreich sein, Zugriff auf eine Übersetzungstabelle für Excel-Formeln zu haben. Wer also schon oft mit einem SVERWEIS gearbeitet hat, weiß nun, dass der englische Begriff hierfür VLOOKUP lautet.

Linke zur Website

* Ausgenommen Microsoft Access bis - ich glaube - Version 2010. Hier gab es früher eine Integration des MSSCCI Providers für die Anbindung an z.B. Visual Source Safe oder den TFS. Allerdings hat diese Funktion nicht bis heute überlebt und wurde auch nur selten genutzt.

 

Wie eine Attribute-Level Remediation in OIA funktioniert…

… wissen wir leider auch nicht.

Das heißt: Eigentlich schon. Aber es ist nicht gerade so, dass die Funktion besonders sinnvoll erscheint. Doch was ist damit eigentlich gemeint?

In Oracle Identity Analytics werden Daten vereinfacht gesagt wie folgt strukturiert:

image

 

Es gibt also globale Benutzer (darunter versteht der OIA Identitäten, also reale Menschen) und darunter Accounts. Sprich: Ein Mensch kann über mehrere Accounts (z.B. Anmeldekonten) verfügen. Jedem Account können mehrere Attribute zugewiesen sein, die den Account besser beschreiben. Dabei können Attribute auch verschachtelt werden. Beispielsweise ist es so möglich, folgendes abzubilden:

Global User > Account > Group Membership > Folder Permissions

In diesem Fall kann also ein Mitarbeiter über einen Account verfügen, der Mitglied in verschiedenen Gruppen ist, wobei jede Gruppe über spezifische Verzeichnisberechtigungen in irgendwelchen Netzwerk-Shares verfügt.

Attribute-Level Remediation

Unter Remediation versteht man in der Welt des OIA die Notwendigkeit von Korrekturen, die immer dann anstehen sollten, wenn eine IST-Situation von einem SOLL abweicht. Hat ein Mitarbeiter z.B. das Unternehmen verlassen, sein Account existiert aber nach wie vor im Active Directory, müsste bei einer Identity Certification genau das herauskommen: Der Zertifizierer bekommt den Mitarbeiter vorgelegt und lehnt ihn direkt ab (disclaim). Der OIA erkennt den Unterschied und führt den Benutzer der Korrekturverfolgung zu (Remediation Tracking).

Was aber, wenn nicht der Benutzer (bzw. die Identität oder wie der OIA sagen würde: der Global User), und auch nicht in dem Sinne dessen Account, sondern stattdessen Gruppenmitgliedschaften zertifiziert werden sollen – bzw. korrigiert werden sollen, falls IST und SOLL voneinander abweichen?

Dann ließe sich das – nach offizieller Aussage – mittels der Data Owner Certification abbilden. Neben der Benutzer-, Rollen- und Ressourcenbasierenden Zertifizierung ist das die Nummer vier im Bunde:

image

 

In dieser Art der Zertifizierung ließe sich nämlich auf Ebene der Attribute arbeiten. Dazu werden einfach die gewünschten Attribute ausgewählt:

image

 

Doch nun kommt der Pferdefuß: Wie bei allen anderen Zertifizierungstypen auch muss natürlich noch die Frage beantwortet werden, wer denn nun die Zertifizierung ausführen soll. Bei einer Identitätsbasierenden Zertifizierung kann das z.B. der Manager der jeweiligen Ressource sein, oder aber der Manager der jeweiligen Abteilung.

Bei der Data Owner Zertifizierung kann entweder nur ein einziger Mitarbeiter dazu auserkoren werden, oder aber – hence the name – der jeweilige Data Owner. Ein einziger Mitarbeiter wäre in den meisten aller Fälle unsinnig. Denn der müsste dann ja die entsprechenden Attribute aller Mitarbeiter des Unternehmens zertifizieren. Und in der Annahme, dass nur Großunternehmen ein Produkt wie den OIA einsetzen, gehe ich davon aus, dass einen Mitarbeiter mit dem Thema zu beschäftigen vermutlich gegen das Arbeitsschutzgesetz verstößt (oder wird Folter hier nicht berücksichtigt?).

Data Owner

Wer ist denn nun also der Data Owner?

Die Ressourcenansicht zeigt: Jedes einzelne Attribut an jedem einzelnen Account hat einen eigenen Data Owner:

image

 

Interessanter Fact am Rande: Die Frage danach ob es Sinn ergibt oder nicht mal beiseite gestellt, lassen sich Data Owner über die OIA Oberfläche hinzufügen. Die Sache ist nur die: Man kann sie nicht wieder entfernen (nur ein Hinweis, falls es jemand versuchen sollte).

Da aber auch hier ein gewissen Mengenproblem dem Tatendrang die Motivationsgrundlage entzieht, stellt sich also eher die Frage, ob sich der Data Owner beim Importieren der Accounts setzen lässt. Einen pfiffigen BI-Experten mit Kenntnissen in der Bedienung eines modernen ETL Tools vorausgesetzt wäre das doch die Lösung. Richtig?

Falsch. Denn der Data Owner lässt sich eben nicht automatisiert importieren.

Ende der Geschichte.

Falls jemand dazu andere Informationen vorliegen hat, oder einen Weg kennt, das Problem zu lösen, freue ich mich über einen Kommentar. Anderenfalls greife ich es vielleicht noch einmal auf, sollten wir selbst dazu eine Lösung finden (mir schwebt hier die Implementierung eines benutzerdefinierten Post-AccountImport Jobs vor – ähnlich den MaintenanceJobs und einer konfigurierbaren Zuordnung zwischen Attribute-Values und Data Ownern).

Nie wieder Ärger mit NuGet!

Vielleicht hast du das auch schon erlebt, wenn du NuGet und TFS verwendest:

Das Updaten eine NuGet Pakets erzeugt völliges Chaos in der Projektmappe:

Im Projektmappen-Explorer sieht alles gut aus. Die Ansicht „Ausstehende Änderungen“ im Team Explorer zeigt ein anderes Bild: Nur ein paar Dateien sind geändert, und viele Dateien sind gelöscht, obwohl sie ebenfalls geändert sein sollten.

Durch Einchecken wird das Projekt dann defekt: Dateien werden fälschlicherweise gelöscht, obwohl sie noch in den Projekten verwendet werden, und die Builds schlagen fehl.

TL; DR: Das Problem tritt nur bei lokalen Arbeitsbereichen (Local Workspace) auf. Benutze einen Serverarbeitsbereich (Server Workspace) zum Aktualisieren von NuGet Content-Paketen (Kurzanleitung siehe Ende des Artikels).

Was ist das Problem?

Das Problem tritt nur mit NuGet Paketen auf, die Dateien in das Projekt hineinkopieren, wie z.B. JavaScript Bibliotheken, Views, etc. Ich nenne diese Pakete „Content-Pakete“. Pakete, die nur DLLs referenzieren, sind nicht betroffen.

Beim Installieren eines Content-Pakets kopiert NuGet die Content-Dateien in dein Projekt und fügt die Dateien korrekt der Versionskontrolle hinzu.

Beim Update eines Content-Paketes geht NuGet vor wie immer:

Zunächst werden das Paket und alle dazugehörigen Dateien gelöscht; auch die in das Projekt kopierten Content-Dateien und alle DLL-Referenzen zu dem Paket entfernt. Daraus ergibt sich dann eine Anzahl von „Ausstehenden Löschungen“.

Im nächsten Schritt installiert NuGet dann die neue Version vom Paket, als wäre es die Erstinstallation: Das Paket landet im Paket-Verzeichnis, DLL-Referenzen werden hinzugefügt, und die Content-Dateien werden in das Projekt kopiert und als neue Dateien der Versionskontrolle hinzugefügt.

Hier fangen die Probleme an:
Die Content-Dateien sind immer noch als „Ausstehenden Löschungen“ in deinem Workspace markiert. Wenn NuGet versucht, genau diese Dateien wieder dem Projekt hinzuzufügen, stolpert der Team Explorer: Er erlaubt nicht, eine Datei der Versionskontrolle hinzuzufügen, für die im gleichen Workspace noch eine ausstehende Löschung besteht, sondern erwartet, dass man die Löschung erst eincheckt, und anschließend die Datei als neue Datei eincheckt. Sinnvoller wäre es, wenn der Team Explorer die ausstehende Löschung automatisch in eine ausstehende Änderung umwandelt.

Daraus entsteht das nächste Problem:
NuGet scheint von dem Fehler im Team Explorer nichts mitzubekommen, und kopiert die aktualisierten Content-Dateien auf die Festplatte und fügt sie dem Projekt hinzu (und meldet keine Fehler). Deshalb sieht im Solution Explorer alles gut aus: Alle Dateien sind dort wo sie hingehören, das Projekt kompiliert. Der Team Explorer sieht das anders: In der Ansicht „Ausstehende Änderungen“ sind die ausstehenden Löschungen immer noch vorhanden. Wenn man diesen Umstand nicht bemerkt und die offenen Änderungen eincheckt ist das Projekt für Alle defekt.

Falls man das Problem noch rechtzeitig bemerkt und versucht die ausstehenden Löschungen rückgängig zu machen, hat man auch verloren: Der Team Explorer weigert sich, die Löschungen rückgängig zu machen, da dadurch bestehende Dateien überschrieben werden würden… die Dateien die NuGet beim Update versucht hat in das Projekt hinzuzufügen!

Das Chaos manuell wieder aufzuräumen, und dabei sicherzustellen, dass man auch die aktuellen Versionen der Dateien an der richtigen Stelle hat, macht keine Freude.

Lösung

Die Problemlösung ist einfach: Benutze einen Server Arbeitsbereich zum Aktualisieren von Content- Pakete;, nur die lokalen Arbeitsbereiche sind betroffen (zumindest in der aktuellen NuGet Version 2.8.60318.667). Für meine tägliche Arbeit bevorzuge ich einen lokalen Arbeitsbereich, daher benutze ich einen zweiten Arbeitsbereich zur Aktualisierung von Content-Paketen.

Anlegen eines neuen Server Arbeitsplatzes in Visual Studio

  1. Datei > Quellcodeverwaltung > Erweitert > Arbeitsbereiche > Hinzufügen > Erweitert
  2. Sprechenden Namen eingeben, z. B. “Server Arbeitsbereich für Content-Package Updates”
  3. “Server” bei “Speicherort” auswählen
  4. OK

clip_image002

Neues zu TouchDevelop (jetzt auch für Minecraft)

Über TouchDevelop haben wir nicht nur hier, sondern auch auf Entwicklerkonferenzen berichtet. Wir haben gezeigt, wie einfach es ist, damit Anwendungen und Spiele auf sämtlichen Devices für sämtliche Devices zu entwickeln und als besonderes Highlight eine eigene (in TouchDevelop entwickelte) Bibliothek vorgestellt, mit der sich sogar ein Lego MindStorms Roboter programmieren ließ.

Mittlerweile nimmt aber die Aussage “für sämtliche Devices” ganz neue Dimensionen an. Statt einfach nur noch als HTML5 Anwendung in allen Browsern zu funktionieren, oder als App exportiert in den Windows (Phone) Store exportiert zu werden, sind inzwischen folgende Möglichkeiten hinzugekommen:

  • Export to App Studio (Windows, Windows Phone)
  • Export to Cordova Apps (iOS, Windows, Android)
  • Export to Azure Web Apps (Node.JS)
  • Export to Raspberry PI (Node.JS)
  • Export to Web App or Office Mix

Es gab vor längerem bereits Tutorials, die gezeigt haben, wie sich für den Arduino programmieren lässt (inkl. Simulation auf dem Touchdisplay eines Smartphones). Ganz neu hinzugekommen ist die Unterstützung für das BBC Projekt micro:bit.

Nachdem zurzeit allerdings Minecraft in aller Munde ist (es scheint sich seit dabei zu einem Signature-Game für Microsoft zu entwickeln), ist folgendes besonders interessant: Mit MinecraftEDU und MinecraftPI werden Versionen angeboten, die es möglich machen, Scripte für Minecraft mittels TouchDevelop zu entwickeln.

Hier ein Beispiel für den Bau einer Pyramide:

PyramidCraft

 

Ich würde sagen: Das klingt doch mal nach einem spannenden Wochenend-Projekt, oder? Hier der Link zur Dokumentation.

Und nun viel Spaß!

Kleine Freuden, die das Leben erleichtern

Manchmal sind es die einfachen Dinge, die uns am meisten begeistern, und oft brauchen sie auch gar nicht viele Wort, um beschrieben oder angekündigt zu werden. Deswegen also auch ganz kurz und bündig und ohne viele Umschweife:

Es wird im Team Foundation Server 2015 möglich sein, in allen Queries mit dem Parameter @CurrentIteration auf den aktuellen Sprint zu referenzieren!

TFS CurrentIteration

 

Das mag im ersten Moment nicht nach viel klingen, aber ich bin mir sicher, dass eingefleischte TFS Benutzer wenigstens einmal laut “Hurra” gerufen haben. Vorbei sind die Zeiten in denen Queries nach jedem Sprint angepasst werden mussten um eine aktuelle Übersicht zu haben, oder in denen alternative Werte herangezogen werden mussten um den gegenwärtigen Sprintstatus zu sehen.

Die Änderung wurde zusammen mit einigen weiteren Anpassungen im Bereich Kanban Karten, der Anzeige von Bugs im Taskboard und Syntax Highlighting für XML, Sass, Objective-C und R im Webeditor, in einem vor kurzen veröffentlichen Blogeintrag bekannt gegeben. Die weiteren Änderungen werden vorerst im Visual Studio Online (VSO) eingepflegt, aber sollten auch in die finale Version des TFS 2015 Einzug erhalten.

In den Schulen unterrichten sie Latein. Warum kein VBA?

Zugegeben, die Überschrift wirkt auf den ersten Blick provokant. Handelt es sich bei Latein doch um eine Sprache, die als Basis aller romanischen Sprachen mindestens die Einstiegshürde zum Erlernen dieser deutlich erleichtert. Heutige Redewendungen und auch viele Wortbedeutungen lassen sich aus der Kenntnis der Sprache Cäsars genauso ableiten, wie die Tatsache, dass die Rolle des “Kaisers” eben auf den Namen desselben Herrschers zurückzuführen ist. Achja… und für das Jura-Studium sowie das Studium der Medizin benötigt man es auch.

Und VBA? Eine tote Sprache? Genau wie Latein?

Mag sein. Nichts desto trotz haben nicht einmal Office Apps, Visual Studio Tools for Office oder selbst OLE Automation dazu geführt, dass VBA vollends in Vergessenheit geraten ist. Warum auch? Leichtgewichtiger geht es kaum: Der Visual Basic Editor (VBE) ist in die Office Produkte integriert, der Zugang ist extrem leicht, es werden keine zusätzlichen Lizenzen benötigt und sämtliche Belange von Word, Excel und Access lassen sich damit programmieren. Zudem benötigt es keine komplexen Installationssysteme und technisch gesehen auch keine Rollout-Gremien, um zeitnah Problemlösungen innerhalb einer Fachabteilung an den Start zu bekommen (was die IT Abteilung davon hält sei einmal dahingestellt).

Trotzdem. Ein ungutes Gefühl bleibt.

  • Es gibt keine integrierte Quellcodeverwaltung.
  • Unter modernen Gesichtspunkten sind viele Verhaltensweisen zunächst nicht nachvollziehbar.
  • Es gibt zwar Klassen und Interfaces (tatsächlich!), aber keine echte Polymorphie oder Funktionsüberladung.
  • Die Arbeit mehrerer Entwickler an einem Projekt gestaltet sich als sehr aufwändig.
  • Aufgrund der nur eingeschränkten Verwaltungsmöglichkeiten sind komplexe Projekte langfristig nur schlecht wartbar.
  • Die Fehlerbehandlung ist auf den ersten Blick wenig intuitiv.
  • etc.

Stellen wir uns aber der harten Realität: In großen sowie kleinen Unternehmen wird VBA innerhalb von speziell Excel und Access noch immer flächendeckend von den Fachabteilungen eingesetzt. Das Phänomen lässt sich nicht einmal auf bestimmte Branchen einschränken. Und so schnell wird sich das auch nicht ändern.

Daher liegt es in unserer Verantwortung, dafür zu sorgen, dass die Entwicklung (und damit auch unsere Dienstleistung) auch in diesem Kontext einem hohen Anspruch an Qualität gerecht wird. Quellcodeverwaltung, Nachvollziehbarkeit, Testing, Requirements-Engineering & Co sind dabei nur einige Stichworte. Und der Einsatz von VBA ist kein Grund, die modernen Prozesse zur Softwareentwicklung links liegen zu lassen.

Im Gegenteil.

Als Einstieg für die Interessierten hier ein paar Querverweise, die zeigen, dass da auch mehr geht:

In Projekten, in denen auch bei uns dann und wann mal VBA genutzt wird, verwenden wir übrigens selbstverständlich den Team Foundation Server für die Requirements, das Work Item Tracking und auch die Quellcodeverwaltung.

Neugierig? Sprechen Sie uns an!

Über die Autoren

Christian Jacob ist Leiter des Geschäftsbereiches Softwarearchitektur und -entwicklung und zieht als Trainer im Kontext der .NET Entwicklung sowie ALM-Themen Projekte auf links.

Marcus Jacob fokussiert sich auf die Entwicklung von Office-Addins sowie Windows Phone Apps und gilt bei uns als der Bezwinger von Windows Installer Xml.

Martin Kratsch engagiert sich für das Thema Projektmanagement mit dem Team Foundation Server und bringt mit seinen Java- und iOS-Kenntnissen Farbe in unser ansonsten von .NET geprägtes Team.

Aktuelle Kommentare

Comment RSS