patternMinor
"Scripting.FileSystemObject" Replacement module in VBA
Viewed 0 times
scriptingfilesystemobjectmodulevbareplacement
Problem
I have found Scripting.FileSystemObject to be slow and unstable. Calling
While I haven't been able to run extensive comparisons against it and FileSystemObject. I have found that it is significantly faster. It varies from operation to operation but the range is 4-10 times faster. However, I do suspect that FileSystemObject may out-perform
There are some few questionable design calls. Nothing is object oriented. Functional programming is preferred whenever possible. Almost all variables are strings (file paths) or collections of strings. The exceptions are the file system operations like
I am looking for more functions, features and improvements for existing functions.
Path Manipulations
These functions would be in
``
' extension or not.
Function BaseName(ByVal file_path As String, Optional suffix As String) As String
Dim fsplit As Variant
fsplit = Split(file
file_object.Name repeatedly has caused my code to crash excel on multiple instances. Therefore I made a module where all of my file System helper functions reside. I called it os after python's os module as I tried to emulate it as much as possible. Admittedly, I have not emulated it enough and much is written from scratch. While I haven't been able to run extensive comparisons against it and FileSystemObject. I have found that it is significantly faster. It varies from operation to operation but the range is 4-10 times faster. However, I do suspect that FileSystemObject may out-perform
os in larger data-sets.There are some few questionable design calls. Nothing is object oriented. Functional programming is preferred whenever possible. Almost all variables are strings (file paths) or collections of strings. The exceptions are the file system operations like
FileCopy, Move, Rename etc that return True if succeeded or False if failed as Error Handling is a horrid mess of GoTos in VB6. Also they are hard set to never overwrite files; only Remove deletes anything.I am looking for more functions, features and improvements for existing functions.
Option Explicit
' Constants
' ------
Public Const EXTSEP As String = "."
Public Const PARDIR As String = ".."
Public Const CURDIR As String = "."
Public Const SEP As String = "\"
Public Const PATHSEP As String = ";"
Private Const ALLPAT As String = "*"Path Manipulations
These functions would be in
os.path. They have no interaction with the file system at all and are primarily helper functions.``
''
' Returns the base name of a path, either the lowest folder or file
' Note! that suffix` will be removed from the end regardless if its an actual filename' extension or not.
Function BaseName(ByVal file_path As String, Optional suffix As String) As String
Dim fsplit As Variant
fsplit = Split(file
Solution
Once you've fixed the things that could potentially crash your code and added some proper error handling you should go back and take a look at some style & readability issues.
-
I like that you created constants for the different separators, but give them better names. Unless you're coding in a plain text editor, intellisense will help you and there's no reason to abbreviate.
-
On the topic of better names, what is
-
Functions should have verb-noun type names.
Should be
-
You considered an object oriented approach. Instead of returning a collection of
-
Think of Mr. Maintainer; add some comments to non obvious logic.
Could I spend a few minutes figuring out what exactly you're doing here? Sure, but it'd be a heck of a lot nicer if you wrote one sentence telling me what you're doing.
All that said, I still think it's a pretty cool little module of functions. Fun idea.
- Remove the underscores from your variable names. Style conventions say to use camelCase.
file_pathshould befilePath, etc.
-
I like that you created constants for the different separators, but give them better names. Unless you're coding in a plain text editor, intellisense will help you and there's no reason to abbreviate.
Public Const EXTSEPERATOR As String = "."
Public Const PARENTDIR As String = ".."
Public Const CURRENTDIR As String = "."
Public Const FWDSLASH As String = "\"
Public Const PATHSEPERATOR As String = ";"
Private Const WILDCARD As String = "*"-
On the topic of better names, what is
fsplit()? It took me way too long to figure out that it's an array that stores the separate parts of a file path.- I recently had it pointed out to me that it's better to use
Not = vbNullStringthan<> ""and I'll pass that advice along to you.
-
Functions should have verb-noun type names.
Function SubFiles(ByVal root As String, _
Optional pat As String = ALLPAT) As Collection
Set SubFiles = SubItems(root, pat, vbNormal)
End FunctionShould be
getSubFiles() or returnSubFiles, but you could keep your naming if...-
You considered an object oriented approach. Instead of returning a collection of
SubItems or SubFiles from a function, you could store them a a property of a parent class. I haven't thought out how I would refactor your code into classes, but any client code might benefit from it. (Of course, this would still require a private getSubFiles() routine though.)-
Think of Mr. Maintainer; add some comments to non obvious logic.
Dim base_length As Integer
base_length = Len(BaseName) - Len(suffix)
BaseName = left$(BaseName, base_length) & _
Replace$(BaseName, suffix, "", base_length + 1)Could I spend a few minutes figuring out what exactly you're doing here? Sure, but it'd be a heck of a lot nicer if you wrote one sentence telling me what you're doing.
All that said, I still think it's a pretty cool little module of functions. Fun idea.
Code Snippets
Public Const EXTSEPERATOR As String = "."
Public Const PARENTDIR As String = ".."
Public Const CURRENTDIR As String = "."
Public Const FWDSLASH As String = "\"
Public Const PATHSEPERATOR As String = ";"
Private Const WILDCARD As String = "*"Function SubFiles(ByVal root As String, _
Optional pat As String = ALLPAT) As Collection
Set SubFiles = SubItems(root, pat, vbNormal)
End FunctionDim base_length As Integer
base_length = Len(BaseName) - Len(suffix)
BaseName = left$(BaseName, base_length) & _
Replace$(BaseName, suffix, "", base_length + 1)Context
StackExchange Code Review Q#52301, answer score: 9
Revisions (0)
No revisions yet.