OSFiles
Cross-platform file and folder selection helper. Wraps Windows FileDialog and macOS AppleScript pickers behind a unified API. Supports single and multi-selection for both files and folders, persists the last-used folder across sessions, and provides iterator-style enumeration over multi-selections. State bag for OS detection, selections, and cursor positions. Exposed methods Workbook-level Name used to persist the last used folder path.
Version: 1.0 (2026-02-09)
Initialization
Create #
create
Factory returning an initialised interface
Signature:
Public Function Create() As IOSFiles
Returns: IOSFiles. Ready to use.
Elements
File #
file
Current loaded file path
Signature:
Private Property Get File() As String
Returns: String. The first selected file path.
Files #
files
All loaded file paths from a multi-selection
Signature:
Private Property Get Files() As Variant
Returns: Variant. Zero-based string array of file paths.
Folder #
folder
Current loaded folder path
Signature:
Private Property Get Folder() As String
Returns: String. The first selected folder path.
Folders #
folders
All loaded folder paths from a multi-selection
Signature:
Private Property Get Folders() As Variant
Returns: Variant. Zero-based string array of folder paths.
Selecting
LoadFolder #
load-folder
Show a single-folder picker dialog
Signature:
Private Sub LoadFolder()
LoadFile #
load-file
Show a single-file picker dialog
Signature:
Private Sub LoadFile(ByVal filters As String, _
Optional ByVal customMacFilter As String = vbNullString)
Parameters:
filters: String. File type filters (e.g. "*.xlsx").customMacFilter: String. Optional UTI override for macOS. Defaults to vbNullString.
LoadFiles #
load-files
Show a multi-file picker dialog
Signature:
Private Sub LoadFiles(ByVal filters As String, _
Optional ByVal customMacFilter As String = vbNullString)
Parameters:
filters: String. File type filters.customMacFilter: String. Optional UTI override for macOS. Defaults to vbNullString.
LoadFolders #
load-folders
Show a multi-folder picker dialog
Signature:
Private Sub LoadFolders()
Iteration
ResetFilesCursor #
reset-files-iterator
Reset the file iteration cursor to the beginning
Signature:
Private Sub ResetFilesCursor()
ResetFoldersCursor #
reset-folders-iterator
Reset the folder iteration cursor to the beginning
Signature:
Private Sub ResetFoldersCursor()
HasNextFileValue #
has-next-file
Check if another file is available in the iterator
Signature:
Private Function HasNextFileValue() As Boolean
HasNextFolderValue #
has-next-folder
Check if another folder is available in the iterator
Signature:
Private Function HasNextFolderValue() As Boolean
NextFileValue #
next-file
Return the next file path and advance the cursor
Signature:
Private Function NextFileValue() As String
NextFolderValue #
next-folder
Return the next folder path and advance the cursor
Signature:
Private Function NextFolderValue() As String
Validation
HasValidFile #
has-valid-file
Whether the loaded file path is valid
Signature:
Private Function HasValidFile() As Boolean
Returns: Boolean. True when a non-empty file path exists.
HasValidFiles #
has-valid-files
Whether the loaded files array contains entries
Signature:
Private Function HasValidFiles() As Boolean
Returns: Boolean. True when at least one file was selected.
HasValidFolder #
has-valid-folder
Whether the loaded folder path is valid
Signature:
Private Function HasValidFolder() As Boolean
Returns: Boolean. True when a non-empty folder path exists.
HasValidFolders #
has-valid-folders
Whether the loaded folders array contains entries
Signature:
Private Function HasValidFolders() As Boolean
Returns: Boolean. True when at least one folder was selected.
Internal members (not exported)
Initialization
Class_Initialize #
class-initialize
Set default values for file and folder state
Signature:
Private Sub Class_Initialize()
ResetFileState #
reset-file-state
Clear file-related state and reset the iteration cursor
Signature:
Private Sub ResetFileState()
ResetFolderState #
reset-folder-state
Clear folder-related state and reset the iteration cursor
Signature:
Private Sub ResetFolderState()
EmptyStringArray #
empty-string-array
Return an empty variant array
Signature:
Private Function EmptyStringArray() As Variant
Returns: Variant. Empty array.
SelectFoldersOnWindows #
select-folders-on-windows
Show the Windows multi-folder picker
Signature:
Private Function SelectFoldersOnWindows() As Variant
Returns: Variant. Zero-based string array of folder paths.
TryGetArrayBounds #
try-get-array-bounds
Safely probe array bounds
Signature:
Private Function TryGetArrayBounds(ByVal candidate As Variant, _
ByRef lowerBound As Long, _
ByRef upperBound As Long) As Boolean
CountArrayItems #
count-array-items
Count the number of items in a variant array
Signature:
Private Function CountArrayItems(ByVal candidate As Variant) As Long
ToStringArray #
to-string-array
Coerce a variant into a zero-based string array
Signature:
Private Function ToStringArray(ByVal value As Variant) As Variant
CloneStringArray #
clone-string-array
Create a safe copy of a string array
Signature:
Private Function CloneStringArray(ByVal source As Variant) As Variant
HasNextArrayItem #
has-next-array-item
Check whether the cursor is within array bounds
Signature:
Private Function HasNextArrayItem(ByVal items As Variant, ByVal cursor As Long) As Boolean
GetNextArrayItem #
get-next-array-item
Fetch the item at the cursor and advance it
Signature:
Private Function GetNextArrayItem(ByVal items As Variant, _
ByRef cursor As Long) As String
SetFilesSelection #
set-files-selection
Persist file selections and prime the iterator
Signature:
Private Sub SetFilesSelection(ByVal selectedItems As Variant)
SetFoldersSelection #
set-folders-selection
Persist folder selections and prime the iterator
Signature:
Private Sub SetFoldersSelection(ByVal selectedItems As Variant)
FirstStringOrEmpty #
first-string-or-empty
Return the first array entry or an empty string
Signature:
Private Function FirstStringOrEmpty(ByVal source As Variant) As String
NormalizeFolderPath #
normalize-folder-path
Trim trailing separators and clean the folder path
Signature:
Private Function NormalizeFolderPath(ByVal folderPath As String) As String
ExtractFolderFromPath #
extract-folder-from-path
Identify the parent directory from a file path
Signature:
Private Function ExtractFolderFromPath(ByVal filePath As String) As String
RememberFolder #
remember-folder
Cache the folder locally and in the workbook
Signature:
Private Sub RememberFolder(ByVal folderPath As String)
RememberFolderFromFiles #
remember-folder-from-files
Persist the parent directory of the first selected file
Signature:
Private Sub RememberFolderFromFiles(ByVal filesSelection As Variant)
RememberFolderFromFolders #
remember-folder-from-folders
Persist the first folder from a folder selection
Signature:
Private Sub RememberFolderFromFolders(ByVal folderSelection As Variant)
ResolveLastKnownFolder #
resolve-last-known-folder
Resolve the last-used folder from cache or workbook storage
Signature:
Private Function ResolveLastKnownFolder() As String
HasWorkbookContext #
has-workbook-context
Check whether ThisWorkbook is accessible
Signature:
Private Function HasWorkbookContext() As Boolean
ReadLastFolderFromWorkbook #
read-last-folder-from-workbook
Read the last-used folder from a workbook-level Name
Signature:
Private Function ReadLastFolderFromWorkbook() As String
WriteLastFolderToWorkbook #
write-last-folder-to-workbook
Persist the folder path in a hidden workbook Name
Signature:
Private Sub WriteLastFolderToWorkbook(ByVal folderPath As String)
EncodeWorkbookStorageValue #
encode-workbook-storage-value
Convert a folder path into a Name.RefersTo-safe string literal
Signature:
Private Function EncodeWorkbookStorageValue(ByVal folderPath As String) As String
DecodeWorkbookStorageValue #
decode-workbook-storage-value
Undo Name serialization to recover the original folder path
Signature:
Private Function DecodeWorkbookStorageValue(ByVal storedValue As String) As String
WrapAppleScriptString #
wrap-apple-script-string
Escape a string for safe insertion into AppleScript
Signature:
Private Function WrapAppleScriptString(ByVal value As String) As String
WrapAppleScriptAlias #
wrap-apple-script-alias
Build an AppleScript alias literal from a colon path
Signature:
Private Function WrapAppleScriptAlias(ByVal aliasPath As String) As String
BuildAppleScriptList #
build-apple-script-list
Translate a VBA array into an AppleScript list literal
Signature:
Private Function BuildAppleScriptList(ByVal entries As Variant) As String
BuildMacFilterList #
build-mac-filter-list
Construct the UTI list for the AppleScript file picker
Signature:
Private Function BuildMacFilterList(ByVal filters As String, _
ByVal customMacFilter As String) As String
ParseMacSelectionResult #
parse-mac-selection-result
Split newline-delimited POSIX paths from AppleScript output
Signature:
Private Function ParseMacSelectionResult(ByVal response As String) As Variant
NormalizeFolderSelections #
normalize-folder-selections
Normalize picker results into clean folder paths
Signature:
Private Function NormalizeFolderSelections(ByVal folderSelection As Variant) As Variant
ConvertPosixToColonPath #
convert-posix-to-colon-path
Translate a POSIX path to AppleScript colon-delimited format
Signature:
Private Function ConvertPosixToColonPath(ByVal posixPath As String) As String
GetMacDefaultFolderAlias #
get-mac-default-folder-alias
Resolve the default folder alias for macOS pickers
Signature:
Private Function GetMacDefaultFolderAlias() As String
BuildMacFileSelectionScript #
build-mac-file-selection-script
Compose the AppleScript for file selection on macOS
Signature:
Private Function BuildMacFileSelectionScript(ByVal filters As String, _
ByVal customMacFilter As String, _
ByVal defaultAlias As String, _
ByVal allowMultiple As Boolean) As String
BuildMacFolderSelectionScript #
build-mac-folder-selection-script
Compose the AppleScript for folder selection on macOS
Signature:
Private Function BuildMacFolderSelectionScript(ByVal defaultAlias As String, _
ByVal allowMultiple As Boolean) As String
RunMacFilePicker #
run-mac-file-picker
Execute the AppleScript file picker and return POSIX paths
Signature:
Private Function RunMacFilePicker(ByVal filters As String, _
ByVal customMacFilter As String, _
ByVal allowMultiple As Boolean) As Variant
RunMacFolderPicker #
run-mac-folder-picker
Execute the AppleScript folder picker and return POSIX paths
Signature:
Private Function RunMacFolderPicker(ByVal allowMultiple As Boolean) As Variant
Elements
Self #
self
Self-reference as IOSFiles
Signature:
Public Property Get Self() As IOSFiles
Returns: IOSFiles. Self-reference.
OS #
os
Current operating system flag
Signature:
Public Property Get OS() As String
Returns: String. "Mac" or "Windows".
OS #
os-set
Override the detected OS flag
Signature:
Public Property Let OS(ByVal currentOS As String)
Parameters:
currentOS: String. "Mac" or "Windows".
File #
file-set
Assign a single file path through the selection pipeline
Signature:
Private Property Let File(ByVal ff As String)
Parameters:
ff: String. The file path.
Folder #
folder-set
Assign a single folder path through the selection pipeline
Signature:
Private Property Let Folder(ByVal ff As String)
Parameters:
ff: String. The folder path.
SelectFolderOnMac #
select-folder-on-mac
Show the macOS single-folder picker
Signature:
Private Function SelectFolderOnMac() As String
SelectFoldersOnMac #
select-folders-on-mac
Show the macOS multi-folder picker
Signature:
Private Function SelectFoldersOnMac() As Variant
SelectFolderOnWindows #
select-folder-on-windows
Show the Windows single-folder picker
Signature:
Private Function SelectFolderOnWindows() As String
SelectFilesOnWindows #
select-files-on-windows
Show the Windows multi-file picker
Signature:
Private Function SelectFilesOnWindows(ByVal filters As String) As Variant
SelectFileOnMac #
select-file-on-mac
Show the macOS single-file picker
Signature:
Private Function SelectFileOnMac(ByVal filters As String, _
Optional ByVal customMacFilter As String = vbNullString) As String
SelectFilesOnMac #
select-files-on-mac
Show the macOS multi-file picker
Signature:
Private Function SelectFilesOnMac(ByVal filters As String, _
Optional ByVal customMacFilter As String = vbNullString) As Variant
SelectFileOnWindows #
select-file-on-windows
Show the Windows single-file picker
Signature:
Private Function SelectFileOnWindows(ByVal filters As String) As String
Test Support
AssignFilesForTesting #
assign-files-for-testing
Inject file selections without showing a dialog
Signature:
Public Sub AssignFilesForTesting(ByVal selections As Variant)
Parameters:
selections: Variant. File paths to assign.TestHook
AssignFoldersForTesting #
assign-folders-for-testing
Inject folder selections without showing a dialog
Signature:
Public Sub AssignFoldersForTesting(ByVal selections As Variant)
Parameters:
selections: Variant. Folder paths to assign.TestHook
Used in (17 file(s))
- ExportButton.cls
- DesignerPreparation.cls
- IOSFiles.cls
- OSFiles.cls
- Linelist.cls
- SetupImportService.cls
- DesignerMain.bas
- EventsDesignerAdvanced.bas
- EventsDesignerCore.bas
- EventsDesignerMulti.bas
- RibbonDev.bas
- FormLogicAdvanced.bas
- FormLogicExportMig.bas
- SetupHelpers.bas
- Exports.bas
- TestManualOSFiles.bas
- TestOSFiles.bas