Neuigkeiten:

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

Mobiles Hauptmenü

Neueste Beiträge

#1
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Bitsqueezer - Heute um 23:28:44
Hallo,

wenn alle Tabellen auf SQL Server liegen, könntest Du zum Beispiel auch eine Stored Procedure schreiben, die die INSERT...SELECT komplett auf dem Server erledigen, u.a. ginge hier auch die Übergabe von Parametern.

@@IDENTITY ist eine Systemvariable von SQL Server, die die letzte PK-AutoID in der aktuellen Sitzung zurückgibt. Das funktioniert auch mit VBA, wenn man sie per SELECT ausliest, allerdings nicht mit DAO und auch nicht mit Pass-Through-Query, weil das eine neue Verbindung/Sitzung erzeugen würde. Wenn Du ein ADO-Recordset verwendest zum Einfügen, kannst Du aber ohne weiteres (vor dem Schließen der Verbindung) die @@IDENTITY-Variable mit einem SELECT auslesen.

@@IDENTITY funktioniert übrigens auch ohne SQL Server in Access mit ADO Recordsets (mit DAO habe ich es nicht probiert). (Besser in SQL Server "SCOPE_IDENTITY()" verwenden.)

Besser ist allerdings, eine SP zu verwenden. Das Problem bei INSERT..SELECT ist, daß Dir die letzte ID nicht hilft, denn hier mußt Du ja alle IDs wissen, die neu hinzugekommen sind, und diese als FK im passenden Datensatz einbauen.

Dazu gibt es in T-SQL (nicht in Access SQL) die OUTPUT TO Klausel, die man in den INSERT..SELECT einfügen kann. Man erstellt vorher z.B. eine Temp-Tabelle mit passenden Feldern und OUTPUT TO schreibt die Daten, die mit INSERT eingefügt wurden, in die Temp-Tabelle. Das geht aber nur mit den Feldern, die Bestandteil von INSERT sind (und der ID). Am Ende kannst Du die ID und andere Felder aus der Temp-Tabelle ermitteln und darauf basierend Fremdschlüssel in andere Tabellen schreiben per UPDATE oder passende neue Datensätze generieren.

Es gibt viele Varianten, Daten in Tabellen zu importieren, SQL Server hat auch noch mehr Varianten, z.B. könntest Du eine lokale Tabelle als XML als Parameter einer SP übergeben( VBA kann das einfach umwandeln). Oder Du könntest den ganz dicken Hammer auspacken und Integration Services verwenden, wo Du genau konfigurieren kannst, welche Datei wie gelesen und importiert werden soll, das ginge auch automatisiert zu bestimmten Tageszeiten... usw.

Da man aus dem Konstrukt hier nicht so richtig schlau wird, kann man das auch nur so allgemein beantworten.

Gruß

Christian
#2
Tabelle/Abfrage / Re: Standartwert für Tabellenf...
Letzter Beitrag von Beaker s.a. - Heute um 16:37:23
Hallo,

Ich kann Klaus nur weiterhin zustimmen.

Das Beispiel schreit förmlich nach
1. weiteren Tabellen und
2. passenden Beziehungen.

Aufzählungsfelder gehen gar nicht, da bekommst du u.U. leere
Felder oder die Anzahl reicht nicht mehr. Dazu ist schon mal
eine Tabelle Disziplinen nötig, und dazu wieder eine n:m-Tabelle,
um den TN ihre Disziplin(en) zu zuordnen (1 bis viele).

Nun gibt es auch noch Mannschaften. Gleiches Prinzip,
Tabelle Mannschaften, n:m TNInMannschaft.

gruss ekkehard

P.S.: Du solltest dir wirklich die Zeit nehmen und dich mit
den Links beschäftigen, die Ulrich gepostet hat.
Vielleicht noch dies: Die Entwicklung einer Db beginnt mit
"Bleistift und Papier". Da schreibst du zuerst mal auf, was
die Db überhaupt leisten soll. Daraus leitest du die benötigten
Tabellen und ihre Eigenschaften (Felder) ab. Beispiel, - die
Eigenschaften eines TN sind im Prinzip nur die persönlichen
Daten. Eine Disziplin ist KEINE einzelne Eigenschaft eines
Teilnehmers, sondern eine Eigenschaft seiner Teilnahme an
einer Ms. Falls es Mehrkampf-Ms gibt muss das auch im DM abgebildet
werden.
#3
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Knobbi38 - Heute um 15:24:35
Das hat ja jetzt nicht direkt etwas mit einem SQL-Server zu tun, sollte dort aber auch laufen. Alternativ gibt es auch noch @@Indentity und deren verwandte Funktionen.

#4
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Doming - Heute um 13:48:26
Hm gut...

...aber da ist ja immer noch die Geschichte mit dem SQL-Server (ich warte noch auf Genehmigung), wie bekomme ich mit SQL-Mitteln die ID heraus?

Gruß
 Doming
#5
Tabelle/Abfrage / Re: Standartwert für Tabellenf...
Letzter Beitrag von MzKlMu - Heute um 10:50:58
Hallo,
nein, das ist immer noch unverständlich. Die beiden Tabellen benötigen zwingend einen Zusammenhang. In welchen Feld der Teilnehmertabelle willst Du die Informationen aus der Meisterschaftstabelle speichern ?
Die Tabelle Meisterschaft hat auch einen etwas eigenartigen Namen für das was in den beiden Feldern steht.
Und mit einem Standardwert hat das auch nichts zu tun.

PS:
ZitatDie DB soll durch mehrere Personen bearbeitet werden,
Da unterschätzt Du den Aufwand der dazu notwendig ist. Die Datenbank muss in diesem Fall auf Backend (nur die Tabellen) und Frontend (der Rest) aufgeteilt werden. Jeder User benötigt dann auch Access auf seinem PC. Mindestens als Runtimeversion (die es kostenlos gibt).
#6
Tabelle/Abfrage / Re: Standartwert für Tabellenf...
Letzter Beitrag von repaan - Heute um 10:34:37
Hallo zusammen,
die beiden Datenfelder "Ort" und "Bezirk" benötige ich für Erstellung von Urkunden. Da auf jeder Urkunde der gleiche Ort und Bezirk vorhanden ist. Ich habe es auch schon mit einem Standartwert versucht. So bin ich eigentlich auf diese Idee gekommen, mit dem Startformular den Ort und den Bezirk für alle Datensätze, die noch hinzukommen festzulegen, um dann die Datenfelder aus der tbl_Meisterschaft einer Abfrage hinzuzufügen. Die DB soll durch mehrere Personen bearbeitet werden, somit kann jeder Bezirk in der gleichen DB seine Teilnehmer erfassen und auswerten.
Ich hoffe ich habe mich verständlich ausgedrückt.
Vielen Dank für eure Antworten und die Muster-DB

Gruß Repaan
#7
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Knobbi38 - Heute um 10:32:34
Wieso sollte das nicht funktionieren?

Probiere das mal mit diesem Zwischenschritt:
rs.Update
rs.Bookmark = rs.LastModified ' Aktualisiert den Zeiger auf den neuen Datensatz
ID = rs!Artikel_ID

Knobbi38
#8
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Doming - Heute um 09:15:32
Hallo,

mir ist klar, das DLookup kein Brandbeschleuniger ist, aber eigentlich läuft der Import der ganzen Geschichte einmal in der Woche. In der Zeit kommen etwa 0-30 neue Datensätze dazu. Häufig sind es neue Versionen von überarbeitetem Material, es ist in der Materialtabelle also schon vorhanden. Es sind also nicht so oft Aufrufe von "NeuMaterial".
Gerne würde ich es ja so verwenden:
rs.AddNew
rs!Materialnummer = MatNr
rs!Bezeichnung = MName
rs.Update
ID = rs!Artikel_ID
Aber wenn das sicher funktionieren würde, gäbe es die vielen Diskussionen, wie man an die ID des gerade eingefügten DS kommt, vermutlich nicht.

Gruß
Doming
#9
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Knobbi38 - Heute um 08:46:30
Hallo Doming,

irgendwie sieht das für mich nicht gerade optimal aus. Massenverarbeitung in Datenbanken wird normalerweise in SQL ausgeführt, nicht in VBA und schon gar nicht mit einem Dictionary.

Ich habe auch mal die KI dazu befragt und bekam folgende Antwort:
ZitatDein aktueller Workflow leidet unter dem sogenannten RBAR-Syndrom (Row-By-Agonizing-Row – Zeile für schmerzhafte Zeile). Du öffnest für jeden fehlenden Datensatz Recordsets, feuerst langsame DLookup-Domänenfunktionen ab und führst nachträglich UPDATE-Befehle aus.In einem relationalen Datenbanksystem wie Access löst man so etwas performant über mengenbasierte SQL-Abfragen. Wir können die komplette Logik aus Schleifen, Dictionaries und VBA-Funktionen in nur drei SQL-Befehle gießen.
Vielleicht solltest du mal deine KI nochmal befragen und in die richtige Richtung "stubsen", von alleine bekommt man nämlich keine optimalen Ergebnisse.

Hier mal der Vorschlag von der KI:
Public Sub Zeich2Mat_Mengenbasiert()
    On Error GoTo Fehler
    Dim cDB As DAO.Database
    Set cDB = CurrentDb
   
    ' Ganzen Prozess in eine einzige Transaktion packen (alles oder nichts)
    DBEngine.BeginTrans
   
    ' 1. Fehlende Materialien massenhaft anlegen
    cDB.Execute "INSERT INTO tbl_Material (Materialnummer, Bezeichnung) " & _
                "SELECT DISTINCT Z.MatNR, 'AutoEingabe_' & Z.Dateiname " & _
                "FROM tbl_Zeichnung_LCL AS Z LEFT JOIN tbl_Material AS M ON Z.MatNR = M.Materialnummer " & _
                "WHERE Z.MatNR Is Not Null AND Z.MatNR <> '0' AND M.Materialnummer Is Null;", dbFailOnError
               
    ' 2. RefID für die neuen Datensätze nachziehen
    cDB.Execute "UPDATE tbl_Material SET RefID = Artikel_ID WHERE RefID Is Null OR RefID = 0;", dbFailOnError
   
    ' 3. Initialen Index (0) für neue Materialien anlegen
    cDB.Execute "INSERT INTO tbl_Index (FS_Mat, IX) " & _
                "SELECT M.Artikel_ID, 0 " & _
                "FROM tbl_Material AS M LEFT JOIN tbl_Index AS I ON M.Artikel_ID = I.FS_Mat " & _
                "WHERE I.FS_Mat Is Null;", dbFailOnError
               
    ' 4. Die Fremdschlüssel in der Zeichnungstabelle aktualisieren
    cDB.Execute "UPDATE tbl_Zeichnung_LCL AS Z INNER JOIN tbl_Material AS M ON Z.MatNR = M.Materialnummer " & _
                "SET Z.FS_MatID = M.Artikel_ID " & _
                "WHERE Z.MatNR Is Not Null AND Z.MatNR <> '0';", dbFailOnError
               
    ' Wenn alles glatt lief: Speichern
    DBEngine.CommitTrans
    Debug.Print Now, "Workflow erfolgreich und mengenbasiert abgeschlossen!"
    Exit Sub

Fehler:
    DBEngine.Rollback
    MsgBox "Fehler " & Err.Number & " im SQL-Workflow: " & Err.Description, vbCritical, "Datenbankfehler"
End Sub

und bitte: die Angaben sind natürlich ungeprüft mangels fehlender Demodaten. Auch hat sich die KI wohl verzählt, denn das Endergebnis hat dann

ZitatWarum diese SQL-Lösung massiv besser ist:Kein Speicherüberlauf mehr:
- Da Access die Abfragen intern im Abfrage-Optimierer verarbeitet, entfällt das manuelle "Chuncking" (Aufteilen in 1000er-Schritte).
- Keine fehleranfälligen Lookups: Das gefährliche DLookup, das bei großen Tabellen die Performance komplett killt, ist restlos eliminiert.
- Echte atomare Transaktion: Tritt an irgendeiner Stelle ein Fehler auf, wird die gesamte Kette (Schritt 1 bis 4) sauber zurückgerollt. Es entstehen niemals "halbe" Datenleichen.

Wenn man jetzt noch die passenden Indizes einsetzt, sollte das eigentlich schön sauber und performant durchlaufen.

Knobbi38
#10
Access Programmierung / Re: blockiert ein Dictionary e...
Letzter Beitrag von Doming - Heute um 06:30:01
Zitat von: PhilS am August 03, 2026, 15:33:05Denke.mal darüber nach was DBEngine.BeginTrans eigentlich bewirkt. ;)

Moin Phil,

vielen Dank für den Hinweis.

            If MatDikt.Exists(MNr) Then
                rs!FS_MatID = MatDikt(MNr)
            Else
                DBEngine.CommitTrans
                MatID = NeuMaterial(MNr, rs!Dateiname)
                MatDikt.Add MNr, MatID
                DBEngine.BeginTrans
                DBEngine.Idle dbRefreshCache
            End If
Damit läuft der Code wie gewünscht durch.
Es ist das erste Mal, dass ich mit Dictionarys gearbeitet habe und ich war über die Geschwindigkeit begeistert.
Das kommt davon, wenn man den Code von der KI einfach mal so übernimmt..