MkDir() (Fehl-) Funktion

  • Excel

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    MkDir() (Fehl-) Funktion

    Hallo Zusammen,

    mir stellt sich aktuell die Frage wo MkDir() einen Ordner erstellt, wenn der Aufruf wie folgt lautet:

    DieseArbeitsmappe:

    Visual Basic-Quellcode

    1. Public Sub testx()
    2. Dim xy As New Directory
    3. xy.Initialize "456"
    4. xy.Create
    5. End Sub


    Klassenmodul Directory:

    Visual Basic-Quellcode

    1. Option Explicit
    2. Private MyDirectoryPath As String
    3. Public Sub Initialize(ByVal DirectoryPath As String)
    4. Dim CheckedPath As String
    5. CheckedPath = Replace(DirectoryPath, "/", "\", 1, -1, vbTextCompare)
    6. MyDirectoryPath = CheckedPath
    7. End Sub
    8. Public Sub Create()
    9. '// Directory exists already.
    10. If Me.Exists = True Then
    11. Exit Sub
    12. End If
    13. 'On Error GoTo CreateDirectoryError
    14. MkDir MyDirectoryPath
    15. 'On Error GoTo 0
    16. Exit Sub
    17. End Sub
    18. '''<summary>Returns True if the folder exists - no matter if it's hidden or not.</summary>
    19. Public Function Exists() As Boolean
    20. '// Folder Attribute | Function Result
    21. '// Normal - True
    22. '// Hidden - True
    23. '// Disconnected - False
    24. On Error GoTo NotConnected
    25. If Len(Dir(MyDirectoryPath, vbDirectory + vbHidden)) <> 0 Then
    26. Exists = True
    27. Else
    28. Exists = False
    29. End If
    30. Exit Function
    31. NotConnected:
    32. Exists = False
    33. End Function


    Normal müsste MkDir() in diesem Fall eine ArgumentException (52) Path is not specified or is empty. werfen.
    Dies geschieht aber bei mir nicht, der Code läuft durch und in einem zweiten Durchlauf sagt mit Me.Exists = True.

    Gruß, FireEmerald

    System: Excel 2010 // Wichtig: Die Excel Datei liegt auf einem Netzwerklaufwerk!
    @Kilian_98 Die Frage ist wieso wirft MkDir() in diesem Fall keine ArgumentException? Dies müsste Sie und macht Sie auch normal, wenn MkDir() außerhalb von dem Klassenmodul steht.

    Siehe: msdn.microsoft.com/en-us/library/k1d22wfh(v=vs.90).aspx



    Mir ist gerade aufgefallen, dass wenn man den Arbeitsmappencode wie folgt ergänzt:

    Visual Basic-Quellcode

    1. Public Sub testx()
    2. Dim strX As String: strX = GetFolder("C:\")
    3. Dim xy As New Directory
    4. xy.Initialize "456"
    5. xy.Create
    6. End Sub
    7. Private Function GetFolder(strPath As String) As String
    8. Dim fldr As FileDialog
    9. Dim sItem As String
    10. Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
    11. With fldr
    12. .Title = "Select a Folder"
    13. .AllowMultiSelect = False
    14. .InitialFileName = strPath
    15. If .Show <> -1 Then GoTo NextCode
    16. sItem = .SelectedItems(1)
    17. End With
    18. NextCode:
    19. GetFolder = sItem
    20. Set fldr = Nothing
    21. End Function


    Die Funktion MkDir "456" den Ordner nicht mehr dort anlegt wo die *.xlsm Datei liegt, sondern immer in C:\ ?(

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „FireEmerald“ ()

    Irgendwie habe ich das Gefühl, deine Klasse lässt sich auf drei Einzeiler runterbrechen:

    Visual Basic-Quellcode

    1. Private MyDirectoryPath As String
    2. Public Sub Initialize(ByVal DirectoryPath As String)
    3. MyDirectoryPath = Replace(DirectoryPath, "/", "\")
    4. End Sub
    5. Public Sub Create()
    6. If Not Exists Then MkDir MyDirectoryPath
    7. End Sub
    8. Public Function Exists() As Boolean
    9. Exists = Len(Dir(MyDirectoryPath, vbDirectory + vbHidden)) > 0
    10. End Function
    Zum eigentlichen Problem:
    Der letztlich ausgeführte Befehl lautet MkDir "456"Das ist ein relativer Pfad, also wird das Verzeichnis 456 in deinem Arbeitsverzeichnis angelegt.
    Wenn das C:\ ist, dann wird halt C:\456 angelegt.
    MkDir wirft übrigens keinen Fehler, falls das Verzeichnis bereits existiert.
    Notfalls kannst du die Abfrage auf Exists also auch ganz weglassen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    FireEmerald schrieb:

    Len(Dir()) wirft z.B. bei einem nicht verbundenen Netzwerkpfad eine Exception
    Auch mit ErrorHandler kann man die Funktion relativ kurz schreiben.

    Visual Basic-Quellcode

    1. ​Public Function Exists() As Boolean
    2. On Error Resume Next
    3. Exists = Len(Dir(MyDirectoryPath, vbDirectory + vbHidden)) > 0
    4. End Function

    FireEmerald schrieb:

    gibt's auch ne Möglichkeit dieses zu ändern?

    ChDir
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Funktioniert bei dieser Funktion.

    Visual Basic-Quellcode

    1. Public Function Exists() As Boolean
    2. On Error Resume Next
    3. Exists = Len(Dir(MyDirectoryPath, vbDirectory + vbHidden)) > 0
    4. End Function

    Aber ich bin kein Freund von On Error Resume Next, weil dort der eigentliche Fehler nicht behandelt wird. Ergo kann man bei On Error Resume Next nicht wirklich von ErrorHandling sprechen, sondern eher von Fehlerunterdrückung. VBA ist was das angeht meiner Meinung nach eh ziemlich unpraktisch/unmöglich.

    Ich stelle mir unter Errorhandling sowas vor:

    Visual Basic-Quellcode

    1. Public Sub Delete()
    2. If Me.Exists Then
    3. On Error GoTo DeleteDirectoryError
    4. RmDir MyDirectoryPath
    5. On Error GoTo 0
    6. End If
    7. Exit Sub
    8. DeleteDirectoryError:
    9. Select Case Err.Number
    10. Case 52
    11. '// ArgumentException | Path is not specified or is empty.
    12. Case 75
    13. '// IOException | Target directory contains files.
    14. Case 76
    15. '// FileNotFoundException | Directory does not exist.
    16. Case Else
    17. '// Unkown
    18. End Select
    19. ' Couldn't delete directory!
    20. End Sub
    Oder statt MKDIR einfach die API.Funktion »MakeSureDirectoryPathExists« verwenden


    Visual Basic-Quellcode

    1. Option Explicit
    2. Declare Function MakePath Lib "imagehlp.dll" _
    3. Alias "MakeSureDirectoryPathExists" _
    4. (ByVal lpPath As String) As Long
    5. Sub test()
    6. Dim Pfad As String, x As Boolean
    7. Pfad = "d:\####\a\b\c\"
    8. x = MakePath(Pfad)
    9. If x Then
    10. MsgBox "OK"
    11. Else
    12. MsgBox "Fehler"
    13. End If
    14. End Sub

    FireEmerald schrieb:

    ich bin kein Freund von On Error Resume Next
    Ich auch nicht, ausser zur Fehlerunterdrückung.
    Und im Falle deiner Exists-Routine kannst du nur ein Boolean zurückgeben.
    Und das ist nun mal True, wenn das Verzeichnis zugriffsbereit ist und in allen anderen Fällen False.
    Da kannst du hundert verschiedene Fehlermöglichkeiten abfangen. Das Ergebnis bleibt dasselbe.

    Ansonsten kannst du deiner Exists-Routine als Return-Parameter ein Integer geben, um granularer zu werden.
    Aber auch dann kannst du ganz einfach Err.Number zurückgeben.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „petaod“ ()