Dynamisches Speichern?

Hallo zusammen!

Ich habe ein Problem, das ich alleine nicht lösen kann. Vielleicht kann mir jemand helfen.

Ich habe ein EXCEL-Tabellenblatt (es handelt sich um eine Art Startmaske), von dem ich über eine User-Form auf (je nach Auswahl) verschiedene andere EXCEL-Dateien zugreifen kann. Dies funktioniert bisher, weil ich den Pfad der entsprechenden Dateien in VBA (User-Form) hinterlegt habe.

Jetzt die Problemstellung:
Die Original-Startmaske und die anderen Original-EXCEL-Dateien sollen zentral auf einem Speicherplatz hinterlegt werden. Jeder User kann sich diese Dateien kopiern, auf sein individuelles Laufwerk ablegen und soll von dort aus in der Lage sein, über die Startmaske die anderen Datein öffnen zu können. Da sich aber die Pfade der ursprünglichen Dateien von der Kopie unterscheiden, funktioniert das ganze nicht. Gibt es in EXCEL oder VBA eine Möglichkeite diese zu realisieren?

Vielen Dank im Voraus
Gruß Matthias

Hallo,

ich bin nicht sicher, ob ich Dich richtig verstanden habe.

Du möchtest dem Anwender die Möglichkeit geben, den Pfad zum Dokument selbst zu suchen?

In Excel unter Extras findest Du den Eintrag: ‚Weitere Steuerelemente‘ und dort in der Liste: ‚Microsoft Common Dilalog Control …‘. Das ist der Dateiexplorer von Windows, den Du verwenden kannst.

Gruß, Rainer

Hallo Matthias

Die Original-Startmaske und die anderen Original-EXCEL-Dateien
sollen zentral auf einem Speicherplatz hinterlegt werden.
Jeder User kann sich diese Dateien kopiern, auf sein
individuelles Laufwerk ablegen und soll von dort aus in der
Lage sein, über die Startmaske die anderen Datein öffnen zu
können. Da sich aber die Pfade der ursprünglichen Dateien von
der Kopie unterscheiden, funktioniert das ganze nicht. Gibt es
in EXCEL oder VBA eine Möglichkeite diese zu realisieren?

Wenn er nur die „Startdatei“ kopiert sollte ja alles klappen, da die Pfade dann noch stimmen würden. Ich gehe daher davon aus, dass alles kopiert wird.

Dann würde ich versuchen mit relativen Pfade zu arbeiten:

..\einOrdner\meinSheet.xls

Wenn du deine function für das Öffnen hats könnte diese auch den Pfad „zusammensetzen“:

ActiveWorkbook.Path + "\..\einOrdner\meinSheet.xls"

mfg

Dirk.Pegasus

Ich habe ein EXCEL-Tabellenblatt (es handelt sich um eine Art
Startmaske), von dem ich über eine User-Form auf (je nach
Auswahl) verschiedene andere EXCEL-Dateien zugreifen kann.
Dies funktioniert bisher, weil ich den Pfad der entsprechenden
Dateien in VBA (User-Form) hinterlegt habe.

Jetzt die Problemstellung:
Die Original-Startmaske und die anderen Original-EXCEL-Dateien
sollen zentral auf einem Speicherplatz hinterlegt werden.
Jeder User kann sich diese Dateien kopiern, auf sein
individuelles Laufwerk ablegen und soll von dort aus in der
Lage sein, über die Startmaske die anderen Datein öffnen zu
können. Da sich aber die Pfade der ursprünglichen Dateien von
der Kopie unterscheiden, funktioniert das ganze nicht. Gibt es
in EXCEL oder VBA eine Möglichkeite diese zu realisieren?

Hi Matthias,
du erfährst doch z.B. mit

Sub tt()
MsgBox ThisWorkbook.Path
'MsgBox ThisWorkbook.FullName
End Sub

innerhalb der Masterdatei wo diese abgelegt ist, wenn da die anderen Dateien auch sind ist das Problem doch gelöst, wenn du im Code der UF keine direkten Pfade sondern Pfade via ThisWorkbook.Path vorgibst.

Klappt logischerweise nur, wenn die Dateien schon mind. einmal gespeichert wurden.

Gruß
Reinhard

Hallo zusammen,

Danke für die Vorschläge. Leider sind meine VBA-Kenntnisse nicht so gut, dass ich die Tipps auch umsetzen könnte. Habe mich für eine Abfrage des Speicherpfades nach dem Starten der START-Datei in einer TextBox, die in einer UserForm integriert ist, entschieden. Voraussetzung ist natürlich, dass die Dateien bereits einmal gespeichert wurden.

Jetzt müsste doch der Wert der TextBox ausgelesen werden
(" x = textbox1.value ") und als Variable in den Modulen, die auf die Datei zugreifen, hinterlegt werden!?

Bisher sind meine Module so aufgebaut:

Sub DateiStrom()
Const Lw = „K:“
Const Pfad = „K:\Eigene_Dateien“
Const DateiStromGK = „Strom.xls“

ChDrive Lw
ChDir Pfad
On Error Resume Next
Workbooks.Open DateiStrom
End Sub

Für mich stellt sich nun die Frage, wie ich die Variable x (siehe oben) wie gewünscht einbauen kann.

Vielen Dank im Voraus

Hallo Matthias,

Leider sind meine VBA-Kenntnisse
nicht so gut

meine leider auch nicht. :frowning: Ich kann Dir nur da weiter helfen, wo VBA meinem VB6 zu ähneln scheint. Vieles ist ja zum Glück identisch.

Jetzt müsste doch der Wert der TextBox ausgelesen werden
(" x = textbox1.value ") und als Variable in den Modulen, die
auf die Datei zugreifen, hinterlegt werden!?

Bisher sind meine Module so aufgebaut:

Sub DateiStrom()
Const Lw = „K:“
Const Pfad = „K:\Eigene_Dateien“
Const DateiStromGK = „Strom.xls“

ChDrive Lw
ChDir Pfad
On Error Resume Next
Workbooks.Open DateiStrom
End Sub

da gefällt mir eine Kleinigkeit nicht und die bereitet Dir auch Probleme. Warum hast Du Konstanten verwendet und keine Variablen? Ich vermute mal, weil Du es nicht besser wusstest und bau den Code etwas um.

Sub DateiStrom()
 Dim LW As String
 Dim Pfad As String
 Dim DateiStromGK As String

 Lw = "K:\"
 Pfad = "K:\Eigene\_Dateien"
 DateiStromGK = "Strom.xls"

 ChDrive Lw
 ChDir Pfad
 On Error Resume Next
 Workbooks.Open DateiStromGK
End Sub

Das macht noch unverändert genau, das, was Dein Code auch macht.
(Vermutlichen Tippfehler beseitigt.)
Nun kannst Du aber Veränderungen einbauen, wenn Du magst. Was In dem Textfeld steht, dessen Inhalt Du an die Variable X übergibst, habe ich nicht verstanden, das ist aber auch nicht wichtig. Ich nehme mal den fall, daß da ein anderer Dateiname steht und Du deinen Code so ändern möchtest, daß der Dateiname aus der Variablen ‚X‘ übernommen wird, dann sieht der geänderte Code so aus:

Sub DateiStrom()
 Dim LW As String
 Dim Pfad As String
 Dim DateiStromGK As String

 Lw = "K:\"
 Pfad = "K:\Eigene\_Dateien"
 DateiStromGK = X

 ChDrive Lw
 ChDir Pfad
 On Error Resume Next
 Workbooks.Open DateiStromGK
End Sub

OK?

Gruß, Rainer

Nachtrag
Hallo,

mir ist gerade noch etwas aufgefallen.

Const DateiStromGK = „Strom.xls“

Workbooks.Open DateiStrom

ist das Absicht, daß das unterschiedliche Variablen sind? Oder doch ein Tippfehler?

Schreib über Dein Projekt in den Deklarationsbereich mal ‚Option Explicit‘. Das zwingt Dich, alle Variablen zu deklarieren und macht Dich bei Tippfehlern darauf aufmerksam, daß die verwendete Variable (mit Tippfehler) nicht deklariert ist.

Gruß, Rainer

Hallo,

Ok, Tippfehler ist beseitigt und Konstanten sind in Variablen geändert worden. Der Benutzer soll den Pfad angeben, allerdings ohne Dateiname. Die bleiben nämlich konstant. Das Makro sieht wie folgt aus:

Sub DateiStromVK()

Dim x as String
Dim Pfad As String
Dim DateiStromVK As String

x = UserForm3.TextBox1.Value

Pfad = x
DateiStromVK = „VK_Strom.xls“

ChDir Pfad
On Error Resume Next
Workbooks.Open DateiStromVK
End Sub

Wenn ich das Makro über F8 schrittweise ablaufen lasse, übergibt er mir immer den voreingestellten Text aus der TextBox1 (habe über ein sub userform_initialize den text voreingestellt). Liegt es vielleicht daran, dass ich insgesamt 3 nacheinandergeschaltete UserForms habe, von denen immer nur eines geöffnet ist? Aus dem ersten userform soll der Pfad ausgelesen werden und erst mit dem dritten userform (da steht dann die zu öffnende datei fest) übergeben werden.

Hallo,

x = UserForm 3.TextBox1.Value

Aus dem ersten userform soll der Pfad
ausgelesen werden …

Da steht, der Pfad soll aus der Textbox1 auf der Userform3 geholt werden. Wenn Du den Pfad aus der Userform1 holen möchtest, dann musst Du auch Userform1 schreiben.

x = UserForm 1.TextBox1.Value

Gruß, Rainer

Sub DateiStromVK()
Dim x as String
Dim Pfad As String
Dim DateiStromVK As String
x = UserForm3.TextBox1.Value
Pfad = x
DateiStromVK = „VK_Strom.xls“
ChDir Pfad
On Error Resume Next
Workbooks.Open DateiStromVK
End Sub

Hi Matthias,
deine eigentliche Anfrage kann ich erst heute Abend angehen.

Aber mal grundsätzlich, ChDir ohne vorheriges ChDrive ist mehr als Risiko, ist quasi fahrlässig.
Bitte benutze immer beide, hattest du doch auch vorher im Code, und ChDrive braucht, im Gegensatz zu allen anderem, nur den Buchstaben, also ChDrive „F“ reicht.

Wieso eigentlich die Variable x?
Pfad = UserForm3.TextBox1.Value
istdoch schlanker.

Warum willst du eigentlich den Ordner wechseln? Es geht ja auch so:

Workbooks.Open Pfad & „“ & DateiStromVK

Und resume next ist zwar chic, z.B. bei Vlookup u.ä., aber so ist das m.E. in diesem Fall besser:

Sub DateiStromVK()
Dim Pfad As String, DateiStromVK As String
Pfad = UserForm3.TextBox1.Value
DateiStromVK = „VK_Strom.xls“
ChDrive „K“
ChDir Pfad
On Error Goto Fehler
Workbooks.Open DateiStromVK
On Error Goto 0 'nur nötig wenn hier noch weiterer Code folgt
Exit Sub
Fehler:
Msgbox „etwas faul im Staate Dänemark mit VK_Strom.xls“
End Sub

Gruß
Reinhard

Hallo Reinhard,

der Pfad wird scheinbar eingetippt, kannst Du mal noch eine Prüfung einbauen, ob der Pfad so existiert? (Mit FSO oder API im Validate Ereignis?) Bei VB6 würde ich es selbst machen, aber mit VBA sieht der Code etwas anders aus und ich kann doch nicht testen. :frowning:

Gruß, Rainer

der Pfad wird scheinbar eingetippt, kannst Du mal noch eine
Prüfung einbauen, ob der Pfad so existiert? (Mit FSO oder API
im Validate Ereignis?) Bei VB6 würde ich es selbst machen,
aber mit VBA sieht der Code etwas anders aus und ich kann doch
nicht testen. :frowning:

Hallo Rainer,
„Mit FSO oder API im Validate Ereignis?“
Aha, warum das denn?

Meinst du so:

Option Explicit

Sub tt()
MsgBox CheckUserDir(„F:\USER“)
MsgBox CheckUserDir(„C:“)
End Sub

Function CheckUserDir(Pfad) As Boolean
If Dir(Pfad, vbDirectory) „“ Then CheckUserDir = True
End Function

PS1: Nur aus Interesse, was müßte geändert werden damit es in VB6 läuft.

PS2: Wegen API, hast du DAS Buch von Dan Appleman zu API?

PS3: If PS2=False Then buy directly and asap :smile: Ich habe es zusammen mit seinem einzigen Buch in Deutsch (auch sehr emfehlenswert) sehr günstig gebraucht im Inet gekauft. Bringt viel.

Gruß
Reinhard

Hallo Reinhard,

„Mit FSO oder API im Validate Ereignis?“
Aha, warum das denn?

weil ich keine andere Variante kenne. :smile:

Option Explicit

Sub tt()
MsgBox CheckUserDir(„F:\USER“)
MsgBox CheckUserDir(„C:“)
End Sub

Function CheckUserDir(Pfad) As Boolean
If Dir(Pfad, vbDirectory) „“ Then CheckUserDir = True
End Function

Hmmm …

PS1: Nur aus Interesse, was müßte geändert werden damit es in
VB6 läuft.

Das muss ich erst mal ausprobieren …

PS2: Wegen API, hast du DAS Buch von Dan Appleman zu
API?

Nein. Ich habe gar keine Bücher zu VB. API-Guide. :smile: Schöne Beispiele, die auch alle laufen.

PS3: If PS2=False Then buy directly and asap :smile: Ich habe es
zusammen mit seinem einzigen Buch in Deutsch (auch sehr
emfehlenswert)

Soll das heißen, das andere ist englisch? Dann kann ich’s doch nicht lesen.

sehr günstig gebraucht im Inet gekauft. Bringt
viel.

Hmmm, nö. :smile: Zum Bücher lesen habe ich keine Zeit/Lust. w-w-w muss reichen.

Gruß, Rainer

Hallo Reinhard,

PS1: Nur aus Interesse, was müßte geändert werden damit es in
VB6 läuft.

… nix, läuft. :smile: Keine Ahnung, warum ich ‚If PahtFileExist …‘ geschrieben hätte. Wahrscheinlich, weil es mir immer zuerst einfällt.

Gruß, Rainer

Hmmm, nö. :smile: Zum Bücher lesen habe ich keine Zeit/Lust. w-w-w
muss reichen.

Hallo Rainer,
Dan ist DER Guru von API,
Auch wenn du sehr belehrungsresistent bist, egal, ich bin zäh :smile:
Um Bücher zu lesen habe ich oft auch keine Lust, aber die zwei nachfolgend beschrieben, sind ein Muß, die müsssen einfach in meiner Reichweite vorhanden sein *find*
Auch wenn ich sie selten benutze, weil sich keine API-Problematiken sooft einfinden.
Kauf dir das!!!: (Ich hasse Betreffs wie Hlfe !!!, schon klar, aber bei dir mach ich das so:smile:)
http://www.amazon.de/Applemans-Visual-Programmers-Au…

und das (da wird dir gezeigt daß du von ByRef und ByVal nahezu Null Ahnung hast, unter anderem, geht zurück in die Bits und Bytes Geschichte, Nibble links usw…)

http://www.amazon.de/Applemans-Puzzle-Tutorial-Visua…

Und mit dem Englischen habe ich es auch nicht so, aber für die APIs langt es und das andere ist in Deutsch.

Und, ich habe, gebraucht, für beide Bücher zusammen, grad mal so ± € 40 bezahlt.

Gruß
Reinhard

Hallo Reinhard,

Dan ist DER Guru von API,
Auch wenn du sehr belehrungsresistent bist, egal, ich bin zäh

-)

*gg* so schlimm bin ich doch gar nicht.

Um Bücher zu lesen habe ich oft auch keine Lust, aber die zwei
nachfolgend beschrieben, sind ein Muß, die müsssen einfach in
meiner Reichweite vorhanden sein *find*
Auch wenn ich sie selten benutze, weil sich keine
API-Problematiken sooft einfinden.

Bei mir auch nicht, das ist nur Interesse.

Kauf dir das!!!: (Ich hasse Betreffs
wie Hlfe !!!, schon klar, aber bei dir mach ich das
so:smile:)

Ok, OK. :smile: Ich habe die Mail mit dem Link schon mal markiert, damit sie nicht verloren geht.

http://www.amazon.de/Applemans-Visual-Programmers-Au…

und das (da wird dir gezeigt daß du von ByRef und ByVal nahezu
Null Ahnung hast,

*gg* Stimmt. Das wusste ich aber auch ohne Buch. :smile:

unter anderem, geht zurück in die Bits und
Bytes Geschichte, Nibble links usw…)

Mit Bits und Bytes kenne ich mich gut aus, ich habe vor langer Zeit (vor Multitasking) mal Assembler programmiert.

http://www.amazon.de/Applemans-Puzzle-Tutorial-Visua…

Und mit dem Englischen habe ich es auch nicht so, aber für die
APIs langt es und das andere ist in Deutsch.

OK, die API-Guide ist ja auch englisch und alle Antworten finde ich da nicht immer.

Und, ich habe, gebraucht, für beide Bücher zusammen, grad mal
so ± € 40 bezahlt.

Das ist schon mehr, als ich mal so nebenbei ausgeben kann. Das muss noch warten.

Gruß, Rainer

Hallo Reinhard, Rainer

sorry das ich auch mal meinem Senf dazu gebe.

Auf die Verwendung der Funktion Dir$ zur Existenzprüfung sollte dringend verzichtet werden, da diese Funktion nicht eintrittsinvariant ist. Ihre Verwendung kann zur Folge haben, dass sich anderen Programmteile nach Aufruf der Funktion zur Existenzprüfung nicht mehr wie erwartet verhalten!

Will man die Existenz eines Files oder Ordners prüfen, so sollten immer Filebezogene Routinen eingesetz werden ( FileLen, GetAttr etc.)

Ein kleines Demo!

Die Zeile wo als Kommentar Test steht, einfach mal mit ausführen und mal nicht. Dabei schaut euch die Ergebnisse in beiden Faellen mal an :wink:

Option Explicit

Private Sub Form\_Load()
 Call EnumDirs("c:\")
End Sub

Private Sub EnumDirs(ByVal Path As String)
Dim CurrentDir As String
CurrentDir = Dir$(Path, vbDirectory)
Do While Len(CurrentDir) \> 0
If CurrentDir "." And CurrentDir ".." Then
If \_
CBool(GetAttr(CombinePath(Path, CurrentDir)) And vbDirectory) \_
Then
Debug.Print CurrentDir
End If
End If
'Debug.Print DirExists("C:\Programme") ' Test
CurrentDir = Dir$
Loop
End Sub

Private Function DirExists(ByVal Path As String) As Boolean
DirExists = (Len(Dir$(Path, vbDirectory)) \> 0)
End Function

Private Function CombinePath(ByVal Part1 As String, ByVal Part2 As String)
CombinePath = Part1
If Right$(CombinePath, 1) "\" Then
CombinePath = CombinePath & "\"
End If
CombinePath = CombinePath & Part2
End Function

MfG Alex

1 Like

Hi Alex,

hübsch! :smile: Ich habe in der Funktion dann mal ‚PathFileExists‘ verwendet … OK, ich bleibe dabei.

Danke für den Hinweis!

Gruß, Rainer

Hallo,

danke für die Hilfe. Es scheint zu funktionieren, einen Haken hat die Sache aber noch. Ich glaube, dass es mit dem Laufwerk zu tun hat.
Muss ich das Laufwerk vorgeben (ChDrive „K“)? Wenn die Dateien nämlich auf einem anderen Laufwerk als „K“ gespeichert werden, klappt es nicht. Kann ich diese fixe Vorgabe umgehen ohne ein zu hohes Risiko einzugehen?

Gruß

Hallo Alex,

sorry das ich auch mal meinem Senf dazu gebe.

Danke für den Senf :smile:

Auf die Verwendung der Funktion Dir$ zur Existenzprüfung
sollte dringend verzichtet werden, da diese Funktion nicht
eintrittsinvariant ist. Ihre Verwendung kann zur Folge haben,
dass sich anderen Programmteile nach Aufruf der Funktion zur
Existenzprüfung nicht mehr wie erwartet verhalten!

Was „eintrittsinvariant“ bedeutte muß ich erst nachlesen, kenne ich nicht.

Will man die Existenz eines Files oder Ordners prüfen, so
sollten immer Filebezogene Routinen eingesetz werden (
FileLen, GetAttr etc.)

Okay, aber vorher möchte ich schon genauer wissen was da Dir verurscht.

Den Code teste ich heute Abend oder morgen, habe gerade am Stück diese Codes programmiert:

http://www.wer-weiss-was.de/cgi-bin/forum/showarticl…

und mein Kopf braucht erstmal was anderes als Vba *gg*

Im Anhang habe ich einen Teilcode gepostet. Wißt ihr zufällig warum, wenn die Prozedur eine Proberty ist, der Code an der Stelle:

lngStartLine = lngStartLine + .ProcCountLines(.ProcOfLine(lngStartLine, vbext_pk_Proc), vbext_pk_Proc)

abbricht und einen Fehler bringt? Fehler soll sein daß er Sub oder Funktion nicht kennt, aber bei allen anderen Dateien/Prozeduren vorher kannte er sie noch, erst wenn in dem auszulesenden Modul ein Property auftaucht bricht er ab. Subs und Functionen liest der Code bestens aus.
Laut Hilfe haben nur Subs und Functions „vbext_pk_Proc“, was auch immer das genau ist.
Wie umgehe ich den Fehler und lese auch eine Property-Prozedur aus?
Ich weiß jetzt gar nicht ob VB Properties kennt usw.
Und es hat auch keinerlei Priorität, würde es halt gerne wissen.

Gruß
Reinhard

Sub ListProcedures(ByVal wb As Workbook)

'Verweis auf Microsoft Visual basic for Applications Extensibility muß gesetzt sein!!
'Code 2007 by Reinhard

Dim VBCodeMod As CodeModule, lngStartLine As Long, strMsg As String
Dim strModName As String, CMdl, Zeile As Long, Spalte As Integer
Dim N As Long, Von As Long, Bis As Long, Prozedur As String
Dim ws As Worksheet
Call ZeileSpalte
Set ws = ThisWorkbook.Worksheets("Tabelle1")
ws.Cells(Zei, Spa) = wb.Name
For Each CMdl In wb.VBProject.VBComponents
 ws.Cells(Zei, Spa + 1) = CMdl.Name
 Set VBCodeMod = wb.VBProject.VBComponents(CMdl.Name).CodeModule
 With VBCodeMod
 lngStartLine = .CountOfDeclarationLines + 1
 Do Until lngStartLine \>= .CountOfLines
 Prozedur = .ProcOfLine(lngStartLine, vbext\_pk\_Proc)
 ws.Cells(Zei, Spa + 2) = Prozedur
 For N = 1 To lngStartLine - 1
 ws.Cells(Zei, Spa + 3) = .Lines(N, 1)
 Call ZeileSpalte
 Next N
 On Error GoTo Weiter 'Fehler wenn Prozedur keine Sub oder Function sondern Property
 lngStartLine = lngStartLine + .ProcCountLines(.ProcOfLine(lngStartLine, vbext\_pk\_Proc), vbext\_pk\_Proc)
 On Error GoTo 0
 Von = .ProcStartLine(Prozedur, vbext\_pk\_Proc)
 Bis = .ProcCountLines(Prozedur, vbext\_pk\_Proc)
 For N = Von To Von + Bis - 1
 ws.Cells(Zei, Spa + 3) = .Lines(N, 1)
 Call ZeileSpalte
 Next N
 Loop
 End With
Weiter:
Next CMdl
ActiveSheet.UsedRange.Columns.AutoFit
End Sub