Team, I am working upon extract the zip file from VBA code but getting error, here is my code:
Sub Un_Zip_File()
Dim flname As String
Call PathCall
flname = Dir(impathn & "Transactions*.zip")
Call PathCall
Call UnZip_File(impathn, flname)
End Sub
Sub UnZip_File(strTargetPath As String, fname As Variant)
Dim oApp As Object, FSOobj As Object
Dim FileNameFolder As Variant
If Right(strTargetPath, 1) <> Application.PathSeparator Then
strTargetPath = strTargetPath & Application.PathSeparator
End If
FileNameFolder = strTargetPath
'destination folder if it does not exist
Set FSOobj = CreateObject("Scripting.FilesystemObject")
If FSOobj.FolderExists(FileNameFolder) = False Then
FSOobj.CreateFolder FileNameFolder
End If
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(fname).Items
Set oApp = Nothing
Set FSOobj = Nothing
Set FileNameFolder = Nothing
End Sub
When I am running Un_zip_file macro, I am getting error:
Object variables or with block variable not set
after debug moving on
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(fname).Items
Here is another example how to unzip a file. the macro unzip the zip file in a fixed folder"C:\test\"
Sub Unzip()
Dim FSO As Object
Dim oApp As Object
Dim Fname As Variant
Dim FileNameFolder As Variant
Dim DefPath As String
Fname = Application.GetOpenFilename(filefilter:="Zip Files (*.zip), *.zip", _
MultiSelect:=False)
If Fname = False Then
'Do nothing
Else
'Destination folder
DefPath = "C:\test\" ' Change to your path / variable
If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
FileNameFolder = DefPath
' 'Delete all the files in the folder DefPath first if you want
' On Error Resume Next
' Kill DefPath & "*.*"
' On Error GoTo 0
'Extract the files into the Destination folder
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(Fname).items
MsgBox "You find the files here: " & FileNameFolder
On Error Resume Next
Set FSO = CreateObject("scripting.filesystemobject")
FSO.deletefolder Environ("Temp") & "\Temporary Directory*", True
End If
End Sub
Found elsewhere on the web and thought it might help here...
Sub UnzipAFile(zippedFileFullName As Variant, unzipToPath As Variant)
Dim ShellApp As Object
'Copy the files & folders from the zip into a folder
Set ShellApp = CreateObject("Shell.Application")
On Error Resume Next
ShellApp.Namespace(unzipToPath).CopyHere ShellApp.Namespace(zippedFileFullName).Items
On Error GoTo 0
End Sub
I had same error "Object variables or with block variable not set".
Solved it by adding reference to "Microsoft Shell Controls & Automation" - Shell32.dll. Then define & use the Shell object in this order.
Do not skip any of these steps. I have also posted full code in this page.
Dim wShApp As Shell
Set wShApp = CreateObject("Shell.Application")
Set objZipItems = wShApp.Namespace(zipFileName).items
wShApp.Namespace(unZipFolderName).CopyHere objZipItems
To avoid the message error:
1 - change "/" per "\"
unzipToPath= Replace(unzipToPath, "/", "\\")
zippedFileFullName= Replace(zippedFileFullName, "/", "\\")
2 - Use double (( to the parameters as below:
ShellApp.Namespace((unzipToPath)).CopyHere
ShellApp.Namespace((zippedFileFullName)).Items
I had exactly the same problem, but in MS Word, trying to extract files from a .zip folder. After a lot of experimentation and testing I discovered that the late-binding objects were not initializing correctly, and when i tested them with the TypeName function were typically "nothing".
I tested my code in both Windows 10 and on an old Windows XP machine, with the same results. All my testing was in Excel 2007 and Excel 2016.
Changing the code from late-binding to early-binding resolved the problem.
Late-binding uses the CreateObject function to initialize the objects in the Shell.Application library. Early-binding requires setting a reference to the "Microsoft Shell Controls and Automation" library in your project.
To set the reference, do this:
In the VBA IDE, use the Tools menu to open the References dialog. Scroll through the list of available references until you find the "Microsoft Shell Controls and Automation" entry, and then click the checkbox to select that library, thus:
The VBA References dialog, showing the "Microsoft Shell Controls and Automation" library after adding it to your project.
Related
Good morning,
I would like to convert the PDF file to Word one (from PDF to DOCX) using Excel macro.
So far I learned the process from this video:
https://www.youtube.com/watch?v=Op25fUfvIl0
and this link:
https://www.pk-anexcelexpert.com/pdf-to-word-converter-macro-in-excel-vba/
but the problem is, that the example is based on the certain cells including the fixed file directory:
pdf_path = sh.Range("E4").Value
word_path = sh.Range("E5").Value
I would like to have always directory the same as my active workbook, which I am working on.
In this event I tried the following code:
Sub Wort_To_PDF()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.DisplayStatusBar = True
Dim pdf_path As String
Dim word_path As String
pdf_path = ThisWorkbook.Path & "\"
word_path = ThisWorkbook.Path & "\"
Dim fso As New FileSystemObject
Dim fo As Folder
Dim f As File
Set fo = fso.GetFolder(pdf_path)
Dim wa As Object
Dim doc As Object
Set wa = CreateObject("word.application")
wa.Visible = True
Dim file_Count As Integer
For Each f In fo.Files
Application.StatusBar = "Converting - " & file_Count + 1 & "/" & fo.Files.Count
Set doc = wa.Documents.Open(f.Path)
doc.SaveAs2 (word_path & "\" & Replace(f.Name, ".pdf", ".docx"))
doc.Close False
file_Count = file_Count + 1
Next
wa.Quit
MsgBox "All PDF files have been converted in to word", vbInformation
Application.StatusBar = ""
End Sub
I am getting an error "Type mismatch" pointing the following line:
Set fo = fso.GetFolder(pdf_path)
I found some hints regarding the usage of active workbook directory in VBA
How to get the path of current worksheet in VBA?
and tried to put it into my code:
pdf_path = Application.ActiveWorkbook.Path
word_path = Application.ActiveWorkbook.FullName
but the error is exactly the same.
Can anyone help me? I would like to convert the PDF file to docx in the same directory, where my active workbook is stored.
UPDATE:
When I change Dim fo as Folder to Dim fo As Object or Dim fo as Scripting.Folder I am getting another error, informing me, that file is corrupted. Debugger shows the following line:
Set doc = wa.Documents.Open(f.Path)
I think, that problem might be somewhere with my excel document, which is already opened and used. In general, the code executes the first sheet only instead of all of them.
The code could fail because ActiveWorkbook.Path contains something invalid:
If the ActiveWorkbook is a new workbook that was not saved yet, Path is empty - you will get Runtime error 5 (Invalid Argument)
If ActiveWorkbook is on a Sharepoint site or something like that, Path might be an URL - you will get Runtime error 76 (Path not found)
However in your case, it seems that the returned object of the GetFolder-method returns something that is not expected by the VBA runtime. It might be case that you have a type definition Folder somewhere that hides the Folder-type of the Scripting Library. Declare your variable qualified:
Dim fo as Scripting.Folder
Do so for all the other scripting object (f for example)
If you add a reference to the Microsoft Word 16 Object Library, you can also declare the word objects with the correct type, eg
Dim wa as Word.Application
Dim doc as Word.Document
Update: If you loop over all files of the folder, make sure you open only Word files with the Word.Application. Opening some other kind of files will throw errors like the one you see (might be corrupt)
Add a check for the filetype before you open it - you want to convert only word files:
For Each f In fo.Files
if fso.GetExtensionName(f.Name) like "doc*" Then
Set doc = wa.Documents.Open(f.Path)
doc.SaveAs2 (word_path & "\" & Replace(f.Name, ".pdf", ".docx"))
doc.Close False
file_Count = file_Count + 1
End If
Next f
I am trying to write some macros in both Excel and Outlook that in the end will automatically unzip and open a CSV, process the data, and sends it where it needs to go when a new email arrives in a specific folder. I have everything worked out on the Excel side but I am having difficulties with Outlook. The below code unzips the file. How would i go about opening the unzipped file and triggering an Excel macro (which is always open in another workbook)?
Another issue I am running into: this code only seems to work when i actually open the target email in it's own window.
Public Sub OpenZippedSheet()
Dim objMail As Outlook.MailItem
Dim objAttachments As Outlook.Attachments
Dim objAttachment As Outlook.Attachment
Dim objShell As Object
Dim objFileSystem As Object
Dim strTempFolder As String
Dim strFilePath As String
Dim strFileName As String
Set objMail = Outlook.Application.ActiveInspector.CurrentItem
Set objAttachments = objMail.Attachments
'Save & Unzip the zip file in local drive
Set objShell = CreateObject("Shell.Application")
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
strTempFolder = objFileSystem.GetSpecialFolder(2).Path & "\Temp" & Format(Now, "yyyy-mm-dd-hh-mm-ss")
MkDir (strTempFolder)
For Each objAttachment In objAttachments
If Right(objAttachment.FileName, 3) = "zip" Then
strFilePath = strTempFolder & "\" & objAttachment.FileName
objAttachment.SaveAsFile (strFilePath)
objShell.NameSpace((strTempFolder)).CopyHere objShell.NameSpace((strFilePath)).Items
End If
Next
End Sub
I'm assuming I would do some sort of object.open but I don't know what the syntax would be to get it to actually open in Excel. And then is there a way to trigger an Excel macro from Outlook?
Thanks so much in advance!
this code only seems to work when i actually open the target email in it's own window.
That is because you rely on the ActiveInspector window. If you want to handle items selected in the Explorer windows you need to check the Selection object (see the corresponding property).
To open an Excel file you can:
Use the Shell.ShellExecute method. This method is equivalent to launching one of the commands associated with a file's shortcut menu. Each command is represented by a verb string. The set of supported verbs varies from file to file. The most commonly supported verb is "open", which is also usually the default verb. Other verbs might be supported by only certain types of files.
Automate Excel from your VBA macro to do the required actions. See How to automate Microsoft Excel from Visual Basic for more information.
To run your VBA macro code from other applications you can use the Application.Run method. Read more about that in the How do I use Application.Run in Excel article.
Application.Run "'" & TestWkbk.Name & "'!MacroNameHere", "parm1", "parm2"
Something like this (untested so may need some fixes):
'Note - any paths passed to objShell should be
' passed as *Variants*, not Strings
Dim oXL As Object, wbCSV As Object, fileNameInZip As Variant
Set objShell = CreateObject("Shell.Application")
For Each objAttachment In objAttachments
If Right(objAttachment.Filename, 3) = "zip" Then
strFilePath = strTempFolder & "\" & objAttachment.Filename
objAttachment.SaveAsFile strFilePath
Set oNS = oApp.Namespace(strFilePath)
For Each fileNameInZip In oNS.items 'loop over the files in the zip
Debug.Print fileNameInZip
If LCase(fileNameInZip) Like "*.csv" Then 'csv file?
'extract the file
objShell.Namespace(strTempFolder).copyhere oNS.items.Item(CStr(fileNameInZip))
If oXL Is Nothing Then Set oXL = GetObject(, "Excel.Application") 'assumes excel is running
Set wbCSV = oXL.Workbooks.Open(strTempFolder & "\" & fileNameInZip)
oXL.Run "'YourMacroFile.xlsm'!YourMacroName" 'run the macro
'clean up stuff...
End If 'is a csv file
Next 'file in zip
End If 'attachment is a zip file
Next 'attachment
So I posted a question here:
VBA - Find Specific Sub Folders by Name Identifiers
This question was very broad, but I was facing specific issues I needed help identifying and resolving. Now, I managed to resolve those issues in the original post, however, there is still a good portion of the question unanswered and I would like to close the question only when I am able to post the full result.
Currently, what I still need to do, it the last 4 steps:
Open ZipFile
Look for .png extenstion
Grab the name of the .png file
Put the name in a cell in excel
The issue I am facing, is that of properly opening the zip file. I been through so many posts on this but NOTHING seems to work for me.
The closest I have come to accomplishing the task is what I found here:
https://www.ozgrid.com/forum/forum/help-forums/excel-general/109333-how-to-count-number-of-items-in-zip-file-with-vba-2007
I figure, if at the very least, I am able to enter the zip file, I can then work from there. But alas, I am still stuck at simply trying to open the file.
Here is the code I have (Using from the link above):
Sub CountZipContents()
Dim zCount As Double, CountContents As Double
Dim sh As Object, fld As Object, n As Object
Dim FSO As Object
CountContents = 0
zCount = 0
x = "C:\Users\UserName\Desktop\Today\MyFolder\"
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(x) Then
For Each FileInFolder In FSO.GetFolder(x).Files
If Right(FileInFolder.Name, 4) = ".png" Then
CountContents = CountContents + 1
ElseIf Right(FileInFolder.Name, 4) = ".Zip" Then
Set sh = CreateObject("Shell.Application")
Set ZipFile = sh.Namespace(CVar(x & "\" & FileInFolder.Name))
Debug.Print FileInFolder.Name
For Each fileInZip In ZipFile.Items
If LCase(fileInZip) Like LCase("*.png") Then
CountContents = CountContents + 1
End If
Next
End If
Next FileInFolder
End If
Set sh = Nothing
End Sub
The issue I get is on this line:
For Each fileInZip In ZipFile.Items
Error Message:
Object variable or With block not set
Whenever I tried to use Shell, like below:
Dim oShell As New Shell
I get this error:
User-defined type not defined
With the below:
Link https://msdn.microsoft.com/en-us/library/windows/desktop/bb776890(v=vs.85).aspx
Dim oApp As Object
Set oApp = CreateObject("WScript.Shell")
'get a shell object
Set oApp = CreateObject("Shell.Application")
If oApp.Namespace(ZipFile).Items.count > 0 Then
I get this error:
Object doesn't support this property or method
On this line:
If oApp.Namespace(ZipFile).Items.count > 0 Then
References to links I have tried:
https://wellsr.com/vba/2015/tutorials/open-and-close-file-with-VBA-Shell/
http://www.vbaexpress.com/forum/showthread.php?38616-quot-shell-quot-not-work-in-Excel
Excel VBA - read .txt from .zip files
I just don't understand why this step is taking so much time to complete.
Your main problem is a really simple one: Your path "C:\Users\UserName\Desktop\Today\MyFolder\" contains already a trailing backslash, and when you set your ZipFile-variable, you are adding another one between path and filename. This will cause the shell-command to fail and ZipFile is nothing.
There are some minor problems with the code. I would recommend to use the GetExtensionName of your FileSystemObject to get the extension and convert this to lowercase so that you catch all files, no matter if they are .PNG, .png or .Png
For Each FileInFolder In FSO.GetFolder(x).Files
Dim fileExt As String
fileExt = LCase(FSO.GetExtensionName(FileInFolder.Name))
If fileExt = "png" Then
CountContents = CountContents + 1
Debug.Print "unzipped " & FileInFolder.Name
ElseIf fileExt = "zip" Then
Dim ZipFileName As String, ZipFile, fileInZip
Set sh = CreateObject("Shell.Application")
ZipFileName = x & FileInFolder.Name
Set ZipFile = sh.Namespace(CVar(ZipFileName))
For Each fileInZip In ZipFile.Items
If LCase(FSO.GetExtensionName(fileInZip)) = "png" Then
CountContents = CountContents + 1
Debug.Print "zipped in " & FileInFolder.Name & ": " & fileInZip
End If
Next
End If
Next FileInFolder
Additionally the strong advice to use Option Explicit and define all your variables. And split commands into smaller pieces. This costs you only a few seconds of typing the extra lines but helps you when debugging your code:
' Instead of
' Set ZipFile = sh.Namespace(CVar(x & "\" & FileInFolder.Name))
' write
Dim fName as string
fName = x & "\" & FileInFolder.Name; ' Now you can check fName and see the problem.
Set ZipFile = sh.Namespace(CVar(fName))
Try this:
Option Explicit
' Just to test CheckZipFolder
Sub TestZip()
Dim sZipFold As String: sZipFold = "C:\Temp\MyZip.zip" ' Change this to the path to your zip file
CheckZipFolder sZipFold
End Sub
Sub CheckZipFolder(ByVal sZipFold As String)
Dim oSh As New Shell ' For this, you need to add reference to 'Microsoft Shell Controls and Automation'
Dim oFi As Object
' Loop through all files in the folder
For Each oFi In oSh.Namespace(sZipFold).Items
' Checking for file type (excel file in this case)
If oFi.Type = "Microsoft Excel Worksheet" Then
MsgBox oFi.Name
'..... Add your actions here
End If
' This will make the UDF recursive. Remove this code if not needed
If oFi.IsFolder Then
CheckZipFolder oFi.Path
End If
Next
' Clear object
Set oSh = Nothing
End Sub
I have an excel file that when opened needs to download and open the latest version of an add in that is stored in Sharepoint. I have this code that downloads the add in, saves it in a specific location (strSavePath) and tries to open it.
Function funLoadRomeFiles(strURL As String, strSavePath As String)
Dim objConnection As Object
Dim objStream As Object
Set objConnection = CreateObject("MSXML2.ServerXMLHTTP.6.0")
On Error GoTo ExitConnect
objConnection.Open "GET", strURL, False
objConnection.send
strURL = objConnection.responseBody
If objConnection.Status = 200 Then
Set objStream = CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1
objStream.Write objConnection.responseBody
objStream.SaveToFile strSavePath, 2
objStream.Close
End If
ExitConnect:
On Error GoTo 0
Shell "C:\WINDOWS\explorer.exe """ & strSavePath & "", vbHide
End Function
However I get an error on the second to last row. The error is: Excel cannot open the file "Filename" because the file format or file extension is not valid [...]". The file downloaded is corrupted and cannot be opened manually either. When I download it and open it manually , it works.
The file size is 30.9 kb, but executing the code will download it as a 51 kb file. I've tried downloading other files using this code, and they have also become corrupted and 51 kb no matter the actual file size. Is there any way to change the code so the file will not be corrupted or any other ways of doing this?
Update: The file downloaded seems to be a html file even though its name still ends with .xlam
Also, I,ve tried using a link that ends with "filename.xlam" and one that ends with "filename.xlam?csf=1&e=b5f7991021ab45c1833229210f3ce810", both gives the same result, and when you copy the links into chrome both immediately downloads the correct file
I had a once a similar Problem.
The Problem by me was, that sharepoint did not allow a certain kind of file Type. So i had to do a workaround. So what you can try is to Zip your *.xlam File and Put that on the Sharepoint. Then you download it with the Code you already have. And then you just unzipped with the Following Code.
Sub Unzip1()
Dim FSO As Object
Dim oApp As Object
Dim Fname As Variant
Dim FileNameFolder As Variant
Dim DefPath As String
Dim strDate As String
Fname = strSavePath' I assume that this is the Path to the File you Downloaded
If Fname = False Then
'Do nothing
Else
'Root folder for the new folder.
DefPath = Application.DefaultFilePath 'Or Change it to the Path you want to unzip the Files
If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
'Create the folder name
strDate = Format(Now, " dd-mm-yy h-mm-ss")
FileNameFolder = DefPath & "MyUnzipFolder " & strDate & "\"
'Make the normal folder in DefPath
MkDir FileNameFolder
'Extract the files into the newly created folder
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(Fname).items
'If you want to extract only one file you can use this:
'oApp.Namespace(FileNameFolder).CopyHere _
'oApp.Namespace(Fname).items.Item("test.txt")
MsgBox "You find the files here: " & FileNameFolder
On Error Resume Next
Set FSO = CreateObject("scripting.filesystemobject")
FSO.deletefolder Environ("Temp") & "\Temporary Directory*", True
End If
End Sub
And after that you just executed the Extension.
I Hope this can help you.
I could not find a way to download to add-ins, tried multiple different way and concluded that there was som authorization error or something else caused by the version of SharePoint I was using. The solution I found that suited my needs was to open the add-ins directly from SharePoint using this code:
On Error Resume Next
ActiveWorkbook.FollowHyperlink Address:="strUrl"
On Error GoTo 0
My code asks the user to input a file name. We'll say we have 5 text files in directory "C:\Users\aUser\Desktop\myFolder". These text files are named A, B, C, D, and E.
If the text file exists, then I would like to write over the contents with a script I've already made. If the text file does not exist, I would like to make one with the file name they inputted, and populate it [with the script I've already written].
Thanks for your help.
The way you explain it, it seems that the easiest workflow would be:
1) Delete the file if exists
Sub test()
Dim FSO As FileSystemObject
Dim sPath As String
sPath = "U:\Test.txt"
Set FSO = New FileSystemObject
If FSO.FileExists(sPath) Then
FSO.DeleteFile (sPath)
End If
End Sub
Copy the script (I assume also a txt file) into the path:
FileCopy "U:\Script", sPath
If you have the script in a string variable:
Set txtFile = FSO.CreateTextFile(sPath, True)
txtFile.WriteLine(sText)
FSO.Close
End Sub
If the script is contained in an array, you can loop through the array and produce multiple writelines.
Don't forget to reference the Microsoft Scripting Runtime library.
Something like this
locates the folder for the logged on user regardless of OS
checks that the user input file is contained in a master list (held by StrFiles)
then either creates a new file if it doesn't exist, or
provides a logic branch for you to add your overrwrite script
Sub
code
GetFiles()
Dim wsShell As Object
Dim objFSO As Object
Dim objFil As Object
Dim strFolder As String
Dim StrFile As String
Dim StrFiles()
StrFiles = Array("A.txt", "B.txt", "C.txt")
Set wsShell = CreateObject("wscript.shell")
strFolder = wsShell.specialFolders("Desktop") & "\myFolder"
StrFile = Application.InputBox("Please enter A.txt, B.txt", "File Selection", , , , , 2)
If IsError(Application.Match(StrFile, StrFiles, 0)) Then
MsgBox StrFile & " is invalid", vbCritical
Exit Sub
End If
If Len(Dir(strFolder & "\" & StrFile)) = 0 Then
'make file
Set objFSO = CreateObject("scripting.filesystemobject")
Set objFil = objFSO.createtextfile(strFolder & "\" & StrFile, 2)
objFil.Close
Else
'write over file
'add your code here
End If
End Sub