<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Groschengedanken zu Software &#187; Lotus Notes</title>
	<atom:link href="http://aysx.de/eingroschen/?feed=rss2&#038;tag=lotus-notes" rel="self" type="application/rss+xml" />
	<link>http://aysx.de/eingroschen</link>
	<description>... und vielleicht auch dem ganzen Rest</description>
	<lastBuildDate>Tue, 18 Jun 2019 17:59:37 +0000</lastBuildDate>
	<language>de-DE</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Notes: Alle Teil-Formulare kennen; Interface</title>
		<link>http://aysx.de/eingroschen/?p=533</link>
		<comments>http://aysx.de/eingroschen/?p=533#comments</comments>
		<pubDate>Thu, 15 Jan 2015 18:55:41 +0000</pubDate>
		<dc:creator><![CDATA[matthias]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[xsl]]></category>

		<guid isPermaLink="false">http://aysx.de/eingroschen/?p=533</guid>
		<description><![CDATA[In der Programmier-Umgebung von Lotus Notes, &#8220;Designer&#8221; genannt, kann man Daten-Eingabemasken, sogenannte &#8220;Formulare&#8221;, erstellen. Ausserdem kann man im Designer Teil-Formulare erstellen. Ein Formular kann beliebig viele Teil-Formulare enthalten. Teil-Formulare clever nutzen Die Möglichkeit, Teil-Formulare zu erstellen und einzubinden, hat zwei &#8230; <a href="http://aysx.de/eingroschen/?p=533">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In der Programmier-Umgebung von Lotus Notes, &#8220;Designer&#8221; genannt, kann man Daten-Eingabemasken, sogenannte &#8220;Formulare&#8221;, erstellen. Ausserdem kann man im Designer Teil-Formulare erstellen. Ein Formular kann beliebig viele Teil-Formulare enthalten.</p>
<h2>Teil-Formulare clever nutzen</h2>
<p>Die Möglichkeit, Teil-Formulare zu erstellen und einzubinden, hat zwei Vorteile. Einen offensichtlichen und einen weniger offensichtlichen.</p>
<p>Der offensichtliche Vorteil ist die Möglichkeit, wiederkehrende Abschnitte zu kapseln. Wenn ich erkenne, dass ein gewisser Bereich in mehreren Formularen vorkommt, dann verschiebe ich diesen Bereich in ein Teil-Formular und entferne ihn aus den entsprechenden Formularen. An der Leerstelle setze ich jeweils das Teil-Formular ein. Das spart Schreibarbeit und folgt dem guten Muster &#8220;Don&#8217;t Repeat Yourself&#8221;. Wenn ich das Teil-Formular ändere, dann wirkt sich das auf alle Formulare aus, die das Teil-Formular verwenden.</p>
<p>Weniger offensichtlich ist dies: Ein Teil-Formular kann als Interface dienen. Seine Feldwerte werden dazu durch einen Event-Handler im Formular gesetzt, beispielsweise durch das Exiting-Event eines zugehörenden Feldes oder das QuerySave-Event des Formulars. Dadurch, dass ein Formular ein Teil-Formular einbindet, codifiziert das Formular, dass es das Interface des Teil-Formluars implementiert &#8211; um java-ähnlich zu sprechen.</p>
<h2>Teil-Formulare auflisten</h2>
<p>Die Notes-Pogrammierung, die ich von meinen Vorgängern geerbt habe, ist voll von Teilmasken und schlecht dokumentiert. Wie erkenne ich, welche Teil-Formulare in einem Formular eingebunden sind? Anders formuliert: Wie erkenne ich, welche Interfaces ein Formluar implementiert? Mit den Bordmitteln des Designer kommt man leider nicht weiter. Das Notes-eigene XML und eine Transformation beenden die Not.</p>
<p>Zum Glück hat jedes (Teil-)Formular eine XML-Repräsentation in einem Dialekt namens dxl. Und der Designer kann eine XML-Transformation auf auswählbare Elemente anwenden. Fehlt nur die passende Transformation. Hier ist sie:</p><pre class="crayon-plain-tag">&lt;?xml version="1.0"?&gt;
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:dxl="http://www.lotus.com/dxl"&gt;

&lt;xsl:output method="text" indent="yes"/&gt;

&lt;xsl:template match="/"&gt;
	&lt;xsl:apply-templates/&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="dxl:*"&gt;
	&lt;xsl:apply-templates select="dxl:*"/&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="dxl:subformref"&gt;
	&lt;xsl:value-of select="@name"/&gt;
&lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;</pre><p>Grafische Tools, wie der Designer eins ist, beschleunigen die Schaffung der Benutzeroberfläche enorm. Aber der gute alte Quelltext wird weiterhin seine Daseinberechtigung haben. Beruhigend.</p>
]]></content:encoded>
			<wfw:commentRss>http://aysx.de/eingroschen/?feed=rss2&#038;p=533</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passwort-Generator</title>
		<link>http://aysx.de/eingroschen/?p=364</link>
		<comments>http://aysx.de/eingroschen/?p=364#comments</comments>
		<pubDate>Wed, 16 Jul 2014 05:20:30 +0000</pubDate>
		<dc:creator><![CDATA[matthias]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Aufgabe]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Quelltext]]></category>

		<guid isPermaLink="false">http://aysx.de/eingroschen/?p=364</guid>
		<description><![CDATA[&#8220;Matthias&#8221;, sagte mein Chef, &#8220;wir brauchen mal eben einen Passwort-Generator&#8221; und schickte mir diese Anforderungen [crayon-69e15abe7e0e6460803785/] Das ist nicht schwer, oder? Die Kommentare im Java-Quelltext sind etwas ausführlicher als für mich üblich, weil ich hoffe, es allgemein unterhaltsam zu machen. &#8230; <a href="http://aysx.de/eingroschen/?p=364">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>&#8220;Matthias&#8221;, sagte mein Chef, &#8220;wir brauchen mal eben einen Passwort-Generator&#8221; und schickte mir diese Anforderungen</p>
<p></p><pre class="crayon-plain-tag">Zw. 8 - 14 Zeichen lang
Start und Ende KEIN Sonderzeichen
Mind. 2 Sonderzeichen
Mind. 2 Großbuchstaben
Mind. 2 Kleinbuchstaben
Mind. 2 Ziffern</pre><p> </p>
<p>Das ist nicht schwer, oder? Die Kommentare im Java-Quelltext sind etwas ausführlicher als für mich üblich, weil ich hoffe, es allgemein unterhaltsam zu machen. LotusScript ist unkommentiert &#8211; quick&#8217;n&#8217;dirty.</p>
<p>Der gezeigte Java-Quelltext entstand, nachdem ich die Aufgabe in LotusScript erledigt hatte. Die Variante in Java gefällt mir, weil sie deutlich zeigt, welche Anforderungen erfüllt werden. Der Quelltext in Java ist viel länger &#8211; das kann man als Nachteil werten. Aber er ist flexibler &#8211; dem LotusScript-Code kann man wegen der Starrheit keinen Vorwurf machen, denn schließlich musste es fertig werden.</p>
<p>Im grossen und ganzen beruhen beide auf derselben Idee, man erkennt viele Ähnlichkeiten, beispielsweise Definition der Menge auszuwählender Zeichen, beispielsweise zufallsgeleitetes finden einer freien Position.</p>
<p><a href="http://aysx.de/eingroschen/PasswordGenerator.jar">WordPress erlaubt es mir nicht, jar-Dateien hochzuladen. What a crap! Anyway, hier ist der Quelltext.</a> Du willst diesen Code benutzen? Erzeuge ein PasswordGenerator-Objekt und rufe getPassword auf. Deadsimple.</p>
<p>Im folgenden die wichtigsten Klassen.</p>
<p>PasswordGenerator</p><pre class="crayon-plain-tag">package de.aysx.pwgen;

import java.util.Random;

import de.aysx.pwgen.common.Auffueller;
import de.aysx.pwgen.common.Bedingungserfueller;
import de.aysx.pwgen.impl.AuffuellerAlleZeichen;
import de.aysx.pwgen.impl.AuffuellerGross;
import de.aysx.pwgen.impl.AuffuellerKlein;
import de.aysx.pwgen.impl.AuffuellerSZ;
import de.aysx.pwgen.impl.AuffuellerZiffer;
import de.aysx.pwgen.impl.KeinSZamAnfang;
import de.aysx.pwgen.impl.KeinSZamEnde;

/**
 * Einstiegspunkt für das Verständnis des PasswordGenerator-Projekts.
 * Diese Klasse wird benutzt, um ein Passwort zu generieren.
 * 
 * Kontrolliert, wie das Passwort erzeugt wird.
 * Steuert die Erzeuger-Klassen, steckt sie passend zusammen.
 *
 */
public class PasswordGenerator {

    /**
     * Minimale Länge des Passworts.&lt;br&gt;
     * Wenn man es noch flexibler möchte, dann macht man aus diesem Wert eine
     * Variable. Für's erste ist es eine Konstante.
     * 
     */
    public static final int MIN = 8;
    
    /**
     * Maximale Länge des Passworts.&lt;br&gt;
     * s.a. MIN.
     */
    public static final int MAX = 14;

    /**
     * 
     * @return ein zufälliges Password, das den Anforderungen entspricht.
     */
    public String getPassword() 
    {
        int lange = zufallsLaenge(); // Eine Zahl zwischen MIN und MAX.
        int egal = 0; // Wird für die syntaktische Korrektheit benötigt.

        /* Diese Variable enthält die Zeichen des Passworts. Noch ist 
         * sie leer.
        */
        char[] c = new char[lange];
        
        /* Hier spiegelt sich deutlich die Anforderung wider, welche Zeichen 
         * enthalten sein sollen und wieviele jeweils.
         * SZ steht für "Sonderzeichen".
         */
        Auffueller fueller =
                new AuffuellerKlein     ( 2,
                new AuffuellerSZ        ( 2,
                new AuffuellerZiffer    ( 2,
                new AuffuellerGross     ( 2,
                /* Wenn das PW mehr als 8 Zeichen hat, dann wird der restliche
                         Freiraum mit beliebigen Zeichen aufgefüllt. Die 
                         Anzahl ist "egal", weil ein AuffuellerAlleZeichen
                         dafür sorgt, dass alle restlichen freien Positionen 
                         belegt werden. */
                new AuffuellerAlleZeichen ( egal, null )))));

        /* Ein weiterer Teil der Anforderung - deutlich sichtbar mit
         * wenig Phantasie.
         */
        Bedingungserfueller bed =
                new KeinSZamAnfang  (
                new KeinSZamEnde    (null));

        // Passwort erzeugen, Variable c verändern; Obacht: Output-Parameter.
        fueller.fuelle ( c );
        bed.pruefenKorrigierenWeitergeben ( c, 0, c.length - 1 );

        // Rückgabewert aufbereiten;
        String erg = "";
        for (int i = 0; i &lt; c.length; i++) {
            erg += new Character(c[i]);
        }
        
        // Fertig. Der uninteressierte Leser kann hier aufhören.
        return erg;
    }

    /**
     * @return eine Zahl zwischen MIN und MAX;
     */
    private int zufallsLaenge() {
        int erg = 0;
        Random r = new Random();
        erg = MIN + r.nextInt(MAX - MIN + 1);
        return erg;
    }
}</pre><p> </p>
<p>Konstanten</p><pre class="crayon-plain-tag">/**
 * Konstanten im Projekt PasswordGenerator.
 */
public class Constants
{
    /* Auf Wunsch sind einige Zeichen nicht enthalten. */
    public static final String SONDERZEICHEN = "!§$%&amp;/()=}][{-_.:,;&lt;&gt;"; 

    /* Kleinbuchstaben */
    public static final String KLEINBUCHSTABEN = "abcdefghijklmnopqrstuvwxyz"; 

    /* Grossbuchstaben */
    public static final String GROSSBUCHSTABEN = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /* Ziffern */
    public static final String ZIFFERN = "0123456789";
	
}</pre><p></p>
<p>Auffueller</p><pre class="crayon-plain-tag">package de.aysx.pwgen.common;

import java.util.Random;

/**
 * Fuellt ein Char[] mit der angegebenen Anzahl von Zeichen.&lt;br&gt;
 * Danach wird der nächste Auffueller aufgerufen, wenn einer vorhanden ist.&lt;br&gt;
 * &lt;br&gt;
 * Die unterschiedlichen konkreten Ausprägungen dieser Klasse leisten 
 * wesentlich eins: Sie stellen eine jeweils passende Menge von Zeichen zur
 * Verfügung, aus der mittels Zufallsgenerator eine bestimmte Anzahl ausgewählt
 * wird.&lt;br&gt;
 * Beispiel: AuffuellerGross ( 2, ...) kennt alle Grossbuchstaben und wählt
 * aus dieser Menge zwei Buchstaben aus.
 */
public abstract class Auffueller {

    public Auffueller(int zeichenAnzahl, Auffueller next) {
        setAnzahl(zeichenAnzahl);
        setNext(next);
    }

    /**
     * Aus welcher Zeichenklassen sollen Zeichen gezogen werden? Aus dieser!
     */
    public abstract String getZeichenklasse();

    /**
     * Wieviele Zeichen sollen gezogen werden? So viele!
     */
    public int getAnzahl() {
        return anzahl;
    }

    /** 
     * Diskutieren: Soll dieser Member immutable sein?
     * s.a. http://en.wikipedia.org/wiki/Immutable
     */
    public void setAnzahl(int i) {
        anzahl = i;
    }
    
    private int anzahl;

    /**
     * Ein Auffueller kann einen anderen Auffueller dekorieren, so dass zuerst
     * das eine getan wird und dann der nächste Auffueller das nächste tut usw.
     * bis zum Ende der Kette.
     * 
     * @return Den dekorierten Auffueller.
     */
    public Auffueller getNext() {
        return nextAuffueller;
    }

    /** 
     * TODO: Immutable?
     */
    public void setNext(Auffueller a) {
        nextAuffueller = a;
    }
    
    private Auffueller nextAuffueller;

    /**
     * TODO Beachten Konstraints, z.B. Laenge des Arrays &gt;= getAnzahl, z.B.
     * Anzahl der freien Plätze im Array &gt;= getAnzahl. Erstmal gehe ich davon
     * aus, dass schon alles gutgeht. Dieser Code ist noch provisorisch.&lt;br&gt;
     * 
     * @param c das zu fuellende Array
     * @return ein char[], das entsprechend diesem Auffueller und seinen
     *         dekorierten Auffuellern bearbeitet wurde.
     */
    public char[] fuelle ( char[] c )
    {
        for (int i = 0; i &lt; getAnzahl(); i++) {
            c [ getLeerePosZufaellig ( c )] = getZufallschar ();
        }

        /* Wie Yoda ich spreche, weil oft zum Vorteil es ist in LotusScript
         * und abgefärbt das hat. http://de.wikipedia.org/wiki/Yoda_Conditions
         */
        if (null != getNext()) {
            getNext().fuelle(c);
        }

        return c;
    }

    /**
     * @return Ein Zeichen, das zufällig aus der Menge der hier bekannten
     * Zeichen ausgewählt wird.
     */
    public char getZufallschar ()
    {
        Random random = new Random ();
        int max = getZeichenklasse ().length ();
        int pos = random.nextInt ( max );
        char erg = getZeichenklasse ().charAt( pos );
        return erg;
    }

    /**
     * Im LotusScript findet sich eine andere Implmentierung und die
     * Idee zum folgenden Allgorithmus.
     *
     * @param c Das zu füllende Array.
     * @return Eine zufällig ausgewählte leere Stelle in c.
     */
    private int getLeerePosZufaellig ( char[] c )
    {
        int erg = 0;
        
        /* Anzahl Leerstelle ermitteln. */
        int anzahlLeer = 0;
        for ( int i = 0; i < c.length; i++ ){
            if ( 0 == c[i]){
                anzahlLeer ++;
            }
        }
        
        /* Mapping Leerstelle zu Index. */
        int[] auswahl = new int [ anzahlLeer ];
        int k = 0;
        for ( int i = 0; i < c.length; i++ ){
            if ( 0 == c[i]){
                auswahl [k] = i;
                k ++;
            }
        }
        
        /* Zufaellig auswaehlen und Zurueck-mapping. */
        Random r = new Random ();
        erg = r.nextInt ( anzahlLeer );
        return auswahl [erg];
    }
}</pre><p> </p>
<p>Bedingungserfueller</p><pre class="crayon-plain-tag">package de.aysx.pwgen.common;

/**
 * Prüft, ob ein Char[] einer bestimmten Bedingung genügt.&lt;br&gt;
 * Wenn es der Bedingung nicht genügt, dann werden Zeichen getauscht, so
 * dass die Bedingung erfüllt ist.&lt;br&gt;
 * Nachdem die Bedingung erfüllt ist, wird das zu prüfende Array an den
 * nächsten Bedingungsprüfer weitergegeben (Dekorator-Pattern).
 * 
 */
public abstract class Bedingungserfueller
{
    private Bedingungserfueller next;

    /**
     * @return Der nächste Bedingungserfüller. Darf null sein.
     */
    public Bedingungserfueller getNext ()
    {
            return next;
    }

    public void setNext ( Bedingungserfueller next )
    {
            this.next = next;
    }

    public Bedingungserfueller ( Bedingungserfueller next )
    {
            this.next = next;
    }

    /**
     * Diese Methode prüft, ob die jeweils zu implementierende Bedingung erfüllt
     * ist. Falls nicht, wird korrigiert. Und wenn es einen nächsten 
     * Bedingungserfüller gibt, dann wird er aufgerufen.
     * 
     * @param c das zu prüfende Array
     * @param vonPos Die Stelle, von der an das Array geprüft und verändert 
     * werden soll. Wenn ich z.B. einen Erste-Stelle-Prüfer habe, und der hat die erste
     * Stelle korrigiert, dann muss verhindert werden, dass die Korrektur verändert
     * wird. Das erreiche ich, indem der vonPos einen passenden Wert hat.
     * 
     * @param bisPos Die Stelle, bis zu der das Array geprüft und verändert
     * werden soll. Gegenstück zu vonPos.
     * 
     * @return ein korrigiertes Array.
     *
     * TODO Methode umbenennen, weil "Weitergeben" redundant ist.
     */
    public abstract char[] pruefenKorrigierenWeitergeben ( char[] c, int vonPos, int bisPos );
	
}</pre><p> </p>
<p>Die konkreten Implementierungen von Auffueller und Bedingserfueller finden sich in der jar-Datei.</p>
<p>Und nun zu etwas ganz anderem: Ein Password-Generator in LotusScript. Entstanden ist er nach einer Skizze an der Tafel. So sind einige Grobheiten enthalten, Beispiel die Variablen S, T, G, K, Z, die zugehörenden *unten und *oben und deren Initialisierung. Die Java-Implementierung hat davon &#8220;gelernt&#8221;. Änderungen werden an diesem Quelltext nicht mehr vorgenommen: Er funktioniert, ist ausreichend schnell und leserlich, so daß auch die Kollegen ihn warten können. Mission erfüllt.</p><pre class="crayon-plain-tag">'++LotusScript Development Environment:2:5:(Options):0:74
%REM
	Library RandomPassword
	Created 10.07.2014 by
	Description: Comments for Library
%END REM
Option Public
Option Declare


'++LotusScript Development Environment:2:5:(Forward):0:1
Declare Sub Initialize
Declare Function pickZufallUndEntferne ( stringArray As Variant ) As String
Declare Function ArrayToString (  stringArray As Variant ) As String
Declare Function findeLeerePosZufaellig ( stringArray As Variant ) As Integer
Declare Function berechnePassword As String

'++LotusScript Development Environment:2:5:(Declarations):0:10
Dim S As String
Dim Sunten As Integer
Dim Soben As Integer

Dim T As String
Dim Tunten As Integer
Dim Toben As Integer

Dim G As String
Dim Gunten As Integer
Dim Goben As Integer

Dim K As String
Dim Kunten As Integer
Dim Koben As Integer

Dim Z As String
Dim Zunten As Integer
Dim Zoben As Integer

Dim sonder (1 To 2 ) As String
Dim gkz (1 To 6 ) As String

Dim Laenge_min As Integer
Dim Laenge_max As Integer
Dim Laenge_akt As Integer

'++LotusScript Development Environment:2:2:Initialize:1:10
Sub Initialize
	' ---------------------------------------------------------------------------------------
	' init Konstanten
	' ---------------------------------------------------------------------------------------
	S = "!§$%&amp;/()=*'_:;,.-&lt;&gt;"
	Sunten = 1
	Soben = Len ( S )
	
	T = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	Tunten = 1
	Toben = Len ( T )
	
	G = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	Gunten = 1
	Goben = Len ( G )
	
	K = "abcdefghijklmnopqrstuvwxyz"
	Kunten = 1
	Koben = Len ( K )
	
	Z = "0123456789"
	Zunten = 1
	Zoben = Len ( Z )
	
	Laenge_min = 8
	Laenge_max = 14
	Laenge_akt = ( Laenge_max - Laenge_min )*Rnd() + Laenge_min
	
	' ---------------------------------------------------------------------------------------
	' init Variablen
	' ---------------------------------------------------------------------------------------
	
	Dim i As Integer
	i = 0
	Dim tmp As Integer
	
	For i = 1 To 2
		tmp = ( Soben - Sunten )*Rnd() + Sunten
		sonder ( i ) =  Mid ( S, tmp, 1 )
	Next
	
	For i = 1 To 2
		tmp = ( Goben - Gunten )*Rnd() + Gunten
		gkz ( i ) =  Mid ( G, tmp, 1 )	
	Next
	
	For i = 3 To 4
		tmp = ( Koben - Kunten )*Rnd() + Kunten
		gkz ( i ) =  Mid ( K, tmp, 1 )	
	Next
	
	For i = 5 To 6
		tmp = ( Zoben - Zunten )*Rnd() + Zunten
		gkz ( i ) =  Mid ( Z, tmp, 1 )		
	Next
	
	Dim erg As String
	erg = ArrayToString ( sonder )
	erg = erg + ArrayToString ( gkz )
End Sub

'++LotusScript Development Environment:2:1:pickZufallUndEntferne:5:8
%REM
	Function pickZufallUndEntferne
	Description: Comments for Function
%END REM
Function pickZufallUndEntferne ( stringArray As Variant ) As String
	Dim max As Integer
	max = UBound( stringArray )
	
	Dim tmp As Integer
	tmp = ( max - 1 ) * Rnd() + 1
	
	Dim erg As String
	erg = stringArray ( tmp ) 
	
	While ( erg = "" )
		tmp = ( max - 1 ) * Rnd() + 1
		erg = stringArray ( tmp ) 
	Wend
	
	stringArray (tmp) = ""
	pickZufallUndEntferne = erg
End Function

'++LotusScript Development Environment:2:1:ArrayToString:2:8

Function ArrayToString (  stringArray As Variant ) As String
	Dim erg As String
	erg = ""
	ForAll x In stringArray
		erg = erg + x
	End ForAll
	ArrayToString = erg
End Function

'++LotusScript Development Environment:2:1:findeLeerePosZufaellig:5:8
%REM
	Function findeLeerePosZufaellig
	Description: Bedenke, dass es lange dauert in einem grossen 
        Array, das nur noch eine Leerstelle hat, die freie Stelle so zu "finden".
        Vorschlag, Skizze: Sei n Anzahl Leerstellen und es gebe ein 
        Mapping für 0 <= i <= n für den Index der Leerstelle. Berechne k als Zufallszahl 
        zwischen 0 und n-1 und ermittle durch das Mapping den gesuchten Index.
%END REM
Function findeLeerePosZufaellig ( stringArray As Variant ) As Integer
	Dim erg As Integer
	erg = 0
	
	Dim s As String
	s = stringArray ( erg )
	
 	Dim max As Integer
 	max = UBound( stringArray )
	
 	While ( s &lt;&gt; "" )
            erg = ( max - 1 ) * Rnd() + 1
 	    s = stringArray ( erg )
 	Wend
	
	 findeLeerePosZufaellig = erg
End Function

'++LotusScript Development Environment:2:1:berechnePassword:5:8
%REM
	Function berechnePassword
	Description: Comments for Function
%END REM
Function berechnePassword As String
	Call Initialize()
	Dim erg () As String
	ReDim erg ( Laenge_akt ) As String 
	
        ' Kein SZ am Anfang und Ende.
	erg (0) = pickZufallUndEntferne ( gkz )
	erg ( Laenge_akt-1 ) = pickZufallUndEntferne ( gkz )
	
	Dim rndPos As Integer
	
        ' Grossbuchstaben, Kleinbuchstaben und Ziffern verteilen.
	ForAll x In gkz
		If Not ( x = "" ) Then 
			rndPos = findeLeerePosZufaellig( erg )
			erg ( rndPos ) = x
		End If
	End ForAll
	
        ' Sonderzeichen verteilen.
	ForAll x In sonder
		rndPos = findeLeerePosZufaellig( erg )
		erg ( rndPos ) = x
	End ForAll
	
	' Nun enthaelt erg 8 nicht-leere Zeichen.
	' Die Leerstellen fuellen mit Zufallsstelle aus T.
	ForAll x In erg
		If ( x = "" ) Then
			rndPos = ( Toben - Tunten )*Rnd() + Tunten
			x = Mid ( T, rndPos, 1 )
		End If 
	End ForAll
	
	berechnePassword = ArrayToString( erg )
End Function</pre><p> </p>
<p>Im LotusScript hat man einen guten Überblick über den gesamten konkreten Algorithmus, in Java erkennt man nur Umrisse. Die Java-Klassen kann ich an anderer Stelle wiederverwenden a) falls so etwas wieder gebraucht wird &#8211; mit der Perspektive &#8220;nie&#8221; und b) falls ich mich daran erinnere, dass die genau passenden Klassen genau hier zu finden sind. Das LotusScript ist &#8220;nur&#8221; als ganzes wiederverwendbar. Nur weil es nicht objektorientiert ist, heisst das nicht, dass es schlecht ist. Just because you&#8217;re paranoid it don&#8217;t mean they&#8217;re not after you. Have a nice day.</p>
]]></content:encoded>
			<wfw:commentRss>http://aysx.de/eingroschen/?feed=rss2&#038;p=364</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tabellen in Lotus Notes</title>
		<link>http://aysx.de/eingroschen/?p=213</link>
		<comments>http://aysx.de/eingroschen/?p=213#comments</comments>
		<pubDate>Wed, 20 Nov 2013 17:59:43 +0000</pubDate>
		<dc:creator><![CDATA[matthias]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[asymmetrie]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Symmetrie]]></category>

		<guid isPermaLink="false">http://aysx.de/eingroschen/?p=213</guid>
		<description><![CDATA[IBM erklärt, wie man eine Tabelle mit komprimierbaren Abschnitten in Lotus Notes erstellen kann. Wer die Beschreibung liest und die Grafik mit den Pastell-Tönen studiert, merkt, dass nichts zur Bedienung so einer Tabelle geschrieben steht. Es geht so: Klicke auf &#8230; <a href="http://aysx.de/eingroschen/?p=213">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>IBM erklärt, wie man eine <a title="Tabelle mit komprimierbaren Abschnitten erstellen" href="http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/topic/com.ibm.notes85.help.doc/doc_create_collapsible_table_t.html" target="_blank">Tabelle mit komprimierbaren Abschnitten in Lotus Notes</a> erstellen kann.</p>
<p>Wer die Beschreibung liest und die Grafik mit den Pastell-Tönen studiert, merkt, dass nichts zur Bedienung so einer Tabelle geschrieben steht. Es geht so: Klicke auf das Maximieren-Symbol in einer Zeile, dann wird der zugehörende Abschnitt aufgeklappt. Das ist alles. Das ist alles?!? Wie klappe ich so einen Abschnitt wieder zu? Indem ich auf den Maximieren-Knopf eines anderen Abschnitts klicke. Das geht klar, solange die Abschnitte so klein sind wie auf der IBM-Seite. Im echten Leben sind die Abschnitte größer, also ist auch der Abstand der Maximieren-Symbole größer, und das ist nicht bequem zu bedienen. Grundübel: Mangel an Symmetrie, nur &#8220;auf&#8221;, kein &#8220;zu&#8221;. Einen Architekten, der eine derartige Tür einbaut, schickt man zum Teufel.</p>
<p>Zum Glück kann man <a title="Tabelle mit Registern erstellen" href="http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.notes85.help.doc%2Fdoc_create_tabbed_table_t.html" target="_blank">eine Tabelle mit Registern erstellen</a>. Ich finde, das ist ein mächtig cooles Feature von Notes. Es sorgt für Ordnung in der Benutzeroberfläche und es ist bequem zu bedienen.</p>
]]></content:encoded>
			<wfw:commentRss>http://aysx.de/eingroschen/?feed=rss2&#038;p=213</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Besser nicht AppendItemValue</title>
		<link>http://aysx.de/eingroschen/?p=170</link>
		<comments>http://aysx.de/eingroschen/?p=170#comments</comments>
		<pubDate>Tue, 19 Nov 2013 05:01:43 +0000</pubDate>
		<dc:creator><![CDATA[matthias]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[asymmetrie]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Symmetrie]]></category>

		<guid isPermaLink="false">http://aysx.de/eingroschen/?p=170</guid>
		<description><![CDATA[In der Klasse NotesDocument in Lotus Notes 8 gibt es eine Methode AppendItemValue (itemName$, value). Zitat aus der API-Doku: If the document already has an item called itemName$, AppendItemValue does not replace it. Instead, it creates another item with the &#8230; <a href="http://aysx.de/eingroschen/?p=170">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In der Klasse NotesDocument in Lotus Notes 8 gibt es eine Methode AppendItemValue (itemName$, value). Zitat aus der API-Doku:</p>
<blockquote><p>If the document already has an item called itemName$, AppendItemValue does not replace it. Instead, it creates another item with the same name, and gives it the value you specify.</p></blockquote>
<p>Und es gibt NotesDocument.GetFirstItem ( name$ ). Zitat aus der API-Doku:</p>
<blockquote><p>However, the recommendation is that you avoid creating multiple items with the same name.</p></blockquote>
<p>Die Bedienungsanleitung von GetFirstItem legt also nahe, AppendItemValue nicht zu nutzen. Seltsam, dass so eine Situation entstanden ist.</p>
<p>Für meine Aufgabe habe ich schließlich NotesItem.AppendToTextList ( value$ ) benutzt. Das zeigt eine Schieflage: Es gibt keine Möglichkeit, einen hinzugefügten Wert wieder zu entfernen.</p>
<p>Also habe ich zwei Programmierungen ergänzt: Zum einen AppendTextToItemsTextlist ( name$, wert$ ) und zum anderen RemoveFromTextList ( wert$ ), jeweils in den entsprechenden <a title="Wrapper Pattern" href="http://c2.com/cgi/wiki?WrapperPattern" target="_blank">Wrapper-Klassen</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aysx.de/eingroschen/?feed=rss2&#038;p=170</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
