1

I try to create vba code that create a zip-file that contains all file in a sourcefolder, and I get problems when I try to create Shell objects (objFolder and objZipFolder). It works fine when I hardcode (Set objFolder = objShell.Namespace("C:.....")). But when I use a variable (Set objFolder = objShell.Namespace(fldPth)), objFolder return "Nothing". In the code below I have included the possibilities I have tried, and made comments of the results after each line. I would be grateful for any solutions that might work.

Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")

Dim objShell As Object
Dim objFolder As Object     'SourceFolder
Dim objZipFile As Object    'ZipFolder

Dim fldPth As String
Dim zipFldPth As String
fldPth = "C:\Users\bruker\Desktop\MyFolder"
zipFldPth = "C:\Users\bruker\Desktop\Archive.zip"
    
If FSO.FileExists(zipFldPth) Then FSO.DeleteFile zipFldPth      'Delete old ZipFile
FSO.CreateTextFile zipFldPth                                    'Create new ZipFile

'Check if the paths exists
If Not FSO.FolderExists(fldPth) Then Exit Sub               'OK
If Not FSO.FileExists(zipFldPth) Then Exit Sub              'OK

'Create objects
Set objShell = CreateObject("Shell.Application")

'objFolder:
Set objFolder = objShell.Namespace(fldPth)                                  'Return: objFolder = Nothing
'Set objFolder = objShell.Namespace("C:\Users\bruker\Desktop\MyFolder")      'Return: objFolder = "MyFolder"  OK
'Set objFolder = objShell.Namespace(Chr(34) & fldPth & Chr(34))              'Return: objFolder = Nothing
'Set objFolder = objShell.Namespace("""" & fldPth & """")                    'Return: objFolder = Nothing
'Set objFolder = objShell.Namespace(fldPth).Self                             'Run-time error 91
'Set objFolder = GetObject(fldPth)                                           'Run-time error 432

'objZipFile:
Set objZipFile = objShell.Namespace(zipFldPth)                              'Return: objZipFile = Nothing
'Set objZipFile = objShell.Namespace("C:\Users\bruker\Desktop\Archive.zip")  'Return: ojbZipFile = "Archive.zip"  OK
'Set objZipFile = objShell.Namespace(Chr(34) & zipFldPth & Chr(34))          'Return: objZipFile = Nothing
'Set objZipFile = objShell.Namespace("""" & zipFldPth & """")                'Return: objZipFile = Nothing
'Set objZipFile = objShell.Namespace(zipFldPth).Self                         'Run-time error 91
'Set objZipFile = GetObject(zipFldPth)                                       'Run-Time error 430


If objFolder Is Nothing Or objZipFile Is Nothing Then       'Check that the Shell objects were created successfully
    MsgBox "Could not create Shell objects.", vbCritical    'THIS LINE IS ACTIVATED. objFolder and objZipFile returne "Nothing"
    Exit Sub
End If

objZipFile.CopyHere objFolder.Items     'Copy the folder items to the zip file

' Clean up objects
Set objZipFile = Nothing
Set objFolder = Nothing
Set objShell = Nothing
Set FSO = Nothing
eradem
  • 43
  • 5

1 Answers1

1

The argument of the Shell.NameSpace() method is supposed to be of type Variant, hence if you are using late binding with the Shell.Application object, you need to explicitly cast the argument of the .Namespace method to Variant, you can do that by using CVar:

Set objFolder = objShell.Namespace(CVar(fldPth))
Set objZipFile = objShell.Namespace(CVar(zipFldPth))

Alternatively, you can declare the variables as Variant right away, then you no longer need to cast:

Dim fldPth As Variant
Dim zipFldPth As Variant

'...

Set objFolder = objShell.Namespace(fldPth)
Set objZipFile = objShell.Namespace(zipFldPth)

If you are using early binding with this object like this:

'Requires reference to "Microsoft Shell Controls and Automation" library
Dim oShell As New Shell32.Shell

VBA will know what the argument type is supposed to be and implicitly do the correct casting, but since your code uses late binding, you need to use the correct type in the first place.

Actually, the fact that this method accepts a variant can be very beneficial to you because it will actually not only accept folder paths but also Shell Special Folder Constants. This can be used to get the path to your folder in a much more reliable way.

Suppose you are on a different PC and the path to the Desktop folder is not fldPth = "C:\Users\bruker\Desktop\, but something else.

By using the Shell object you can get the desktop path on any PC like this: objShell.NameSpace(CVar(&H0)), so you can get your path like this:

objShell.NameSpace(CVar(&H0)) & "\MyFolder"

Note that it's okay to use "\" as a path separator here because this is Windows-only code anyways.

There are more methods to get paths of Known Folders like the Desktop folder dynamically, a comprehensive summary and explanation, of the various methods, is available here.

GWD
  • 3,081
  • 14
  • 30
  • 1
    Thank you so much for a quick and very good answer. I have tested both solutions, and they work very well. I am so grateful. – eradem May 06 '23 at 20:59