VBA Code um dynamisches Speicherpfad zu ermitteln

BomberHarry

Enthusiast
Thread Starter
Mitglied seit
04.01.2011
Beiträge
301
Hallo zusammen,
ich habe bisher kleinere Ergänzungen eines VBA Projektes hinzugefügt, doch tiefer hört es dann auch auf.

Ich möchte, z. B. unter dem Laufwerk K: immer den ersten Ordner (für den User gibt nur einen, können aber durch Gruppenmitgliedschaft dynamisch angezeigt und berechtigt werden) ermitteln und dahinter noch eine zu öffnende Datei dazugeben, da diese immer gleich heißt.

In der Vergangenheit habe ich bereits etwas rumexperementiert und es nicht hinbekommen.

bisher Set Db = OpenDatabase(Name:="K:\Datei.mdb")

Beispiele (NEU):
K:\1000\Datei.mdb
K:\2500\Datei.mdb
K:\2650\Datei.mdb


"öffne" K: + "<dynamisch>" + Datei.mdb
 
Zuletzt bearbeitet:
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Code:
    Dim objFSO As Object
    Dim objFolder As Object
    Dim objSubFolder As Object
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder("K:\")
    
    For Each objSubFolder In objFolder.subfolders
        Debug.Print objSubFolder.Name
    Next objSubFolder

zeigt dir alle Subfolders aus dem Laufwerk K:\ an -> dann pickst du dir einfach den raus, den du brauchst bzw. den, der für dich relevant ist und hängst hinten deinen Filename dran -> und hast damit effektiv den kompletten Pfad.
Bedenke, es ist nicht zwangsweise so, dass du den ersten Ordner nutzen können wirst. Bspw. wenn es einen "$Recycle.Bin" als versteckten Ordner gibt ;) -> der steht dann halt trotzdem als ersten Ordner ganz oben. Deswegen solltest du aus meiner Sicht alle relevanten Ordner im Pfad durchbrowsen und dann den für dich relevanten Ordner dort rauspicken...
 
müsste ich es dann so machen? Es ist anhand von Berechtigungen ausgeschlossen, dass es mehr als ein Ordner geben kann.

Code:
    Dim objFSO As Object
    Dim objFolder As Object
    Dim objSubFolder As Object
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder("K:\")
    
    For Each objSubFolder In objFolder.subfolders
        Debug.Print objSubFolder.Name
    Next objSubFolder

Set Db = OpenDatabase(Name:="K:\" + "objSubFolder.Name" + "Datei.mdb")

Die Debug.Print objSubFolder.Name kann man bestimmt auskommentieren?
 
Zuletzt bearbeitet:
Jop, kannst Du. Debug.Print gibt einen Wert im Direktfenster aus, hat für die Funktionalität keine Relevanz.
 
Die Schleife (For Each) durchläuft jeden Ordner auf der Platte ausgehend von der Root, die du dort angibst (K:\). Kommt halt immer drauf an, in welchem Userkontext und damit mit welcher Berechtigung da agiert wird.
Sprich du solltest also in der Schleife -> dort wo jetzt debug.print erfolgt, den Ordner sichern, den Namen speichern oder was auch immer du damit vor hast.
Wenn du aber schreibst, dass es maximal zwei Ordner sein können, muss natürlich auch noch definiert werden, dass er den richtigen Ordner nimmt. Zweimal Set DB... zu machen wäre sinnfrei, weil der zweite Durchlaut den ersten überschreiben würde...

Kurzum, du benötigst noch irgendwie ein Kriterium, damit der Code zweifelsfrei nur einen Ordner zurück bekommt. Heist also, eine Logik, die erkennt, welcher der Ordnernamen dort nun verwendet werden sollen, wenn mehrere zurück kommen. -> und sowas wie versteckte Ordner oder Ordner, wo nur lesend zugegriffen wird, müsstest du auch noch abfangen.

In "objSubFolder.Path" steht der vollständige Pfad. Dort dahinter hängst du dann nur noch deinen Dateinamen an.
Die Set DB Zeile müsste dann also eher so lauten:
Code:
Set Db = OpenDatabase(Name:=objSubFolder.Path + "\Datei.mdb")
Zumindest wenn du es IN der Schleife verwendest. Ansonsten könntest du bspw. dir einfach den Pfad des Ordners in eine Variable speichern und dann anstatt direkt von objSubFolder.Path + "\Datei.mdb" die Variable dafür nutzen...
 
Sorry, hatte es oben falsch erläutert, denn es ist ausgeschlossen, dass es mehr als einen Ordner geben kann :)

Mir fällt gerade noch ein, dass es glaube ich noch wichtig war und der VBA Code weiß, dass der Ordner und die Datei alle unsichtbar sind. Denn dies ist für die User unsichtbar, damit sie da nicht einfach so reinschauen, wird aber dennoch für eine Funktion benötigt, weil er daraus auswählbare Werte in ein Dokument übertragen soll.
 
Ob sichtbar oder nicht, sollte keinen Unterschied machen -> es sei denn, ihr habt das durch falsche NTFS Berechtigungen gelöst -> sprich wenn unsichtbar heist, keine Rechte, dann kannst du da mit Code auch nix ändern.

Wenn die Schleife nur einen Ordner sehen wird/kann, dann läuft sie auch nur 1x mal. Du kannst also wie oben erwähnt entweder in diesem einen Durchlauf den Namen in eine Variable schreiben oder gleich dein Set DB whatever machen...
 
Ich möchte das Thema nochmal aufgreifen.

Momentan habe ich Probleme, die den Pfad bzw OpenDatabase aufzurufen. Ich erhalte die Fehlermeldung "Laufzeitfehler '91' - Objektvariable oder With-Blockvariable nicht festgelegt" Wenn ich danach google, dann sagt mir Beschreibung bei MS absolut garnichts. Es muss irgendwo bei dem grünmarkierten Code liegen, da es ohne diesen Code und wenn ich den Pfad bei OpenDatabase manuell reinschreibe funktioniert.

Im Visual Basic Express funktioniert der Einzelaufruf, jedoch noch in Excel (VBA).

Jemand eine Idee?


Code:
Private Sub UserForm_Initialize()

[COLOR="#008000"]    Dim objFSO As Object
    Dim objFolder As Object
    Dim objSubFolder As Object
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder("K:\")
    
    For Each objSubFolder In objFolder.subfolders
        Debug.Print objSubFolder.Name
    Next objSubFolder[/COLOR]

Set Db = OpenDatabase(Name:=objSubFolder.Path + "\Datei.mdb")

End Sub
 
Schuss ins Blaue:
Was passiert wenn du objSubFolder vor der Schleife mit Set einen Wert zuweist? Bei den anderen Variablen machst du das ja...
Ich erinnere mich dunkel an meine VBA Vergangenheit und daran, das ich ohne Set fast immer Ärger an der Backe hatte.
 
Wenn ich Set objSubFolder vor die Schleife baue, dann erscheint weiterhin die selbe Meldung im VBA.

Wobei ich in VB2010 Exprees die Meldung erhalte:
Warnung 1 Die objSubFolder-Variable wird verwendet, bevor ihr ein Wert zugewiesen wird. Zur Laufzeit kann eine Nullverweisausnahme auftreten

EDIT: Problem gelöst, im Projekt war die "Microsoft Scripting Runtime" nicht aktiviert.
 
Zuletzt bearbeitet:
Code:
Private Sub UserForm_Initialize()

[COLOR="#008000"]    Dim objFSO As Object
    Dim objFolder As Object
    Dim objSubFolder As Object
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder("K:\")
    
    For Each objSubFolder In objFolder.subfolders
        Debug.Print objSubFolder.Name
    Next objSubFolder[/COLOR]

Set Db = OpenDatabase(Name:=objSubFolder.Path + "\Datei.mdb")

End Sub

Disclaimer: ich kann eigtl. gar kein VBA.

kurze Antwort: Der Fehler scheint zu bemängeln dass eine Variable unter Umständen nicht gesetzt ist
lange Antwort:
Ich sehe keinen Fehler den ein Compiler direkt anmängeln sollte, aber trotzdem erklär ich mal was mit dem Code an sich falsch ist....
Dein For Each macht im Prinzip nichts:
For Each iteriert über eine Liste/ein Array o.ä. und tut etwas in jedem Schleifendurchlauf. In diesem Fall macht er nichts anderes ausser den Namen des Verzeichnisses auszugeben.
Im Endeffekt dient dein For Each also quasi nur dazu, die Variable "objSubFolder" zu befüllen.
Ich erklärs nochmal weil ich vermute dass du nicht weißt was der Code macht:
Code:
For Each objSubFolder In objFolder.subfolders
Hier ist objFolder ein Objekt das Informationen über ein Verzeichnis enthält (beispielsweise den Pfad, die enthaltenen Dateien etc.). objFolder.subfolders ist eine Liste aller Unterverzeichnisse. Über Listen kann man auf verschiedene Weisen iterieren, eine davon ist eben das For Each. Bei einer For Each Schleife wird für jeden Schleifendurchlauf ein Element der Liste in eine Variable gespeichert:
Code:
For Each <ELEMENT> In <LISTE>
Stell dir eine Liste mit den Zahlen 1 bis 10 vor... Dann wäre in der Variable <ELEMENT> beim ersten Schleifendurchlauf eine 1 gespeichert, beim zweiten eine 2 etc.
Genauso bei dir mit den Verzeichnisnamen.
Da die Variable objSubFolder vorher deklariert wurde (bin mir nicht sicher ob das in VB pflicht ist oder nicht, in den meisten anderen Programmiersprachen ist es das nicht und könnte u.U. zu Fehlern führen), iteriert er über die Liste, speichert jeweils das subfolder Objekt in objSubFolder und gibt den Namen auf der Debugkonsole aus. D.h. wenn du OpenDatabase aufrufst ist in objSubFolder immer der "letzte" Verzeichnisname gespeichert. Wäre ja kein Problem eigentlich, schließlich hast du gesagt es kann nur ein Verzeichnis geben...
Was aber wenn es KEIN verzeichnis gibt? Dann fliegt dir der Code nämlich um die Ohren (dein For Each läuft nie an, über eine leere Liste muss ich nicht iterieren, die Variable objSubFolder wird nie gefüllt).
Zumal es natürlich auch overkill ist... stell dir vor es hat 1000 Unterverzeichnisse und du willst immer das letzte (oder das erste, oder ein bestimmtes... ist egal). Würdest du tatsächlich JEDES Verzeichnis angucken? Die gesamte Liste? Oder würdest du dir das Verzeichnis raussuchen das du willst?
ein "Set objSubFolder = objFolder.subfolders(0)" würde z.B. auch machen was du willst (auch hier mit der Gefahr dass dir alles um die Ohren fliegt wenn es keine Unterverzeichnisse gibt).

Richtigerweise müsstest du also etwas in dieser Art programmieren (Pseudocode):
Code:
Wenn Verzeichnisliste.Anzahl ungleich 0
   Datenbank öffnen mit erstem Element der Verzeichnisliste
 
Zuletzt bearbeitet:
Dein For Each macht im Prinzip nichts:

Richtig... denn er hat einfach nicht das gemacht, was oben dazu schon geschrieben stand ;)
"zeigt dir alle Subfolders aus dem Laufwerk K:\ an -> dann pickst du dir einfach den raus, den du brauchst bzw. den, der für dich relevant ist und hängst hinten deinen Filename dran -> und hast damit effektiv den kompletten Pfad.
Bedenke, es ist nicht zwangsweise so, dass du den ersten Ordner nutzen können wirst. Bspw. wenn es einen "$Recycle.Bin" als versteckten Ordner gibt -> der steht dann halt trotzdem als ersten Ordner ganz oben. Deswegen solltest du aus meiner Sicht alle relevanten Ordner im Pfad durchbrowsen und dann den für dich relevanten Ordner dort rauspicken...
"

Das war eigentlich der Part um den es ging...
Die Schleife durchläuft einfach alle gefundenen Ordner im Pfad -> und der TE müsste im Endeffekt nun nur noch IN der Schleife die/eine Prüfung auf den für ihn relevanten Ordner machen und dort den Dateinamen dran hängen, da wie ich oben schon erwähnt habe, nicht zwangsweise der erste Ordner der richtige sein MUSS.

"objSubFolder.Path" außerhalb der Schleife zu nutzen ist halt irgendwie nicht zielführend... :wink:
 
Hatte gestern meinen obigen Post ergänzt :) Möchte mich trotzdem für die Mühe bei euch bedanken :)

>>EDIT: Problem gelöst, im Projekt war die "Microsoft Scripting Runtime" nicht aktiviert.<<
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh