In der letzten Spalte „SortNr“ soll jetzt ein Wert hochgezählt werden, solange die Einträge für die Gruppierung gleich bleiben und unter Berücksichtigung der Sortierung.
Solange also in den ersten drei Spalten „Deutschland“, „Düsseldorf“ und „Hansa-Allee“ steht, soll hochgezählt werden, der Schmidt-Anton vor dem Schmidt-Egon.
Danach wieder bei „0“ anfangen, usw.
Zu schade, dass man keine Dateien hochladen kann. Ich habe nämlich eine Beispiel-Datei vorbereitet…
Land Stadt Strasse Nachname Vorname SortNr
D Köln Oststr. Schmidt Dieter 1
D Köln Oststr. Schmidt Johannes 2
D Köln Oststr. Schmidt Peter 3
D Köln Südring Schüssler Dieter 1
D Köln Südring Schüssler Günther 2
D Bern Bachstr. Müller Anton 1
D Bern Seestr. Meier Egon 2
D Bern Seestr. Kopp Petra 1
FR Paris Rue Pierro Jaques 1
FR Paris Ave Kaas Pat 1
das ist ja bis hierher wunderbar. Der Code macht genau das, was ich wollte. Danke dafür.
Jetzt habe ich noch zwei Fragen:
Wenn ich sehr viele Daten nehme (1.600.000 Datensätze), bekomme ich relativ schnell (bei Datensatz 9.494) eine Fehlermeldung, die da lautet:
„Anzahl der Dateisperrungen überschritten. (Fehler 3052)“
Wenn ich dann debugge zeigt der gelbe Marker auf den Code-Eintrag „rs.Edit“.
Was könnte das sein?
Wäre es auch möglich, die Sortierung nicht über eine Abfrage zu machen, sondern ebenfalls in den Code einzubauen?
Denken Sie es wäre grundsätzlich möglich, die ganze Sache in einen SQL-String einzubauen? Andere schlaue Leute schrieben etwas von einer Count-Anweisung…?
Danke für eine Antwort und ein schönes Wochenende noch!
mit sovielen Datensätzen habe ich nicht gerechnet. Der Grund dafür ist: die geänderten Datensätze werden immer zurückbehalten um die Aenderungen wieder rückgängig machen zu können. Nach ca 9000 Aenderungen ist Schluss damit, darum erledige ich das jetzt alle 1000 Datensätze im Programm. Diese Datenmenge könnte bei der Auswertung (Zeit-)Probleme schaffen, um diese zu beheben müsste ich allerdings mehr über den Gebrauch nachher wissen (müssen die Daten noch bearbeitet werden, ist das einlesen einmalig usw.) Es könnte auch sein, dass das Aendern immer langsamer wird. Ich habe drum einen Timer eingebaut, der alle 100000 die verwendete Zeit auflistet. SQL ist natürlich auch möglich, bietet aber keine Vorteile, das Resultat ist ja eh nur mit der Abfrage ersichtlich. Der Count Befehl funktioniert m.E. nicht weil drei Kriterien abgefragt werden müssen
Public Sub Numerieren()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim lgZähler, lgCommit As Long
Dim strLand, strStadt, strStrasse As String
Dim datAnf, datEnd, datCalc As Date
lgZähler = 0
lgCommit = 0
Set db = CurrentDb
'Set rs = db.OpenRecordset(„qrySortNr“)
Set rs = db.OpenRecordset(„SELECT Adressen.Land, Adressen.Stadt, Adressen.Strasse, Adressen.Nachname, Adressen.Vorname, Adressen.SortNr FROM Adressen ORDER BY [Adressen].[Land], [Adressen.Stadt], [Adressen.Strasse], [Adressen.Nachname], [Adressen.Vorname]“)
rs.MoveFirst
strLand = rs!land
strStadt = rs!stadt
strStrasse = rs!strasse
datAnf = Now
Do While Not rs.EOF
If strLand = rs!land _
And strStadt = rs!stadt _
And strStrasse = rs!strasse _
Then GoTo zählen
’ Gruppenbruch festgestellt
lgZähler = 0
strLand = rs!land
strStadt = rs!stadt
strStrasse = rs!strasse
lgZähler = 0
’ kein Gruppenbruch
zählen:
lgZähler = lgZähler + 1
rs.Edit
rs!SortNr = lgZähler
rs.Update
lgCommit = lgCommit + 1
’ immer nach 1000 Datensätze deren Lock wieder aufheben
If (lgCommit Mod 10) = 0 Then
DBEngine.BeginTrans: DBEngine.CommitTrans
End If
’ gegebenenfals wieder löschen
'--------------------
If (lgCommit Mod 100000) = 0 Then
datEnd = Now
datCalc = datEnd - datAnf
MsgBox lgCommit & " Datensätze in " & datCalc & " Sekunden", vbOKOnly
End If
'--------------------
rs.MoveNext
Loop
Set rs = Nothing
Set db = Nothing
End Sub
um sicher zu stellen, dass ich mir über das Richtige Gedanken mache:
Du brauchst eine Abfrage in welchem die Spalte SortNr berechnet wird und entsprechend ein anderes Ergebnis liefert wenn Datensätze hinzugefügt oder gelöscht werden.
Habe ich das so richtig verstanden?
ich nehme mal an, dass die SortNr nicht in der Tabelle Land/Stadt/Strasse erscheinen soll. Bei Änderung der Datensätze muss diese dann auch geändert werden. Ich würde ein Unterformular der Tabelle Land/Stadt/Strasse erstellen, dieses um ein ungebundenes Textfeld ergänzen, in der die SortNr erscheinen soll.
Die Generierung der SortNr erfolgt in einen Formular über eine Ereignisprozedur, z.B die einer Befehlsschaltfläche. In der Prozedur wird die Tabelle Land/Stadt/Strasse in der Sortierreihenfolge als Recordset geöffnet und in einer Schleife jede Recordsetnummer dem ungebundenen Textfeld zugeordnet.
dim rsin as recordset
dim zaehler as integer
dim gruppe_alt as string
dim gruppe_neu as string
dim str as string
str=„select * from tabellenname order by
land,stadt,strasse,nachname,vorname“
set rsin=currentdb.Openrecordset(str)
do until rsin.eof
gruppe_neu=rsin!land & rsin stadt & rsin!strasse
if gruppe_alt gruppe_neu then
zaehler=0
gruppe_alt=gruppe_neu
else
zaehler=zaehler + 1
end if
rsin.edit
rsin!SortNr=zaehler
rsin.update
rsin.movenext
loop
Hallo und entschuldigung, dass ich mich nicht melden konnte.
Was ich brauche ist eine Abfrage, Modul oder Makro, welches statisch einmalig aufgrund der Parameter Einträge in der Spalte „SortNr“ vornimmt. Also keine dynamische Aktionen. Wenn ein neuer Datensatz hinzugefügt wird, oder ein vorhandener editiert wird, hat das keinen Einfluss auf die bisherigen Einträge.
ich benötige keine dynamischen Aktionen, sondern lediglich eine Abfrage, Makro oder Modul, welches an den vorhandenen Werten und Parametern einmalig Einträge in der Spalte „SortNr“ vornimmt. Sollten neue Datensätze hinzukommen oder vorhandene editiert werden, beeinflusst dieses nicht die bereits gemachten Einträge.
Die Parameter:
also ich habe eine Tabelle mit folgenden Spalten:
Land
Stadt
Straße
Nachname
Vorname
SortNr
Gruppiert werden sollen diese Spalten:
Land
Stadt
Straße
Sortiert werden soll über (in der Reihenfolge):
Land
Stadt
Straße
Nachname
Vorname
In der letzten Spalte „SortNr“ soll jetzt ein Wert hochgezählt werden, solange die Einträge für die Gruppierung gleich bleiben und unter Berücksichtigung der Sortierung.
Solange also in den ersten drei Spalten „Deutschland“, „Düsseldorf“ und „Hansa-Allee“ steht, soll hochgezählt werden, der Schmidt-Anton vor dem Schmidt-Egon.
herzlichen Dank für diese erneut präzise Ausfertigung. Alle Datensätze (immerhin 1.600.000) werden exakt und in guter Geschwindigkeit abgearbeitet. Ich bin wirklich sehr begeistert und würde gerne mit Ihnen Kontakt aufnehmen, um über eine generelle Zusammenarbeit zu sprechen. Wenn Sie Interesse haben, können Sie mir gerne Ihre Mail-Adresse oder Tel.-Nr. zukommen lassen.
Freut mich, dass ich Ihnen helfen konnte. Falls noch weitere Probleme auftauchen bei der Weiterverarbeitung bin ich Ihnen natürlich gerne noch behilflich. Ich bin diese Jahr, nach 15 Jahren selbständiger Access-Programmierung in Rente gegangen und es dürfte natürlich nicht in Stress ausarten . Es würde mich noch interessieren wie lange es etwa gedauert hat. Meine e-Mail Adresse ist:
bitte entschuldigen Sie die späte Reaktion. Ihre Antwort muss ich wohl übersehen haben.
Habe die Zeilen jetzt mal in einem Modul eingebaut. Nach geraumer Zeit erscheint eine Fehlermeldung:
„Anzahl der Dateisperrungen überschritten (Fehler 3052)“
Nach dem debuggen wird der Eintrag „rsin.Edit“ gelb hinterlegt.
Das Modul aktualisiert aber bis zum Datensatz 9.495 die Spalte „SortNr“ absolut korrekt, somit ist Funktion einwandfrei!
Fairerweise muss ich noch zwei Dinge hinzufügen:
Ich habe das Modul an einer Tabelle mit ca. 1.600.000 Datensätzen ausprobiert. Das ist ungefähr die Menge, für die ich das Modul zukünftig verwenden muss (eher noch mehr).
Das Aktualisieren der Spalte „SortNr“ ist rein statisch. Wenn ein neuer Datensatz hinzugefügt, oder ein vorhandener Datensatz editiert wird, muss dieses nicht berücksichtigt werden. Die Funktion wird nur zur einmaligen Verwendung benötigt. Vielleicht ist das wichtig für Sie.
Schon jetzt möchte ich mich bei Ihnen für diesen fundierten Beitrag bedanken.
sowas passiert, wenn man nicht alle Informationen hat.
Setze noch Folgendes ein:
dim i as long
ergänze die Zeile set rsin=…
set rsin=currentdb.Openrecordset(str,dbOpenDynaset)
vor der Zeile rsin.update:
i=i+1
if i>1000 then
DBEngine.BeginTrans: DBEngine.CommitTrans
i=0
end if
Dadurch wird eine NULL-Transaktion durchgeführt.
Es werden die durch die Edit-Aktion gesperrten Datensätze in die Tabelle gespeichert und die Locks wieder freigegeben.
bitte entschuldige, dass ich nicht gleich alle Informationen bereitgestellt habe. Aber ich habe (leider) so wenig Ahnung vom Programmieren, dass ich nicht mal eindeutig entscheiden kann, was wichtig ist und was nicht…
Das Modul läuft einwandfrei durch! 1.647.201 Datensätze in unter einer Minute verarbeitet.
Das ist echt super!
Wäre es eigentlich grundsätzlich auch möglich, die Spalte „SortNr“ als Text (Länge = 9 Zeichen) mit einer festen Formatierung, z.B. „000000237“ zu füllen, also mit vorlaufenden Nullen? Somit wäre es nämlich möglich, Text so zu sortieren, als wäre es eine Zahlenspalte.
Welche Änderungen im Modul wären nötig? Wird die Performance darunter leiden?
Würde gerne auch zukünftig Deine Hilfe in Anspruch nehmen. Gegebenenfalls gegen Bezahlung. Vielleicht kannst Du Dir ja auch eine Zusammenarbeit vorstellen. Wenn Du Interesse hast, kannst Du mir ja Deine Kontaktdaten zukommen lassen.
entschuldige dass ich erst heute Antworte.
Hier eine Lösung für die Aufgabe.
Erstelle ein neues Modul in Deiner Datenbank und kopiere folgenden Code rein:
Option Explicit
Function ergänzeZähler()
Dim dbs As Database
Dim rst As Recordset
Dim sql As String
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset(sql, dbOpenDynaset)
With rst
Do While Not .EOF
If !Vergleich str_lastVergleich Then
str_lastVergleich = !Vergleich
lng_SortNr = 1
Else
lng_SortNr = lng_SortNr + 1
End If
.Edit
!SortNr = lng_SortNr
.Update
.MoveNext
Loop
.Close
End With
Set rst = Nothing
End Function
Ersetzte ‚Tabelle1‘ im sql durch den Namen Deiner Tabelle.
Dann erstellst Du ein neues Makro.
Wähle als Aktion „AusführenCode“ und füge unten bei Funktionsname "ergänzeZähler () " hinzu.
Dann alles speichern
Jetzt das Makro nur noch doppelklicken oder mit Rechtsklick ausführen.
Jetzt ist die Spalte SortNr Deiner Tabelle wie gewünscht gefüllt.
herzlichen Dank für Deine Antwort. Das ist von allen mir zugestellten Lösungen diejenige, welche am schnellsten läuft. Geschwindigkeit ist hier deswegen so gefragt, da teilweise mehrere Millionen Datensätze verarbeitet werden. Dein Modul schafft 1.6 Mio. Datensätze in unter 30 sec., was ca. doppelt so schnell ist, als die beste andere Lösung.
Jetzt habe ich nur eine Frage:
Es ist jetzt so, das die Spalte „SortNr“ nicht als „Zahl“ formatiert ist, sondern als „Text“ mit einer Länge von 5 Zeichen. Die hochgezählten Werte sollen hierin mit vorgestellten Nullen erscheinen, z.B. 00001 oder 00002 usw. In den Abfragen benutze ich dafür die Funktion „Format“. Wie könnte ich das in Dein Modul einbauen?
danke für die Blumen
Freut mich, dass es für die richtig Lösung ist.
Das mach ich den ganzen Tag
Schnelligkeit ist da wichtig.
Schneller wirst Du es aber nicht mehr bekommen, da es keine direkteren Datenzugriffsbefehle gibt.
Aber zurück zu Deiner Anfrage.
Die Lösung ist ganz einfach und Du hast schon den richtigen Befehl gebracht.
Ersetzt einfach im Modul die Zeile
!SortNr = lng_SortNr
durch
!SortNr = Format(lng_SortNr, „00000“)