Hallo Access-Kenner, -Freunde und -Hasser ;D,
ich bin zwar noch ein Access-Greenhorn, habe aber schon einige Jahre Erfahrung mit Word, Excel und VBA sammeln können. Ich hoffe, das wird mir noch helfen. Im Moment stehe ich aber ziemlich auf dem Schlauch.
Nun aber zu meinem Problem:
Nicht daß ich größenwahnsinnig wäre (ok, vielleicht ein bißchen 8)). Mein Ziel ist der Aufbau einer Mehrnutzer-Datenbank für die Verwaltung verschiedener Dokumente, die miteinander verknüpft sind. Fürs Erste habe ich drei Tabellen zu einer Dokumentenart erstellt, die sich separat handhaben läßt. Die Abfrage in einem eigenständigen Formular klappt auch einwandfrei. Im Formularkopf habe ich drei Kombinationsfelder eingerichtet, die mir eine Auswahl aus zwei der Tabellen anbieten (ja, es ist eine gewisse, aber notwendige Redundanz vorhanden), aus denen ich den Output im Detailbereich generiere. Die Kombinationsfelder werden per VBA vorbelegt, verfügen aber auch über eigene Select-Statements in der Eigenschaft Datensatzherkunft.
Wie gesagt, als standalone-Formular funktioniert es wunderbar. Nun möchte ich dem Anwender eine Oberfläche bieten, die ihm den Zugriff auf die gesamte geplante Funktionalität gewährt. Dafür möchte ich ein Navigationsformular verwenden. Nachdem Einfügen des standalone-Formulars in ein Navigations-Unterformular muß ich die Verweise auf das Originalformular in den Kombinationsfeldern entfernen, damit die untereinander bestehende Abhängigkeit funktioniert. Soweit ok. Leider steuern die Kombinationsfeldinhalte nun nicht mehr die Feldinhalte im Detailbereich. Die sind statisch.
Wo muß ich denn jetzt welchen Teil der ursprünglichen Abfrage für den Detailbereich platzieren?
Eigenschaft der Navigationsschaltfläche des Navigationsunterformulars: Name des Navigationsziels = Name des Ursprungs-Formulars?
Eigenschaft der Navigationsschaltfläche des Navigationsunterformulars: WHERE-Klausel für Navigation = WHERE-Klausel der ursprünglichen Abfrage, aber ohne WHERE und ohne [Formulare]!Formularname?
Eigenschaft des Formulars unter der Navigationsschaltfläche: Datensatzquelle = ursprüngliche SELECT-Abfrage ohne WHERE-Klausel?
Wo hakt das Ganze?
Ach, bevor die Frage kommt: mit Registern habe ich es auch schon versucht, der Effekt ist der Gleiche.
Falls nötig, lade ich ein Beispiel hoch.
Georg
Hallo,
in der Tat wäre es sinnvoll, eine Beispiel-DB hochzuladen...
Vermutlich liegt die Krux daran, dass in gespeicherten Abfragen (für die Datensatzherkunft der Kombis) Formular-Steuerelement-Verweise als Referenz benutzt werden, die bei Verwendung als Unterformulare eben ohne Anpassung nicht nehr gültig sind.
http://www.donkarl.com/?FAQ4.2
Hallo DF6GL,
ja, das ist gut möglich. Das habe ich noch nicht so ganz durchschaut. Die Bücher, die ich bestellt habe, kann ich heute abend abholen. Die planlose Fummelei, die ich bisher betrieben habe, führt zu nichts, ich will mir eine ordentliche Wissensbasis schaffen. So ganz alleine ist das aber auch nicht optimal, es ist immer gut, wenn man sich austauschen kann. Ich hoffe, daß ich mal was zurückgeben kann.
So, hier ist nun das Beispiel. Bin mal gespannt, wo ich den Wald vor Bäumen nicht mehr gesehen habe.
Georg
[Anhang gelöscht durch Administrator]
Hallo,
da gibt es jede Menge Baustellen... :'(
Ein Vergleich mit "*" ist nur bei Feldern mit Datentyp Text sinnvoll. Zudem muss dafür der "Like"-Operator verwendet werden.
Vorschlag:
1) Beziehungen im Beziehungsfenster herstellen.
2) Nachschlagefelder in Tabellen herauswerfen.
3) für "all"-Einträge in Such-Kombifeldern gleichen Datentyp wie die entspr. Tabellenspalte und mit einem "Spezialwert" z. B. 0, verwenden.
4) In Formular-Abfragen keine Formularfeld-Verweise benutzen.
5) für Such(abfrage)vorgänge, die die Modifikation der Form-Recordsource benutzen, den SQL-String per VBA zusammenbauen und mit den entspr. Kriterien versehen (den Auswahlwerten der Such-Kombis. Dabei den Spezialwert für den "all"-Eintrag passend berücksichtigen.
Hallo,
Du läßt mich einigermaßen verwirrt zurück. Das sind eine ganze Menge Aussagen. Ich versuche mal, adäquat darauf zu antworten.
- 0) Vergleich mit *: dabei vergleiche ich mit Werten aus einer Abfrage. Dort habe ich keinen Einfluß auf den Datentypen. Gut, in zwei Fällen baut die zugrundeliegende UNION-Abfrage auf einem Autowert-Feld auf. Was ist das Problem dabei, und warum ist es besser, eine "0" zu verwenden als einen "*", wenn man alle Einträge als Ergebnis sehen will? Das entspricht doch der Access-Syntax?
Der Like-Operator wird als Datensatzquelle des Formulars verwendet, und nur dort. Dort möchte ich ja die Möglichkeit haben, entweder einen bestimmten oder alle Einträge "auszuwählen". Im Kombifeld "CB_Status" ist die UNION-Abfrage überflüssig, ich habe sie dort rausgeworfen. - 1) Beziehungen: zwischen den Tabellen existieren Beziehungen. Müssen zwischen den Abfragen auch welche hergestellt werden?
- 2) Nachschlagefelder in Tabellen: finde ich als Hilfe bei der manuellen Eingabe zwar hilfreich, aber ich habe sie jetzt mal rausgeworfen.
- 3) Such-Einträge in Kombifeldern: beziehe ich jeweils aus einer UNION-Abfrage, mit der ich die entsprechende dahinterliegende Tabelle um den Spezialwert "*" ergänze. Wo ist denn da der Haken?
- 4) Formular-Abfragen: wie soll ich denn sonst die Felder im Formular-Detailbereich von den Formularfeldern im Formularkopf abhängig machen? Oder habe ich Dich hier falsch verstanden?
- 5) Verstehe ich das richtig, daß es besser ist, die SQL-Abfrage, die die Felder im Detailbereich füllen soll, als VBA-Code zu hinterlegen? Welches Ereignis würde sich denn dafür am Besten eignen? Ich würde eine Routine bauen, die nach jeder Änderung in einem der drei Kombinationsfelder ausgeführt würde.
Immerhin hast Du mir eine ganze Menge Hinweise gegeben, in welche Richtung ich gehen soll. Wie Du siehst, habe ich jetzt aber mehr Fragen als vorher, was ich allerdings nicht negativ sehe. Offensichtlich stehe ich noch ganz am Anfang meiner "Karriere" als Access-Anwendungsentwickler.
Kannst du vielleicht nochmal auf meine Fragen eingehen? Das würde mir glaube ich sehr helfen.
Georg
P.S. Warum springt die Anzeige im Eingabefeld für den Beitrag denn immer hoch, sobald der Text länger wird als das Eingabefeld hoch ist?
Hallo
0) Die Datentypen in der Abfrage richten sich nach den ersten gefundenen Werten, hier ein "*" demzufolge ist die gesamte Spalte "Text"
Access Syntax reicht allein nicht, um Laufzeitfehler zu vermeiden. Die "Datenlogik" dahinter muss auch stimmen.
1) Wenn Tabellenbeziehungen (im BE, falls vorhanden) bestehen, werden diese beim Generieren von Abfragen in der Entwurfsansicht mit berücksichtigt.
2) m. E. ist das nur für Gelegenheitsentwickler (GelegenheitsUser) und auch da nur anfänglich hilfreich....
3) da ist kein Haken, außer den o. angesprochenen Problemen mit den Datentypen.
4) Überhaupt nicht "abhängig", d, h. keine Verweise in der Formular-Abfrage. Hier ist eh zu fragen, warum eine Abfrage überhaupt über mehrere Tabellen benutzt wird. Sollen 1:n-bezogene Tabellendaten angezeigt werden, ist es ratsam(er) , HFo/UFo-Konstruktionen zu benutzen.
5) Ja, geeignete Ereignisse sind After_Update der jeweiligen Suchfelder. Sonderfall ist z. B. ein ungebundenes Kombifeld in einem Hauptform, das über die UFO-Steuerelementeigenschaften "Verknüpfen von/nach" ein Filterung der UFO-Daten bewirkt.
PS: ??
Vorschlag: Link 2 und 3 in meiner Signatur "durchforsten"
Hallo,
danke für Deine Antwort.
0) Das mit den Datentypen gibt mir zu denken. Die Lösung mit dem "*" ist von Minhorst, da bin ich davon ausgegangen, daß das in Ordnung ist.
1) Wie gesagt, die Beziehungen sind im BE vorhanden und zu besichtigen.
2) Sind ja jetzt weg.
3) Kann es sein, daß ein Datumsfeld in einer Abfrage zum Textfeld wird, wenn das Datum des ersten Datensatzes keinen Eintrag hat?
4a) Interessant. Wie schnell man doch ans Programmieren gerät, wenn man ein wenig mehr haben will, als der Standard hergibt.
4b) Die Beziehung zwischen den Daten ist nicht ganz trivial. Es ist eine Kombination aus 1:n und n:1 - Beziehungen.
5) Zusammen mit 4a wird ein Bild draus.
Jetzt muß ich die Infos erstmal verarbeiten und umsetzen. Über das Ergebnis werde ich informieren.
Der Tip mit den Links ist gut. Mein Problem ist, daß ich mich in solchen Quellen immer verliere.
Georg
Hallo,
jetzt bin ich ein gutes Stück weiter.
Das erste, was ich mir klarmachen mußte, und das hat eine Weile gedauert, war, daß ich die Logik meiner Abfrage komplett selbst abbilden muß und die Methoden von Access (z.B. Abfragen in den Eigenschaften von Formularen oder Steuerelementen fest hinterlegen) nicht nutzen kann, sondern mich davon lösen und alles programmieren muß.
Damit war ich aber noch lange nicht am Ziel. Ihr werdet das kennen: Du willst eine Lösung finden, die genau das tut, was Du willst und wenn tagsüber die Zeit nicht reicht, setzt Du Dich eben auch abends hin und findest Dich mitten in der Nacht konzentrationslos glotzend immer noch vor der gleichen Fehlermeldung wieder. Im Schlaf, wenn Du denn schlafen kannst, verfolgen Dich die Objekte und Ereignisse weiter und höhnisch blinkt Dich immer wieder die Meldung: Laufzeitfehler 2185 an. Nach dem Aufstehen - natürlich alles andere als ausgeschlafen - würdest Du Dich am liebsten sofort wieder hinhocken und ausprobieren, was Dir in der Nacht so an Ideen gekommen ist. Die sonstigen Verpflichtungen werden mißmutig erledigt, bis endlich wieder Zeit ist, weiterzumachen. Nur noch den einen kleinen Fehler ausmerzen, dann ist es endlich geschafft!
Denkste.
Zum Glück klappt es ja doch irgendwann und die Anwendung läuft tipptopp. Kein Anwender wird sie zum Absturz bringen können!
Hoffentlich.
Äh, ja. Jedenfalls habe ich jetzt ein Formular, in dessen Kopf drei Kombinationsfelder, zwei Optionsfelder und zwei Textfelder die schnelle Suche in einer Tabelle mit über 20.000 Einträgen ermöglichen. Nichts besonderes, möchte man meinen. Ein paar eigene Ideen habe ich aber realisiert:
Alle Kombinationsfelder erlauben, nicht nur einen einzelnen Eintrag auszuwählen, sondern es kann auch der Eintrag "alle" ausgewählt werden.
Zwei der Kombinationsfelder sind voneinander abhängig, bilden eine Liste von Listen ab.
Es muß immer mindestens ein Optionsfeld ausgewählt sein (=> ja/nein/alle).
Die Textfelder werden nach jedem eingegebenen Zeichen ausgewertet. Der Cursor wird immer ans Ende des Textes gesetzt, damit man gleich weitertippen kann.
Nach jeder Auswahl bzw. Eingabe werden alle Felder in einer Form_Update-Sub ausgewertet und ein WHERE-Abschnitt für eine SQL-Abfrage zusammengebaut, die dann ausgeführt wird. Das ist sehr schnell und man kann so mit wenigen Klicks die Auswahl der Datensätze, die im Detailbereich angezeigt werden, auf wenige bis einen einschränken.
Der Laufzeitfehler 2185 tritt übrigens auf, wenn in einem der Textfelder ein Suchstring eingegeben wird, der ein leeres Ergebnis der SQL-Abfrage zur Folge hat bzw. wenn das leere Ergebnis der Abfrage dem Formular als RecordSource zugewiesen wird. Um das abzufangen, erzeuge ich vorher mit ebendieser Abfrage ein Recordset und prüfe den RecordCount. Ist der 0, weise ich dem Textfeld das letzte Value als Inhalt zu.
Mit dem bisher Erreichten bin ich sehr zufrieden, auch wenn ich lange dafür gebraucht habe.
Dafür möchte ich mich bei Dir, DF6GL, bedanken. Ich mußte mir das zwar alles mühselig erarbeiten, aber das hat wahrscheinlich mehr gebracht, als wenn Du mir detailliertere Antworten gegeben hättest.
Georg