2016-06-22 4 views
1

Ich bin neu in Access, aber habe langjährige Erfahrung mit "Enterprise" -Datenbanken. Ich habe Probleme bei der Umsetzung einer einfachen Aufgabe und vermute, dass meine Vorurteile dazu führen, dass ich den Punkt verpasse, deshalb bitte ich um Hilfe.Access Forms - Catch 22 versucht, Daten in mehrere verwandte Tabellen einzufügen

Die einfache Aufgabe verwendet Access-Formulare für die Dateneingabe, die zwei Tabellen füllt: Customer und CustomerAddress (kann mehrere Adressen pro Kunde sein).

Die Kundentabelle hat den Primärschlüssel CustomerID. Die CustomerAddress-Tabelle hat den Primärschlüssel CustomerAddressID und CustomerID als Fremdschlüssel mit RI für diese Beziehung.

Form1 ist an die Customer-Tabelle gebunden. Nach der Eingabe von Informationen für verschiedene Felder kann der Benutzer auf eine Schaltfläche klicken, um Form2 anzuzeigen, die an CustomerAddress gebunden ist und die Dateneingabe für mehrere Adressen ermöglicht.

Form1 übergibt die CustomerID (von Access zugewiesen) an Form2. Form2 ist kein Unterformular aufgrund der Größe, aber es könnte sein, wenn das das Problem lösen würde.

In einer perfekten Welt möchte ich, dass alle neuen Daten von Form1 und Form2 zusammen festgelegt werden. Vermutlich könnte ich dies mit ungebundenen Formularen tun und die Einfügeanweisungen innerhalb einer einzigen Transaktion codieren.

Frage 1: Gibt es eine Möglichkeit, dies mit gebundenen Formen zu tun?

Wenn ich Form1 verwende, ohne jemals auf die Schaltfläche "Adresse" zu klicken, wird eine Zeile erfolgreich zur Tabelle Customer hinzugefügt. Das Problem tritt auf, wenn versucht wird, CustomerAddress-Zeile (n) in Form2 hinzuzufügen, bevor die Customer-Zeile der Tabelle hinzugefügt wurde.

Wenn in Form2 die CustomerID nicht verwendet wird, liegt ein Einfügefehler vor, da eine CustomerAddress-Zeile ohne eine CustomerID nicht hinzugefügt werden kann. Wenn die CustomerID verwendet wird, liegt ein Einfügefehler vor, da die CustomerID noch nicht in der Kundentabelle vorhanden ist (obwohl die ID anscheinend "reserviert" ist).

Es ist nicht praktikabel, die Customer-Zeile vor dem Öffnen von Form2 zu erzwingen, da an diesem Punkt im Workflow einige Felder für den Kunden nicht vorhanden sind.

Frage 2: Gibt es einen Weg um dies? Es scheint eine allgemeine Anforderung zu sein.

Ich könnte dies umgehen, indem Sie die RI entfernen, so dass die CustomerAddress-Zeilen zuerst hinzugefügt werden können, aber dies scheint schlechte DB-Design und ich würde auch Bereinigungslogik für den Fall, dass der Kunde hinzufügen wird später abgebrochen.

Wie bereits erwähnt, vermisse ich wahrscheinlich den Punkt und es gibt einen besseren Ansatz. Jede Hilfe wird sehr geschätzt.

Antwort

2

Ich denke, dass Sie das gleiche Problem haben würden, unabhängig davon, welches RDBMS Sie verwendet haben, wenn Sie referenzielle Integrität erzwingen. Die CustomerID muss in der Kundentabelle vorhanden sein, bevor ein Datensatz in der CustomerAddress-Tabelle vorhanden sein kann. Ich vermute, dass CustomerID eine automatische Nummer ist. Was wahrscheinlich verwirrend ist, ist, dass Access sofort eine automatische Nummer "reserviert", sobald ein neuer Datensatz gestartet wird. Es ist jedoch nicht in der Customer-Tabelle vorhanden. Wenn dieser Datensatz niemals gespeichert wird, geht dieser Wert automatisch verloren und der nächste Datensatz erhält die nächste Nummer. Das Anfordern einer Adresse, die vor dem Speichern des Kundendatensatzes abgeschlossen werden muss, klingt wie ein Entwurfsproblem. Es scheint nicht logisch. Persönlich würde ich das Design überdenken. Das heißt, eine Lösung wäre, eine temporäre Tabelle für Adressen zu erstellen und das Formular CustomerAddress an dieses zu binden.Wenn der Kundendatensatz gespeichert wird, führen Sie eine Append-Abfrage aus, um die neuen Adressen der CustomerAddress-Tabelle hinzuzufügen. Denken Sie jedoch daran, dass, wenn ein Benutzer einige Adressen eingibt und der Kundendatensatz nie gespeichert wird, der gesamte Dateneintrag verloren geht.

+0

Vielen Dank für die Beantwortung. Der Grund, warum ich die Frage gestellt habe, ist, dass andere RDBMS, die ich verwendet habe, eine Lösung für dieses Problem haben. d. h. Zeilen zu verschiedenen Tabellen innerhalb einer einzelnen Transaktion hinzufügen. Das DBMS gibt den automatisch generierten Schlüssel zurück, wenn jeder Datensatz eingefügt wird. Die Änderung wird jedoch erst dauerhaft, wenn sie festgeschrieben wird. Sie Vorschlag re Temp Tabellen ist hilfreich - danke. Ich bin nicht ganz damit einverstanden, dass es hier ein Designproblem gibt - das Hinzufügen von Zeilen zu mehreren Tabellen in der gleichen Transaktion ist in einer normalisierten Datenbank sehr üblich. Es zeigt jedoch, dass ich meine Vorgehensweise bei der Verwendung von Access ändern muss. Danke noch einmal. – Grayman

+0

Sie können innerhalb einer Transaktion in Access in zwei Tabellen einfügen. Innerhalb dieser Transaktion muss der übergeordnete Datensatz immer noch vor dem Detaileintrag eingefügt werden. Dies ist jedoch nicht Ihr Fall. Sie versuchen, es mit zwei getrennten nicht gebundenen gebundenen Formen zu tun. Es ist keine einzelne Transaktion beteiligt. Sie müssten das über Code tun. – AVG

0

Ich denke, die Antwort in Ihrer Frage liegt 1. Ja, es gibt eine Möglichkeit, dies mit gebundenen Formen zu tun, und wäre der Ansatz, den ich verwenden würde.

Form1 ist an die Customer-Tabelle gebunden. Fügen Sie Form 2 als Teilformular auf Form 1 hinzu. Markieren/markieren Sie Formular 2, gehen Sie zum Eigenschaftenblatt. Legen Sie auf der Registerkarte Daten das Link-Masterfeld auf CustomerID fest, und verknüpfen Sie untergeordnete Felder mit CustomerID.

Dann nach jeder auf Formular getroffenen Maßnahmen 1, requery Formular 2.

Ich denke, das wird man es am wenigsten beginnen und sollte Ihnen eine Idee geben, wie einmal abgeschlossen, um fortzufahren.

0

Ich verstehe nicht, warum beide sein muss oder man würde sogar beide Kunden und einen Datensatz aus der untergeordneten Tabelle zur gleichen Zeit einreichen möchten.

Was ist, wenn Sie eine zusätzliche Adresse hinzufügen möchten, dann müssen Adresse Schaltfläche hinzufügen und Code jetzt überprüfen + testen, wenn der Hauptkunde bereits existiert, und separate Logik verwenden, wenn der Kundendatensatz existiert, oder tut nicht. Und was ist, wenn ein Benutzer den Kundennamen und die Information eingegeben hat und noch nicht die Adresse hat, da der Kunde auf dem Telefon gerade umgezogen ist und mit der neuen Adresse zurückrufen muss. Ich kann mir ein weiteres halbes Dutzend Fälle vorstellen, in denen ein Entwurf erstellt wird, bei dem sowohl Kunden- als auch Kundenadresssätze gleichzeitig hinzugefügt werden müssen.

Wie andere bereits erwähnt, gehen Sie dieses Problem mit einer beliebigen relationalen Datenbank, einschließlich Access. Ich sollte auch darauf hinweisen, dass Access genau das gleiche hier funktioniert, wenn Sie Access als Front-End für SQL-Server oder Oracle verwenden.

Es macht also wenig Sinn, einen anderen UI- und Coding-Prozess zum Hinzufügen des Kunden und der Adresse zu erstellen, und dann einen VERSCHIEDENEN Satz von Regeln und UI zum Hinzufügen zusätzlicher Adressen im Laufe der Zeit. Erstellen Sie also ein Formular, um einen Kunden zu suchen, einen Kunden hinzuzufügen und diesen Kunden hinzuzufügen und diesen Kunden anzuzeigen. Sobald dieser Prozess abgeschlossen ist, fügen Sie den Prozess (und den UI-Teil) hinzu, damit der Benutzer die Adresse für diesen Kunden anzeigen oder hinzufügen kann. Ich glaube nicht, dass ich jemals eine Benutzeroberfläche mit separaten Formularen zum Hinzufügen/Bearbeiten von Kunden und einem separaten Formular gesehen habe, um zu ermöglichen, dass zusätzliche Adressen eine Anforderung haben, dass sie gleichzeitig zusammen eingereicht werden.

Wenn die Benutzer kautionen der Adresse, weil sie erkennen, die Adresse nicht vorhanden, falsch usw. ist dies vorschlagen soll nicht, dass die Kundendaten so weit geworfen werden eingegeben und nicht hinzugefügt. Wenn der Benutzer nach dem Bailing die Adresse hinzufügt (sagen Sie schließen oder das Formular abbrechen), dann kehren Sie zum Kundenformular zurück. Wenn der Benutzer zu diesem Zeitpunkt aus irgendeinem seltsamen Grund entscheidet, dass er den Kunden NICHT mehr im System haben möchte, dann geben Sie eine Lösch-Schaltfläche an.

Wenn die Geschäftsregeln so lauten, dass IMMER mindestens eine Adresse in allen Fällen vorhanden sein muss, erlauben Sie beim Schließen des Kundenformulars nicht, dass das Formular geschlossen wird und bitten diesen Benutzer, mindestens eine Adresse einzugeben Benutzer. Und vielleicht sind sie gestoßen oder haben die falsche Taste gedrückt, um das Adresseingabe-Teil zu verlassen - keine Notwendigkeit, diesen Benutzer zu bestrafen und sie dazu zu zwingen, die Kundendaten erneut einzugeben. Lassen Sie sie also das Kundenformular nicht verlassen, bis sie eine Adresse eingeben oder sie dem Benutzer zur Verfügung stellen, damit sie den Kunden löschen/entfernen können, wenn sie ihn verlassen möchten.

Wenn Sie ein Formular + Subform Setup verwenden, dann wird Null-Code für den relationalen Teil erforderlich. Und ein Tab-Steuerelement bekommt Sie beide Formen können in der Nähe der vollen Bildschirmgröße sein. (Sie müssen kein separates Formular starten).

Natürlich könnten Sie eine Menge Code schreiben und alles in einer Transaktion platzieren, aber das ist eine Verschwendung von Programmierzeit für keine Vorteile und beläuft sich auf Diebstahl von Firmenstunden und Zeit, wenn nicht erforderlich.

1

Im Hinblick auf Ihre Aussage:

Es ist nicht sinnvoll, die Kunden Reihe zu zwingen, vor dem Öffnen Form2, da einige Kunden erforderlichen Felder hinzugefügt werden sollen an dieser Stelle im Workflow nicht vorhanden.

Sie sind richtig, dass Sie die Kunden Zeile einzufügen, wenn die „erforderlich, aber noch nicht bekannt“ Felder haben ihre Required Eigenschaft auf Yes (das heißt, NOT NULL) nicht in der Lage sein. Mit Access   2010 und höher können Sie jedoch ein ereignisgesteuertes Datenmakro verwenden, um solche Felder beim Einfügen als "nicht erforderlich" zu setzen, aber beim Aktualisieren als "erforderlich". In Ihrem Fall könnten Sie

  • ermöglichen es dem Kunden aufnehmen, ohne die „evtl.“ Felder eingefügt werden,
  • erlauben die Zugabe von Customer Aufzeichnungen (mit RI aktiviert ist), und dann
  • wieder öffnen der Kundendatensatz für die Aktualisierung, wobei das Datenmakro nun den Status "erforderlich" der anderen Felder erzwingt.

Die Bevor Daten ändern Makro könnte wie folgt aussehen:

BeforeChange.png

+0

Danke - Ich werde diesen Ansatz berücksichtigen und ich habe ein paar Dinge aus Ihren Beispielmakros gelernt. Im Moment ist der Gedanke, einer Tabelle ohne Pflichtfelder eine Zeile hinzuzufügen, für mich zu weit. Ich bin immer noch mit einigen der Kompromisse vertraut, die für die Verwendung von Access erforderlich sind. – Grayman

+0

Ich bin nicht sicher, was andere DBMS (s) Sie denken, aber zumindest mit SQL Server können Sie immer noch eine Zeile einfügen - auch innerhalb einer TRANSACTION -, die NOT NULL Spalten (T-SQL-Beispiel [hier ] (http://pastebin.com/KfWCTQFe)). Wenn Sie die übergeordnete Zeile nicht einfügen können, können Sie SELECT @ IDENTITY nicht auswählen, sodass Sie die untergeordneten Zeilen nicht einfügen können. Daher beschäftigen Sie sich immer noch mit Problemen, die für Access-Datenbanken in keiner Weise spezifisch sind. –

Verwandte Themen