Discussion:
PrimaryKey und Indeces ohne Duplikate setzen (VBA)
(zu alt für eine Antwort)
Ahmed Martens
2013-04-13 13:17:08 UTC
Permalink
Hallo Leute,

ich sitze hier wieder und weine in mein Taschentuch!
Und das nicht nur wegen dem Wetter.

Ich möchte zu einem CreateTableDef und CreateField jeweils ein
PrimaryKea und einen Index ohne Duplikate hinzufügen. Damit auch alle
Werte immer eindeutig sind.

Ich bekomme das aber irgendwie nicht hin.

Hier meine Funktion:

<Code>

Function tableExists(mytable As String, blnAdd As Boolean) As Boolean

Dim td As DAO.TableDef
Dim rec As Recordset
Dim ndx As Index

On Error GoTo tableExists_Error
Set td = CurrentDb.TableDefs(mytable & "_Konto")
tableExists = True

On Error GoTo 0
Exit Function



tableExists_Error:

If blnAdd = False Then
Exit Function
End If

Set td = CurrentDb.CreateTableDef(mytable & "_Konto")

With td
.Fields.Append .CreateField("Konto_MaDa", dbLong) '<=PrimaryKey
.Fields.Append .CreateField("Konto_Firma", dbLong) '<=Index ohne Duplikate
End With
CurrentDb.TableDefs.Append td


Set td = CurrentDb.CreateTableDef(mytable & "_Sonstiges")
With td
.Fields.Append .CreateField("Kennung", dbText)
.Fields.Append .CreateField("Funktion", dbText)
End With
CurrentDb.TableDefs.Append td
CurrentDb.TableDefs.Refresh

Set rec = CurrentDb.OpenRecordset("tblMdNr_Lerndatei",
dbOpenDynaset)

rec.AddNew
rec.Fields(0) = mytable
rec.Update
End Function


</Code>

Kann mir irgendeiner einen Schubs in die richtige Richtung geben?
Vielen Dank im voraus.

Gruß Ahmed
--
Antworten bitte nur in der Newsgroup
Windows 7 64bit Home Premium
Office Prof. 2010
Lars P. Wolschner
2013-04-13 14:16:41 UTC
Permalink
Post by Ahmed Martens
Ich möchte zu einem CreateTableDef und CreateField jeweils ein
PrimaryKea und einen Index ohne Duplikate hinzufügen. Damit auch
alle Werte immer eindeutig sind.
Ich bekomme das aber irgendwie nicht hin.
<Code>
... in der nirgends ein Index erzeugt wird. Du müßtest Dich in der
Onlinehilfe mit dem DAO.Index-Objekt vertraut machen.

Exemplarisch die Anlage einer Tabelle mit AutoWert-
Primärschlüssel, strTbl enthalte bereits den Tabellennamen, strFld
den Feldnamen (beides sind natürlich String-Variablen) und db ist
ein DAO.Database-Objekt:

---8<-------------------------------------------------------
Dim tbldef as DAO.TableDef
Set tbldef = db.CreateTableDef(strTbl)

Dim flddef as DAO.Field
Set flddef = tbldef.CreateField(strFld, dbLong)
flddef.Attributes = _
flddef.Attributes Or FieldAttributeEnum.dbAutoIncrField
tbldef.Fields.Append flddef

Dim inddef1 As DAO.Index
Set inddef1 = tbldef.CreateIndex("idx" & strTbl & "_" & strFld)
Set flddef = inddef1.CreateField(strFld)
inddef1.Fields.Append flddef
inddef1.Primary = bNew
tbldef.Indexes.Append inddef1

db.TableDefs.Append tbldef
db.TableDefs.Refresh
Set tbldef = db.TableDefs(strTbl)
------------------------------------------------------->8---

Eine Name für den Index (Objekt inndef1) wird hier automatisch
generiert, man kann diesen natürlich auch fest vorgeben.

Nachdem man das Tabellenobjekt (hier: tbldef) hat, legt man die
Felder mit TableDef.CreateField() an, legt ihre Eigenschaften fest
und "fixiert" das Ganze mit TableDef.Fields.Append(). Nach diesem
letzten Aufruf können die Feldeigenschaften nicht mehr verändert
werden.

Genauso läuft die Anlage von Indices: TableDef.CreateIndex()
erzeugt ein DAO.Index-Objekt (hier in der Variablen inddef1), die
Methode Index.CreateField() ordnet ein Feld diesem Index zu,
Index.Fields.Append() "fixiert" das Feld. Wenn ein Index aus
mehreren Feldern bestehen soll, können mit Index.CreateField() und
Index.Fields.Append() auch mehrere Felder hintereinander
zugeordnet werden.
Nun können noch weitere Eigenschaften des Index-Objektes
festgelegt werden, insbesondere Primary, Required, IgnoreNulls und
Unique. Schließlich wird der Index mit TableDef.Indexes.Append()
"fixiert".
--
Mit freundlichen Grüßen
Lars P. Wolschner
Ahmed Martens
2013-04-13 15:25:28 UTC
Permalink
Hallo Lars,

vielen Dank für Deine Erklärungen. Ich habe es aber dennoch nicht
hinbekommen.

Folgenden Code habe ich verwendet:

Set td = CurrentDb.CreateTableDef(mytable & "_Konto")

With td
.Fields.Append .CreateField("Konto_MaDa", dbLong)
.Fields.Append .CreateField("Konto_DATEV", dbLong)
End With
CurrentDb.TableDefs.Append td


'1. Primary key index.
Set ind = td.CreateIndex("PrimaryKey")
With ind
.Fields.Append .CreateField("Konto_MaDa")
.Unique = False
.Primary = True
End With
td.Indexes.Append ind

'2. Single-field index.
Set ind = td.CreateIndex("Konto_DATEV")
With ind
.Fields.Append .CreateField("Konto_DATEV", dbLong)
.Unique = True
.Primary = False
End With
td.Indexes.Append ind


Ich habe aber immer einen Fehler erhalten.

Aber ich mache es jetzt ganz anders.
Ich kopiere einfach eine Master-Tabelle mit allen Einstellungen und gut
ist.

DoCmd.CopyObject , mytable & "_Konto", acTable, "Master_Konto"
DoCmd.CopyObject , mytable & "_Sonstiges", acTable, "Master_Sonstiges"

Damit umgehe ich jegliche Problemen.

Gruß Ahmed
--
Antworten bitte nur in der Newsgroup
Windows 7 64bit Home Premium
Office Prof. 2010
Lars P. Wolschner
2013-04-13 16:56:19 UTC
Permalink
Post by Ahmed Martens
Hallo Lars,
vielen Dank für Deine Erklärungen. Ich habe es aber dennoch
nicht hinbekommen.
Set td = CurrentDb.CreateTableDef(mytable & "_Konto")
With td
.Fields.Append .CreateField("Konto_MaDa", dbLong)
.Fields.Append .CreateField("Konto_DATEV", dbLong)
End With
CurrentDb.TableDefs.Append td
Von hier an sind schon fast keine Veränderungen an dem
DAO.TableDef-Objekt mehr möglich. Der TableDefs.Append()-Aufruf
darf erst zum Schluß kommen, wenn alle anderen Festlegungen
abgeschlossen sind.
Post by Ahmed Martens
Aber ich mache es jetzt ganz anders.
Ich kopiere einfach eine Master-Tabelle mit allen Einstellungen
und gut ist.
DoCmd.CopyObject , mytable & "_Konto", acTable,
"Master_Konto" DoCmd.CopyObject , mytable & "_Sonstiges",
acTable, "Master_Sonstiges"
Damit umgehe ich jegliche Problemen.
Naja, immer wird man damit nicht zurandekommen. Ich habe mir in
meinem Database-Modul auch eine Funktion geschaffen, die Tabellen
mit Feldern und Indices anlegen kann. Die ist auch in der Lage,
eine bereits existierende Tabelle entweder zuvor gänzlich zu
löschen oder ihre Einstellungen teilweise weiter zu bearbeiten.
--
Mit freundlichen Grüßen
Lars P. Wolschner
Raimo Becker
2013-04-13 18:29:41 UTC
Permalink
Hallo Ahmed,

kannst Du die Tabelle auch via SQL-Statement erstellen?

CREATE TABLE DeineTabelle (DeinTabName LONG CONSTRAINT
IndexNameIsAuchEgal PRIMARY KEY, Spalte1 TEXT(55),Spalte2 TEXT(55))

Und den mit CurrentDb.execute,DBFAILONERROR durchziehen?

Ich geh konform mit Karl - auch wenn die Syntax im String nicht
natürlich nicht geprüft werden kann

http://www.donkarl.com/Katalog/#3.5

Gruß
Raimo
Siegfried Schmidt
2013-04-13 19:27:58 UTC
Permalink
Post by Raimo Becker
Ich geh konform mit Karl - auch wenn die Syntax im String nicht
natürlich nicht geprüft werden kann
Wenn es sein muss, kann kann der natürlich geprüft werden:
http://www.sqlparser.com/access-sql-parser.php

Einfache SQL-Parser lassen sich auch in VBA schreiben.


Siegfried
Siegfried Schmidt
2013-04-13 19:05:51 UTC
Permalink
Post by Ahmed Martens
Damit umgehe ich jegliche Problemen.
Was ist dir an zwei Zeilen mit

DoCmd.RunSQL "create table " & mytable & "_Konto (Konto_MaDa long, " & _
"Konto_DATEV long, constraint _konto_pk primary key (Konto_MaDa));"

DoCmd.RunSQL "create unique index _konto_idx1 on " & mytable & _
"_Konto (konto_DATEV);"

eigentlich zu kompliziert?

Siegfried
Ahmed Martens
2013-04-13 20:11:03 UTC
Permalink
Post by Siegfried Schmidt
Post by Ahmed Martens
Damit umgehe ich jegliche Problemen.
Was ist dir an zwei Zeilen mit
DoCmd.RunSQL "create table " & mytable & "_Konto (Konto_MaDa long, " & _
"Konto_DATEV long, constraint _konto_pk primary key (Konto_MaDa));"
DoCmd.RunSQL "create unique index _konto_idx1 on " & mytable & _
"_Konto (konto_DATEV);"
eigentlich zu kompliziert?
Siegfried
Äh, gar nichts. Ich hatte es bisher nur mit der TableDefts-Auflistung
versucht.

Ich werde mir das ganze noch einmal in Ruhe anschauen.
In diesem speziellen Fall ist die Kopieraktion aber ausreichend, da max.
2-3 mal überhaupt eine Datei erstellt werden muss.

Aber für die Zukunft werde ich es einmal testen.

Noch einmal vielen Dank an alle.

Gruß Ahmed
--
Antworten bitte nur in der Newsgroup
Windows 7 64bit Home Premium
Office Prof. 2010
Wolfgang Badura
2013-04-14 11:56:03 UTC
Permalink
Hallo Ahmed!
Post by Ahmed Martens
Und das nicht nur wegen dem Wetter.
Irgendwie kommt mir
"wegen des Wettter" schon bald anachronistisch vor.
Dann müßte es auch bald "demwegen" heißen.

Oder steht das schon so im Duden.

Wolfgang
Claus Maier
2013-04-15 22:33:01 UTC
Permalink
Post by Wolfgang Badura
Hallo Ahmed!
Post by Ahmed Martens
Und das nicht nur wegen dem Wetter.
Irgendwie kommt mir
"wegen des Wettter" schon bald anachronistisch vor.
<klugscheiß>:
"wegen des Wetters"
</klugscheiß>
Post by Wolfgang Badura
Dann müßte es auch bald "demwegen" heißen.
Bestimmt nicht. Selbst auf hessisch sagt man: "desdeweesche".
Post by Wolfgang Badura
Oder steht das schon so im Duden.
Dem würde ich das zutrauen.

mfg
Claus
Wolfgang Badura
2013-04-16 09:03:02 UTC
Permalink
Hallo Claus!
Post by Claus Maier
"wegen des Wetters"
</klugscheiß>
Passiert einem immer dann, wenn man klüger sein will.
Post by Claus Maier
Post by Wolfgang Badura
Oder steht das schon so im Duden.
Dem würde ich das zutrauen.
Es steht dort tatsächlich als "umgangssprachlich auch mit Dativ"!
Es muß etwas nur lang genug falsch gesagt oder geschrieben werden
bis deren "Experten" es als Regel formulieren.

Wolfgang
Claus Maier
2013-04-16 21:00:13 UTC
Permalink
Post by Wolfgang Badura
Hallo Claus!
Post by Claus Maier
"wegen des Wetters"
</klugscheiß>
Passiert einem immer dann, wenn man klüger sein will.
Post by Claus Maier
Post by Wolfgang Badura
Oder steht das schon so im Duden.
Dem würde ich das zutrauen.
Es steht dort tatsächlich als "umgangssprachlich auch mit Dativ"!
Es muß etwas nur lang genug falsch gesagt oder geschrieben werden
bis deren "Experten" es als Regel formulieren.
Aha. Ich hatte es befürchtet.
Mein: "Dem (Duden) würde ich das zutrauen" war garnicht ernst gemeint.
Nun bin ich von der Realität[tm] überholt worden.
Gut, ich verstehe endlich, was mit "Sprachen sind immer in Bewegung,
sie verändern sich ständig" u.ä. Statements gemeint ist.
Traurig, aber wohl Tatsache:
Nicht etwa Lautverschiebungen, Bedeutungs-Änderung/-wechsel von Worten
u.ä., was Heere von Linguisten in schlaflosen Nächten zu erforschen sich
bemühen, machen den Großteil der sprachlichen Änderungen aus.
Nein, es sind die sprachinkompetenten Deppen, die langfristig bestimmen,
wie wir reden.

Nun aber genug davon, es ist hier OT.

mfg
Claus

Loading...