ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 19.07.2001

Diese Seite wurde zuletzt aktualisiert am 19.07.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Gelistete Auswahl

Zurück...


Anzeige

(-hg) mailto:hg_cdlgfilepaths@aboutvb.de

Wenn Sie im Common Dialog-Steuerelement das Flag cdlOFNAllowMultiselect setzen, kann der Anwender mehrere Dateien im gleichen Ordner auf einmal auswählen. Eine solche Mehrfachauswahl wird in der FileName-Eigenschaft zurückgegeben.

With CommonDialog1
  .CancelError = True
  On Error Resume Next
  .ShowOpen
  If Err.Number = 0 Then
    Debug.Print .FileName
  End If
End With

Sie werden einen String zu sehen bekommen, der mit dem Pfad des Ordners beginnt und anschließend die Namen der gewählten Dateien. Die einzelnen Teile sind dabei durch Leerzeichen voneinander getrennt - so behauptet es jedenfalls die Visual Basic-Hilfe, und so sieht es offensichtlich auch aus. Dass die Behauptung der Hilfe so nicht stimmen kann, sollte Ihnen spätestens dann aufgehen, wenn Dateinamen ausgewählt worden sind, die selber schon Leerzeichen enthalten, oder wenn schon der Ordner-Pfad Leerzeichen enthält.

Es gibt zwar unter Windows die Konvention, dass Datei- und Pfadnamen, die Leerzeichen enthalten, komplett in Anführungszeichen eingeschlossen werden, und dass eine Trennung einer Aufreihung per Leerzeichen damit eindeutig unterscheidbar sei. Doch ist das Aufteilen mit der Notwendigkeit der Unterscheidung, ob sich ein Leerzeichen innerhalb oder außerhalb eines Anführungszeichenpaares befindet, zum einen recht mühselig. Und zum anderen: die Debug-Ausgabe der Rückgabe in der FileName-Eigenschaft enthält keinerlei Anführungszeichen und scheint sich also nicht an diese Konvention zu halten.

In Wahrheit ist die Behauptung der VB-Hilfe, dass das Leerzeichen das Trennzeichen sei, schlicht falsch. Sie war mal richtig, als seinerzeit unter Windows 3.x Dateinamen noch keine Leerzeichen enthalten durften, und daher der Kunstgriff zu umschließenden Anführungszeichen noch nicht existierte.

Tatsächlich werden die Teile durch Nullzeichen (Ascii 0, vbNullChar) voneinander getrennt. Und die Debug-Ausgabe führt uns lediglich auf Glatteis, indem sie das Nullzeichen als Leerzeichen darstellt. Die Teilung der Aufreihung lässt sich somit über die Split-Funktion (die allerdings erst seit VB 6 zur Verfügung steht) ganz einfach erledigen:

Dim nParts() As String
Dim l As Long

With CommonDialog1
  .CancelError = True
  On Error Resume Next
  .ShowOpen
  If Err.Number = 0 Then
    nParts = Split(.FileName, vbNullChar)
    For l = 0 To UBound(nParts)
      Debug.Print nParts(l)
    Next 'l
  End If
End With

Das sieht schon viel besser und brauchbarer aus, nicht wahr? Als erstes Element mit dem Index 0 erhalten Sie den Pfad, und in den Elementen ab Index 1 die einzelnen Dateinamen.

Wenn Sie nun die Dateinamen noch mit vollständigen Pfad benötigen, können Sie den jeweiligen Dateinamen mit dem im ersten Element des Split-Arrays enthaltenen Pfad kombinieren. Sie sollten dabei allerdings nicht vergessen, dafür zu sorgen, dass der Pfad mit einem Backslash ("\") endet - einfach so immer einen Backslash einzufügen, ist nicht korrekt, da ein möglicherweise zurückgegebenes Wurzelverzeichnis eines Laufwerks bereits mit einem Backslash endet und dann zwei Backslashes aufeinander folgen würden.

Sie können nun in einem Schleifendurchgang dafür sorgen, dass alle Dateinamen mit dem vollständigen Pfad versehen sind. Und wenn Sie den Ordnerpfad anschließend nicht mehr benötigen, ignorieren Sie bei der weiteren Verarbeitung einfach das nullte Element des Arrays oder redimensionieren das Array mit der Angabe Preserve und dem Start-Index 1.

Dim nParts() As String
Dim l As Long

With CommonDialog1
  .CancelError = True
  On Error Resume Next
  .ShowOpen
  If Err.Number = 0 Then
    nParts = Split(.FileName, vbNullChar)
    If Right$(nParts(0), 1) <> "\" Then
      nParts(0) = nParts(0) & "\"
    End If
    For l = 0 To UBound(nParts)
      nParts(l) = nParts(0) & nParts(l)
    Next 'l
    ReDim Preserve nParts(1 To UBound(nParts))
  End If
End With

Nun haben Sie das Array, das alle gewählten Dateien mit vollständigem Dateipfad enthält, nach Belieben verwenden. Nein, doch nicht. Denn falls der Anwender von Ihrem gut gemeinten Angebot, mehrere Dateinamen auszuwählen, keinen Gebrauch macht, sondern nur einen Dateinamen auswählt, tut das Common Dialog-Steuerelement leider so, als wäre das Mehrfachauswahl-Flag nicht gesetzt, und gibt in der Eigenschaft FileName lediglich den kompletten Pfad zu der einen gewählten Datei zurück. Und leider nicht wenigstens den Pfad und den Dateinamen getrennt, so dass die Behandlung auf die oben gezeigte Weise konsistent und ohne Bruch möglich wäre.

Sie müssen also noch diesen Fall unterscheiden und separat behandeln. In jedem Fall ist es sinnvoll, zunächst die Split-Funktion ihre Arbeit tun zu lassen. Ist die Obergrenze des von ihr zurückgegebenen Arrays 0, so wurde nur ein Dateiname ausgewählt, und Sie können die Sonderbehandlung anwenden.

Dim nParts() As String
Dim l As Long

With CommonDialog1
  .CancelError = True
  On Error Resume Next
  .ShowOpen
  If Err.Number = 0 Then
    nParts = Split(.FileName, vbNullChar)
    If UBound(nParts) = 0 Then
      ReDim Preserve nParts(0 To 1)
      nParts(1) = nParts(0)
      ReDim Preserve nParts(1 To 1)
    Else
      If Right$(nParts(0), 1) <> "\" Then
        nParts(0) = nParts(0) & "\"
      End If
      For l = 0 To UBound(nParts)
        nParts(l) = nParts(0) & nParts(l)
      Next 'l
      ReDim Preserve nParts(1 To UBound(nParts))
    End If
  End If
End With

Bis auf die abschließende Redimensionierung zum Entfernen des ersten Elements mit dem Pfad erledigt die folgende Funktion CDlgFilePathsArr diese Arbeit für Sie. Ihr übergeben Sie den Inhalt der FileName-Eigenschaft des Common Dialog-Steuerelements und erhalten ein Array zurück, in dem alle Dateinamen mit vollständigem Pfad enthalten sind. Dieses Array enthält im ersten Element noch den "nackten" Ordner-Pfad - dieser endet aber in jedem Fall mit einem Backslash.

Public Function CDlgFilePathsArr(FileName As String) As String()
  Dim nParts() As String
  Dim l As Long
  Dim nPos As Long
  
  nParts = Split(FileName, vbNullChar)
  Select Case UBound(nParts)
    Case 0
      ReDim Preserve nParts(0 To 1)
      nParts(1) = nParts(0)
      nPos = InStrRev(nParts(0), "\")
      nParts(0) = Left$(nParts(0), nPos)
      CDlgFilePathsArr = nParts
    Case Is > 0
      If Right$(nParts(0), 1) <> "\" Then
        nParts(0) = nParts(0) & "\"
      End If
      For l = 1 To UBound(nParts)
        nParts(l) = nParts(0) & nParts(l)
      Next 'l
      CDlgFilePathsArr = nParts
  End Select
End Function

Falls Sie statt eines Arrays lieber eine Collection hätten, die die Dateipfade enthält, wird Ihnen diese von der folgenden Funktion CDlgFilePathsColl geliefert. Da eine Collection immer mit dem Index 1 beginnt, wäre hier kein sinnvolles Plätzchen für die Rückgabe des Ordner-Pfades vorhanden. Daher können Sie der Funktion optional eine String-Variable übergeben, die den Pfad zur weiteren Verwendung zurückgibt.

Public Function CDlgFilePathsColl(FileName As String, _
 Optional Path As String) As Collection

  Dim nParts() As String
  Dim l As Long
  Dim nPos As Long
  Dim nColl As Collection
  
  nParts = Split(FileName, vbNullChar)
  Set nColl = New Collection
  Select Case UBound(nParts)
    Case 0
      nPos = InStrRev(nParts(0), "\")
      Path = Left$(nParts(0), nPos)
      nColl.Add nParts(0)
    Case Is > 0
      If Right$(nParts(0), 1) <> "\" Then
        nParts(0) = nParts(0) & "\"
      End If
      Path = nParts(0)
      With nColl
        For l = 1 To UBound(nParts)
          .Add nParts(0) & nParts(l)
        Next 'l
      End With
  End Select
  Set CDlgFilePathsColl = nColl
End Function

Leider können Sie diese beiden Funktionen so nicht in Visual Basic 5 verwenden, da dort die beiden verwendeten Visual Basic-Funktionen Split und InstrRev noch nicht zur Verfügung stehen. Zwar könnten Sie entsprechende Ersatzfunktionen verwenden, wie Sie sie beispielsweise unter Teile-Haberschaft"Teile-Haberschaft" und unter Retourkutsche"Retourkutsche" finden können. Sie können aber auch die folgenden Varianten der oben stehenden Funktionen verwenden, den Ersatz der besagten VB-Funktionen direkt und effizienter enthalten. Da in VB 5 jedoch ein Array als Rückgabewert einer Funktion noch nicht möglich ist, ist CDlgFilePathsArr hier als Prozedur angelegt, der Sie im zweiten Parameter ein deklariertes, aber noch nicht dimensioniertes String-Array zur Rückgabe übergeben.

Public Sub CDlgFilePathsArr(Filename As String, FilePaths() As String)
  Dim l As Long
  Dim nPos As Long
  Dim nStart As Long
  
  ReDim FilePaths(0 To Len(Filename) \ 10)
  nStart = 1
  Do
    nPos = InStr(nStart, Filename, vbNullChar)
    If nPos Then
      If nStart = 1 Then
        FilePaths(0) = Left$(Filename, nPos - 1)
        If Right$(FilePaths(0), 1) <> "\" Then
          FilePaths(0) = FilePaths(0) & "\"
        End If
      Else
        l = l + 1
        If UBound(FilePaths) < l Then
          ReDim Preserve FilePaths(0 To UBound(FilePaths) + 10)
        End If
        FilePaths(l) = _
         FilePaths(0) & Mid$(Filename, nStart, nPos - nStart)
      End If
      nStart = nPos + 1
    Else
      If nStart = 1 Then
        ReDim FilePaths(0 To 1)
        FilePaths(1) = Filename
        For l = Len(Filename) To 1 Step -1
          If Mid$(Filename, l, 1) = "\" Then
            FilePaths(0) = Left$(Filename, l)
            Exit For
          End If
        Next 'l
        Exit Sub
      Else
        l = l + 1
        If UBound(FilePaths) < l Then
          ReDim Preserve FilePaths(0 To UBound(FilePaths) + 10)
        End If
        FilePaths(l) = FilePaths(0) & Mid$(Filename, nStart)
      End If
    End If
  Loop While nPos
  ReDim Preserve FilePaths(0 To l)
End Sub

Public Function CDlgFilePathsColl(Filename As String, _
 Optional Path As String) As Collection

  Dim l As Long
  Dim nPos As Long
  Dim nStart As Long
  Dim nColl As Collection
  
  Set nColl = New Collection
  With nColl
    nStart = 1
    Do
      nPos = InStr(nStart, Filename, vbNullChar)
      If nPos Then
        If nStart = 1 Then
          Path = Left$(Filename, nPos - 1)
          If Right$(Path, 1) <> "\" Then
            Path = Path & "\"
          End If
        Else
          .Add Path & Mid$(Filename, nStart, nPos - nStart)
        End If
        nStart = nPos + 1
      Else
        If nStart = 1 Then
          .Add Filename
          For l = Len(Filename) To 1 Step -1
            If Mid$(Filename, l, 1) = "\" Then
              Path = Left$(Filename, l)
              Exit For
            End If
          Next 'l
          Set CDlgFilePathsColl = nColl
          Exit Do
        Else
          .Add Path & Mid$(Filename, nStart)
        End If
      End If
    Loop While nPos
  End With
  Set CDlgFilePathsColl = nColl
End Function

Noch zwei Anmerkungen zum Schluss. Zum einen ist die Eigenschaft MaxFileSize des Common Dialog-Steuerelements auf eine Länge von 255 Zeichen voreingestellt. Dies reicht natürlich kaum aus, wenn mehr als ein, zwei handvoll Dateien ausgewählt werden. Damit die Eigenschaft FileName genügend Raum bekommt, alle ausgewählten Dateien ablegen zu können, sollte MaxFileSize auf einen genügend hohen Wert gesetzt werden, etwa 10.000 oder mehr. Zum anderen kann der Anwender natürlich nach wie vor auch manuell Dateinamen und -pfade in die Eingabe-Zeile des Dialogs einfügen. Da er aber kaum in der Lage sein wird, die Teile mit einem Nullzeichen voneinander zu trennen, wird die oben beschriebene Aufteilung natürlich kein brauchbares Ergebnis liefern. Den Fall zu unterscheiden, dass der Anwender die Teile mit Leerzeichen voneinander trennt und vorsorglich Pfade, die selbst Leerzeichen enthalten, konventionsgemäß in Anführungszeichen einschließt, wäre zwar auch möglich, aber recht aufwändig. Einfacher ist es, die anzugebenden Flags noch mit der Konstante cdlOFNFileMustExist zu verknüpfen, wodurch solche "eigenmächtigen" Eingaben schon vom Common Dialog-Steuerelement selbst zurückgewiesen werden.


Beispiel-Projekte und Module modCDlgFilePaths (VB 5 und 6) (cdlgfilepaths.zip - ca. 7,6 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer