September 24, 2020, 03:15:15

Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!


User/DB Daten in Settings Tabelle speichern

Begonnen von maddhin, August 20, 2020, 04:45:27

⏪ vorheriges - nächstes ⏩

maddhin

Hallo,

ich habe seit längerem nach einer Lösung gesucht, aber bisher nichts für mich Brauchbares bzw. Verständliches gefunden. Daher habe ich im Moment alle Einstellungen fest programmiert.

Ich möchte aber Einstellungen (konkret z.B. den Dateipfad zu den mit Access verbundenen Ordnern/Dateien oder auch Namen von temp Tabellen beim Import, etc.) in einer Tabelle speichern damit ich diese, wo nötig, auslesen/nutzen kann. Die Einstellungen sollen auch, wo sinnvoll, über ein Formular benutzerfreundlich zugänglich sein.

Diese Einstellungen sollen einerseits DB-abhängig sein (Einstellungen der DB, tblSettingDB) auch Nutzer-abhängig sein (Einstellungen für Nutzer wie Dateipfade, tblSettingsUser) - dies kann ich man aber später nachrüsten (ich muss das User/Login-System noch bauen/implementieren).

Meiner Meinung nach ist die Speicherung in einer Tabelle die beste Möglichkeit vs. .ini Datei (kompliziert und eigentlich unnötige Datei) vs. Property (erscheint mir eher für andere Sachen geeignet und habe ich noch nicht damit gearbeitet). In der Registry würde ich eher Dinge "ohne notwendige Default-Werte" wie die letzte Fenstergröße o.ä. speichern wollen.

Was ich nun tuen möchte ist eine Tabelle mit den Feldern ("IDUser",) "VarName", "VarType" und "VarValue" erstellen (Inspiration/Wissen von hier) und dann damit arbeiten.

Woran es jetzt bei mir scheitert ist, wie ich diese Tabelle "richtig" nutze. Hole ich die Werte mit Dlookup oder macht man das über recordset? Oder ganz anders? Irgendwie stehe ich diesbezüglich auf der Leitung und konnte auch fast keine Info (bis auf den Link oben) finden. Oder ist hier doch Property die richtige Methode?

Hat hier jemand eine Idee und könnte mich in die richtige Richtung stubsen? :) Lieben Dank im Voraus!

markus888

Zitat von: maddhin am August 20, 2020, 04:45:27Hole ich die Werte mit Dlookup oder macht man das über recordset?

Du beschäftigst dich also mit den wirklich wichtigen Fragen.

Hab mal gelesen, man soll ein Recordset nehmen - ich hoffe das hilft dir weiter.
10 Jahre Access

ebs17

DLookup holt genau einen Wert oder ersatzweise NULL, eine Abfrage und damit das Recordset liefert mehrere bis alle Werte wie auch Datensätze, je nach Definition.

Jetzt darf man überlegen, was man für sinnvoller hält, wenn man eine Party veranstalten will. Würde man für jede Getränkeflasche einzeln zum Markt fahren (besser laufen) und die abholen, oder wäre man der Versuchung nahe, viel bis alles auf einmal mitzunehmen?

Also: Es kommt darauf an.
Mit freundlichem Glück Auf!

Eberhard

crystal

August 24, 2020, 19:53:19 #3 Letzte Bearbeitung: August 25, 2020, 04:55:48 von crystal Grund: noch ein Nachtrag
Lieber maddhin,

ich freue mich sehr über die Fortschritte, die du machst!

Obwohl ich aus gesundheitlichen Gründen nur noch wenig in diesem Forum schreiben kann/will, möchte ich dir folgende Antwort geben (wieder etwas lang).

So allgemeine Dinge wie Pfade etc. in passenden Tabellen zu speichern, halte ich für eine SEHR gute Idee.

Ich selbst nutze solche "Settings-Tabellen" gern, um genau das zu machen.

Dazu benutze ich globale Variable, die über eine "Start-Funktion" besetzt werden; eine allgemeine globale Variable "Settings_geladen" erlaubt es mit dabei, eine simple Funktion in "jedem" Formular etc. aufzurufen, um zu prüfen, ab diese globalen Variablen bereits geladen sind oder nicht und sie im Bedarfsfall (oder gesteuert über einen Parameter "NeuLadenErzwingen" zu laden, z. B.
if not Settings_geladen then call Load_Settings(True)

In so einer Funktion "Load_Settings" kannst du dann natürlich "alles" machen, was das Herz begehrt. Wenn sich ein User angemeldet hat, kannst du dessen Kennung übergeben, um die userspezifischen Settings zu laden, oder eben allgemeine. Es kommt darauf an, was deine Settings beinhalten - sind sie userspezifisch oder allgemein oder von beidem etwas.

Von Dlookup würde ich eher abraten. Dein Code würde sonst einfach nur viele Dlookup-Zeilen enthalten. Zweifellos ist es besser, eine schlichte Abfrage zu benutzen (mit User-Id als Parameter) und die Daten dann einzeln den globalen Variablen zuzuweisen.

Es stellt sich hier die Frage, ob es sinnvoll ist, die Settings - wie in deiner Frage dargestellt - 1:n zu speichern, oder sie schlicht als Tabellen-Werte (Spalten) abzulegen. Da es sich vermutlich nur um wenige Werte handelt, macht es m. E. durchaus Sinn, sie als Tabellen-Felder abzulegen, so dass du mit einem einfachen Select auf alle diese Werte (zu einem bestimmten User) zugreifen kannst. Die Code-Sequenz für die Zuordnung der Werte zu den globalen Variablen wäre dann auch recht gut überschaubar.

Ich möchte hier nicht zu sehr ausschweifen, aber im Prinzip kannst du dir eine globale Klasse "Settings" bauen, die im Konstruktor die Daten aus der Settings-Tabelle lädt und als Member/Property zur (lesenden) Verfügung stellt. Das würde dann auch im Code die Verwendung solcher Werte anschaulicher machen:
statt
strOutputFile = gblOutputDir & "\irgend.was"           'simple Verwendung globaler Variabler
würde es dann lauten
strOutputFile = ActualUser.OutputDir & "\irgend.was"   'Verwendung einer globalen Klasse

Da es sich bei solchen Settings um eine eher beschränkte Anzahl an Datenfeldern handelt (jedenfalls aus meiner Erfahrung), ist es eine leichte Übung, hierfür eine Tabelle (also eine Tabelle mit einem Autowert-Schlüssel und z. B. der User-Kennung sowie einer Anzahl an Settings-Feldern) und ein passendes Formular zur Pflege zu erstellen. Auch die Ergänzung der Tabelle um weitere Felder wäre einfach möglich (und eher nur zur Entwicklungszeit erforderlich) und die Interpretation von inhalts-beschreibenden Feldern bei einer 1:n-Auftrennung würde entfallen. Im Event "Dirty" oder "OnClose" des Formulars könntest du sogar die Übernahme der geänderten Werte in die globale Klasse anstoßen.

Bei einer 1:n-Auftrennung müsstest du richtigerweise zu jedem "eigentlichen" Wert auch dessen Beschreibung und den Wert-Typ (Text, Zahl, Datum etc.) speichern, was entsprechende If-Kaskaden beim Einlesen erfordern würde. Bei einer "linearen" Tabelle würde sich das ganz erheblich reduzieren oder überflüssig sein.

Auch ein Bericht kann da natürlich sehr hilfreich sein (zu Dokumentations-Zwecken).


Lange Rede, kurzer Sinn: eine (oder ggf. 2: Allgemein und User [oder 0 für Allgemein]) "lineare" Settings-Tabelle(n) (also nicht mühsam via 1:n und zusätzlich beschreibendem Feld) halte ich für eine sehr gute Idee; satt einzelner Dlookup-Aufrufe würde ich einem Recordset deutlich den Vorzug geben (auch wenn nur genau ein Record zurückgegeben wird), da die Zuordnung der globalen (Klassen-)Variablen sowohl lesend als auch schreibend übersichtlicher ist und keine Inhalte anhand eines beschreibenden Feldes interpretiert werden müssen.

Eine "lineare" Tabelle hätte weiter den Vorteil, alle Felder übersichtlich in einem Formular (mit entspr. Beschreibungen) darstellen zu können, statt die einzelnen Werte in einem Unterformular anzeigen zu lassen und es würde sich erübrigen, zu jedem Wert die Beschreibung und den Typ (String, Zahl etc.) zu speichern, da dies in der Feld-Definition der Tabelle erledigt wird.

Also viel Erfolg weiterhin,
crystal

Nachtrag/Ergänzung

Vor einiger Zeit habe ich eine Applikation gesehen, bei der solche Setting-Daten unsichtbar in einem Login-Formular untergebracht waren. Statt dieses Formular mit seinen Daten nach dem Login zu schließen, hat der Entwickler es schlicht unsichtbar gemacht. Somit war es während der gesamten Laufzeit der Access-Anwendung geöffnet und er konnte auf die Daten zugreifen. Erst bei aktivem Logout oder Beenden der Anwendung hat er das Formular dann geschlossen und dadurch die aktuellen Settings in die Tabelle zurück geschrieben.

Dadurch stehen die Daten während der Laufzeit global zur Verfügung und können gelesen und geschrieben/geändert werden. Der Zugriff erfolgte schlicht durch
LoginForm.Feldname (oder Forms("LoginForm").Feldname - bin mir nicht ganz sicher),
denn das Formular ist ja nichts anderes als eine Klasse bzw. Instanz einer Klasse. Selbst Subs und Funktionen dieses Formulars können aufgerufen werden und man braucht sich nur wenig um das Zurückschreiben der Daten zu kümmern. Durch diesen genialen Trick erübrigt sich das Einlesen der Daten in eigene globale Variable oder eine globale Klasse (wie von mir oben angedeutet), da das Formular mit seinen Daten ja bereits global ist - nur eben unsichtbar  (Form.visible = false).

Noch ein Nachtrag:
Ein solches Login-Formular zu nutzen, um die Benutzer-Daten stets im Zugriff zu haben, eröffnet natürlich auch noch ganz andere Möglichkeiten, denn du hast jetzt ein Formular, das quasi als Kopf der Applikation dient oder als "Container", von dem aus alles andere aufgerufen wird, ohne den "Container" jedoch zu verlassen. Beispiele:
-> über einen Timer Aktionen starten oder den User ausloggen (inactivity logout)
-> über eine globale Funktion (per Hotkey aufzurufen und mit Passwort geschützt) das Formular sichtbar machen und Änderungen vornehmen
-> userspezifisches "Clipboard"/Phrasenspeicher

Logisch, dass dazu programmiert werden muss, aber das muss es sonst ja auch... Einfache Funktionen, die in anderen Formularen z. B. im Current-Event aufgerufen werden, könnten relativ einfach Informationen an das Login-Formular schicken, dortige Timer setzen/zurücksetzen etc. pp. Ungeahnte Möglichkeiten!

Viel Spaß.
Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

Aus gesundheitlichen Gründen nur noch selten dabei...

maddhin

Super, lieben Dank für die Antworten, das hilft mir sehr weiter!

Ich habe jetzt die Settings "erstmal" via normaler Tabelle, wie von @crystal vorgeschlagen, realisiert. Das erscheint mir im Moment am sinnvollsten. Da weiß ich wenigstens was ich tue... LOL Die VarName, etc Geschichte ist sicherlich auch sinnvoll und vorteilhaft, aber da blicke ich noch nicht richtig durch.

Zitat von: crystal am August 24, 2020, 19:53:19Ich möchte hier nicht zu sehr ausschweifen, aber im Prinzip kannst du dir eine globale Klasse "Settings" bauen, die im Konstruktor die Daten aus der Settings-Tabelle lädt und als Member/Property zur (lesenden) Verfügung stellt. Das würde dann auch im Code die Verwendung solcher Werte anschaulicher machen:
statt
strOutputFile = gblOutputDir & "\irgend.was"           'simple Verwendung globaler Variabler
würde es dann lauten
strOutputFile = ActualUser.OutputDir & "\irgend.was"   'Verwendung einer globalen Klasse

Guter Tipp! Das wäre eigentlich ideal und was ich möchte, aber mit Klassen habe ich mich noch nicht beschäftigt. Da muss ich mich erstmal schlau machen, wie das funktioniert  ;D

Zitat von: crystal am August 24, 2020, 19:53:19Vor einiger Zeit habe ich eine Applikation gesehen, bei der solche Setting-Daten unsichtbar in einem Login-Formular untergebracht waren.

Das ist in der Tat sehr cool! Ein Login(-Formular) ist ziemlich weit oben auf meiner to-Do-Liste, weil ich demnächst die Daten(bank) teilen muss. Dann werde ich mal probieren, das zu implementieren!

Bis dahin werde ich erstmal lernen mit recordsets umzugehen...  ;D Da kommt später auch gleich noch eine konkrete Frage dazu im Forum haha

DANKE für Euren Input!