Výběr složek a souborů ve VBA V článku Systémové proměnné a složky jsme si povídali o tom, jak se dobrat speciálních složek operačního systému. Dnes se podíváme na to, jak složky a soubory vybírat prostřednictvím dialogů. Excel nabízí jakýsi univerzální objekt FileDialog, který v sobě nese čtyři podtypy dialogů – pro výběr složky (Folder Picker), výběr souborů (File Picker), a pro otevření (Open), resp. uložení souboru (SaveAs). Nejprve si ukážeme výběr složky. Sub DialogVyberSlozky() 'víceúčelový dialog, zde pro výběr složky With Application.FileDialog(msoFileDialogFolderPicker) 'titulek, běžně "Procházet" .Title = "Výběr složky" 'výchozí styl zobrazení, zde velké ikony 'Windows 7, 64 bit, nefunkční .InitialView = msoFileDialogViewLargeIcons 'vícenásobný výběr složek nelze použít '.AllowMultiSelect = True 'výchozí zobrazená složka, zde Temp .InitialFileName = Environ("Temp") 'popis tlačítka, běžně "OK" .ButtonName = "Vybrat" 'zobrazení dialogu .Show 'byla vybrána složka? If .SelectedItems.Count > Then 'výpis do okna Immediate Debug.Print .SelectedItems(1) End If End With End Sub
Excelplus.NET | 1
Výběr složek a souborů ve VBA
Výběr složky Na chvilku si odskočíme pro výběr složky do API a tak trochu se vrátíme k tématu systémových složek, abychom si nastavili výchozí složku v dialogu. Private Type BROWSEINFO hOwner As Long pidlRoot As Long pszDisplayName As String lpszTitle As String ulFlags As Long lpfn As Long lParam As Long iImage As Long End Type Private Const CSIDL_PERSONAL As Long = &H5 Private Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias _ "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
Excelplus.NET | 2
Výběr složek a souborů ve VBA Private Declare Function SHBrowseForFolder Lib "shell32.dll" Alias _ "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long Sub TestSlozkaVyber() Dim strSlozka As String strSlozka = GetDirectory() End Sub Function GetDirectory(Optional Msg) As String Dim bInfo As BROWSEINFO Dim path As String Dim r As Long, x As Long, pos As Integer 'výchozí složka 'http://www.garybeene.com/code/visual%20basic252.htm 'zde moje složka Dokumenty bInfo.pidlRoot = CSIDL_PERSONAL 'popisek dialogu If IsMissing(Msg) Then bInfo.lpszTitle = "Výběr složky" Else bInfo.lpszTitle = Msg End If 'typ složky bInfo.ulFlags = &H1 'zobrazení dialogu x = SHBrowseForFolder(bInfo) 'parsování path = Space$(512) r = SHGetPathFromIDList(ByVal x, ByVal path) If r Then pos = InStr(path, Chr$()) GetDirectory = Left(path, pos - 1) Else GetDirectory = "" End If End Function
Excelplus.NET | 3
Výběr složek a souborů ve VBA
Výběr složky přes API funkce Ale teď už zpět k objektu FileDialog a možnosti výběru souborů. Sub DialogVyberSouboru() Dim i As Integer 'víceúčelový dialog, zde pro výběr souborů With Application.FileDialog(msoFileDialogFilePicker) 'vícenásobný výběr souborů .AllowMultiSelect = True 'výchozí zobrazená složka, zde Temp .InitialFileName = Environ("Temp") 'zobrazení dialogu .Show 'byl vybrán nějaký soubor? If .SelectedItems.Count > Then 'pro každou vybranou položku For i = 1 To .SelectedItems.Count 'výpis do okna Immediate Debug.Print .SelectedItems(i)
Excelplus.NET | 4
Výběr složek a souborů ve VBA Next i End If End With End Sub Určitě vás bude zajímat také možnost filtrování složky podle přípony souborů. Sub DialogVyberSouboruFiltr() Dim i As Integer 'víceúčelový dialog, zde pro výběr souborů With Application.FileDialog(msoFileDialogFilePicker) 'vícenásobný výběr souborů .AllowMultiSelect = True 'výchozí zobrazená složka, zde složka tohoto souboru .InitialFileName = ThisWorkbook.path 'přidání dvou filtrů .Filters.Add "Vybrané typy obrázků", _ "*.gif; *.jpg; *.jpeg; *.bmp; *.png", 1 .Filters.Add "Soubory aplikace Excel", "*.xl*", 2 'výchozí druhý filtr .FilterIndex = 2 'zobrazení dialogu .Show 'byl vybrán nějaký soubor? If .SelectedItems.Count > Then 'alternativně If .Show = -1 then 'pro každou vybranou položku For i = 1 To .SelectedItems.Count 'výpis do okna Immediate Debug.Print .SelectedItems(i) Next i
Excelplus.NET | 5
Výběr složek a souborů ve VBA End If End With End Sub
Výběr souborů Ještě se podíváme na třetí podtyp objektu FileDialog. Zatímco předchozí dialogy pouze vracely seznam vybraných položek, tento je otevírá prostřednictvím metody Execute. Sub DialogSouborOtevrit() Dim i As Integer 'víceúčelový dialog 'zde pro výběr a otevření souborů 'a to pouze takových, které jsou přidružené 'hostitelské aplikaci, tj. Microsoft Excel! With Application.FileDialog(msoFileDialogOpen)
Excelplus.NET | 6
Výběr složek a souborů ve VBA 'vícenásobný výběr souborů .AllowMultiSelect = False 'výchozí zobrazená složka, zde Temp .InitialFileName = ThisWorkbook.path 'zobrazení dialogu .Show 'byl vybrán nějaký soubor? If .SelectedItems.Count > Then 'spuštění (lépe řečeno otevření souboru) .Execute End If End With End Sub Jak už napovídá komentář v kódu, není bohužel možné si kupříkladu nastavit filtr na obrázky a čekat, že je metoda Execute spustí v přidruženém grafickém programu. Ostatně podívejte se na filtry tohoto dialogu.
Excelplus.NET | 7
Výběr složek a souborů ve VBA
Výběr souborů k otevření I zde je cítit ze strany Microsoftu schizofrenie, vždyť už dávno existuje jiný způsob… Sub DialogSouborOtevritAlternativa() Dim varFName As Variant Dim i As Integer 'metoda GetOpenFilename varFName = _ Application.GetOpenFilename( _ FileFilter:="Soubory aplikace Excel (*.xl*), *.xl*", _ MultiSelect:=True) If IsArray(varFName) Then
Excelplus.NET | 8
Výběr složek a souborů ve VBA For i = LBound(varFName) To UBound(varFName) 'otevření sešitů Workbooks.Open (varFName(i)) Next End If End Sub Různorodost a změny v dialozích typu Otevřít/Uložit jsou leckdy přínosné (tipy si ukážeme jindy), ale nezřídka i pitomé a neergonomické (viz Excel 2013 a trotlovské proklikávání se k dialogu). Peklo s nimi zažívám ve smyslu kompatibility starších programů, které jednoduše spadnou, i když by jinak fungovali naprosto normálně. Obzvláště se to týká portable aplikací.
Excelplus.NET | 9