PDA

Vollständige Version anzeigen : Formular mit abhängigen Datenblättern


Helchi
24.09.2003, 11:11
Hallo zusammen,

wieder mal stehe ich vor einem Problem, mit dem ich nicht alleine fertig werde und eure Hilfe brauche.

Ich möchte ein Formular erstellen, bei dem man mit Kombifeldern auf Datenblätter zugreifen kann.
Datenblätter würden sich anbieten, da man hier am einfachsten die Daten verändern kann.
Da ich Datenblätter verwenden möchte, bin ich ja auf Unterformulare angewiesen.

Ich hab jetzt ein Hauptformular mit einem Unterformular sForm_FG, das folgende Datenherkunft hat:

SELECT FG.Functional_Group_ID, FG.Functional_Group_Name FROM Table_Functional_Groups AS FG WHERE (FG.Ref_Discipline_ID=txtDiscipline )
txtDiscipline ist das Kombifeld im Hauptformular

Mit einem Unterformular kein Problem - aber wie kann ich ein zweites Unterformular auf die aktuelle Auswahl des ersten Unterformulars beziehen? Also wenn ich z.B. den Datensatz XY auswähle, soll er im der Datenblattansicht sForm_SG auch die zugehörigen Datensätze anzeigen - wie geht das? Hier skizziert:

SELECT SG.Functional_Subgroup_ID, SG.Functional_Subgroup_Name FROM Table_Functional_Subgroups AS SG WHERE (SG.Ref_Functional_Group_ID=XXX )

Zudem möchte ich auch noch die roten Veränderungen in angehängtem Bild realisieren - es wäre wirklich super, wenn mir jemand helfen könnte, der sich damit auskennt, weil ich nämlich damit hoffnungslos überfordert bin. Danke!!!

Nouba
24.09.2003, 11:26
Hallo Helchi,

schreibe mal folgendes in das Formularmodul von sForm_FG.Private Sub Form_Current()
Dim strSQL As String

strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " SG.Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & ", SG.Functional_Subgroup_Name" & vbCrLf
strSQL = strSQL & "FROM Table_Functional_Subgroups AS SG" & vbCrLf
strSQL = strSQL & "WHERE SG.Ref_Functional_Group_ID = " & Me!Functional_Group_ID

Me.Parent!sForm_SG.Form.RecordSource = strSQL

End Sub

Helchi
24.09.2003, 11:38
Hi Nouba,

danke für deine Antwort - leider meckert der Compiler bei der Ausführung:

Helchi
24.09.2003, 11:45
PS: Anbei das DB-Muster, wenn es bei der Problemlösung helfen sollte. (leider nur 1 Anhang pro Posting)

Anne Berg
24.09.2003, 11:58
Beim 1. Aufruf ist noch keine Auswahl vorhanden und der SQL-String somit fehlerhaft.

Nouba
24.09.2003, 12:03
Hallo Helchi,

setzte für sForm_SG den Namen des Unterformularsteuerelements, das die Sub Groups enthält, ein.

Anne Berg
24.09.2003, 12:14
sForm_SG ist ok, da Name des Steuerelements = Name des Ufos.

Mein Vorschlag:Private Sub Form_Current()
Dim strSQL As String
If Me.RecordsetClone.RecordCount > 0 Then
strSQL = strSQL & "SELECT " & _
"SG.Functional_Subgroup_ID, " & _
"SG.Functional_Subgroup_Name " & _
"FROM Table_Functional_Subgroups AS SG " & _
"WHERE SG.Ref_Functional_Group_ID = " & Me!Functional_Group_ID

Me.Parent!sForm_SG.Form.RecordSource = strSQL
End If
End Sub
()
Unbedingt die Vorschub-Steuerzeichen entfernen! (wer kommt bloß auf so eine Idee :confused: )

Wenn es allerdings keine Daten gibt (Beispiel license), musst du noch eine andere Lösung finden, um sForm_SG zu aktualisieren...

Nouba
24.09.2003, 12:53
@Anne,

Unbedingt die Vorschub-Steuerzeichen entfernen! (wer kommt bloß auf so einen :confused: Idee )

FYI: Das stammt von mir und ist gültige Jet-SQL Syntax. Zugegeben verschwendet es ein Zeichen mehr als ein Leerzeichen. Nebenbei erhalte ich aber dadurch eine strukturierte Ansicht meiner Abfragen.

Helchi
24.09.2003, 12:54
Danke Anne & Nouba,

ich hab jetzt den von Anne geposteten Code verwendet und es funktioniert! :)

Wenn es allerdings keine Daten gibt (Beispiel license), musst du noch eine andere Lösung finden, um sForm_SG zu aktualisieren...

Wenn ich jetzt license wähle, bleiben die Daten in sForm_SG von der vorherigen Auswahl im Datenblatt...eigentlich müsste es doch aber auch möglich sein, leere Felder anzuzeigen, wenn keine existieren - bei der Kombination aus Kombifeld-Datenblatt (sForm_FG) funktioniert dies ja ziemlich einfach. Wie mach ich das bei der Kombination Datenblatt-Datenblatt?

Danke, Helchi

Nouba
24.09.2003, 12:59
Hallo,

dann könnte doch eine Dummyabfrage zugewiesen werden
SELECT
Null AS Functional_Subgroup_ID
, Null AS Functional_Subgroup_Name;, die Du bei RecordCount = 0, bzw. auch bei NewRecord verwenden kannst.

Anne Berg
24.09.2003, 13:02
Die Abfrage für sForm_FG liefert in dem Fall eine leere Datenmenge, für sForm_SG lässt sich dann aber kein sinnvoller Filter setzen. Oder du setzt einen nie erreichbaren Dummywert (9999999) ein.

Helchi
24.09.2003, 13:09
Also ich hab jetzt folgendes versucht:


Private Sub Form_Current()
Dim strSQL As String
If Me.RecordsetClone.RecordCount > 0 Then
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " SG.Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & ", SG.Functional_Subgroup_Name" & vbCrLf
strSQL = strSQL & "FROM Table_Functional_Subgroups AS SG" & vbCrLf
strSQL = strSQL & "WHERE SG.Ref_Functional_Group_ID = " & Me!Functional_Group_ID
Me.Parent!sForm_SG.Form.RecordSource = strSQL
ElseIf Me.RecordsetClone.RecordCount = 0 Then
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " NULL AS Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & ", NULL AS Functional_Subgroup_Name"
Me.Parent!sForm_SG.Form.RecordSource = strSQL
ElseIf Me.RecordsetClone.NewRecord = True Then
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " NULL AS Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & ", NULL AS Functional_Subgroup_Name"
Me.Parent!sForm_SG.Form.RecordSource = strSQL
End If
End Sub


Allerdings weiß ich nicht, ob das so toll ist - beim 1.Aufruf kommt zumindest wieder der Fehler von oben.

@ Anne:
Tut mir leid, aber das versteh ich nicht - bin noch in der Lernphase von Access und VBA. :(

Nouba
24.09.2003, 13:32
Hallo Helchi,

Du kannst es mal hiermit versuchen. Wobei die vbCrLfs auch gegen Annes Leerzeichen ersetzt werden können. :)
Private Sub Filter_sForm_SG()
Dim strSQL As String

If Me.RecordsetClone.RecordCount > 0 And Not Me.NewRecord Then
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " SG.Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & ", SG.Functional_Subgroup_Name" & vbCrLf
strSQL = strSQL & "FROM Table_Functional_Subgroups AS SG" & vbCrLf
strSQL = strSQL & "WHERE SG.Ref_Functional_Group_ID = " & Me!Functional_Group_ID
Else
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " Null AS Functional_Subgroup_ID"
strSQL = strSQL & ", Null AS Functional_Subgroup_Name"
End If

Me.Parent!sForm_SG.Form.RecordSource = strSQL
End Sub

Private Sub Form_AfterUpdate()
Call Filter_sForm_SG
End Sub

Private Sub Form_Current()

Static boolFirstStart As Boolean

If Not boolFirstStart Then
boolFirstStart = True
Exit Sub
End If

Call Filter_sForm_SG

End Sub

Private Sub Form_Delete(Cancel As Integer)
Call Filter_sForm_SG
End Sub

Anne Berg
24.09.2003, 13:37
Ich denke das Problem liegt daran, dass beim 1. Aufruf das 2. ufo noch nicht geladen ist und daher nicht angesprochen werden kann.

Die 3. Befehlsgruppe kommt nicht zum Zuge, RecordCount kann nur 0 oder >0 sein. ;) Mußt du wohl den Wert (NULL) von Functional_Group_ID abfragen.

Helchi
24.09.2003, 14:11
Hey Nouba ich könnte dich abknutschen für deine Hilfe, wenn du eine Frau wärst! ;)

Es funktioniert einwandfrei - auch wenn ich den Code selbst nicht ganz nachvollziehen kann.
Aber vielleicht kommt das mit der Zeit.

Nur noch eine Frage:

Wie kann ich
- die Spaltenüberschriften der Datenblattansicht
- die erste Spalte mit den IDs
- den nicht benötigten dunklen Raum am Ende des Datenblatts
ausblenden (siehe erstes Posting)?

Danke, Helchi

Helchi
24.09.2003, 14:23
Mist, zu früh gefreut - es gibt noch ein zusätzliches Problemchen: :(

Wenn ich neue DS einfüge, wird die Referenz auf die Discipline_ID nicht gespeichert. :confused:

Nouba
24.09.2003, 14:24
Hallo Helchi,

das BeimAnzeigen Ereignis wird wohl beim Öffnen eines neuen Formulars oder Unterformulars zweimal aufgerufen. Der erste Aufruf wird durch setzen einer Statischen Variablen abgebrochen. Beim nächsten Aufrufen ist der Wert vorhanden und die Prozedur wird ganz abgearbeitet. Damit Deine Sub Groups auch immer aktuell zu den Groups sind, wird das ganze Prozedere auch beim NachAktualisieren und beim Löschen benötigt. Um das nicht 3x aufzuführen ist die kleine Prozedur Filter_sForm_SG da.

Du kannst die Autowertfelder ganz aus den Formularen als Textfeld (nicht aus der Abfrage) herausnehmen - Value kann weiterhin angesprochewn werden. Dann ziehst Du Dein Feld soweit wie benötzigt auf und speicherst die Ansicht. Beim nächsten öffnen sollten die Einstellungen erhalten bleiben.

Nouba
24.09.2003, 14:34
Hallo Helchi,

füge in das Unterformular sForm_FG noch folgendes ein
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Not IsNull(Me.Parent!txtDiscipline) Then
Me!Ref_Discipline_ID = Me.Parent!txtDiscipline
Else
Cancel = True
MsgBox "Bitte zuerst eine Disziplin auswählen."
End If
End Sub
und mache das Feld Ref_Discipline_ID in der Abfrage sichtbar.

Helchi
24.09.2003, 14:48
DANKE NOUBA !!!

Helchi
25.09.2003, 11:30
Hallo Nouba und alle anderen hier im Forum,

jetzt probier ich schon seit 5 Stunden an meinem Formular rum, aber ich komm einfach nicht drauf, wie sich das realisieren lässt. Ich würde gerne alle Funktionalitäten auf dem Bild umsetzen - dabei soll das ganze Formular dynamisch sein, d.h. wenn ich einen Datensatz anklicke sollen immer die durch Pfeile dargestellten anderen Datenblätter aktualisiert werden.

Kannst du (Nouba) oder jemand anders mir dabei helfen? Ich weiß echt nicht mehr weiter! :(

Danke, Helchi

Helchi
25.09.2003, 11:30
Hier zum besseren Verständnis die DB:

Nouba
25.09.2003, 12:20
Hallo Helchi,

vermutlich müssen die AfterUpdate Events zum Anstossen der Kaskaden verwendet werden. Darin kannst Du entweder auf die Unterformulare Filter anwenden oder die RecordSource entsprechend neu schreiben.

Helchi
25.09.2003, 12:45
Hi Nouba,

du sprichst in Rätseln - was sind Kaskaden und was soll ich mit ihnen machen? :confused:

Kannst du mir dabei nochmal unter die Arme greifen? :angel:

Gruß Helchi

Helchi
25.09.2003, 14:26
Tappe leider immer noch TOTAL im Dunkeln, daher on the top. :(

Bin für jede Hilfe dankbar!

Nouba
25.09.2003, 14:52
Hallo Helchi,

du sprichst in Rätseln - was sind Kaskaden und was soll ich mit ihnen machen? :confused:
Eine Kaskade ist eine feste Aufeinanderfolge von mehreren Abläufen oder Reaktionen.

In jedem Afterupdate der Kombifelder, muß das abhängige Unterformular gefiltert werden. Ein Beispiel für ein Unterformular hatten wir doch schon - wo ist das Problem :confused: :confused:

Helchi
25.09.2003, 15:25
Irgendwie steh ich auf dem Schlauch - gestern als du mir das mit dem Unterformular erklärt hast, hab ich durchgeblickt, aber jetzt check ichs einfach nicht mehr, was ich machen muss. Kannst du dir eventuell bis morgen mal meine DB ansehen und schauen, wo es hackt? In jedem Formular steht fast der gleiche Code (der von dir), daher dürft es ja für dich leicht verständlich sein.

Danke, Helchi (Access & VBA is doch schwieriger als ich dachte)

Nouba
25.09.2003, 15:41
Hallo Helchi,

da es sich um <i>Deine</i> Datenbank handelt, finde ich es an der Zeit, dass sie langsam mal mit Deinem Kode gefüllt wird. Wenn es dann nicht zum Erfolg führt, gibt es konkrete Stellen, wo man bei der Hilfe ansetzen kann. Der zu beschreitende Weg ist ja gut "bepfeilt". Überall wo ein Pfeil anfängt, sorgst Du dafür, dass bei jegwelchen Änderungen des Inhalts, das Kind-Element aktualisiert wird. Bei Formularen kann das durch Ändern der RecordSource (Abfrage) oder durch Setzen und einschalten eines Filters das Recordset beeinflußen. Für Listen- und Kombifelder ist die RowSoure zu beeinflußen.

Wenn's beim Abfragenbau Probleme gibt, kannst Du die Abfragen zuerst im QBE-Editor erstellen und die nötigen Parameter setzen. Nach dem Kopieren in Dein VBA Skript sind die Parameter durch die richtigen Werte zu ersetzt. Das Thema Zeichenketten Zusammensetzen sollte ja wohl kein Thema sein.

Da Deine Beziehungen alle auf Autowertfeldern beruhen, müßen keine Sonderregelungen bei der Parameterübergabe berücksichtigt werden.

Ich hoffe, dass Du von Erfolg beschieden bist.

Helchi
25.09.2003, 22:57
Naja, so richtig erfolgreich war ich bis jetzt noch nicht...aber vielleicht bringt ja der morgige Tag die Erleuchtung! Tut mir leid, dass ich da jetzt so oft deine Hilfe beanspruche, aber ich muss das Projekt in 2 Wochen abgeben und dazu brauch ich noch die Eingabemaske und dann muss ich das Ding noch mit 1200 Datensätzen füttern, daher geht mir langsam der Kackstift... :(

Nouba
25.09.2003, 23:10
Hallo Helchi,

das unterste UFo kann editiert werden, wenn als Eigenschaft für Recordset Type Dynaset (Inconsistent Update) eingestellt wird.

Helchi
26.09.2003, 07:43
Ok also ich bin glaub ich schon ein wenig weiter gekommen - aber folgende Probleme machen mich schwach:

(1)
Wenn ich "Licence" als Discipline auswähle und es noch keine Datensätze hierfür in den Datenblättern gibt , kommt ein Fehler weil ich die nicht vorhandenen Datensätze als Kriterium in dem SQL-Filter für die anderen Uforms hab.

strSQL = strSQL & "WHERE PFFS.Ref_Functional_Subgroup_ID = " & Me!sForm_SG.Form.Functional_Subgroup_ID & vbCrLf


(2)
Ich kann keine Datensätze in sForm_FG oder sForm_SG löschen:

Laufzeitfehler '2074': Dieser Vorgang wird innerhalb von Transaktionen nicht unterstützt.


(3)
Dann häng ich noch mit der Button Geschichte, die von der Gesamtteileliste Part_Key_New, Part_Key_Old (falls vorhanden), Part_Name in die entsprechenden Felder von sForm_SGP schieben soll.


Hoffe, du kannst mir nun weiterhelfen. Das Aktualisieren mit den Listenfeldern klappt jetzt eigentlich! DANKE!

Gruß Helchi

Helchi
26.09.2003, 08:22
(1) selbst gelöst mit:


If Not IsNull(Me!txtPeriod) And Not IsNull(Me!sForm_SG.Form.Functional_Subgroup_ID) Then
(...)
strSQL = strSQL & "WHERE PFFS.Ref_Functional_Subgroup_ID = " & Me!sForm_SG.Form.Functional_Subgroup_ID & vbCrLf
strSQL = strSQL & " AND PFP.Ref_Time_Period_ID = " & Me!txtPeriod & vbCrLf
(...)
Else
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " Null AS Part_Key_New" & vbCrLf
strSQL = strSQL & ", Null AS Part_Key_Old" & vbCrLf
strSQL = strSQL & ", Null AS Part_Name" & vbCrLf
strSQL = strSQL & ", Null AS Amount_For_Functional_Subgroups" & vbCrLf
strSQL = strSQL & ", Null AS Price" & vbCrLf
strSQL = strSQL & ", Null AS Price_Unit" & vbCrLf
End If
Me!sForm_SGP.Form.RecordSource = strSQL


Schaut der Code so einigermaßen gut aus?

Andere 2 Probleme leider noch nicht gelöst.

Helchi
26.09.2003, 10:05
(2)
Ich kann keine Datensätze in sForm_FG oder sForm_SG löschen:

Laufzeitfehler '2074': Dieser Vorgang wird innerhalb von Transaktionen nicht unterstützt.

(3)
Dann häng ich noch mit der Button Geschichte, die von der Gesamtteileliste Part_Key_New, Part_Key_Old (falls vorhanden), Part_Name in die entsprechenden Felder von sForm_SGP schieben soll.

(4)

Wenn ich in dem UFO sForm_SGP einen Datensatz lösche, steht in sForm_P bei allen Feldern des ursprünglichen Datensatzes #Gelöscht, obwohl ich sForm_SGP Requery verwende:
Private Sub Form_AfterUpdate()
Me.Parent!sForm_P.Form.Requery
End Sub

Need Help please! :(

Helchi
26.09.2003, 10:15
(4) auch wieder selbst gelöst:

Private Sub Form_AfterDelConfirm(Status As Integer)
Me.Parent!sForm_P.Form.Requery
End Sub

Helchi
26.09.2003, 11:13
Zu Problem (3) hab ich jetzt folgenden Button im Hauptform erstellt:

Private Sub InsertPart_Click()
Dim strSQL As String
' Button fügt Bauteile der Gesamtteileliste in Subgruppe ein
If Not IsNull(Me!sForm_P.Form.Part_ID) And Not IsNull(Me!sForm_SG.Form.Functional_Subgroup_ID) Then
strSQL = strSQL & "INSERT INTO Table_Parts_For_Functional_Subgroups" & vbCrLf
strSQL = strSQL & " ( Ref_Part_ID, Ref_Functional_Subgroup_ID )" & vbCrLf
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " P.Part_ID" & vbCrLf
strSQL = strSQL & ", SG.Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & "FROM Table_Parts AS P, Table_Functional_Subgroups AS SG" & vbCrLf
strSQL = strSQL & "WHERE P.Part_ID = " & Me!sForm_P.Form.Part_ID & vbCrLf
strSQL = strSQL & " AND SG.Functional_Subgroup_ID = " & Me!sForm_SG.Form.Functional_Subgroup_ID & vbCrLf & ";"
Else
MsgBox "INSERT NICHT ERFOLGREICH!"
End If
Me!sForm_SGP.Form.NewRecord = strSQL
End Sub

Ich möchte quasi das/die ausgewählten Teil/e den Subgruppen zuordnen.
Was stimmt bei dem SQL-Statement nicht?

Nouba
26.09.2003, 11:22
setze mal ein Debug.Print strSQL vor die rote Zeile und kopiere die Ausgabe aus dem Direktfenster <Strg g> in eine neue Abfrage. Dort werden eventuelle Syntax-Fehler kritisiert.

Zum Ausführen der Abfrage sollte CurrentDB().Execute strSQL, dbFailOnError gut sein.

Helchi
26.09.2003, 11:50
Danke Nouba,

wie kann man zwei SQL-Statements verknüpfen?

strSQL = strSQL & "INSERT INTO " (...) & ";" & vbCrLf
strSQL = strSQL & "INSERT INTO " (...) & ";"

funzt nicht... :(

Nouba
26.09.2003, 11:56
Jet-SQL erlaubt nur eine Anfügeanweisung pro Abfrage.

Helchi
26.09.2003, 13:07
Ok noch eine Frage:

Wie kann ich die Daten bestimmen, die durch Rechtsklick auf eine Zeile in der Datenblattansicht gelöscht werden sollen? Kann man das Access vorgeben?

Danke, Helchi

Helchi
26.09.2003, 13:44
Kann man mit der INSERT Anweisung Daten auch in ZWEI Tabellen einfügen?

Hab an folgenden Code gedacht, der allerdings nicht funktioniert:


strSQL = strSQL & "INSERT INTO" & vbCrLf
strSQL = strSQL & " Table_Parts_For_Functional_Subgroups ( Ref_Part_ID, Ref_Functional_Subgroup_ID ), " & vbCrLf
strSQL = strSQL & " Table_Prices_For_Parts ( Ref_Part_ID, Ref_Time_Period_ID, Price ) " & vbCrLf
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " P.Part_ID" & vbCrLf
strSQL = strSQL & ", SG.Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & ", P.Part_ID" & vbCrLf
strSQL = strSQL & ", TP.Time_Period_ID" & vbCrLf
strSQL = strSQL & ", '0'" & vbCrLf
strSQL = strSQL & "FROM Table_Parts AS P, Table_Functional_Subgroups AS SG, Table_Time_Periods AS TP" & vbCrLf
strSQL = strSQL & "WHERE" & vbCrLf
strSQL = strSQL & " P.Part_ID = " & Me!sForm_P.Form.Part_ID & vbCrLf
strSQL = strSQL & " AND SG.Functional_Subgroup_ID = " & Me!sForm_SG.Form.Functional_Subgroup_ID & vbCrLf
strSQL = strSQL & " AND TP.Time_Period_ID = " & Me!txtPeriod & vbCrLf & ";"

Nouba
26.09.2003, 13:46
Nein. Du kannst aber mehrere Abfragen hintereinander ausführen.

Helchi
26.09.2003, 14:17
Sorry, aber ich verzweifel jetzt bald...habs jetzt wie du gesagt hast mit 2 Abfragen gelöst.

Wenn ich den Button das 1.mal drücke, schreibt er den DS einmal in sForm_SGP.
Wenn ich den Button das 2.mal drücke, schreibt er den DS dreimal in sForm_SGP.

Dabei sollte er jedes mal immer nur einen DS in sForm_SGP schreiben!??

Vielleicht kannst du dir das ja mal anschauen Nouba, ich komm echt nicht mehr weiter und ich häng da jetzt schon ewig dran! Ist echt zum heulen! :bawling:

...und dann ist da noch dieses Problem, wenn ich DS in sForm_SGP lösche, soll davon aber sForm_P nicht beeinflusst werden...sForm_P ist die Gesamtteileliste und sForm_SGP die Zuordnung der Teile zu Subgruppen...ein Teil kann, muss aber nicht einer Subgruppe zugeordnet sein, d.h. wenn ich es in sForm_P lösche muss es auch in sForm_SGP gelöscht sein aber nicht umgekehrt...

Kannst du mir bitte dabei noch helfen? :(

Helchi
26.09.2003, 16:42
Also für heute geb ich auf... keine Ahnung wie das funktioniert! :(

Helchi
26.09.2003, 19:13
Hast du schon mal einen Blick auf meine DB riskiert Nouba?
Wäre super, wenn du dir das mal übers Wochenende anschauen könntest.
Ich steig da mit meinen Kenntnissen nämlich nicht mehr durch. :(

Gruß Helchi

Helchi
29.09.2003, 07:07
Ok anscheinend hast du keinen Blick drauf riskiert - dann muss ich es eben so schaffen... :(

Ich glaube ich weiß jetzt warum er bei klick auf den Button die Datensätze falsch einträgt. Ein Bauteil kann in einer Zeitperiode nur einen Preis haben. Daher muss ich irgendwie prüfen, ob in der Tabelle Table_Prices_For_Parts schon eine Kombination aus Ref_Part_ID und Ref_Time_Period_ID besteht. Wie kann ich das realisieren?

So funzt es noch nicht - er trägt gar nichts ein:


' Part_ID in Table_Prices_For_Parts NUR EINMAL einfügen, da jedes Teil in jeder Periode nur einen Preis!
varPID = DLookup("Ref_Part_ID ", "Table_Prices_For_Parts", "Ref_Part_ID= " & Me!sForm_P.Form.Part_ID )
varTID = DLookup("Ref_Time_Period_ID ", "Table_Prices_For_Parts", "Ref_Time_Period_ID= " & Me!txtPeriod )
If IsNull(varPID & varTID ) Then
(... INSERT ...]
End If

Helchi
29.09.2003, 08:58
weiß denn keiner rat? :(

Nouba
29.09.2003, 09:49
Hallo Helchi,

im untersten UFo wird eine Abfrage über drei Tabellen als Datenquelle verwendet. Bei Neuanlage eines DS kann Access gar nicht anders, als mehrere DS anlegen. Versuche die Abfrage auf eine Tabelle zu reduzieren.

Helchi
29.09.2003, 10:09
Hi Nouba,

das Problem ist leider immer bei einer n:m Beziehung gegeben, dass man auf mehrere Tabellen zugreifen muss. Oder muss an sowas anders rangehen?

Es würde auch funktionieren - bis auf das Problem, dass in der Tabelle Table_Prices_For_Parts nicht zweimal dieselbe Kombination aus Ref_Part_ID und Ref_Time_Period_ID vorkommen darf . Wenn ich auf den Button drücke, soll er auf jeden Fall dieses Teil der Subgruppe zuordnen , aber nur einen neuen DS in Table_Prices_For_Parts anlegen, falls die Kombination aus Bauteil-TimePeriod noch nicht existiert. Und genau das funzt so nicht:


Private Sub InsertPart_Click()
Dim strSQL As String
Dim varPID As Variant
Dim varTID As Variant

' Button fügt Bauteile der Gesamtteileliste in Subgruppe ein
If Not IsNull(Me!sForm_P.Form.Part_ID) And Not IsNull(Me!sForm_SG.Form.Functional_Subgroup_ID) And Not IsNull(Me!txtPeriod) Then
' Part_ID in Table_For_Functional_Subgroups einfügen
strSQL = strSQL & "INSERT INTO" & vbCrLf
strSQL = strSQL & " Table_Parts_For_Functional_Subgroups ( Ref_Part_ID, Ref_Functional_Subgroup_ID )" & vbCrLf
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " P.Part_ID" & vbCrLf
strSQL = strSQL & ", SG.Functional_Subgroup_ID" & vbCrLf
strSQL = strSQL & "FROM Table_Parts AS P, Table_Functional_Subgroups AS SG" & vbCrLf
strSQL = strSQL & "WHERE" & vbCrLf
strSQL = strSQL & " P.Part_ID = " & Me!sForm_P.Form.Part_ID & vbCrLf
strSQL = strSQL & " AND SG.Functional_Subgroup_ID = " & Me!sForm_SG.Form.Functional_Subgroup_ID & vbCrLf & ";"

' SQL-Statement ausführen
CurrentDb().Execute strSQL, dbFailOnError
strSQL = vbNullString
' Part_ID in Table_Prices_For_Parts NUR EINMAL einfügen, da jedes Teil in jeder Periode nur einen Preis!
varPID = DLookup("Ref_Part_ID", "Table_Prices_For_Parts", "Ref_Part_ID=" & Me!sForm_P.Form.Part_ID)
varTID = DLookup("Ref_Time_Period_ID", "Table_Prices_For_Parts", "Ref_Time_Period_ID=" & Me!txtPeriod)
If IsNull(varPID & varTID) Then
strSQL = strSQL & "INSERT INTO" & vbCrLf
strSQL = strSQL & " Table_Prices_For_Parts ( Ref_Part_ID, Ref_Time_Period_ID, Price )" & vbCrLf
strSQL = strSQL & "SELECT" & vbCrLf
strSQL = strSQL & " P.Part_ID" & vbCrLf
strSQL = strSQL & ", TP.Time_Period_ID" & vbCrLf
strSQL = strSQL & ", '0'" & vbCrLf
strSQL = strSQL & "FROM Table_Parts AS P, Table_Time_Periods AS TP" & vbCrLf
strSQL = strSQL & "WHERE" & vbCrLf
strSQL = strSQL & " P.Part_ID = " & Me!sForm_P.Form.Part_ID & vbCrLf
strSQL = strSQL & " AND TP.Time_Period_ID = " & Me!txtPeriod & vbCrLf & ";"

' SQL-Statement ausführen
CurrentDb().Execute strSQL, dbFailOnError
strSQL = vbNullString
Else
MsgBox "INSERT MIT DLOOKUP NICHT ERFOLGREICH!"
End If Else
MsgBox "INSERT NICHT ERFOLGREICH!"
End If
'Datenblatt aktualisieren
Me!sForm_SGP.Form.Requery
End Sub

Nouba
29.09.2003, 10:33
Du könntest mal versuchen, die Abfrage für das unterste UFo mit Outer Joins in den Abfragebeziehungen einzustellen, ob es damit besser wird, kann ich Dir nicht mitteilen.
SELECT
P.Part_ID
, P.Part_Key_New
, P.Part_Key_Old
, P.Part_Name
, PFFS.Parts_For_Functional_Subgroup_ID
, PFFS.Ref_Part_ID AS PFFS_Ref_Part_ID
, PFFS.Ref_Functional_Subgroup_ID
, PFFS.Amount_For_Functional_Subgroups
, PFP.Prices_For_Parts_ID
, PFP.Ref_Part_ID AS PFP_Ref_Part_ID
, PFP.Ref_Time_Period_ID, PFP.Price
, PFP.Price_Unit
FROM
(
Table_Parts AS P LEFT JOIN Table_Parts_For_Functional_Subgroups AS PFFS ON
P.Part_ID = PFFS.Ref_Part_ID
) LEFT JOIN Table_Prices_For_Parts AS PFP ON
P.Part_ID = PFP.Ref_Part_ID
WHERE
(((PFFS.Ref_Functional_Subgroup_ID)=9) AND
((PFP.Ref_Time_Period_ID)=1))
ORDER BY P.Part_Name;

Helchi
29.09.2003, 11:45
Ich glaube wir reden noch aneinander vorbei. Die Select-Abfrage liefert ja nur die Datenherkunft, ich möchte aber die richtigen Datensätze in die Tabelle eintragen. Ich hab mal zum besseren Verständnis einen Screenshot angefügt und hier der Code mit dem ich das - in etwa - realisieren wollte, leider stimmt das zusammenfügen so nicht, er springt erst gar nicht in if-Schleife:


varPID = DLookup("Ref_Part_ID", "Table_Prices_For_Parts", "Ref_Part_ID=" & Me!sForm_P.Form.Part_ID)
varTID = DLookup("Ref_Time_Period_ID", "Table_Prices_For_Parts", "Ref_Time_Period_ID=" & Me!txtPeriod)
If IsNull(varPID & varTID) Then

Nouba
29.09.2003, 12:04
Wenn beide Bedingungen zugleich gelten sollen, müssen sie auch in der Domänenaggregat-Funktion geinsam verwendet werden.
If DCount("*", _
"Table_Prices_For_Parts", _
"Ref_Part_ID = " & Me!sForm_P.Form.Part_ID & " AND " _
& "Ref_Time_Period_ID = " & Me!txtPeriod) = 0 Then

Helchi
29.09.2003, 12:35
PERFEKT - genau das wars wonach ich schon seit 5 Tagen suche, danke Nouba! :top:

Bis jetzt hatte ich noch kein Problem seit meinem Beginn mit Access vor 2 Monaten, das du nicht lösen konntest! Noch einmal ein herzliches Dankeschön von meiner Seite für deine sehr kompetente Hilfe! :hands:

Gruß Helchi