14 September 2011

InfoPath: Mehrsprachigkeit in Formularen

Um mehrsprachige Formulare umzusetzen, gibt es im Wesentlichen drei verschiedene Möglichkeiten. Jede hat Vor- und Nachteile, die es im entsprechenden Anwendungsfall zu berücksichtigen gilt.

1. Mehrere verschiedene Inhaltstypen erstellen
Die erste und für die Erstellung einfachste Variante ist, ein Formular in einer Sprache zu publizieren. Anschliessend werden die Texte übersetzt und das Formular als zweiten Inhaltstyp publiziert (resp. für jede Sprache wird das Formular als neuer Inhaltstyp publiziert).

Vorteile:


  • Einfache Erstellung.

  • Der Benutzer muss im Formular selbst keine Sprache wählen.

Nachteile:



  • Verschiedene Inhaltstypen (je nach dem komplizierter für Auswertungen)

  • Kein allgmeiner Link zum Formular möglich (für jede Sprache ein separater Link, kann auch ein Vorteil sein).

  • Aufwändig bei Änderungen, jede Änderung muss in jedem Formular gemacht werden. Datenfelder müssen alle jeweils neu erstellt werden.

  • Mapping auf SharePoint-Spalten etwas kompliziert.

  • Jeder Benutzer muss das Formular in der Sprache sehen, in der es ausgefüllt wurde.

  • Aufwändiger für dazugehörige Workflows, da diese auf mehrere Inhaltstypen publiziert werden müssen.

2. Verschiedene Ansichten im Formular
Die Zweite Variante ist wahrscheinlich für die meisten Anwendungsfälle am besten geeignet. Hier wird nur ein Formular erstellt. Innerhalb des Formulars wird für jede Sprache eine separate Ansicht erstellt. Ausserdem wird eine Default-Ansicht erstellt, in der der Benutzer seine gewünschte Sprache auswählen kann (Für jede Sprache ein Button, beim Klick darauf wird die Ansicht gewechselt).


Vorteile



  • Weniger Aufwändig bei Änderungen, da die Datenfelder in jeder Ansicht wiederverwendet werden.

  • Jeder Benutzer kann das Formular in seiner gewünschten Sprache bearbeiten, egal in welcher Sprache dieses ausgefüllt wurde.

  • Einfaches Mapping auf SharePoint-Spalten.

  • Es wird nur ein Inhaltstyp benötigt.

Nachteile:



  • Änderungen am Formular sind aufwändiger als bei der dritten Variante, da Textanpassungen in jeder Ansicht gemacht werden müssen.

  • Der Benutzer muss beim Öffnen eines Formulars immer zuerst eine Sprache auswählen.

Allenfalls können die Button zur Sprachänderung auch auf jeder Ansicht abgebildet werden. Somit könnte das Formular in einer Default-Sprache geöffnet werden und die Benutzer können die Sprache bei Bedarf jederzeit ändern.

3. Sprachfelder in SharePoint-Liste pflegen
Die letzte Variante ist wahrscheinlich die elganteste Variante um Mehrsprachigkeit in Formularen abzubilden. Diese Variante benötigt ebenfalls nur einen Inhaltstyp und kommt sogar auch nur mit einer einzigen Ansicht für alle Sprachen zurecht. Änderungen am Formular sind daher einfach durchzuführen, allerdings ist die Erstellung des Formulars am aufwendigsten.


Die Texte, die im Formular verwendet werden, werden in einer SharePoint-Liste gepflegt. Im Formular gibt es für jede Sprache ein Radio-Button, das ausgewählt werden kann. Die Texte im Formular werden in Form-Felder geschrieben, die aufgrund der Auswahl im Radio-Button aus der SharePoint-Liste ausgelesen werden.


Ein paar Texte können so nicht abgebildet werden (z.B. Personenfelder). Diese müssen für jede Sprache auf dem Formular abgebildet werden (innerhalb von separaten Sections), die dann bei Nicht-Bedarf einfach ausgeblendet werden.


Vorteile:



  • Nur ein Formular und eine Ansicht.

  • Wartungsfreundlich. Kleinster Aufwand bei Änderungen

  • Default-Sprache möglich (z.B. 80% der Benutzer müssen keine Sprachauswahl mehr machen, da sie mit der Default-Sprache arbeiten).

  • Einfache Anpassungen an Texten können in der SharePoint-Liste gepflegt werden. => Keine Anpassungen am Formular notwendig.

  • Jeder Benutzer kann das Formular in seiner gewünschten Sprache bearbeiten, egal in welcher Sprache dieses ausgefüllt wurde.

  • Es wird nur ein Inhaltstyp benötigt.

  • Einfaches Mapping auf SharePoint-Spalten.

Nachteile:



  • Aufwändig in der Erstellung.

InfoPath: Benutzen von SharePoint Standard-Workflows für InfoPath Forms

Szenario:
Nach dem Speichern und schliessen eines Formulares soll der Approval Prozess gestartet werden, der an den Vorgesetzten des Erstellers geht. Der Vorgesetzte wird im Formular angegeben.

Problem:
Der Vorgesetzte kann nicht im Listenworkflow vorkonfiguriert werden, da dieser in jedem Workflow unterschiedlich ist. Nach dem Speichern des Formulars erscheint auch nicht automatisch das Workflow-Formular, in dem der Benutzer die Workflow-Empfänger konfigurieren kann.

Lösung:
Der Vorgesetzte wird bereits im InfoPath Formular als Peoplepicker-Feld angegeben. Das Feld "AccountID" des Vorgesetzten wird auf den Sharepoint gemappt. Anschliessend wird ein SharePoint-Designer Workflow erstellt der wie folgt aufgebaut ist:

Step 1
Vorgang 'Genehmigung' für 'Current Item' mit 'Current Item:Vorgesetzter' starten.
dann Workflow beenden.

Über den SharePoint-Designer Workflow lässt sich der Standard Approval Workflow starten und mit bereits vorhandenen Daten aus dem Formular konfigurieren.

Der Workflow muss so eingestellt werden, dass er bei einem neuen Element automatisch startet.

Automatische Nummerierung von Formularen

Bei vielen Formularprojekte tritt die Anforderung auf, dass Formulare automatisch durchnummeriert werden sollen. Diese Anforderung kann wie folgt abgedeckt werden:


1. Datenverbindung Einrichten zum Empfangen von Inhalten.
Die Datenverbindung zeigt auf die SharePoint-Bibliothek in welche die Formulare gespeichert werden. Die Daten müssen nicht automatisch beim Öffnen des Formulars abgerufen werden.
Wichtig ist hier, dass die Spalte ID ausgewählt ist.


2. Regeln beim Submitten definieren
Unmittelbar bevor das ausgefüllte Formular gespeichert wird, muss die Datenabfrage gemacht werden. Am besten wird dazu auf dem Speicher-Button eine Regel zum abfragen der Daten hinzugefügt.
Anschliessend wird die Laufnummer in ein dafür vorgesehenes Feld geschrieben.
Die Laufnummer wird wie folgt generiert: max(ID) + 1
Die Spalte ID stammt aus der externen Datenquelle, die in Schritt 1 erstellt wurde. Dadurch wird die höchste ID ausgelesen und eins dazugezählt. Jedes ausgefüllte Formular erhält dadurch eine Laufnummer.


Wichtig



  • Das Generieren der Laufnummer muss unmittelbar vor dem Speichern geschehen. Wenn diese zu Beginn generiert wird, können mehrere Formulare dieselbe Laufnummer erhalten wenn mehrere Benutzer gleichzeitig am Formulare ausfüllen sind.

  • Die Laufnummer darf nur generiert werden, wenn noch keine Laufnummer generiert wurde. Also nur beim erstmaligen Speichern des Formulars. Dies muss in der Regel berücksichtigt werden. Zum Beispiel mit der Condition:
    Laufnummer is blank.

InfoPath: Form Library oder Liste mit Customized Form?

In folgenden Fällen sollte eine Liste mit customized Form verwendet werden:


  • Wenn schnell, einfach und mit kleinem Aufwand gearbeitet werden soll

  • Wenn das Formular offline mit SharePoint Workspace zur Verfügung stehen soll

  • Wenn die SharePoint-Liste basierend auf Personen oder Gruppen gefiltert werden sollen. (nur ihre eigenen Elemente sehen)

  • Wenn die Built-in Display und Edit-Ansichten verwendet werden sollen

In folgenden Fällen muss eine Formularbibliothek verwendet werden:



  • bei wiederholenden Daten (Repeating Table, oder Section)

  • komplexe Schemen

  • Das Formular muss digital signiert sein

  • wenn Code verwendet wird im Formular

  • Wenn das Formular nicht auf SharePoint verwendet wird

  • Wenn das Formular schön ausgedruckt werden soll

InfoPath: Personenfelder Mappen

Personenfelder aus dem InfoPath können tatsächlich nicht direkt auf Personenfelder im SharePoint gemappt werden. Hoffentlich kommt das in einer späteren Version. Im Moment kann es nur durch einen Workflow (oder Eventhandler) gelöst werden. Es muss wie folgt vorgegangen werden:



  1. Account-ID des Personenfeldes auf ein Textfeld im SharePoint mappen (DisplayName ist nicht eindeutig).

  2. Workflow im Designer erstellen, der beim Erstellen eines Formulars startet.

  3. Workflow überprüft ob das Textfeld leer ist.

  4. Wenn das Feld nicht leer ist schreibt er die AccountID aus dem Textfeld in ein PeopleFeld aus dem SharePoint. Da die Account-ID eindeutig ist, kann sie in jedem Fall aufgelöst werden und es gibt keinen Fehler. (Wird der Displayname verwendet gibt es hier einen Fehler, sofern es mehrere gleiche Displaynamen gibt).

  5. In der Ansicht oder Auswertungen kann das Personenfeld von SharePoint verwendet werden, das Textfeld wird für den Endbenutzer nicht benötigt und muss nicht angezeigt werden.

Hinweis: Das Personenfeld ist natürlich erst ausgefüllt wenn der Workflow gestartet ist. Gleich nach dem Abspeichern ist das Feld also noch ein paar Sekunden leer.

InfoPath: Erster Wert aus SharePoint-Liste als Default in Dropdown-Feld

Problem
Ein Dropdown wird mit Werten aus einer SharePoint-Liste gefüllt. Der erste Wert soll dabei defaultmässig ausgewählt sein.

Lösung
Um den ersten Wert aus einer SharePoint-Liste als Default in einem Dropdownfeld zu setzen muss wie folgt vorgegangen werden:




  1. Default-Wert des Dropdown bearbeiten


  2. Formula öffnen und "Edith xPath" Häckchen aktivieren


  3. folgender Default-Wert eintragen: xdXDocument:GetDOM("Kunden")/dfs:myFields/dfs:dataFields/d:SharePointListItem_RW[1]/d:Title (Kunden durch den Namen der Datenverbindung ersetzen).

InfoPath: Dropdown zeigt nicht alle Werte aus SharePoint-Liste an

Problem
Ein Dropdownfeld soll mit Werten aus einer SharePoint-Liste abgefüllt werden. Die Liste beinhaltet aber so viele Einträge, dass nicht alle im InfoPath im Dropdown angezeigt werden.

Ursache
InfoPath verwendet für diese Abfrage das "Item Limit" der Default-Ansicht und liefert nur so viele Einträge zurück, wie dort eingestellt ist.

Lösung 1:
Das Item Limit in der Default-Ansicht höher einstellen, so dass alle Elemente in der Default-Ansicht ersichtlich sind.

Lösung 2:
Wenn das Item Limit nicht angepasst werden kann/soll, weil die Liste auch für anderes verwendet wird, gibt es eine Möglichkeit, die Daten via WebService ins Infopath zu holen.


  1. Öffentliche Ansicht erstellen, die alle Elemente anzeigt.

  2. Datenverbindung im InfoPath erstellen:

  3. Neue Datenverbindung

  4. Receive Data

  5. XML Document

  6. folgende URL verwenden:
    http://SERVERURL/_vti_bin/owssvr.dll?Cmd=Display&List={5BDB2F37-7239-4B23-B5C3-107E93C41FB0}&XMLDATA=TRUE&noredirect=true&View={D58966DE-F019-4F44-ADE5-F8CF4D4A957A}&SortField=LinkTitle&SortDir=Asc
    Dazu muss natürlich die Basis URL, die List-ID, und die ID der Ansicht angepasst werden. Optional kann am Ende die Sortierung der Daten angegeben werden.

  7. Access the data from the specified location

  8. Finish

  9. Dem Dropdown die Daten aus der sekundären Datenverbindung zuweisen.

InfoPath: Personenfeld mit aktuellem Benutzer vergleichen

Manchmal ist es nützlich den aktuellen Benutzer mit einem Benutzer in einem Peoplefeld zu vergleichen. Zum Beispiel wenn nur ein bestimmter Benutzer ein Fomular gehemigen kann.

Die einfachste Variante ist ein Peoplefeld zu erstellen, in dem beim Öffnen des Formulars der aktuelle Benutzer reingeschrieben wird. (Das Feld kann angezeigt werden oder auch nicht).

Somit kann man einfach die beiden AccountID-Felder miteinander vergleichen und für benutzerdefinierte Regeln benutzen.



Problem Gross-Kleinschreibung
Es kann vorkommen, dass Benutzernamen im ersten Feld Grossgeschrieben und im zweiten Feld kleingeschrieben sind und daher beim Vergleich nicht übereinstimmen, obschon es sich um denselben Benutzer handelt.

Dieses Problem kann wie folgt gelöst werden:
Anstatt bei der Kondition in der Regel die beiden Felder direkt zu vergleichen, soll die Regel mit einer Expression erstellt werden. Dort kann die Funktion "translate()" benutzt werden. Damit können alle Grossbuchstaben in Kleinbuchstaben umgewandelt werden.

Die ursprüngliche Expression sieht beispielsweise so aus:

my:Vorgesetzter/pc:Person/pc:AccountId != my:CurrentUser/pc:Person/pc:AccountId

Die Expression, welche Gross- und Kleinschreibung ignoriert sieht dann so aus:


translate(my:Vorgesetzter/pc:Person/pc:AccountId, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz") != translate(my:CurrentUser/pc:Person/pc:AccountId, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")