Anúncio

FMK2022 Dokumentation - Thomas Hirt

Verein FM Konferenz
25 de Jun de 2022
Anúncio

Mais conteúdo relacionado

Similar a FMK2022 Dokumentation - Thomas Hirt(20)

Mais de Verein FM Konferenz(20)

Anúncio

FMK2022 Dokumentation - Thomas Hirt

  1. www.filemaker-konferenz.com FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation zur Planung, Ausführung und Wartung von FileMaker-Lösungen Thomas Hirt Dokumentation
  2. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Über den Sprecher • Studium der Biochemie und des Software Engineering • betreut seit 25+ Jahren Kleinunternehmen und Privatkunden in Informatikbelangen • Geschäftsführer und Inhaber der Tek:Guides GmbH • Windows Umgebungen als Hauptbetätigungsfeld • Einsatz von FileMaker als Entwicklungsplattform seit 2009
  3. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Inhalt • Zweck und Arten von Dokumentation • Pro und Contra • Grenzen der Dokumentation • Requirements Engineering • eine häufig unterschätzte Dokumentation • Tipp: Mockups als Gesprächsbasis erstellen • Aufgabenliste & Stundenliste • In-Code Dokumentation • Deployment-Dokumentation • Visualisierung von Struktur und Abläufen
  4. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Zweck und Arten von Dokumentation Zweck Art Requirements Engineering • User Stories • diverse Diagrammarten • Mockups • Prototypen Vereinbarungen mit dem Endkunden • Lastenheft • Pflichtenheft Unterstützung von Entwicklung und Software-Unterhalt • Aufgabenliste, Stundenliste • in-Code Dokumentation • Datenbankschema • Diagramme zur Visualisierung von Struktur und Abläufen der Lösung (z.B. UML) Unterstützung von Administratoren bei Installation und Betrieb • Installationsanleitung • Deployment-Diagramm • Diagramme zur Visualisierung der Interaktion der Lösung mit weiteren Diensten/Geräten (z.B. UML) Bedienungsanleitung für Benutzer Benutzerdokumentation
  5. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Zweck und Arten von Dokumentation Zweck Art Requirements Engineering • User Stories • diverse Diagrammarten • Mockups • Prototypen Vereinbarungen mit dem Endkunden • Lastenheft • Pflichtenheft Unterstützung von Entwicklung und Software-Unterhalt • Aufgabenliste, Stundenliste • in-Code Dokumentation • Datenbankschema • Diagramme zur Visualisierung von Struktur und Abläufen der Lösung (z.B. UML) Unterstützung von Administratoren bei Installation und Betrieb • Installationsanleitung • Deployment-Diagramm • Diagramme zur Visualisierung der Interaktion der Lösung mit weiteren Diensten/Geräten (z.B. UML) Bedienungsanleitung für Benutzer Benutzerdokumentation
  6. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Contra Pro und Contra Pro • mindert den Gewinn • behindert den Projektfortschritt • bei einigen Entwicklern unbeliebt • fördert Kundenzufriedenheit • verbessert Kommunikation mit dem Kunden • bringt Struktur in Projektverlauf • unabdingbar für Entwicklung im Team • unabdingbar für längerfristige Wartbarkeit
  7. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Grenzen der Dokumentation • Abwägung der Notwendigkeit • Was ist wirklich wichtig und nötig? • Was ist wünschbar? • Was kann und darf weggelassen werden? • Abwägung der Kosten • Aufwand für Doku in Preiskalkulation einbeziehen • Aufwand für Doku darf Projekt nicht unrentabel machen • Fehlen von Doku darf Lösung später nicht unwartbar machen
  8. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Requirements Engineering (eine häufig unterschätzte Dokumentation) • Requirements Engineering ist v.a für folgende Fälle äusserst wichtig: • "Custom Apps" • Customizations (kundenspezifische Anpassungen) • Neuentwicklungen von Standardlösungen • Benutzer und Entwickler stellen sich unter einem bestimmten Begriff häufig unterschiedliche Dinge vor. • "Aber es ist doch logisch, dass wir das so gemeint haben..." • "Aber technisch ist das nur so und so ausführbar..." • Benutzer kommen am Anfang eines Projektes häufig in eine "Weihnachts- wunschlisten-Stimmung" • "Wir schreiben einfach alles auf, was wir auch noch brauchen könnten." • hinführen des Kunden zu einem gesunden Verhältnis von Aufwand und Ertrag (80/20-Regel)
  9. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Requirements Engineering (eine häufig unterschätzte Dokumentation) • Wie arbeitet der Kunde genau? • den Kunden dazu "nötigen", seine Abläufe in allen Untervarianten genau wiederzugeben • Abläufe gemeinsam mit dem Kunden dokumentieren • Welche Abläufe sollen möglichst unverändert abgebildet werden? • Welche Abläufe sollen durch die Software-Lösung auf neue Art unterstützt werden? (Redesign der Abläufe) • Bereitschaft des Kunden, sich einzubringen und Zeit zu investieren ist essentiell. • Fehlende Bereitschaft des Kunden, sich mit der neuen Lösung auseinanderzusetzen, ist ein frühes Warnsignal, das bei Einführung der Lösung Probleme und Streitigkeiten drohen.
  10. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt User Stories • Erfassung aller Abläufe, die mit einer Software ausgeführt werden sollen, als Beschreibung in Textform, als kleine "Geschichte". • Falls es unterschiedliche Typen von Benutzern gibt, müssen die Abläufe zusätzlich pro Art von Benutzer erfasst werden. • Empfehlung: Überarbeitung in mehreren Durchläufen • erstellen einer ersten Version (evtl. gemeinsam) • erstellen einer Liste von Rückfragen durch die Entwickler für die zukünftigen Benutzer • überdenken der Abläufe durch zukünftige Benutzer • Haben wir etwas vergessen? • Brauchen wir etwas eigentlich gar nicht?
  11. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt User Stories Benutzer- Kategorie Geschichte Details Wichtigkeit Sekretariat Ich erfasse Kundendaten mit vielen Zusatzangaben. Ich schaue diese Kundendaten in einer Detailansicht und in einer Listenübersicht an. In beiden Ansichten muss ich auch Daten ausdrucken und exportieren können. Die Kundendaten müssen insb. umfassen: Adressdaten, Kontaktdaten, Tätigkeitsfelder, Einteilung in Rabattkategorien, regelmässige Korrespondenzen 1 Sekretariat Über die Ansicht der Kundendaten gelange ich mit 1-2 Klicks auf die Ansicht zu den Angeboten, Aufträgen und Rechnungen des jeweiligen Kunden. Rückweg von Angeboten, Aufträgen, Rechnungen zurück zum Kunden muss einfach sein. 1 Geschäftsleitung Ich rufe regelmässig die tagesaktuellen Umsatzzahlen des aktuellen Geschäftsjahres auf. Allnächtliche Berechnung der aktuellen Umsatzzahlen ist erwünscht. 2 Administrator Es gibt eine Übersicht über fehlgeschlagene Logins, welche ich einmal pro Woche kontrolliere. Art des Fehlers, genaue Zeit und Angaben zum Quellsystem sind enthalten, konkret: ... 3
  12. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Mockups fürs Requirements Engineering
  13. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Aufgabenliste mit/ohne Stundenliste • bringt Struktur in tägliche Arbeit der Umsetzung • Aufteilung der Aufgaben über die Zeit und/oder über mehrere Entwickler möglich • Tracking des Arbeitsfortschritts und der geleisteten Arbeitszeit auf beliebig einfachem oder komplexem Level, je nach Bedarf • Form der Aufgabenliste frei für eigenen Arbeitsstil wählbar • mit oder ohne formeller Methode (z.B. Kanban, Scrum, usw.) • physisch als Post-it Zettel auf Board im Büro • Tool-Unterstützung (z.B. Trello, Microsoft 365 Planner, Nextcloud, usw.) • usw. • Möglichkeit des Trackings, ob voraussichtliche Einnahmen und geleisteter Aufwand im richtigen Verhältnis stehen
  14. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Aufgabenliste mit/ohne Stundenliste
  15. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Aufgabenliste mit/ohne Stundenliste
  16. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Stundenliste als Instrument für Führung und Verbesserung der Kalkulation 270 37% 185 26% 213 29% 60 8% Entwicklung (vereinbart) Entwicklung (Änderungen) Testing/Debugging Customer Interaction
  17. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Stundenliste als Instrument für Führung und Verbesserung der Kalkulation 95 17% 295 52% 63 11% 113 20% Adressverwaltung Auftragsbearbeitung Benutzer- & Rechteverwaltung nicht funktionale Anforderungen
  18. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt In-Code Dokumentation • Voraussetzung für schnelles Verständnis von Skripten, Berechnungen und Custom Functions, kann auch FileMaker Datenbankschemas einfacher lesbar machen • hilft sowohl bei Entwicklung im Team wie auch bei Wartung einer eigenen Lösung, die man nicht jeden Tag bearbeitet • "Was hab ich da gemacht?" • "Wieso macht er das so?" • mein 2 wichtigsten Tipps: • kleine Code-Geschichten erzählen! • lieber etwas zu ausführlich • eine Variante, das auf die Spitze zu treiben: Documentation-Driven Development
  19. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt In-Code Dokumentation Case ( Artikel::gl_temp_startdatum = "" and Verkaufszahlen__Artikel::gl_temp_startdat = ""; MonthName ( Verkaufszahlen__Artikel::art_startdat ) & " " & Year ( Verkaufszahlen__Artikel::art_startdat ); Artikel::gl_temp_startdatum ≠ "" and Verkaufszahlen__Artikel::gl_temp_startdat = ""; If ( Artikel::gl_temp_startdatum < Verkaufszahlen__Artikel::art_startdat; MonthName ( Verkaufszahlen__Artikel::art_startdat ) & " " & Year ( Verkaufszahlen__Artikel::art_startdat ); MonthName ( Artikel::gl_temp_startdatum ) & " " & Year ( Artikel::gl_temp_startdatum )); Artikel::gl_temp_startdatum = "" and Verkaufszahlen__Artikel::gl_temp_startdat ≠ ""; If ( Verkaufszahlen__Artikel::gl_temp_startdat < Verkaufszahlen__Artikel::art_startdat; MonthName ( Verkaufszahlen__Artikel::art_startdat ) & " " & Year ( Verkaufszahlen__Artikel::art_startdat ); MonthName ( Verkaufszahlen__Artikel::gl_temp_startdat ) & " " & Year ( Verkaufszahlen__Artikel::gl_temp_startdat ) ); Artikel::gl_temp_startdatum ≠ "" and Verkaufszahlen__Artikel::gl_temp_startdat ≠ ""; If ( Verkaufszahlen__Artikel::gl_temp_startdat < Verkaufszahlen__Artikel::art_startdat; MonthName ( Verkaufszahlen__Artikel::art_startdat ) & " " & Year ( Verkaufszahlen__Artikel::art_startdat ); MonthName ( Verkaufszahlen__Artikel::gl_temp_startdat ) & " " & Year ( Verkaufszahlen__Artikel::gl_temp_startdat )); )& " ....... " & If ( Artikel::gl_temp_enddatum = ""; MonthName ( Date ( Month ( Get ( CurrentDate ) ) - 1; Day ( Get ( CurrentDate ) ); Year ( Get ( CurrentDate ) )) ) & " " & If( Month ( Get ( CurrentDate ) ) = 1; Year ( Get ( CurrentDate ) )-1; Year ( Get ( CurrentDate ) )); If ( Year ( Artikel::gl_temp_enddatum ) & Right ( 0 & Month ( Artikel::gl_temp_enddatum ); 2) ≥ Year ( Get ( CurrentDate ) ) & Right ( 0 & Month ( Get ( CurrentDate ) ); 2); MonthName ( Date ( Month ( Get ( CurrentDate ) ) - 1; Day ( Get ( CurrentDate ) ); Year ( Get ( CurrentDate ) )) ) & " " & Year ( Get ( CurrentDate ) ); MonthName ( Artikel::gl_temp_enddatum ) & " " & Year ( Artikel::gl_temp_enddatum ) ))
  20. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt In-Code Dokumentation (Custom Functions) /* * ===================================================================== * file.isLocal ( ) * * RETURNS: * - TRUE if the active FileMaker database file is * located on the local machine. * - FALSE if the active FileMaker file is either * hosted or even open on the server directly * * GLOBAL VARIABLES SET: NONE * * PURPOSE: determining whether a FileMaker file is located on the * local client machine * * ERROR RETURN VALUES: NONE * DEPENDENCIES: NONE * * AUTHOR: Thomas Hirt * NOTES: * * ===================================================================== * VERSION 1.00, 29.04.2014 * - initial version * * ===================================================================== */ /* * ===================================================================== * file.isLocal ( ) * * RETURNS: * - TRUE if the active FileMaker database file is * located on the local machine. * - FALSE if the active FileMaker file is either * hosted or even open on the server directly * * GLOBAL VARIABLES SET: NONE * * PURPOSE: determining whether a FileMaker file is located on the * local client machine * * ERROR RETURN VALUES: NONE * DEPENDENCIES: NONE * * AUTHOR: Thomas Hirt * NOTES: * * ===================================================================== * VERSION 1.00, 29.04.2014 * - initial version * * ===================================================================== */ Case ( // The file is local and network sharing is switched off. Get ( MultiUserState ) = 0; True; // The file is local but network sharing is turned on. Get ( MultiUserState ) = 1; True; // The file is hosted on either FileMaker Server or FileMaker Pro Get ( MultiUserState ) > 1; False )
  21. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt In-Code Dokumentation (Custom Functions) Case ( // The file is local and network sharing is switched off. Get ( MultiUserState ) = 0; True; // The file is local but network sharing is turned on. Get ( MultiUserState ) = 1; True; // The file is hosted on either FileMaker Server or FileMaker Pro Get ( MultiUserState ) > 1; False ) /* * ===================================================================== * file.isLocal ( ) * * RETURNS: * - TRUE if the active FileMaker database file is * located on the local machine. * - FALSE if the active FileMaker file is either * hosted or even open on the server directly * * GLOBAL VARIABLES SET: NONE * * PURPOSE: determining whether a FileMaker file is located on the * local client machine * * ERROR RETURN VALUES: NONE * DEPENDENCIES: NONE * * AUTHOR: Thomas Hirt * NOTES: * * ===================================================================== * VERSION 1.00, 29.04.2014 * - initial version * * ===================================================================== */ Case ( // The file is local and network sharing is switched off. Get ( MultiUserState ) = 0; True; // The file is local but network sharing is turned on. Get ( MultiUserState ) = 1; True; // The file is hosted on either FileMaker Server or FileMaker Pro Get ( MultiUserState ) > 1; False )
  22. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt In-Code Dokumentation (Documentation-Driven Development eines Skriptes) #prevent users from aborting the script ################################################################# #check if membercard has expired ################################################################# ################################################################# #membercard has expired ################################################################# ################################################################# #set global fields and variables ################################################################# ################################################################# #open layout to define members associated with letter template ################################################################# #make sure there are no unstored records before the layout change #show all selected members #sort records #prevent users from aborting the script Allow User Abort [ Off ] Freeze Window ##################################################################### #check if membercard has expired ##################################################################### If [ not IsEmpty ( aMembercards::useAllowedUntil ) and ( aMembercards::useAllowedUntil < Get ( CurrentDate ) ) ] ##################################################################### #membercard has expired ##################################################################### Set Variable [ $json.msg.params; Value:JSONSetElement ( "" ; "type" ; "error" ; JSONString ) ] Set Variable [ $json.msg.params; Value:JSONSetElement ( $json.msg.params ; "title" ; "Mitgliederausweis abgelaufen" ; JSONString ) ] Set Variable [ $json.msg.params; Value:JSONSetElement ( $json.msg.params ; "message" ; "Die Gültigkeit dieser Mitgliederkarte ist abgelaufen. Mitglieder für die Zustellung können nicht mehr ausgewählt werden." ; JSONString ) ] Perform Script [ “mbs.dialog.simple ( JSON: +title ; +message ; -type )”; Parameter: $json.msg.params ] Else ##################################################################### #set global fields and variables ##################################################################### Set Field [ GLOBALS::MEMBERCARD.ID; aMembercards::id ] Set Field [ GLOBALS::MEMBERCARD.VALID.THROUGH; Right ( "0" & aMembercards::validThroughMonth ; 2 ) & "." & aMembercards::validThroughYear ] Set Field [ GLOBALS::MEMBERCARD.USE.DISTROGROUPS; aMembercards::useDistributionGroups ] ###################################################################### #open layout to define members associated with letter template ###################################################################### #make sure that there are no unstored records before the layout change Commit Records/Requests [ No dialog ] If [ GLOBALS::MEMBERCARD.USE.DISTROGROUPS ] Go to Layout [ “Mitgliederausweise.Versandgruppen” (aDistributionGroups); Animation: Flip from Left ] Set Field [ aDistributionGroups::RESTRICTOR.ID; GLOBALS::MEMBERCARD.ID ] Else Go to Layout [ “Mitgliederausweise.Mitglieder” (aMembers); Animation: Flip from Left ] Set Field [ aMembers::RESTRICTOR.ID; GLOBALS::MEMBERCARD.ID ] End If #show all selected members Perform Script [ “global.filter.fields.clear”; Parameter: "" ] Set Field [ GLOBALS::FILTER.BOOL.3; 1 ] Perform Script [ “filtering.dispatcher”; Parameter: "" ] #sort records Perform Script [ “sorting.dispatcher ( List: columnNr ; resort )”; Parameter: List ( 4 ; 1 ) ] End If
  23. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt In-Code Dokumentation (Documentation-Driven Development eines Skriptes) #prevent users from aborting the script ##################################################################### #check if membercard has expired ##################################################################### If [ ] ##################################################################### #membercard has expired ##################################################################### Else ##################################################################### #set global fields and variables ##################################################################### ###################################################################### #open layout to define members associated with letter template ###################################################################### #make sure that there are no unstored records before the layout change #show all selected members #sort records End If #prevent users from aborting the script Allow User Abort [ Off ] Freeze Window ##################################################################### #check if membercard has expired ##################################################################### If [ not IsEmpty ( aMembercards::useAllowedUntil ) and ( aMembercards::useAllowedUntil < Get ( CurrentDate ) ) ] ##################################################################### #membercard has expired ##################################################################### Set Variable [ $json.msg.params; Value:JSONSetElement ( "" ; "type" ; "error" ; JSONString ) ] Set Variable [ $json.msg.params; Value:JSONSetElement ( $json.msg.params ; "title" ; "Mitgliederausweis abgelaufen" ; JSONString ) ] Set Variable [ $json.msg.params; Value:JSONSetElement ( $json.msg.params ; "message" ; "Die Gültigkeit dieser Mitgliederkarte ist abgelaufen. Mitglieder für die Zustellung können nicht mehr ausgewählt werden." ; JSONString ) ] Perform Script [ “mbs.dialog.simple ( JSON: +title ; +message ; -type )”; Parameter: $json.msg.params ] Else ##################################################################### #set global fields and variables ##################################################################### Set Field [ GLOBALS::MEMBERCARD.ID; aMembercards::id ] Set Field [ GLOBALS::MEMBERCARD.VALID.THROUGH; Right ( "0" & aMembercards::validThroughMonth ; 2 ) & "." & aMembercards::validThroughYear ] Set Field [ GLOBALS::MEMBERCARD.USE.DISTROGROUPS; aMembercards::useDistributionGroups ] ###################################################################### #open layout to define members associated with letter template ###################################################################### #make sure that there are no unstored records before the layout change Commit Records/Requests [ No dialog ] If [ GLOBALS::MEMBERCARD.USE.DISTROGROUPS ] Go to Layout [ “Mitgliederausweise.Versandgruppen” (aDistributionGroups); Animation: Flip from Left ] Set Field [ aDistributionGroups::RESTRICTOR.ID; GLOBALS::MEMBERCARD.ID ] Else Go to Layout [ “Mitgliederausweise.Mitglieder” (aMembers); Animation: Flip from Left ] Set Field [ aMembers::RESTRICTOR.ID; GLOBALS::MEMBERCARD.ID ] End If #show all selected members Perform Script [ “global.filter.fields.clear”; Parameter: "" ] Set Field [ GLOBALS::FILTER.BOOL.3; 1 ] Perform Script [ “filtering.dispatcher”; Parameter: "" ] #sort records Perform Script [ “sorting.dispatcher ( List: columnNr ; resort )”; Parameter: List ( 4 ; 1 ) ] End If
  24. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Deployment-Dokumentation • soll nicht auf reine Entwickler fokussiert sein • IT-Administratoren und FileMaker-Entwickler als Zielgruppe • ist nötig und sinnvoll, wenn eine Lösung mehr als nur den reinen FileMaker Server und FileMaker Client benötigt • soll involvierte Geräte, Shares, Dienste, evtl. spezielle Zugriffsarten und Konti enthalten • kann in beliebiger Kombination die Struktur des Deployments und/oder das Zusammenspiel der Komponenten nach dem Deplyoment erklären.
  25. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Visualisierung von Struktur und Abläufen • ist dort sinnvoll, wo... • ... Struktur und Abläufe komplex sind. • ... reine in-Code Dokumentation nicht ausreicht. • ... erst erheblicher Einarbeitungsaufwand ein Verständnis der übergeordneten Strukturen und Abläufe erlaubt. • unterschiedliche Diagrammarten mit/ohne Tool-Unterstützung stehen zur Verfügung • meine Tipps: • UML Sequenz-Diagramm • UML Deployment-Diagramm • Diagramme durch Texte ergänzen, wo sinnvoll
  26. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Sequenzdiagramm
  27. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Deployment Diagramm
  28. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Q & R Vielen Dank für Ihr Interesse!
  29. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Links auf Tools • Erstellung von Mockups • https://balsamiq.com/ • Microsoft Visio • u.v.m • Erstellung von UML-Diagrammen • https://www.visual-paradigm.com (Community Edition, Modeler Edition) • Microsoft Visio • u.v.m
  30. FileMaker Konferenz | Hamburg | 22.-24. Juni 2022 Dokumentation – Thomas Hirt Vielen Dank unseren Sponsoren
Anúncio