Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Datensatz mit Daten im Unterformular kopieren

Begonnen von gsaccess, Februar 25, 2023, 10:47:50

⏪ vorheriges - nächstes ⏩

gsaccess

Ich habe ein Hauptformular für die Kalkulation. In diesem Hauptformular ist das Unterformular für die Kalkulation des Materials.
Jetzt sollte ich die gesamte Kalkulation kopieren.
Hauptformular mit Daten im Unterformular.

Den Datensatz im Hauptformular kopiere ich mit folgendem vbacode:
Set dbs = CurrentDb
        Set rstKalk = dbs.OpenRecordset("t_auftrag_kalk")
       
    rstKalk.AddNew
        rstKalk!Kalknr = DMax("KalkNr", "t_auftrag_kalk") + 1
        rstKalk!auftragnr_kalk = Me.auftragnr_kalk
        rstKalk!kundennr_kalk = Me.kundennr_kalk
        rstKalk!kalkdatum = Date
        rstKalk!materialpreis_lager = Me.materialpreis_lager
        rstKalk!materialpreis_sonstige = Me.materialpreis_sonstige
        rstKalk!Verzinkungskosten = Me.Verzinkungskosten
        rstKalk!FK_janein = -1
        rstKalk!FKSatz = Me.FKSatz
        rstKalk!Fixkosten = Me.Fixkosten
        rstKalk!Multiplikator = 1
    rstKalk.Update

Die Daten im Unterformualar zu kopieren sollte nach meinen Recherchen im Internet mit einer Anfügeabfrage funktionieren.
Der SQL code für diese Anfügeabfrage:
INSERT INTO t_Kalkmaterial ( IDKalkmaterial, FSKalkNrMaterial, auftragnr_kalk_m, Artikelgruppe, Artikelnummer, Artikel, Dimension, VKEinheit, VKjeEinheit, MENGE, GesamtVK, Stueck, Laenge, Breite, kgProEinheit, verzinken, VerzBetrag )
SELECT t_Kalkmaterial.IDKalkmaterial, t_Kalkmaterial.FSKalkNrMaterial, t_Kalkmaterial.auftragnr_kalk_m, t_Kalkmaterial.Artikelgruppe, t_Kalkmaterial.Artikelnummer, t_Kalkmaterial.Artikel, t_Kalkmaterial.Dimension, t_Kalkmaterial.VKEinheit, t_Kalkmaterial.VKjeEinheit, t_Kalkmaterial.MENGE, t_Kalkmaterial.GesamtVK, t_Kalkmaterial.Stueck, t_Kalkmaterial.Laenge, t_Kalkmaterial.Breite, t_Kalkmaterial.kgProEinheit, t_Kalkmaterial.verzinken, t_Kalkmaterial.VerzBetrag
FROM t_auftrag_kalk INNER JOIN t_Kalkmaterial ON t_auftrag_kalk.Kalknr = t_Kalkmaterial.FSKalkNrMaterial
WHERE (((t_Kalkmaterial.auftragnr_kalk_m)=[Formulare]![f_Kalkulation]![auftragnr_kalk]));

Damit werden die Datensätze in die t_Kalkmaterial auch angefügt.
Nur sollte in den Fremdschlüssel FSKalkNrMaterial die neue Kalkulationsnummer des kopierten Datensatzes übernommen werden.
Ich schaffe es aber nicht in die Anfügeabfrage  bei FSKalkNrMaterial diesen Wert = Max von t_auftrag_kalk zu
übernehmen.
FSKalkNrMaterial: DomMax([kalknr];"t_auftrag_kalk") liefert auch nicht das gewünschte Ergebnis

Kann mir jemand sagen, wie die Anfügeabfrage geändert werden muss oder wie eine Schleife für das Anfügen der Datensätze aussehen könnte.

Vielen Dank im Voraus für jede Hilfe!

Günther



gsaccess

Ich versuche die Frage nochmals auf das Wesentliche zu reduzieren.
In einem Hauptformular mit Unterformular soll der gesamte Datensatz kopiert werden.
Im Hauptformular funktioniert das gut mit Recordset.
Im Unterformular (mehrere Zeilen) können die Datensätze mit einer Anfügeabfrage kopiert werden.
Problem: Wie kann ich in der Anfügeabfrage beim Feld FSKalkNrMaterial den Maximalwert aus der Tabelle FSKalkNrMaterial Feld KalkNr übernehmen?
Abfrageentwurf siehe Bild

MzKlMu

Hallo,
in dem Link von Eberhard steht alles drin was Du brauchst, sehr ausführlich.
Und für den Datensatz des Hafo auch eine Anfügeabfrage verwenden.
Gruß Klaus

gsaccess

Vielen Dank für eure Unterstützung.
Ich habe versucht mich durch den Code durchzukämpfen. Leider bin ich mit VBA nicht sehr versiert.
Bereits beim Versuch den Hinweis von Klaus auch die Daten des Hafo mit Anfügeabfrage umzusetzen scheitere ich.
Könnt ihr mir erklären was bei
Begintrans
       db.Execute strSQL, dbFailOnError
       
        lngArtIDNew = db.OpenRecordset("Select @@Identity")(0)
CommitTrans
passiert.

Fehler -Transaktion konnte nicht gestartet werden, bereits zu viele verschachtelte Transaktionen vorhanden

Mein Code:
BeginTrans
        '--- tab.Artikel t_auftrag_kalk
        strSQL = " INSERT INTO t_auftrag_kalk ( Kalknr, auftragnr_kalk, kundennr_kalk, kalkdatum, materialpreis_lager, materialpreis_sonstige, preis_leistung, Verzinkungskosten, FK_janein, FKSatz, Fixkosten,Multiplikator) " & _
                " SELECT Kalknr, auftragnr_kalk, kundennr_kalk, kalkdatum, materialpreis_lager, materialpreis_sonstige, preis_leistung, Verzinkungskosten, FK_janein, FKSatz, Fixkosten,Multiplikator " & _
                " FROM t_auftrag_kalk  WHERE kalknr = " & Me!txtKalkNr
       
        db.Execute strSQL, dbFailOnError
       
        lngArtIDNew = db.OpenRecordset("Select @@Identity")(0)
CommitTrans

Beaker s.a.

Hallo,
db.Execute strSQL, dbFailOnErrorKopiert den DS im HFo.
lngArtIDNew = db.OpenRecordset("Select @@Identity")(0)Speichert den zuletzt vergebenen PK.
Wenn "Kalknr" der PK ist (AutoWert?) muss der aus beiden Feldlisten
raus; - beim INSERT wird ja ein neuer vergeben, und das darf natürlich
nicht der letzte sein (der im SELECT).
Beim INSERT der DS aus dem UFo musst du dann im SELECT die Variable
"lngArtIDNew" einsetzen
... SELECT t_Kalkmaterial.IDKalkmaterial, " & lngArtIDNew & ", ...
gruss ekkehard

Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

gsaccess

Vielen Dank für deine ausführlichen Erklärungen. Super dass du dir immer wieder für solche Anfänger wie mich Zeit nimmst. Mich fasziniert Access, aber ich bin eben am Lernen.

Ich steh aber trotzdem noch auf dem Schlauch.
Leider kommt immer noch eine Fehlermeldung (siehe Bild).

In der Tabelle t_auftrag_kalk gibt es folgende Felder:
KalkID =AutoWert
KalkNr=Integer ohne Duplikate (es soll immer der Wert Max+1) eingetragen werden
Auftragnr_kalk = double Duplikate möglich...

In der Tabelle t_kalkmaterial:
IDKalkmaterial=Autowert
FSKalkNrMaterial=Integer mit Duplikaten
auftragnr_kalk_m=double mit Duplikaten ...

Mein Code:
        '--- tab.Artikel t_auftrag_kalk
        strSQL = " INSERT INTO t_auftrag_kalk ( Kalknr, auftragnr_kalk, kundennr_kalk, kalkdatum, materialpreis_lager, materialpreis_sonstige, preis_leistung, Verzinkungskosten, FK_janein, FKSatz, Fixkosten, Multiplikator) " & _
    " SELECT  max(kalknr)+1, auftragnr_kalk, kundennr_kalk, kalkdatum, materialpreis_lager, materialpreis_sonstige, preis_leistung, Verzinkungskosten, FK_janein, FKSatz, Fixkosten, Multiplikator " & _
                 " FROM t_auftrag_kalk   WHERE auftragnr_kalk = " & Me!auftragnr_kalk
       
        db.Execute strSQL, dbFailOnError
       
        lngArtIDNew = db.OpenRecordset("Select @@Identity")(0)
       
'        '--- tab_Artikel_Material t_Kalkmaterial
        strSQL = " INSERT INTO t_Kalkmaterial (  auftragnr_kalk_m, Artikelgruppe, Artikelnummer, Artikel, Dimension, VKEinheit, VKjeEinheit, MENGE, GesamtVK, Stueck, Laenge, Breite, kgProEinheit, verzinken, VerzBetrag  ) " & _
                 " SELECT " & lngArtIDNew & " As FSKalkNrMaterial, auftragnr_kalk_m, Artikelgruppe, Artikelnummer, Artikel, Dimension, VKEinheit, VKjeEinheit, MENGE, GesamtVK, Stueck, Laenge, Breite, kgProEinheit, verzinken, VerzBetrag  " & _
                 " FROM t_Kalkmaterial  Where auftragnr_kalk_m = " & Me!Me!auftragnr_kalk


        db.Execute strSQL, dbFailOnError

ich wäre dir sehr dankbar wenn du nochmals drüber schauen kannst.

Günther


ebs17

#7
Du hast hier zwei Probleme versammelt:

1) Du verwendest nicht den Primärschlüssel in den Tabellenverknüpfungen, sondern einen eigenen "beliebigen" Wert. Der Autowert erhöht sich selber und bedarf keiner Zusatzberechnung. Du hättest nicht das Folgeproblem.
Genau genommen bin ich erstaunt: In meiner Wahrnehmung benötigt man zur Erstellung einer Beziehung auf der einen Seite einen Primärschlüssel - was bei Dir nicht der Fall ist ...

2) SELECT  max(kalknr)+1, ...
Ein bisschen so aggregieren geht so nicht.
Zitat3. Schritt: Gruppieren und Aggregation, GROUP BY-Abschnitt
Hier sollte am Rande bekannt sein, dass alle Felder im SELECT-Teil entweder im GROUP BY-Abschnitt enthalten sein müssen oder zu aggregieren sind (Bildung von Summen, Anzahlen, Durchschnitten, Maxima, Minima) oder einfach einen konstanten Inhalt aufweisen. Berechnete Ausdrücke aus solchen Feldern sind auch möglich.
Aus: Grundlagen - SQL ist leicht (11) - Reihenfolge der Abfrageabarbeitung
In diesem Sinne müsstest Du also die gesamte Abfrage aufarbeiten, oder aber die kleine Berechnung durch eine komplette Unterabfrage ersetzen.

"...
SELECT 
   (SELECT max(kalknr) FROM t_auftrag_kalk WHERE auftragnr_kalk = " & Me!auftragnr_kalk & ") + 1,
   auftragnr_kalk,
   ...
"
(Die Zeilentrennung, die hier per VBA nötig wäre, habe ich aus Übersichtsgründen unterschlagen.)

Aber siehe 1): Ich würde davon abraten, eigene "kreative Wege" zu gehen und so Herausforderungen zu suchen, die andere nicht kennen. Die resultierende Einsamkeit müsstest Du durch eigene Fähigkeiten ausgleichen und diesen Kraftakt durchstehen => Probleme erzeugen oft Nachfolgeprobleme.
Mit freundlichem Glück Auf!

Eberhard

Beaker s.a.

Hallo,
Wie Eberhard bereits schrieb, sind die Beziehungen über die PK
herzustellen.
Lade die DB mit wenigen Beispieldatensätzen hier hoch, dann schau
ich mir das an und mache einen Vorschlag.

gruss ekkehard
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

Josef P.

Hallo!

ZitatGenau genommen bin ich erstaunt: In meiner Wahrnehmung benötigt man zur Erstellung einer Beziehung auf der einen Seite einen Primärschlüssel - was bei Dir nicht der Fall ist ...
Es muss nicht unbedingt der PK sein, ein eindeutiger Index ist auch erlaubt.

LG
Josef

Beaker s.a.

Hallo Josef,
Das ist wohl richtig, aber für eine Beziehung würde ich so ein
Feld trotzdem nicht verwenden.

gruss ekkehard
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

Josef P.

@ekkehard:
kommt immer auf das Vorhaben an. Ich nutze z. B. schon hin und wieder bewusst einen Mehr-Felder-PK und gebe dann aber für 1:n-Detailtabellen nur einen Autowert als FK-Wert weiter.

Im Datenmodell von #6 fällt mir auf, dass ein Kalk-Datensatz datentechnisch Kunde A und einen Auftrag von Kunde B enthalten könnte. .. Vielleicht braucht man die Kunden-Beziehung gar nicht in der Tabelle.
Sieht ein wenig nach einer Excel-Tabelle mit Ausfüllhilfen aus. ;)

Gruß
Josef

gsaccess

Vielen Dank für deine ausführlichen Erläuterungen. Ein großes Lob und vielen Dank, dass du immer so schnell und ausführlich antwortest. Auch allen anderen die sich einbringen vielen Dank. Ich stelle mir vor, dass du über meine Anfängerfehler oft nur lachen kannst. Aber ich muss mich erst so langsam in Access und speziell in VBA und SQL einlesen. Danke für den Link zu Grundlagen SQL.
Dass bei einer 1:n Verknüpfung immer der Primärschlüssel auf der einen Seite stehen muss war mir nicht klar. Wie aber Josef schreibt ist auch ein anderer eindeutiger Schlüssel (Long Integer indiziert ohne Duplikate möglich)!?
Ich werde aber meiner Datenbank diesbezüglich durchforsten. Das wird aber eine größere Baustelle. ::)
Auf den Vorschlag die Datenbank mit wenigen Datensätzen hochzuladen komme ich gerne noch zurück.

Nochmals vielen Dank

:D  :)

Günther

Beaker s.a.

Hallo,
@Josef
Du bist ja auch in anderen Sphären unterwegs. Ich bevorzuge einen AutoWert als PK
um den ich mich nicht kümmern muss. "Schöne" Nummern (flfd. oder mit Buchstaben
oder Sonderzeichen) kann ich zur Anzeige oder Suche trotzdem verwenden.

@Günther
Unabhängig davon stimmen die Beziehungen aber auch noch nicht alle.

gruss ekkehard
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

Josef P.

Hallo!

@Günther:
Es gibt ein gutes Skript von Michael Zimmermann zum Thema "Normalisierung für Access-Entwickler" von der AEK7 auf den Download-Seiten der AEK unter http://www.donkarl.com/

Gruß
Josef