Neuigkeiten:

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

Mobiles Hauptmenü

Unterformular in Abhängigkeit von Kombinationsfeld

Begonnen von ThinkPink, September 03, 2010, 11:29:35

⏪ vorheriges - nächstes ⏩

ThinkPink

Hallo,
meine Datenbank ist fast fertig - ich habe nur noch ein (hoffentlich) kleines Problem zu lösen und komme seit Ewigkeiten nicht weiter. Ich habe in diesem Forum zwar ähnliche Beiträge gefunden, aber irgendwie nichts, was mir wirklich geholfen hat. Ich hoffe, von euch hat jemand eine Idee und bedanke mich schonmal im Voraus.
Also:

Erstmal zu den Tabellen:
Es gibt eine Tabelle unternehmen, eine Tabelle abteilungen und eine Tabelle mitarbeiter.
Jeder Mitarbeiter gehört zu einem Unternehmen, deswegen sind die Tabellen über u_id (Primärschlüssel in der Tab. unternehmen) verknüpft und zwar mit referentieller Integrität.
Jede Abteilung gehört ebenfalls zu einem Unternehmen, deswegen sind die Tabellen auch über u_id verknüpft, ebenfalls mit referentieller Integrität.
Die Tabellen mitarbeiter und abteilungen sind über a_id (Primärschl. in Tab. abteilungen) miteinander verknüpft, allerdings nicht mit referentieller Integrität, weil es nicht zu jedem Mitarbeiter eine Angabe über seine Abteilung gibt.

Jetzt zu den Formularen:
Es gibt ein Formular mitarbeiter, in das man die Informationen zu den Mitarbeitern eingibt. Über ein Kombinationsfeld (kombi_unternehmen) muss man dann das entsprechenden Unternehmen auswählen. Wenn das Unternehmen noch nicht vorhanden ist, kann man über einen Button oder über das "nicht in Liste"-Ereignis das Formular unternehmen öffnen und die Daten zum Unternehmen eintragen.
Außerdem gibt es im Formular mitarbeiter ein Kombinationsfeld (kombi_abteilungen), über das man (falls vorhanden) eine Abteilung aussuchen kann, zu der der Mitarbeiter gehört. Es werden immer nur die Abteilungen zur Auswahl angeboten, die zu dem Unternehmen gehören, das in kombi_unternehmen gerade ausgewählt ist.

Und schließlich zu meinem Problem:
Ich will dem Benutzer die Möglichkeit geben, sowohl über das "nicht in Liste"-Ereignis, also auch über einen Button "Abteilung hinzufügen" das Formular abteilungen zu öffnen und dort eine neue Abteilung einzutragen.
Jetzt muss das Formular aber irgendwie kapieren, dass es in das Feld u_id den Wert eintragen soll, den das Unternehmen hat, das in kombi_unternehmen gerade ausgewählt ist. Und das bekomme ich einfach nicht hin.
Am liebsten wäre mir auch, wenn der Benutzer das Feld u_id gar nicht sehen würde (was ja irgendwie gehen dürfte, weil der Wert ja sowieso vom Programm zugewiesen werden soll), aber den Namen des Unternehmens (gespeichert im Feld firmenname in der Tabelle unternehmen), damit er sich bewusst ist, zu welchem Unternehmen er gerade eine Abteilung hinzufügt.

Ich hoffe, ich hab irgendwie erklären können, was mein Problem ist und mir kann jemand helfen.
Viele Grüße
Kerstin

database

#1
Hallo,
vorab:
Zitatallerdings nicht mit referentieller Integrität, weil es nicht zu jedem Mitarbeiter eine Angabe über seine Abteilung gibt
Es sollte trotzdem nicht hinderlich sein, RI einzustellen - die AbteilungsID bleibt in dem Fall leer, also auch kein Standardwert --- NULL-Werte dürfen schon sein.
RI soll dabei verhindern, dass eine AbteilungsID eingetragen werden kann, die in der Abteilungstabelle NICHT existiert - und das macht so richtig Sinn!

zum Rest - na, dann lass es uns mal miteinander versuchen... :)

Zitatüber einen Button "Abteilung hinzufügen" das Formular abteilungen zu öffnen...

... (benamse diesen als cmdAbteilungHinzufuegen) ... sollte ja nicht unbedingt das große Problem darstellen...

DoCmd.OpenForm "abteilungen"

Nun hast du auf deinem Quellformular ein Kombifeld, in dem du ein Unternehmen ausgewählt hast.
Dieses Kombifeld wird so aufgebaut sein, dass als gebundene Spalte die U_id definiert ist und der Name im Feld angezeigt wird.
Wenn das so ist, kannst du im Klick-Ereignis deines Buttons diese Infos ermitteln:


Private Sub cmdAbteilungHinzufuegen_Click()

   Dim ID As Long, strName As String

   ID = Me!kombi_unternehmen
   strName = Me!kombi_unternehmen.Column(1)

End Sub


Dein Formular zur Erfassung einer neuen Abteilung öffnest du von diesem Button aus.
Abhängig davon ob das Formular als gebundenes oder ungebundenes Formular ausgeführt ist, wird ein Datensatz angezeigt werden oder ein leeres Formular.
Wenn gebunden (empfohlen) solltest du beim Öffnen des Formulars auf einen leeren , neuen Datensatz springen um nicht unbeeabsichtigt bestehende Einträge zu überschreiben.

Dazu schreibst du ins Load-Ereignis deines Abteilungsformulars 'abteilungen':


Private Sub Form_Load()
   DoCmd.GoToRecord , , acNewRec
End Sub


Auf dem Abteilungsformular erzeugst du 2 Textfelder, nennst diese txtID zur Aufnahme der U_ID und txtName um den Unternehmensnamen anzuzeigen.
Für das Feld U_ID bestimmst du im Entwurf ... Sichtbar ... NEIN
Im Fall eines gebundenen Formulars - darauf bezieht sich der ganze Code, ist dann natürlich das Textfeld txtID an das Tabellenfeld U_ID der Datenherkunft gebunden,
das Textfeld txtName steht als Standallone zu Informationszwecken zur Verfügung und hat natürlich KEINE Bindung.


Tja und dann setzt du mal die Codes zusammen...

Im Button_Click-Ereignis sollte dann stehen:


Private Sub cmdAbteilungHinzufuegen_Click()

   Dim ID As Long, strName As String

   ID = Me!kombi_unternehmen
   strName = Me!kombi_unternehmen.Column(1)

   DoCmd.OpenForm "abteilungen"

   Forms!abteilungen!txtID = ID
   Forms!abteilungen!txtName = strName

End Sub


... und klickst mal nach Auswahl eines Unternehmens auf den Button ...

Sollte funktionieren   ;D

Peter


ThinkPink

Danke für die schnelle und ausführliche Antwort:)! Ich versuch jetzt mal das umzusetzten und werde danach hoffentlich eine Erfolgsmeldung hier reinschreiben können;)

ThinkPink


database

#4
Hallo Kerstin,

freut mich! ;D ;D ;D

Viel Erfolg noch weiterhin ...  !

Grüße
Peter

p.s.
Magst du den Beitrag bitte noch auf 'GELÖST' setzen - Danke

ThinkPink

Danke Peter:)!

Mir sind da grad noch zwei Kleinigkeiten aufgefallen, die ich noch gerne hinbekommen würde:

Also der Code zum Ereignis beim Clicken des Buttons, der ein neues Unternehmen hinzufügt, heißt jetzt so:

Private Sub butten_abteilung_hinzu_Click()
Dim ID As Long, strName As String

    ID = Me!kombi_unternehmen
    strName = Me!kombi_unternehmen.Column(1)

    DoCmd.OpenForm "abteilungen"

    Forms!abteilungen!txtID = ID
    Forms!abteilungen!txtName = strName
End Sub


(als ich versucht hab, den Button umzubenennen, hat nichts mehr funktioniert, deswegen heißt er jetzt so, wie er heißt;) )

Was ich jetzt noch total genial fände, wäre, wenn ich den Code noch durch etwas ergänzen könnte, sodass, wenn ich das Formular abteilungen schließe (oder spätestens wenn ich das formular mitarbeiter aktualisiere) die neu eingegebene Abteilung im Kombinationsfeld ausgewählt ist.

Wäre super, wenn mir da nochmal jemand helfen könnte....is ja bestimmt auch nur ein kleiner befehl, den ich aber halt nicht kenne.

Und wenn mir jetzt noch jemand verraten könnte, wie ich diesen Code modifizieren muss, damit ich ihn im "nicht in Liste"-Ereignis von kombi_abteilungen eintragen kann (und dort gleichzeitig noch im Feld bezeichnung schon das in kombi_abteilungen eingetragene steht), wär das einfach nur genial....ich mach da auch schon wieder ewig rum, aber je mehr ich veränder, desto weniger funktioniert.....und so langsam rennt mir die Zeit davon....

Tut mir Leid, dass ich noch mehr Fragen hatte. Aber das sind hoffentlich wirklich meine allerletzten!

database

Hallo Kerstin,

das mit dem Umbenennen des Button kann ich nicht nachvollziehen - im Formularentwurf dem Button einen neeuen Namen verpassen und im VBA-Editor das Klickereignis umbenennen auf den neuen Namen sollte eigentlich problemlos funktionieren.
Aber egal....
Zu deiner neuen Frage:
Im Prinzip schaut das so aus:
Du erstellst eine neue Abteilung und speicherst diese in der entsprechenden Tabelle.
Durch diesen Vorgan erhält die neue Abteilung in der Tablle eine neue AbteilungsID.
Diese ID ist deinem Kombifeld, welches ja b eim Öffnen des Quellformulars befüllt wurde noch nicht bekannt.
Daher muss beim Ereignis 'Beim Schließen' des Formulars 'abteilungen' diese neue ID ermittelt werden,
das Kombifeld im Quellformular NEU mit Daten befüllt werden und dann die neue ID ausgewählt werden.

Die neue ID der Tabelle Abteilungen kannst du mit

Dim abtID as Long
abtID = DMax("AbteilungsID","TabelleAbteilungen")

ermitteln (ist zwar nicht unbedingt die sauberste Variante aber sie funktioniert)

Somit kannst du im Ereignis 'Beim Schließen' des Formulars abteilungen folgedes machen:


Private Sub Form_Close()

    Dim id As Long
    id = DMax("AbteilungsID", "TabelleAbteilungen")
    Forms!DeinQuellFormular!kombi_abteilungen.Requery
    Forms!DeinQuellFormular!kombi_abteilungen = id

End Sub



Sollte eigentlich laufen  ;)

Zitatwie ich diesen Code modifizieren muss, damit ich ihn im "nicht in Liste"-Ereignis von kombi_abteilungen eintragen kann

....schau' ich mir noch später an und melde mich wieder!

Grüße
Peter

ThinkPink


database

So,
da bin ich wieder!

Zitatwie ich diesen Code modifizieren muss, damit ich ihn im "nicht in Liste"-Ereignis von kombi_abteilungen eintragen kann
Wenn du das Ereignis 'Bei Nicht In Liste' im VBE anschaust wirst du dort 2 Einträge finden, die sonst bei keinem Ereignis vorkommen:
NewData As String und Response as Integer

New Data enthält, wenn das Ereignis ausgelöst wird, den im Kombi eingetragenen TEXT und mit Response kannst du Access deine 'Absichten' oder 'Wünsche' bekanntgeben d.h. du reagierst damit auf den verursachten 'Fehler' (der Eintrag eines unbekannten Wertes stellt mehr oder weniger ja einen Fehler dar).
Dazu sollte beim Kombifeld die Möglichkeit gegeben sein, unbekannte Werte einzutragen --->  Entwurf .... Daten ... Nur Listeneinträge ---> JA
Wird jetzt ein unbekannter Wert eingegeben löst dieses das Ereignis Not In List aus.
Also folgender Code...


Private Sub kombi_abteilungen_NotInList(NewData As String, Response As Integer)

    Response = acDataErrContinue

    DoCmd.OpenForm "abteilungen"

    Forms!abteilungen!txtName = NewData
   
End Sub


Die Übergabe der ID entfällt hier, da si ja noch nicht bekjannt ist.

Versuch einfach mal das kurz umzusetzen.

Peter

ThinkPink

#9
Guten Morgähn,
sorry, dass ich jetzt erst wieder da bin...war am Wochenende nicht im Büro.
Danke für die Antwort!!!
Leider hat es nicht ganz funktioniert - das, was ich Neues in kombi_abteilungen eingegeben hab, wurde dem Unternehmen und nicht der Abteilung zugeordnet.
Ich dachte jetzt aber, ich hätte es geschafft, deinen Code mit Hilfe der anderen Ereignisse in meiner Datenbank so zu modifizieren, dass es passt.
Im Moment steht also beim "nicht in Liste"-Ereignis folgender Code:

Private Sub kombi_abteilungen_NotInList(NewData As String, Response As Integer)

If MsgBox("Die Abteilunge ist noch nicht in der Datenbank erfasst. Wollen Sie die Abteilung in die Liste eintragen?", vbYesNo) = vbYes Then
  Response = acDataErrContinue
 
Dim ID As Long, strName As String
 
  ID = Me!kombi_unternehmen
    strName = Me!kombi_unternehmen.Column(1)
 
  DoCmd.OpenForm "abteilungen", , , , acFormAdd
  Forms!abteilungen!bezeichnung = NewData
 
    Forms!abteilungen!txtID = ID
    Forms!abteilungen!txtName = strName

Else  'z.B. bei Tippfehler
  Response = acDataErrContinue
  Me!kombi_abteilungen.Undo
End If

End Sub


Es scheint alles zu funktionieren, bis zu dem Moment, wo ich das Formular schließen will - da kommt dann folgende Fehlermeldung:
"Laufzeitfehler 2118: Sie müssen das aktuelle Feld speichern, bevor Sie die Aktion AktualisierenDaten ausführen können."

Jetzt bin ich sooo kurz vor dem Ziel..aber leider immernoch nicht da ???

database

Hallo,

Zitatdas, was ich Neues in kombi_abteilungen eingegeben hab, wurde dem Unternehmen und nicht der Abteilung zugeordnet

tut mir leid, da hab' ich nicht aufgepasst ... und die Info dass es ein Feld 'abteilungen.bezeichnung ' gibt hat mir auch gefehlt.

Die Fehlermeldung wird m.E. dadurch ausgeslöst, weil beim Schließe des Formulars 'abteilungen' eine Datenmanipulation stattfindet, welche die erforderlichen Aktualisierungen noch nicht erhalten hat.
Das wird die neue AbteilungsID sein, welche noch nicht in die Tabelle geschrieben wurde.

Vesuche bitte daher folgendes:


Private Sub kombi_abteilungen_NotInList(NewData As String, Response As Integer)

If MsgBox("Die Abteilunge ist noch nicht in der Datenbank erfasst. Wollen Sie die Abteilung in die Liste eintragen?", vbYesNo) = vbYes Then
    Response = acDataErrContinue
 
    Dim ID As Long, strName As String
 
    ID = Me!kombi_unternehmen
    strName = Me!kombi_unternehmen.Column(1)
 
    DoCmd.OpenForm "abteilungen", , , , acFormAdd
    'Die neue Abteilung per SQL in die Abteilungs-Tabelle eintragen
    DoCmd.RunSQL "INSERT INTO TabelleAbteilungen(Abteilungsbezeichnung)VALUES('" & NewData & "')"

    Forms!abteilungen!bezeichnung = NewData
 
    Forms!abteilungen!txtID = ID
    Forms!abteilungen!txtName = strName

Else  'z.B. bei Tippfehler
    Response = acDataErrContinue
    Me!kombi_abteilungen.Undo
End If

End Sub


Lass mich bitte im Lauf des Nachmittags wissen obs geklappt hat.

Grüße

Peter

ThinkPink

Hallo Peter,

mit diesem (also deinem, mit meinen Tabellenbezeichnungen) Code

Private Sub kombi_abteilungen_NotInList(NewData As String, Response As Integer)

If MsgBox("Die Abteilung ist noch nicht in der Datenbank erfasst. Wollen Sie die Abteilung in die Liste eintragen?", vbYesNo) = vbYes Then
    Response = acDataErrContinue
 
    Dim ID As Long, strName As String
 
    ID = Me!kombi_unternehmen
    strName = Me!kombi_unternehmen.Column(1)
 
    DoCmd.OpenForm "abteilungen", , , , acFormAdd
    'Die neue Abteilung per SQL in die Abteilungs-Tabelle eintragen
    DoCmd.RunSQL "INSERT INTO abteilungen(bezeichnung)VALUES('" & NewData & "')"

    Forms!abteilungen!bezeichnung = NewData
 
    Forms!abteilungen!txtID = ID
    Forms!abteilungen!txtName = strName

Else  'z.B. bei Tippfehler
    Response = acDataErrContinue
    Me!kombi_abteilungen.Undo
End If

End Sub

passiert folgendes:
Zuerst werde ich gefragt ob ich wirklich einen Datnesatz anfügen will. Wenn ich dann auf ja klicke, kommt:
"Microsoft Office Access kann nicht alle Datensätze anfügen, die von der Anfügeabfrage betroffen sind.
Microsoft Office Access hat 0 Felder wegen Typenumwandlungsfehlern auf Null eingestellt, und es hat 1 Datensätze wegen Schlüsselverletzungen, 0 Datensätze wegen Sperrverletzungen und 0 Datensätze wegen Gültigkeitsregelverletzungen nicht an die Tabelle angefügt.
Möchten Sie trotzdem, dass die Aktionsabfrage weiter ausgeführt wird?
..."
Wenn ich dann auf ja klicke, komme ich wieder in das Feld, wo ich die Abteilung hinzufügen kann und beim Schließen kommt dann die alte Fehlermeldung ???
Also so langsam bin ich echt davon überzeugt, dass Computer ein Eigenleben haben;)

DF6GL

Hallo,

der Computer hat kein Eigenleben...



Warum übergibst Du nicht gleich den neuen Wert (Newdata) via Openargs an das EingabeForm (modal öffnen) und füllst das entspr. Form-Feld damit?
Das Form speichert dann schon selber den neuen DS in die Tabelle, sofern man das nicht im Form ggfls. verhindert.


database

Hallo, wie schon von DF6GL erwähnt - gibt's kein Eigenleben...   :)

Folgenden Code ins Formular 'abteilungen' ...  Beim Öffnen

Private Sub Form_Open(Cancel As Integer)
    If Not IsNull(Me.OpenArgs) Then
        Me!bezeichnung = Me.OpenArgs
        Me!txtID = Forms!DeinQuellformular!kombi_unternehmen
        Me!txtName = Forms!DeinQuellformular!kombi_unternehmen.Column(1)
    End If
End Sub


und im Quellformular wie gehabt ... mit geändertem Formularaufruf


Private Sub kombi_abteilung_NotInList(NewData As String, Response As Integer)


If MsgBox("Die Abteilunge ist noch nicht in der Datenbank erfasst. Wollen Sie die Abteilung in die Liste eintragen?", vbYesNo) = vbYes Then
   
    DoCmd.OpenForm "abteilungen", , , , acFormAdd, acDialog, NewData
 
    Response = acDataErrAdded

Else  'z.B. bei Tippfehler
  Response = acDataErrContinue
  Me!kombi_abteilungen.Undo
End If


Mal sehen ob's dem Ding jetzt passt!?

Greets


ThinkPink

Hallo Peter,
vielen vielen Dank, dass du dich schon wieder bemüht hast mir zu helfen!!!!!
Jetzt kommt "Laufzeitfehler: Sie können diesem Objekt keinen Wert zuweisen". Die Zeile die Probleme macht (also die, die beim debuggen markiert ist) scheint
Me!bezeichnung = Me.OpenArgs
zu sein.
Ich glaub, ich geb jetzt einfach auf...die Datenbank funktioniert ja auch ohne diese Eigenschaft.
Und dem Button setz ich auf "gelöst", weil ja meine Hauptprobleme gelöst sind:)
Vielen vielen Dank nochmal für die Hilfe und die Bemühungen (auch an DF6GL)!!!!!
Viele Grüße
Kerstin