Office Forum
www.Office-Loesung.de
Access :: Excel :: Outlook :: PowerPoint :: Word :: Office :: Wieder Online ---> provisorisches Office Forum <-
Mehrere Autowerte in einer Tabelle / @@IDENTITY
zurück: Regionals-Funktionsbibliothek für regionale Formatumwandlung weiter: Automatischer Mailversand ohne Warnmeldung Unbeantwortete Beiträge anzeigen
Neues Thema eröffnen   Neue Antwort erstellen     Status: Tutorial Facebook-Likes Diese Seite Freunden empfehlen
Zu Browser-Favoriten hinzufügen
Autor Nachricht
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
10. Sep 2010, 18:25
Rufname:

Mehrere Autowerte in einer Tabelle / @@IDENTITY - Mehrere Autowerte in einer Tabelle / @@IDENTITY

Nach oben
       Version: Office 2007

Hallo zusammen,

den folgenden Thread: DS nicht Speichern - Autowert wird übersprungen
habe ich mal zum Anlass genommen, die angehängte kleine Demo zu basteln.

Problem:
Wenn man einer Tabelle einen Autowert hinzufügt und diesen Wert zum Beispiel für eine Rechnungsnummer verwenden will, dann wird man im Formular feststellen, daß ein Undo auf den Datensatz diesen zwar nicht speichert, beim nächsten Mal die Autowert-Nummer aber bereits um eins hochgezählt wurde. Was für einen PK kein Problem ist, ist für den Gebrauch als Rechnungsnummer (oder Ähnliches) nicht zu gebrauchen.
Access bietet von Haus aus keine Möglichkeit, dieses Verhalten zu umgehen.

Lösungsansatz:
In Oracle gibt es zum Beispiel gar keinen Datentyp Autowert. Hier kann man sich einen externen Zähler mit SQL anlegen und diesen dann einer beliebigen Datenspalte zuweisen. Da man beliebig viele Zähler aufsetzen kann, kann man auch beliebig viele Autowerte in einer Tabelle anlegen.

Lösungsmöglichkeit:
Was Oracle kann, kann (in diesem Fall) auch Access, nur muß man einen kleinen Umweg über eine Hilfstabelle machen. Da die Lösung ein ADO voraussetzt, muß man noch eine Referenz auf die ADO Library 2.8 setzen.

Eine Neuigkeit in Access ist, daß man nunmehr auch, wie der "große Bruder" SQL Server die Systemvariable "@@IDENTITY" auslesen kann. Diese gibt die ID zurück, die beim letzten Einfügevorgang in der Autowertspalte der betroffenen Tabelle verwendet wurde.

Der gesamte Code, der dazu notwendig ist, sieht so aus:
Code:
Private Sub Form_BeforeUpdate(Cancel As Integer)
    Dim cn As ADODB.Connection
    Dim cmd As ADODB.Command
    Dim rs As ADODB.Recordset
   
    If Nz(Me.Rng_Nr, 0) = 0 Then
        Set cn = New ADODB.Connection
        Set cn = CurrentProject.Connection
        If Not cn Is Nothing Then
            Set cmd = New ADODB.Command
            cmd.ActiveConnection = cn
            cmd.CommandText = "INSERT INTO tblRngNr (Dummy) VALUES ('X')"
            cmd.CommandType = adCmdText
            cmd.Parameters.Refresh
            cmd.Execute
            Set rs = New ADODB.Recordset
            rs.ActiveConnection = cn
            rs.Open "SELECT @@IDENTITY"
            Me.Rng_Nr = rs.Fields(0)
        End If
        Set cmd = Nothing
        If Not rs Is Nothing Then
            If rs.State = adStateOpen Then rs.Close
            Set rs = Nothing
        End If
        If Not cn Is Nothing Then
            Set cn = Nothing
        End If
    End If
End Sub
Es wird eine ADO-Verbindung zur laufenden Datenbank erstellt. Mit dieser Verbindung wird ein ADO Command Objekt erstellt, mit dessen Hilfe einfach eine neue Zeile in die Hilfstabelle "tblRngNr" eingefügt wird (dazu das Dummy-Feld, da man dem Autowert ja keinen Wert zuweisen kann).
Nach dem Execute des Commands öffnet man dann eine ADO Recordset-Verbindung, die mit "SELECT @@IDENTITY" den erzeugten Autowert wieder ausliest.

Zuletzt kopiert man diesen Wert noch in das Rechnungsnummer-Feld der eigenen Tabelle (deren Feld für den Benutzer zur Eingabe gesperrt ist) und läßt den "BeforeUpdate"-Event weiterlaufen, der im Anschluß den Datensatz speichert.

Bei einer Backend-Datenbank würde man hier stattdessen eine Connection zu der externen Datenbank erstellen, die man dann am Ende auch wieder mit Close schließt. "@@IDENTITY" gibt immer die Nummer zurück, die mit dieser Verbindung erstellt wurde, daher ist diese Methode auch mehrbenutzerfähig, da jeder Client seine eigene Connection erstellt und die Autowert-Tabelle selbst dafür sorgt, daß es keine Duplikate gibt.

Die IF-Abfrage zu Beginn stellt dann noch sicher, daß nur dann eine neue Rechnungsnummer erzeugt wird, wenn das Feld noch keinen Inhalt hat. Ansonsten würde auch bei jeder Datensatzänderung eine neue Rechnungsnummer erzeugt werden.

Wenn man nun in das Feld "Rng_Customer" irgendeinen Wert eingibt, dann aber doch einen Undo mit der ESC-Taste durchführt, dann wird der Autowert-Zähler der ID erhöht - aber nicht die Rechnungsnummer, die bleibt solange frei, bis der User wirklich speichern drückt und ändert sich von da an auch nicht mehr.

Mit der gleichen Methode und weiteren Hilfstabellen kann man sich auch weitere Autowerte in der gleichen Tabelle erzeugen lassen.

Geschrieben und getestet mit Access 2007, sollte aber auch in älteren Versionen funktionieren. Allerdings muß man beachten, daß @@IDENTITY" erst ab JET OLE 4.0 funktioniert.

Gruß

Christian



AutoValue.zip
 Beschreibung:
Zeigt, wie man den Autowert einer externen Tabelle verwenden kann, um damit andere Tabellen mit lückenlosen Nummernfolgen zu versehen.

Download
 Dateiname:  AutoValue.zip
 Dateigröße:  20.09 KB
 Heruntergeladen:  96 mal

Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
04. Jun 2013, 21:55
Rufname:


AW: Mehrere Autowerte in einer Tabelle / @@IDENTITY - AW: Mehrere Autowerte in einer Tabelle / @@IDENTITY

Nach oben
       Version: (keine Angabe möglich)

Hallo,

oben wurde ja bereits gezeigt, wie man die Autowert-ID einer anderen Tabelle verwenden kann, um einen numerischen Counter ohne Doppelte in eine Tabelle einzufügen.

Was aber, wenn der Counter nicht einfach nur ein numerisches LongInteger-Format hat, sondern beliebig aufgebaut ist?

Für diesen Zweck habe ich hier mal ein Modul gebaut, das in der Lage ist, die allermeisten Counterformate inklusive aller herkömmlichen Zahlensysteme als Counter zu verwenden. Dabei kann jede Stelle des Counters sowohl aus beliebig vielen Ziffern bestehen (beispielsweise für einen Hexadezimalcounter jede Stelle des Counters aus 16 Ziffern) als auch aus beliebig vielen Zeichen. Jede Stelle kann ebenso eine andere Menge an Ziffern/Zeichen, aus denen die Ziffer besteht enthalten. Während normale Zahlensysteme für jede Stelle der Zahl die gleiche anzahl Ziffernwerte enthält (etwa 10 Ziffern von 0 bis 9 für Dezimalzahlen), kann der Counter hier auch so definiert werden, daß z.B. die erste Stelle (von rechts beginnend) aus den Ziffern 0-3, die zweite aus den Zeichen A-K und die dritte aus den Texten "XX", "YY" und "ZZ" besteht.

Einzige Bedingung für den Counter ist, daß er mit der Zahl 0 zurechtkommt (Gegenbeispiel ist das konfuse Buchstabensystem der Excel-Spalten, die von 1-26 A-Z ergeben und dann wieder mit AA anfangen - das läßt sich hiermit nicht umsetzen, da es in Excel keine Spalte 0 gibt und damit Spalte 1 als "AAB" errechnet werden würde).

Um also eine LongInteger-Zahl in eine 8-stellige Hex-Zahl zu verwandeln, muß man nur ein Counterformat erstellen:
Code:
InitCounter "Hex8", fnCounterHex(8)
Dann kann man mit fnCounterValue den umgerechneten Wert erhalten:
Code:
? fnCounterValue("Hex8",255)
000000FF
Der Text "Hex8" ist nur ein Name für den Counter, der kann beliebig sein. Man kann beliebig viele Counter erstellen und so mit dem Counternamen darauf zugreifen.

Um den Wert in eine Tabelle zu schreiben, erstellt man eine Tabelle, die nur aus zwei Spalten besteht: Der Autonumber-Spalte und einer Textspalte, die groß genug ist, um das Format des Counters aufzunehmen.

Mit der Funktion "GetNextValue" kann man dann einen neuen Wert in diese Tabelle schreiben lassen und gleichzeitig dabei das gewünschte Format angeben. Da die Funktion die entsprechenden Namen für Tabelle, ID-Feldname und Wert-Feldname entgegennimmt, kann man beliebig viele Countertabellen mit unterschiedlichsten Formaten verwenden. Die Funktion gibt die gespeicherte ID zurück, die man dann in die eigene Tabelle schreibt, wo der Counter verwendet werden soll, so hat man auch eine Nachschlagetabelle für den Counter.

In der angehängten Demodatei ist auch ein Demoformular und passende Demotabellen enthalten, das zeigt, wie man z.B. zwei getrennte Counter in eine Tabelle speichern kann.

Weitere Infos über die Verwendung sind im Code dokumentiert, so z.B. eine Methode, um anhand des aktuellen Datums ein Format "2013 Jan" auszugeben.

Zur Verwendung in eigenen Datenbanken benötigt man nur das Modul und das Klassenmodul, die Tabellen kann man beliebig selbst erstellen.

Viel Spaß beim Experimentieren mit Countern

Christian



CCCounter.zip
 Beschreibung:
CCCounter Demodatenbank in den Formaten A2000 und A2007. Geschrieben und getestet mit A2007

Download
 Dateiname:  CCCounter.zip
 Dateigröße:  122 KB
 Heruntergeladen:  26 mal

Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind
GMT + 1 Stunde

Diese Seite Freunden empfehlen

Seite 1 von 1
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen

Verwandte Themen
Forum / Themen   Antworten   Autor   Aufrufe   Letzter Beitrag 
Keine neuen Beiträge Access Tabellen & Abfragen: Kreuztabellenabfrage für neue Tabelle nutzen 3 WaterMan 805 06. Jul 2004, 14:39
mabe38 Kreuztabellenabfrage für neue Tabelle nutzen
Keine neuen Beiträge Access Tabellen & Abfragen: Tabelle exportieren als Excel2000 Arbeitsblatt 1 thomassch 916 06. Jul 2004, 12:46
stpimi Tabelle exportieren als Excel2000 Arbeitsblatt
Keine neuen Beiträge Access Tabellen & Abfragen: Tabelle von Excel importieren 1 Sonnenschein 2640 15. Jun 2004, 06:57
stpimi Tabelle von Excel importieren
Keine neuen Beiträge Access Tabellen & Abfragen: Tage auf Datum addieren und an bestehende Tabelle anfügen... 1 lorelei 1234 11. Jun 2004, 08:38
stpimi Tage auf Datum addieren und an bestehende Tabelle anfügen...
Keine neuen Beiträge Access Tabellen & Abfragen: tabelle exportieren 1 Gast 1501 01. Jun 2004, 12:25
Willi Wipp tabelle exportieren
Keine neuen Beiträge Access Tabellen & Abfragen: Duplikate einer Tabelle löschen?! 3 Esel 2108 28. Mai 2004, 08:53
lothi Duplikate einer Tabelle löschen?!
Keine neuen Beiträge Access Tabellen & Abfragen: Spaltennamen einer Tabelle ermitteln 1 Alexander Neron 899 27. Mai 2004, 13:47
lothi Spaltennamen einer Tabelle ermitteln
Keine neuen Beiträge Access Tabellen & Abfragen: kein Wert in der Tabelle, dann immer Null (0)?? 3 Michel_9 1005 26. Mai 2004, 14:28
Michel_9 kein Wert in der Tabelle, dann immer Null (0)??
Keine neuen Beiträge Access Tabellen & Abfragen: Operant aus Tabelle in Abfrage verwenden 3 AccessGeek 673 06. Mai 2004, 09:15
lothi Operant aus Tabelle in Abfrage verwenden
Keine neuen Beiträge Access Tabellen & Abfragen: Tabelle formatiert in txt-Datei exportieren 1 robby 1115 12. Apr 2004, 23:10
Helge Tabelle formatiert in txt-Datei exportieren
Keine neuen Beiträge Access Tabellen & Abfragen: Tabelle aus Abfrage erstellen 1 dasti 3317 09. Apr 2004, 12:14
Gast Tabelle aus Abfrage erstellen
Keine neuen Beiträge Access Tabellen & Abfragen: Zeilenumbruch nach Einfügen Word Tabelle 2 topflop 1698 30. März 2004, 16:06
Gast Zeilenumbruch nach Einfügen Word Tabelle
 

----> Diese Seite Freunden empfehlen <------ Impressum - Besuchen Sie auch: Microsoft Word Serienbriefe