Hallo
Folgendes:
Ich habe ein Endlosformular. Eine Änderungshistorie. Die Änderungen die da hinein kommen, stammen aus verschiedenen Tabellen.
Es gibt die Felder:
Table_Origin (Herkunftstabelle), Table_ID (welche ID hat der Datensatz in der Herkunftstabelle), Field_Name (Name des veränderten Feldes), OldValue, NewValue und Zeitstempel
Nun möchte ich aber in dem Formular nicht nur die ID des Datensatzes anzeigen, sondern auch den Namen des Datensatzes.
Dazu habe ich ein leeres ungebundenes Textfeld (txt_Name) erzeugt das je nach Situation den Namen der verknüpften Tabelle anzeigen soll.
Mein Mangel an VBA-Erfahrung verwehrt mir das weiter kommen.
Ich habe unten einen Quelltext eingefügt von dem ich denke, so ungefähr müsste das aussehen, der funktioniert aber noch nicht korrekt.
Wie muss der richtig aussehen?
Zitat
Private Sub Form_Open(Cancel As Integer)
If Me!Table_origin = "tbl_Signals" Then
Me!txt_Name = FM_Signals.Name
End If
If Me!Table_origin = "tbl_Desktile" Then
Me!txt_Name = FM_DT.Name
End If
End Sub
Hallo,
dein Vorhaben scheitert an der Art der Zuweisung.
Was bitte ist
FM_Signals.Name
- was meinst du damit, was möchtest du da ansprechen?
Zitatsondern auch den Namen des Datensatzes
Datensätze haben in der Regel keinen Namen - meinst du hier den Namen des Feldes?
Das Endlosformular bezieht ja seine Daten aus einer Tabelle.
Sind denn die Felder der Tabelle zu dem Zeitpunkt zu dem du sie anzeigen willst bereits mit Daten befüllt oder soll das dein Code bewerkstelligen?
Wie heisst denn diese Tabelle und wie heisst der Primärschlüssel aus dieser Tabelle:
ZitatTable_Origin (Herkunftstabelle), Table_ID (welche ID hat der Datensatz in der Herkunftstabelle), Field_Name (Name des veränderten Feldes), OldValue, NewValue und Zeitstempel
Aber ....ZitatDazu habe ich ein leeres ungebundenes Textfeld (txt_Name) erzeugt das je nach Situation den Namen der verknüpften Tabelle anzeigen soll.
Das klingt wieder als würdest du im Feld 'txt_Name' die Datenherkunft des Formulars anzeigen wollen. ???
Das kannst du ganz einfach lösen:
Me!txt_Name = Me!RecordSource...zeigt die Datenherkunft des Formulars zum Zeitpunkt an, zu dem der Code ausgeführt wird.
Grüße
Peter
Ach Mist! Bei dem FM_Signals habe ich mich verschrieben. Mein Fehler.
Eigentlich meinte ich tbl_Signals.Name
Ich meine nicht den Namen des Feldes.
Ich meine den "Namen" des Datensatzes. Also wenn ich z.B. eine Personalverwaltung habe, dann ist in der History-Tabelle die ID der Person vermerkt. Ich möchte aber im History-Formular (auch) den Namen der Person anzeigen.
Die zugrundlegende Tabelle tbl_History ist bereits gefüllt. Es geht um die Anzeige im Formular. Nichts darf an der Tabelle geändert werden.
Ich möchte in das Textfeld "txt_Name" also (um im Beispiel zu bleiben) den Namen der Person anzeigen, zu der die ID im Feld "Table_ID" gehört. Dieser Name muss aus der Tabelle verknüpft werden
Also bisher steht in der History für einen Datensatz:
Tabelle / ID / Geändertes Feld/ Alter Wert / Neuer Wert
tbl_Signals / 12345 / Wohnort / Berlin /München
Ich möchte nun aber zusätzlich für jeden Datensatz noch, dass statt der ID der Name der Person angezeigt wird in dem ungebundenen Textfeld.
Also ich glaube ich muss dann irgendwie das ganze verlinken, aber wie?
Me!txt_Name=tbl_Signal.Name bei der ID die dieser Datensatz übergibt
So, dann lass uns einen neuen Versuch starten, ich denke ich habe jetzt verstanden was du WIRKLICH willst. ;D
ZitatIch möchte in das Textfeld "txt_Name" also (um im Beispiel zu bleiben) den Namen der Person anzeigen, zu der die ID im Feld "Table_ID" gehört. Dieser Name muss aus der Tabelle verknüpft werden
wenn ich dich wie oben angedeutet richtig verstehe, dann möchtest du den Eintrag im Feld txt_Name haben, der in der tbl_Signals bei der ID 12345 gespeichert wurde.
Nun denn:
Me!txt_Name = DLookup("Namensfeld", Me!Table_origin, "TabellenID=" & Me!Table_ID)
Wenn sich die Feldnamen der Primärschlüssel in den einzelnen Tabllen unterscheiden (SignalsID, DesktitleID, ...)
dann KANNST du natürlich wie du es geplant hast mit Bedingungen auf diese Gegebenhieten reagieren:
If Me!Table_origin = "tbl_Signals" Then
Me!txt_Name = DLookup("Namensfeld", Me!Table_origin, "tbl_SignalsID=" & CLng(Me!Table_ID))
End If
If Me!Table_origin = "tbl_Desktile" Then
Me!txt_Name = DLookup("Namensfeld", Me!Table_origin, "tbl_DesktitleID=" & CLng(Me!Table_ID))
End If
Die explizite Konvertierung mit CLng kannst du weglassen, wenn die Felder in der Tabelle UND am Formular als Zahlenfeld deklariert sind.
Handelt es sich in BEIDEN Fällen um Textfelder - was ja mitunter auch vorkommen kann - dann müsstest du die Bedingung z.B. so formulieren:
Me!txt_Name = DLookup("Namensfeld", Me!Table_origin, "tbl_DesktitleID='" & Me!Table_ID & "'")
BTW
Ich kenne zwar deine Gegebenheiten nicht genau aber ich kann mit nicht vorstellen, dass das im Ereignis 'Beim Öffnen' des Formulars stehen kann.
Wenn in dem Endlosformular mehrere Datensätze angezeigt werden und in JEDEM Datensatz eine andere Tabelle und eine andere ID angegeben ist, kann das m.E. beim Öffnen NICHT funktionieren.
HTH
Peter
Ja du hast Recht.
Es funktioniert nicht. Liegt das daran, dass ich es "beim Öffnen" mache?
Wo sollte ich es sonst machen?
Insgesamt kommen in die History vorraussichtlich Datensätze aus 3 verschiedenen Tabellen und mit den IF-Blöcken wird jedesmal abgefangen aus welcher der Tabellen.
Ich hatte kurz die Idee das irgendwie über eine Abfrage abzuhandeln aber das ist mir auch nicht gelungen.
Um das noch mal ganz stark herunter zu brechen auf das Ursprungsproblem, vielleicht weißt du ja da einen besseren Ansatz als meinen:
In die Tabelle tbl_History werden wichtige Veränderungen gespeichert. Die veränderten Felder werden da aber nur über ihre IDs identifiziert.
Wenn der Benutzer nun das Dokument aufmacht, sieht er, dass bei ID 12345 der FK von 2 auf 8 verändert wurde. Theoretisch müsste man das nun in den zugrundeliegenden Tabellen von hand nachsehen (das soll dem Benutzer später unmöglich sein!) um zu wissen welches Element nun auf welchen Wert geändert wurde.
Darum möchte ich in dem Endlosformular auch die Klarnamen der veränderten Datensätze anzeigen und auch die verlinkten Werte aus den Lookup-Tabellen, statt ihrer IDs.
---
Eine Frage die nur entfernt damit zu tun hat, wenn ich in das Textfeld (txt_Name) mehr als einen Feldinhalt eintragen möchte, wie mache ich das?
Also um das Beispiel Personalverwaltung zu nehmen: Statt "Nachname" möchte ich "Vorname und Nachname" in das Feld eintragen?
Hallo,
ich habe es fast befürchtet.
Nun, da es so sein wird, dass in den betroffenen 3 Tabellen die ID Felder nicht gleich heissen - so wie ich in meinem vorangegangenem Posting angedeutet habe,
kannst du jeden direkten Weg über die Abfrage vergessen - das geht nicht. Grund ist der, dass die Abfrage nicht 'weiß' mit welchem Feld der betreffenden Tabelle eine Beziehung herzustellen ist.
So, was kannst du dann tun ohne das ganze Konzept zu zerwursteln.
Du kannst dich über eine Funktion retten, die dir in Abhängigkeit der eingetragenen Tabelle den Namen zurückliefert.
Hier ist dann die entfernte Frage aus deiner letzten Antwort schon berücksichtigt.
Folgendes ist nun zu tun:
Dein Formular ist an die Tabelle 'tbl_History' gebunden und beinhaltet daraus Felder.
Das muss als erstes geändert werden, da wir an den Tabellendaten selbst nichts ändern wollen und können.
Erstelle eine Auswahlabfrage und füge in diese ALLE Felder der tbl_History ein.
Dann erzeugst du ein neues Feld in dem du folgendes in die erste leere Spalte der Abfrage schreibst:
HName: LeseNamen([Tabelle];[ID])
(Ich gehe davon aus, dass die beiden Felder so heissen - entnommen aus deinem Posting)
Speichere die Abfrage unter einem passenden Namen und FÜHRE SIE NICHT AUS!
Dann erstellst du ein neues VBA-Modul (Standardmodul) speicherst es, benennst es 'basAction' und fügst dort folgenden Code ein:
Public Function LeseNamen(tabelle As String, schluessel As Long) As String
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim ind As Index
Dim fld As Field
Dim pk As String
'Wenn eine Tabelle übergeben wurde...
If tabelle <> "" Then
Set db = CurrentDb
'Feststellen des Primäschlüssel-Namens (ID-Feld) der übergebenen Tabelle
For Each tdf In db.TableDefs
If tdf.Name = tabelle Then
For Each ind In tdf.Indexes
If ind.Primary Then
For Each fld In ind.Fields
pk = fld.Name
Next fld
End If
Next ind
End If
Next tdf
'Auslesen und zusammenfügen von Vorname und Nachname aus der übergebenen Tabelle
'zurückliefern des zusammengesetzten Namens
LeseNamen = DLookup("[Vorname]", tabelle, "" & pk & "=" & schluessel) & " " & DLookup("[Nachname]", tabelle, "" & pk & "=" & schluessel)
Else
LeseName = ""
End If
End Function
Nun bindest du dein Formular an die Abfrage und dein ungebundenes Textfeld txt_Name bindest du an das Feld HName (steht für History-Name) der Abfrage.
Wenn du nun das Formular anzeigst, wird die Abfrage ausgeführt und der (zusamengesetzte) Name durch die VBA-Function ermittelt und ins Abfrageergebnis eingebunden.
Dieser Name wird dann im Feld txt_Name angezeigt.
Wichtig ist, dass in der Herkunftstabelle tbl_History für JEDEN Datensatz sowohl ein Tabellenname als auch eine ID eingetragen ist.
Das Fehlen dieser INfos würde einen Fehler verursachen da diese Möglichkeit in meinem Code NICHT durch eine entsprechende Fehlerbehandlung abgefangen ist!
Hoffe du kannst damit was anfangen ...
Grüße
Peter
Ach Herrje und ich hoffte auf eine einfache Lösung! ;D
Das mache ich heute nicht mehr. Aber vielen Dank für deine Hilfe, ich melde mich nochmal ob das geklappt hat.
Na komm ...
DAS IST EINFACH! ;D ;D ;D
Hallo,
einfacher: ;D ;D ;D ;) (braucht nur einmal manuell gemacht werden, evtl beim Hinzufügen einer neuen Tabelle halt erweitern.)
in einer separaten Tabelle die Tabellennamen mit deren PK-Feldnamen hinterlegen , den man dann mit Dlooup ausliest.
Hallo,
@Franz
die Kernaussage von OPS war "Ach Herrje ..."
Hmmm... quasi copy and paste ... und ein paar Zeilen Text 8)
Schöne Grüße
:) ;) :D ;D
Hallo,
ich befürchte das da kein vernünftiges Ergebnis herauskommt da das ungebundene Textfeld ja nur einen Wert bekommen kann und
daher auch nur immer der Personenname des gerade benutzten Ds angezeigt wird.
Wenn ich es richtig verstanden habe ist die PersonenID gespeichert und es gibt noch einen Tabelle wo der Name der Person zur ID
hinterlegt ist.
Vieleicht hilft hier sogar einen simple Lösung ohne VBA.
Versuch doch mal im Endlosformular ein Kombifeld einzubauen. DS-Herkunft die Tabelle mit ID und Name, verknüpft mit ID der History.
Gruß
Johann
Ich möchte mal bei der History-Tabelle nachhaken; sie existiert und ist bereits gefüllt. Ich nehme an, die Füllung vollzieht sich über Anfügeabfragen o.ä.? Dann könnte man doch
a) ein neues Textfeld in die History-Tabelle einfügen, was ja die vorhandenen Daten nicht verändern würde und
b) die Anfügeabfragen so verändern, dass der gewünschte Klartextname in das neue Feld eingetragen wird.
Für die bereits vorhandenen Datensätze könnte dieser Name mittels einer Aktualisierungsabfrage mit entsprechenden Bedingungen geschrieben werden. Nicht so elegant wie die Lösung über VBA, sollte aber gehen.
Hallo,
Zitat...da das ungebundene Textfeld ja nur einen Wert bekommen kann und
daher auch nur immer der Personenname des gerade benutzten Ds angezeigt wird.
hmmm... na wieviele verschiedene Werte pro Datensatz soll denn das Feld anzeigen?
Wenn ich den Sinn und Zweck einer History verstanden habe, soll in Tabellenform die Änderung an verschiedenen Feldern protokolliert werden.
Wenn nun in einer BESTIMMTEN Tabelle EINE BESTIMMTE Person eine Änderung durchführt (an einem zuvor gespeicherten Feldwert) dann gehe ich davon aus,
dass zwecks Protokollierung dieser Änderung EIN EINDEUTIGER Datensatz in der History-Tabelle abgelegt wird.
Wenn du nun die Tabelle per Abfrage in einem Endlosformular (oder auch in der Tabellenansicht) darstellst, wirst du für JEDE Zeile in der Historytabelle EINE Zeile im Formular erhalten.
Da in der ersten Zeile nun z.B. eine Änderung in der Tabelle 1 protokolliert wurde und in der zweiten Zeile die Änderung an der Tabelle 2 und diese Änderungen von jeweils anderen
Personen durchgeführt wurde, wirst du in deinem Endlosform nicht nur einen Namen vorfinden sondern eben genau für JEDEN Datensatz die protokollierte Person, die dann auch für JEDEN Datensatz der Tabelle eine andere sein KANN.
ZitatWenn ich es richtig verstanden habe ist die PersonenID gespeichert und es gibt noch einen Tabelle wo der Name der Person zur ID
hinterlegt ist.
Wenn ICH es richtig verstanden habe sollte es wohl so sein - zumindest gehe ich sehr stark davon aus, denn....
ZitatIch möchte in das Textfeld "txt_Name" also (um im Beispiel zu bleiben) den Namen der Person anzeigen, zu der die ID im Feld "Table_ID" gehört
hieraus lese ich, dass in einem Datensatz jener Tabelle, die unter dem Feld 'Tabelle' gespeichert wurde ein Name zu finden ist ....
.... und nach dieser Aussage ging ich auch davon aus, dass in der protokollierten Tabelle ZWEI Namensfelder existieren müssten 'Vorname' und 'Nachname'!!!!
ZitatEine Frage die nur entfernt damit zu tun hat, wenn ich in das Textfeld (txt_Name) mehr als einen Feldinhalt eintragen möchte, wie mache ich das?
Also um das Beispiel Personalverwaltung zu nehmen: Statt "Nachname" möchte ich "Vorname und Nachname" in das Feld eintragen?
Dieser begründeten Annahme zufolge habe ich dir dann gezeigt, wie aus dem geänderten Datensatz - und der sollte ja die ID haben, die in der Historytabelle under 'ID' gespeichert wurde - 'Vor- und Nachname gelesen, zusammengefügt und in das Feld 'txt_Name' geschrieben wird - und zwar per ...
DLookup("[Vorname]", tabelle, "" & pk & "=" & schluessel) & " " & DLookup("[Nachname]", tabelle, "" & pk & "=" & schluessel)
Diese Vorgänge werden natürlich für JEDEN Datensatz der Historytabelle wiederholt und im Endlosformular angezeigt.
@Jonny
ZitatVersuch doch mal im Endlosformular ein Kombifeld einzubauen. DS-Herkunft die Tabelle mit ID und Name, verknüpft mit ID der History
... na dann versuch mal dem Kombifeld beizubringen in welcher Tabelle die anzuzeigenden Namen zu finden sind - mit einer simplen Lösung ohne VBA ...
ZitatInsgesamt kommen in die History vorraussichtlich Datensätze aus 3 verschiedenen Tabellen
...wobei dann in allen drei Tabellen die IDs verschieden heissen ... das wird sich beim besten Willen nicht so ohne Weiteres in die Datenherkunft des Kombis reinwürgen lassen.
Da würde ich persönlich schon die Methode
Copy und Paste und das
genaue Lesen von ein paar Zeilen diesem Bauchwehkonstrukt vorziehen
Wenn du dir meine Function mal genauer ansiehst, wirst du erkennen, dass die nämlich genau diese unterschiedlichen Namen aus den Tabellen fischt um damit die Namen der protokollierten Personen zu finden.
Und dieses mittels der in der History gespeicherten ID!
@ulli
Zitatb) die Anfügeabfragen so verändern, dass der gewünschte Klartextname in das neue Feld eingetragen wird.
... und auf diese Weise die Relation bewusst zu denormalisieren ist ein Ansatz - aber sicher nichts, das ich gutheissen würde.
Was ist denn so furchtbar daran das Feld einer Abfrage durch das Ergebnis einer VBA-Function befüllen zu lassen - Leute, das ist 'normal' und keine Kriegserklärung!
Ich habe ja schon erwähnt...
Zitatwas kannst du dann tun ohne das ganze Konzept zu zerwursteln
... und indirekt darauf hingewiesen, dass das Datenmodell für eine
EINFACHERE Lösung zu ändern sein wird.
EOF
Peter
;D
ES GEHT ES GEHT!
Mein anfängliches: "Ach Herrje" bezog sich auf eine relativ lange Antwort und es war schon so spät am Abend... Ich habe mir die Antwort da noch garnicht richtig durchgelesen sondern lieber Feierabend gemacht.
Jetzt habe ich es eingebaut und es geht!
Vielen Dank für die Hilfe!
Na denn, ...
freut mich, dass es nun auch bei dir geklappt hat.
Zitat"Ach Herrje" bezog sich auf eine relativ lange Antwort
Schon OK, die nachfolgenden Texte waren da mehr als Scherz denn als Kritik zu werten :D ;D ;)
Wenn ich merke, dass der Bedarf dazu gegeben sein könnte, dann erkläre ich eine von mir vorgeschlagenen Vorgehensweise gerne etwas detaillierter und genauer.
Tja, dass dann die Texte auch mal ein wenig umfangreicher ausfallen ist kein Bug sondern ein Feature :D
Grüße und Erfolgswünsche
Peter