HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

"Scripting.FileSystemObject" Replacement module in VBA

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scriptingfilesystemobjectmodulevbareplacement

Problem

I have found Scripting.FileSystemObject to be slow and unstable. Calling 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.

  • Remove the underscores from your variable names. Style conventions say to use camelCase. file_path should be filePath, 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 = vbNullString than <> "" 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 Function


Should 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 Function
Dim 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.