PDA

Vollständige Version anzeigen : Berechtigung für Tabellen einbinden


Kai W.
25.09.2003, 09:46
FAQ DonKarl 3.1 (http://www.donkarl.com/FAQ/FAQ3TAbfragen.htm#3.1)

Hallo zusammen,

ich habe den folgenden Code von donkarl bei mir ins Startformular unterm Ereignis "Beim Öffnen" eingetragen.


Dim db As DAO.Database
Dim Daten As String
Dim i as Integer

On Error GoTo FehlerMeldung

Set db = CurrentDB()

Daten = Left(db.Name, Len(db.Name) - Len(Dir(db.Name))) & "DeineDaten.mdb"

For i = 0 To db.TableDefs.Count - 1
If db.TableDefs(i).Connect <> "" Then
If Mid(db.TableDefs(i).Connect, 11) <> Daten Then
db.TableDefs(i).Connect = ";database=" & Daten
db.TableDefs(i).RefreshLink
End If
End If
Next i

Exit Sub

FehlerMeldung:
MsgBox "Bei der Installation ist ein Fehler aufgetreten. ", 16, "FEHLER !"
Exit Sub

Es funktioniert auch wunderbar bei mir als admin. Beim user hingegen bekomme ich eine Fehlermeldung. Daher meine Frage:

WELCHE RECHTE MUSS ICH DEM USER DAFÜR (SCHÄTZUNGSWEISE AUF DIE TABELLEN) GEBEN???


Gruß, Kai

Johnny Loser
25.09.2003, 10:18
Hi Kai,

ich habe es bei mir so gelöst, daß ich einen neuen Arbeitsbereich erstelle und über diesen meine Tabellen neu verknüpfe.

In globalem Modul
Public OwnerJet As Workspace 'Variable für Owner-Arbeitsbereich
Public OwnerDb As Database 'Variable für Datenbank mit Owner-Rechten
In der Funktion bei Initialisierung der Datenbank:
Set OwnerJet = DBEngine.CreateWorkspace("OwnerRights", "DeinAdminName", "DeinAdminPasswort", dbUseJet)
Workspaces.Append OwnerJet
Set OwnerDb = OwnerJet.OpenDatabase(DatenbankPfad & DatenbankName)

'danach mit OwnerDb.TableDef.... die Verknüpfungen vornehmen

Einziges Problem bei mir ist, daß die Tabellenverknüpfung mittels VBA mit .Connect und .Refresh nur in der MDB, aber nicht in der MDE funktioniert. Selbst, wenn ich als Administrator eingeloggt bin. Über Menü funktioniert die Neu-Verknüpfung in der MDE allerdings einwandfrei.

Kai W.
25.09.2003, 11:06
Hi Johnny,

zunächst vielen Dank für die Antwort. Vielleicht können wir da ja ansetzen...(für VBA-Dummies).


Set OwnerJet = DBEngine.CreateWorkspace("OwnerRights", "DeinAdminName", "DeinAdminPasswort", dbUseJet)
Workspaces.Append OwnerJet
Set OwnerDb = OwnerJet.OpenDatabase(DatenbankPfad & DatenbankName) 'Muss ich hier ein festen Pfadnamen eintragen???
Den habe ich ja gerade nicht.

'danach mit OwnerDb.TableDef.... die Verknüpfungen vornehmen

bloß wie? :confused: Kannst Du es mir evtl. posten

Gruß, Kai

PS: Das Problem der mde stellt sich für mich nicht, da ich keinen Code zu schützen habe...

Johnny Loser
25.09.2003, 13:28
Hi Kai,

o.k., das mit DatenbankPfad & Name kann man geschmeidiger lösen:

Set OwnerDb = OwnerJet.OpenDatabase(CurrentDb.Name)
Danach die Einbindung wiefolgt vornehmen, wobei die Datei- und Tabellennamen von Dir zugewiesen werden müssen.

Dim NewTblName As String
Dim SrcTblName As String
Dim SrcDbName As String
Dim td As TableDef

'NewTblName zuweisen
'SrcTblName zuweisen
'SrcDbName zuweisen

Set td = OwnerDb.CreateTableDef(NewTblName)
td.Connect = ";Database=" & SrcDbName
td.SourceTableName = SrcTblName
OwnerDb.TableDefs.Append td

Kai W.
26.09.2003, 12:55
Hi Johnny (und natürlich auch alle anderen im Forum),

langsam macht mir das hier keinen Spaß mehr :bawling:

Wenn ich die erste Anweisung in einem Modul als Public Function einfüge, kriege ich beim Kompilieren die Fehlermeldung "Variable nicht definiert" für OwnerJet. Meine Suche zu 'Owner Jet' in der OLH brachte den nächsten Fehler ('Hilfedatei 129 nicht vorhanden...) :redface:
Ich habe mittlerweile die Lösung zum Einbinden der Tabellen aus der KnowHow-DB von Klaus Oberdalhoff bei mir eingebaut, aber auch die funktioniert anscheinend auch nur mit Owner-Status.

Beim Googlen habe auch nix Brauchbares zum Problem OwnerJet gefunden, und so steh ich fast unverrichteter Dinge wieder hier.

1. Warum diese Fehlermeldung? Ist das keine allgemeine Anweisung? Habe VBA, MS Access Object Library 8.0 und MS DAO 3.51 installiert

2. Wenn es denn funktionierte, würde ich über das autoexec- Makro erst die Prozedur zum "Owner-Status herstellen" (Johnny's Code) aufrufen und dann das Verbinden-Modul ausführen. Dann muss ich aber doch danach wieder zum User-Status zurück??? Oder kann ich die Owner-Anweisung auch nur für das eine Modul setzen???

Gruß, Kai

Johnny Loser
26.09.2003, 16:41
Hi Kai,

OwnerJet ist eine von mir gewählte Variable, die im Deklarationsbereich eines Moduls deklariert werden muß.

Die Verweise sind o.k.

Erstelle mal ein neues Modul und kopiere den ganzen Code hinein. Danach kannst Du mit "Testen und kompilieren" prüfen, ob eine Fehlermeldung kommt, sollte nicht, es sei denn Du hast noch Fragmente von Deinen Versuchen in der DB.

Die Funktion fncInit kannst Du über ein AutoExec-Makro aufrufen.

Option Compare Database
Option Explicit

Public OwnerJet As Workspace 'Variable für Owner-Arbeitsbereich
Public OwnerDb As Database 'Variable für Datenbank mit Owner-Rechten

Public Function fncInit()
Dim NewTblName As String
Dim SrcTblName As String
Dim SrcDbName As String
Dim td As TableDef

Set OwnerJet = DBEngine.CreateWorkspace("OwnerRights", "DeinAdminName", "DeinAdminPasswort", dbUseJet)
Workspaces.Append OwnerJet
Set OwnerDb = OwnerJet.OpenDatabase(CurrentDb.Name)

'NewTblName zuweisen
'SrcTblName zuweisen
'SrcDbName zuweisen

Set td = OwnerDb.CreateTableDef(NewTblName)
td.Connect = ";Database=" & SrcDbName
td.SourceTableName = SrcTblName
OwnerDb.TableDefs.Append td

End Function

Die Variablen kannst Du nach der Zuweisung auf Nothing setzen, falls Du sie nicht weiterhin in Deiner Anwendung benötigst.

Der angemeldete User erhält durch diesen zusätzlichen WorkSpace nicht mehr Rechte, als er per Berechtigungszuordnung von Dir bekommen hat.

Kai W.
29.09.2003, 11:36
Hi Johnny,

Deine Hilfe trägt so langsam Früchte! Vielen Dank!

Ich habe tatsächlich noch "Modulreste" gefunden. Seit ich die entfernt habe, läuft das Modul.

Es ergeben sich aus Deiner Lösung noch zwei Fragen:

1. Das Modul sucht im Standarddatenbankverzeichnis. Das kann ich nicht beeinflussen bzw. der DAU vom Dienst kann es ja ohne weiteres ändern und dann fängt das Spiel von vorne an. "Der geht nicht..." Stattdessen das Verzeichnis der Programmdatenbank zu durchsuchen würde mir enorm weiterhelfen... Und ich verspreche, als Nächstes bringe ich mir VB(A) bei ;)

Kann man also so etwas in der Art wie bei donkarl (http://www.donkarl.com/FAQ/FAQ3TAbfragen.htm#3.1) noch einbauen? ...
Dim Daten As String
.
.
Daten = Left(db.Name, Len(db.Name) - Len(Dir(db.Name))) & "DeineDaten.mdb"
...


2. Dein Modul prüft nicht, ob schon vorhandene Tabellenverknüpfungen funktionieren. Ich könnte natürlich die Programmdatenbank "nackt" lassen, und erst beim Öffnen die Tabellenverknüpfung herstellen lassen. Wenn ich das jetzt mit dem Modul aus der KnowHow-DB mische:
Option Compare Database
Option Explicit

Public OwnerJet As Workspace 'Variable für Owner-Arbeitsbereich
Public OwnerDb As Database 'Variable für Datenbank mit Owner-Rechten

Function checkconnect()
'Überprüft, ob die Datenbank verbunden sind
Dim DB As DATABASE
Dim tbl As Recordset
Dim Nix
' ??? muss ich doch bestimmt auch hier einbinden ???
Set OwnerJet = DBEngine.CreateWorkspace ("OwnerRights", "DeinAdminName", "DeinAdminPasswort", dbUseJet)
Workspaces.Append OwnerJet
Set OwnerDb = OwnerJet.OpenDatabase(CurrentDb.Name)

On Error GoTo checkconnectError
Set DB = DBEngine.Workspaces(0).Databases(0)

' Hier einen existierenden Tabellennamen eingeben
' Es wird davon ausgegangen, daß wenn diese Tabelle nicht korrekt connected ist,
' die anderen Tabellen auch nicht korrekt connected sind.

Set tbl = DB.OpenRecordset("tblBeispiel")

Exit Function

checkconnectError:
'Verbindung aufbauen
Nix = switchConnect() 'stattdessen nehme ich jetzt fncInit()

Exit Function

End Function

Public Function fncInit()
Dim NewTblName As String
Dim SrcTblName As String
Dim SrcDbName As String
Dim td As TableDef

Set OwnerJet = DBEngine.CreateWorkspace("OwnerRights", "DeinAdminName", "DeinAdminPasswort", dbUseJet)
Workspaces.Append OwnerJet
Set OwnerDb = OwnerJet.OpenDatabase(CurrentDb.Name)

'NewTblName zuweisen
'SrcTblName zuweisen
'SrcDbName zuweisen

Set td = OwnerDb.CreateTableDef(NewTblName)
td.Connect = ";Database=" & SrcDbName
td.SourceTableName = SrcTblName
OwnerDb.TableDefs.Append td

End Function


Vielen Dank für die bisherige Unterstützung, wenn das noch klappt, schlage ich Dich für den Forums-Oscar vor...

Gruß, Kai

--- UPDATE ---

Das Einbinden von "checkconnect" scheint so zu funktionieren, wie ich mir das gedacht habe. Allerdings bekomme ich noch den Fehler "Tabelle schon vorhanden" in der zweiten Funktion, sprich diese verbindet die Tabelle nicht neu, obwohl Funktion 1 bereits gemerkt hat, dass die alte Verknüpfung nicht mehr funktioniert. Kann ich für den Fall, dass die Verknüpfung nicht mehr funktioniert nicht zunächst alle verknüpften Tabellen löschen lassen???

Kai W.
06.10.2003, 13:17
Ein letzter Dank an Johnny & donkarl :10points: , und dann noch die abschließende Lösung. Das Wieder-Einbinden der Tabllen funktioniert jetzt einwandfrei auch ohne Admin-Rechte sobald die Daten.mdb im gleichen Verzeichnis liegt. Bei erstmaligem Einbinden der Tabellen gilt natürlich Johhny's Lösung s.o....


Option Compare Database
Option Explicit

Public OwnerJet As Workspace 'Variable für Owner-Arbeitsbereich
Public OwnerDb As Database 'Variable für Datenbank mit Owner-Rechten

Public Function TblEinbinden()

Dim db As DAO.Database
Dim Daten As String
Dim i As Integer

Set OwnerJet = DBEngine.CreateWorkspace("OwnerRights", "DeinOwner", "DeinPwd", dbUseJet)
Workspaces.Append OwnerJet
Set OwnerDb = OwnerJet.OpenDatabase(CurrentDb.Name)

On Error GoTo FehlerMeldung

Set db = CurrentDb()

Daten = Left(db.Name, Len(db.Name) - Len(Dir(db.Name))) & "DeineDaten.mdb"

For i = 0 To db.TableDefs.count - 1
If db.TableDefs(i).Connect <> "" Then
If Mid(db.TableDefs(i).Connect, 11) <> Daten Then
db.TableDefs(i).Connect = ";database=" & Daten
db.TableDefs(i).RefreshLink
End If
End If
Next i

Exit Function

FehlerMeldung:
MsgBox "Bei der Installation ist ein Fehler aufgetreten. ", 16, "FEHLER !"
Exit Function
End Function

Gruß, Kai

Robert Briggen
12.11.2003, 13:01
Hallo zusammen

Ich habe dasselbe Problem wie Kai und habe mich schon gefreut, die Lösung gefunden zu haben. Ich habe die Codezeiten von Johnny eingebaut, aber erhalte als User mit nur Leseberechtigung trotzdem noch die Meldung, dass ich keine Berechtigung hätte.

Mein Code:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre><span class="TOKEN">Option</span> <span class="TOKEN">Compare</span> <span class="TOKEN">Database</span>
<span class="TOKEN">Option</span> <span class="TOKEN">Explicit</span>
&nbsp;
<span class="TOKEN">Public</span> OwnerJet <span class="TOKEN">As</span> Workspace <span class="REM">'Variable f&uuml;r Owner-Arbeitsbereich</span>
<span class="TOKEN">Public</span> OwnerDb <span class="TOKEN">As</span> <span class="TOKEN">Database</span> <span class="REM">'Variable f&uuml;r Datenbank mit Owner-Rechten</span>
&nbsp;
<span class="TOKEN">Public Function</span> PlanungsphaseWechseln(Planungsjahr <span class="TOKEN">As</span> Integer, Phase <span class="TOKEN">As</span> <span class="TOKEN">Integer</span>)
<span class="TOKEN">Dim</span> dbs <span class="TOKEN">As</span> DAO.Database
<span class="TOKEN">Dim</span> Datenbank <span class="TOKEN">As</span> <span class="TOKEN">String</span>
<span class="TOKEN">Dim</span> Datenbank1 <span class="TOKEN">As</span> <span class="TOKEN">String</span>
<span class="TOKEN">Dim</span> PlanungsVJ <span class="TOKEN">As</span> <span class="TOKEN">Integer</span>
<span class="TOKEN">Dim</span> i <span class="TOKEN">As</span> <span class="TOKEN">Integer</span>
&nbsp;
DoCmd.Hourglass (<span class="TOKEN">True</span>)
&nbsp;
<span class="TOKEN">Set</span> OwnerJet = DBEngine.CreateWorkspace(&quot;OwnerRights&quot;, &quot;Briggen_R&quot;, &quot;1&quot;, dbUseJet)
Workspaces.Append OwnerJet
<span class="TOKEN">Set</span> OwnerDb = OwnerJet.OpenDatabase(CurrentDb.Name)
<span class="TOKEN">Set</span> dbs = CurrentDb
&nbsp;
PlanungsVJ = Planungsjahr - 1
&nbsp;
<span class="REM">'Pfad der Laufjahres-Datenbank bestimmen</span>
<span class="TOKEN">If</span> gfPlanPhase = &quot;RRA&quot; <span class="TOKEN">Then</span>
Datenbank = &quot;F:\SF DRS\Planung &quot; &amp; Planungsjahr &amp; &quot;.mdb&quot;
<span class="TOKEN">Else</span>
Datenbank = &quot;F:\SF DRS\Start &quot; &amp; Planungsjahr &amp; &quot;.mdb&quot;
<span class="TOKEN">End</span> <span class="TOKEN">If</span>
&nbsp;
<span class="REM">'Pfad der Vorjahres-Datenbank bestimmen</span>
Datenbank1 = &quot;F:\SF DRS\Start &quot; &amp; PlanungsVJ &amp; &quot;.mdb&quot;
&nbsp;
<span class="TOKEN">On Error GoTo</span> F1
&nbsp;
<span class="REM">'Tabellen einbinden</span>
<span class="TOKEN">For</span> i = 0 <span class="TOKEN">To</span> dbs.TableDefs.Count - 1
<span class="TOKEN">If</span> dbs.TableDefs(i).Connect &lt;&gt; &quot;&quot; <span class="TOKEN">And</span> dbs.TableDefs(i).Name &lt;&gt; &quot;Info von neuster Version&quot; <span class="TOKEN">And</span> dbs.TableDefs(i).Name &lt;&gt; &quot;Benutzer&quot; <span class="TOKEN">Then</span>
<span class="TOKEN">If</span> dbs.TableDefs(i).Name Like &quot;*1&quot; <span class="TOKEN">Then</span>
<span class="REM"> 'Vorjahrestabellen</span>
dbs.TableDefs(i).Connect = &quot;;database=&quot; &amp; Datenbank1
<span class="TOKEN">Else</span>
<span class="REM"> 'Laufjahrestabellen</span>
dbs.TableDefs(i).Connect = &quot;;database=&quot; &amp; Datenbank
<span class="TOKEN">End</span> <span class="TOKEN">If</span>
dbs.TableDefs(i).RefreshLink
<span class="TOKEN">End</span> <span class="TOKEN">If</span>
<span class="TOKEN">Next</span> i
&nbsp;
<span class="TOKEN">On Error GoTo 0</span>
DoCmd.Hourglass (<span class="TOKEN">False</span>)
MsgBox (&quot;Die Verkn&uuml;pfungen wurden Erfolgreich vorgenommen!&quot;), , gfTitel
Forms!switchboard.Refresh
<span class="TOKEN">Exit Function</span>
&nbsp;
F1: DoCmd.Hourglass (<span class="TOKEN">False</span>)
MsgBox Err.Description
&nbsp;
MsgBox (&quot;Die Datenbank &quot; &amp; Datenbank &amp; &quot; kann nicht gefunden werden!&quot;), , gfTitel
<span class="TOKEN">End</span> <span class="TOKEN">Function</span>
&nbsp;</pre></div>
Code eingefügt mit dem MOF Code Converter (http://www.ms-office-forum.net/forum/codeconverter.php)

Hat jemand einen Tipp, was ich falsch gemacht habe?

Besten Dank für die Hilfe und Gruss
Robert

Sascha Trowitzsch
12.11.2003, 13:41
Die vermeintlich funktionierende Lösung von Kai war ja auch Humbug!
Reiner Zufall, dass es funktioniert hat.

Bei ihm wie bei dir kommt die OwnerDB ja gar nicht zum Einsatz :confused:

Stattdessen nehmt ihr zum Neuverknüpfen wieder CurrentDB statt OwnerDB. ( Set dbs = CurrentDb )

Wenn du es mit: Set dbs = OwnerDB ersetzt, so könnte es laufen, wobei ich diesen Code nicht getestet hab und die Probleme bei mir auch noch nie aufgetaucht sind.

Der Code ist auch sonst nicht das Gelbe vom Ei, weil weder angelegtes Workspace noch geöffnete DB je wieder geschlossen oder abgebaut werden.

Ciao, Sascha

Robert Briggen
13.11.2003, 07:23
Hallo Sacha

Du hast mir geholfen. Jetzt funktionierts.

Da ich kein Crack bin, würde mich aber noch interessieren, was du mit deiner Bemerkung "Der Code ist auch sonst nicht das Gelbe vom Ei, weil weder angelegtes Workspace noch geöffnete DB je wieder geschlossen oder abgebaut werden" meinst.

Nochmals herzlichen Dank und Gruss
Robert

Johnny Loser
13.11.2003, 08:30
Der Code ist auch sonst nicht das Gelbe vom Ei, weil weder angelegtes Workspace noch geöffnete DB je wieder geschlossen oder abgebaut werden
OK! Wenn der Workspace in der Anwendung nicht weiter benötigt wird, sollte man diesen schließen.

Set OwnerDb = Nothing
Set OwnerJet = Nothing
OwnerDb.Close
OwnerJet.Close
Bei mir ist es so, daß ich mehrere Tabellen unterschiedlicher Datenbanken einbinde, die ich während der ganzen Anwendung benötige. Auf diese Tabellen hat kein User auch nur eine Leseberechtigung. Durch den zweiten Workspace ermögliche ich es dem User, in Formularen einzelne Datensätze zu lesen und zu editieren. Aus diesem Grund bleibt der Workspace bis zum Schließen der Anwendung erhalten.


@Sascha

Die Aussage "...auch sonst nicht das Gelbe vom Ei..." würde ich gerne näher erläutert bekommen.
Bezieht sich diese nur auf das Löschen der Objekt-Variablen oder gibt es einfachere, bessere oder sinnvollere Methoden?
Ich lerne ja auch gerne dazu...

Und nebenbei: Gibt es auch eine Möglichkeit, Tabellen einer externen Access-Datenbank zu lesen, wenn diese Datenbank auf einer anderen Arbeitsgruppendatei basiert, sprich weder Admin noch Eigentümer in der aktuellen Arbeitsgruppendatei existieren?

Sascha Trowitzsch
13.11.2003, 11:15
Herrje, das war kurz mal so dahin gesagt gewesen... und hat sich tatsächlich im Wesentlichen auf die geöffneten Objekte bezogen. Sorry!

Übrigens sollte das so aussehen:

OwnerDb.Close
OwnerJet.Close
Set OwnerDb = Nothing
Set OwnerJet = Nothing

(.Close und Nthing verdreht; wenn eine Objektvariable auf nothing gesetzt wird, so kann man keine Methode mehr ausführen, außer sie wurde mit New deklariert. In diesem Fall hat es aber dann den gegenteiligen Effekt und das Ausführen irgendeiner Methode oder Auslesen einer Eigenschaft führt dazu, dass das Objekt neu erzeugt wird!)

Ich stolpere auch über den Bezeichner OwnerJet; dahinter würde ich eine JetEngine vermuten, kein Workspace. (Ich würde es z.B. wrkOwner nennen, die Database dbsOwner.) Aber das ist ja nur kosmetisch.

Und nebenbei: Gibt es auch eine Möglichkeit, Tabellen einer externen Access-Datenbank zu lesen, wenn diese Datenbank auf einer anderen Arbeitsgruppendatei basiert, sprich weder Admin noch Eigentümer in der aktuellen Arbeitsgruppendatei existieren?

Ja, auch das. Dazu ist ein weiterer Schritt nötig. Die SystemMDW ist ja eine Eigenschaft der DBEngine. Folglich muss sie auf dort gesetzt werden - es muss also eine zweite erezugt werden. Dies geschieht mit dem "undokumentierten" Objekt PrivDBEngine von DAO:

Dim PrvEng As DAO.PrivDBEngine, wrk As Workspace

Set PrvEng = New PrivDBEngine
PrvEnd.SystemDB = "c:\meine.mdw"
Set wrk = PrvEng.CreateWorkSpace("OwnerRights", "DeinAdminName", "DeinAdminPasswort", dbUseJet)
....
wrk.Close
Set wrk = Nothing
Set PrvEng = Nothing

Ciao, Sascha

Johnny Loser
13.11.2003, 11:55
Hi Sascha,

danke erstmal für die Info. Werde es aber erst nach meinem Urlaub ausprobieren können.

P.S.: Nothing <-> Close: Logisch, mein Kopierfehler