Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Zeilennummern in einer Abfrage generieren

Begonnen von Erklärbär, Dezember 27, 2010, 18:21:15

⏪ vorheriges - nächstes ⏩

Erklärbär

Hallo Leute,

ich möchte in Abfragen Zeilenummern erzeugen, die ich für weitere Berechnungen brauche.
Damit die Erklärung nicht zu Kompliziert wird habe ich die Problemstellung vereinfacht und auf das Wesentliche beschränkt.


Szenario:
Umgebung Access 2003
Gegeben sei eine Tabelle "T1" mit den Feldern "ID" und "Wert".
ID ist der Primärindex und eindeutig.
Da auch mal Datensätze gelöscht werden sind die IDs nicht lückenlos.

Das Feld "Wert" enthält Zahlen in beliebiger Reihenfolge (also nicht nach IDs sortiert)
Hierin sind auch doppelte Werte möglich!

Beispiel für T1:
ID   Wert
1   10
2   2
4   3
7   100
8   87
10   87
11   65
12   77

Ausgabe der Tabelle erfolgt über die Abfrage "Q1" sortiert nach "Wert"

ID   Wert
2   2
4   3
1   10
11   65
12   77
8   87
10   87
7   100

Zu der Ausgabe Q1 soll eine Zeilennummerierung hinzugefügt werden damit das Ergebnis so aussieht:
Zeile   ID   Wert
1   2   2
2   4   3
3   1   10
4   11   65
5   12   77
6   8   87
7   10   87
8   7   100


Mit der üblichen Count-Funktion (siehe Beispiel) klappt das nicht so ohne weiteres, da in Zeile 6 und 7 die gleichen Werte stehen. Da kommt im Ergebnis natürlich dieselbe Zeilennummer raus.

Beispiel:
Zeile: (Select Count (*) FROM [T1] as Temp WHERE [Temp].[wert] < [T1].[wert])+1


Hat jemand sowas schonmal gelöst, oder einen Ansatz?




Gruß Erklärbär

DF6GL

Hallo,


es stellt sich die Frage, wozu Du überhaupt eine LfdNr brauchst...


Verwendbar für "weitere Berechnungen " ist eine solche jedenfalls nicht...


Man könnte z. B. einen nach "Wert" sortierten Recordset durchlaufen und jede "Zeile" (Datensatz) mit einem hochlaufenden Zählerwert aktualisieren.

Erklärbär

@DF6GL

Danke für die Antwort,

so in diese Richtung habe ich auch schon gedacht. Die Abfrage Q1 ist ja bereits nach "Wert" sortiert. Einen Platzhalter für  "Zeile" lässt sich da auch noch einbauen.
Wie aber sieht das Durchlaufen des Recordsets konkret aus? Das habe ich in VBA noch nicht gemacht. Hast Du vielleicht ein syntaktisches Beispiel für mich?
Oder lässt es sich doch irgendwie in die Abfrage mit einbauen?


PS.
Ich habe die Problemstellung bewußt abstrakt dargestellt damit nicht wie so oft über das "warum" sondern über die Problemstellung diskutiert wird.  ;)

Danke und Gruß


MzKlMu

Hallo,
ZitatIch habe die Problemstellung bewußt abstrakt dargestellt damit nicht wie so oft über das "warum" sondern über die Problemstellung diskutiert wird.
Aber meistens führt die Abstraktion auch zu einer Vereinfachung, sodass die dann vorgeschlagene Lösung in der Realität gar nicht passt. Und im Regelfall lohnt es sich auch für den Fragesteller das warum zu hinterfragen, dann das führt auch oft zu besseren Lösungen.

Mit einer solchermaßen erzeugten LfdNr lässt sich nicht viel anfangen.
Gruß Klaus

database

#4
Hallo,

ZitatWie aber sieht das Durchlaufen des Recordsets konkret aus
in Etwa so...


Private Sub Befehl_Click()
   Dim i  As Long
   Dim rs As DAO.Recordset

   Set rs = CurrentDb.OpenRecordset( _
       "SELECT Nachname, Vorname, Gebdatum " & _
       "FROM tabPersonen", dbOpenDynaset)
   
   For i = 1 To rs.RecordCount 
       MsgBox i & ", " & rs!Nachname & " " & rs!Vorname & ", " & rs!Gebdatum
       rs.MoveNext
   Next
 
   rs.Close
   Set rs = Nothing
End Sub

Erklärbär

@database

Hallo Peter,

Dein Tip ging schon recht gut in die richtige Richtung, danke.
Ich habe zum Testen ein Fomular in Datenblattansicht erstellt und in die Abfrage ein Dummyfeld eingefügt und mit Null belegt - klappt.
Deine Prozedur habe ich mit einem Knopf reingelegt. (für die Formularansicht)

Set rs = CurrentDb.OpenRecordset("Q1", dbOpenDynaset)

Mit der Prozezur kann ich mir auch wunderbar jeden Datensatz über die MsgBox ansehen. - soweit so gut.

Jetzt hänge ich beim Ändern / Update der Datensätze um die Zeilennummer in den Recordset zu schreiben.
Ich hab's erst mal intuitiv versucht mit:
rs!zeile=i  (klappte natürlich nicht, wäre ja auch zu einfach gewesen)

danach habe ich folgendes probiert:
rs.edit
rs!zeile=i
rs.update

Daraufhin kam die Fehlermeldung" Feld konnte nicht aktualisiert werden. (Fehler 3164)"

Vermutlich ist der Datensatz noch irgendwie gesperrt.
Wie schreibt man denn richtig in den Record?

Gruß
Ralph







database

Hallo,

um Felder in einem Recordset ändern zu können brauchst du ein aktualisierbares Recordset.
Du schreibst von einem Dummyfeld in der Abfrage - ich gehe davon aus, dass du das in der Form .... 0 As zeile .... in der Abfrage stehen hast.
Dieses Feld kannst du nicht ändern!
Du musst das Dummyfeld (Datentyp Zahl, Standardwert 0) in der Tabelle führen, dann geht es.

An Hand meines bisherigen Beispiels mal auf diese Sache angenähert...
aber mit einer anderen Art des Durchlaufs


Private Sub Befehl_Click()
    Dim i  As Long
    Dim rs As DAO.Recordset
    i = 1

    Set rs = CurrentDb.OpenRecordset( _
        "SELECT Nachname, Vorname, Gebdatum, zeile " & _
        "FROM tabPersonen", dbOpenDynaset)
 
    'zum Beginn des Recordsets gehen
    rs.MoveFirst

    'Solange das Ende nicht erreicht ist ...
    Do While Not rs.EOF
        rs.Edit
        rs!zeile= i
        rs.Update
        i = i + 1
        rs.MoveNext
    Loop
 
    rs.Close
    Set rs = Nothing

End Sub


Erklärbär

Hallo Peter,

ein frohes neues Jahr wüsche ich Dir und danke für den Hinweis.
Das sieht aber jetzt fast so aus als ob es in Abfragen doch nicht geht.   :(
Du hattest Recht in der SQL Ansicht meiner Abfrage steht "0 AS Zeile" drin.
Die Werte werden auch brav auf 0 gesetzt. Mein Gedanke war tatsächlich
im Dynaset dieser Abfrage diese Werte durch die Prozedur nach der Abfrage nochmal zu verändern.

Jetzt nur noch mal zum Verständnis: Wenn ich eine Abfrage ausführe wird dieses Ergebnis doch
in einer temporären Tabelle dem Dynaset gespeichert oder? Und diese Tabelle ist danach nur noch read only?
Oder liegt das Problem nur in der Typendeklaration?

Prinzipiell würde es mit dem Datenfeld in der Tabelle gehen. Das wollte ich aber eigentlich vermeiden
denn der Laufindex wir nur in der Abfrage gebraucht und braucht nicht dauerhaft gespeichert werden.
Hinzu kommt noch das auf diese Tabelle  mehrere Abfragen dieser Art gleichzeitig einwirken und somit
die Werte überschrieben würden.
Hast Du noch eine Idee? Ein Kollege sagte mir mal was vom "Datagrid" Objekt, damit könnte man Zeilenoperationen durchführen.


Gruß Ralph