VBScript to open a dialog to select a filepath - vba

At present I am opening a file with my vbscript as follows:
strFile = "C:\Users\test\file.txt"
Set objFile = objFSO.OpenTextFile(strFile)
I would like to change this so that a file can be selected/navigated to by the user and that file is used in the script. How can I add this ability? I have tried to search for how to load a file dialog/prompt the user for a file etc just not sure how to complete in a VBScript.

There is another solution I found interesting from MS TechNet less customization but gets what you wanted to achieve. This returns the full path of the selected file.
Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("mshta.exe ""about:<input type=file id=FILE><script>FILE.click();new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>""")
sFileSelected = oExec.StdOut.ReadLine
wscript.echo sFileSelected

Here you go:
http://www.robvanderwoude.com/vbstech_ui_fileopen.php
strFile = GetFileName("C:\Users\test\", "Text files|*.txt")
Set objFile = objFSO.OpenTextFile(strFile)
Function GetFileName( myDir, myFilter )
' Written by Rob van der Woude
' http://www.robvanderwoude.com
' Standard housekeeping
Dim objDialog
' Create a dialog object
Set objDialog = CreateObject( "UserAccounts.CommonDialog" )
' Check arguments and use defaults when necessary
If myDir = "" Then
' Default initial folder is "My Documents"
objDialog.InitialDir = CreateObject( "WScript.Shell" ).SpecialFolders( "MyDocuments" )
Else
' Use the specified initial folder
objDialog.InitialDir = myDir
End If
If myFilter = "" Then
' Default file filter is "All files"
objDialog.Filter = "All files|*.*"
Else
' Use the specified file filter
objDialog.Filter = myFilter
End If
' Open the dialog and return the selected file name
If objDialog.ShowOpen Then
GetFileName = objDialog.FileName
Else
GetFileName = ""
End If
End Function

The currently chosen answer doesn't support filters, but hta can be manipulated to support them.
Here's an answer based on this tek-tips.com post (which is also mentioned in
How to add filter to a file chooser in batch?), but I added a full function structure plus support for relative folders:
Function GetFileDlgEx(sIniDir,sFilter)
sTitle = "Choose File"
set objShell = WScript.CreateObject("WScript.Shell")
if instr(sIniDir, ":") <= 0 then
sIniDir = objShell.CurrentDirectory & "\" & sIniDir
end if
sIniDir = Replace(sIniDir,"\","\\")
Set oDlg = objShell.Exec("mshta.exe ""about:<object id=d classid=clsid:3050f4e1-98b5-11cf-bb82-00aa00bdce0b></object><script>moveTo(0,-9999);eval(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).Read("&Len(sIniDir)+Len(sFilter)+Len(sTitle)+41&"));function window.onload(){var p=/[^\0]*/;new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(p.exec(d.object.openfiledlg(iniDir,null,filter,title)));close();}</script><hta:application showintaskbar=no />""")
oDlg.StdIn.Write "var iniDir='" & sIniDir & "';var filter='" & sFilter & "';var title='" & sTitle & "';"
GetFileDlgEx = oDlg.StdOut.ReadAll
End Function
sIniDir = "*.*pdf" ' will look in current folder - note extension must be preceded by an asterisk *.
'sIniDir = "docs\*.*pdf" ' will look in a relative folder
'sIniDir = "C:\Windows\*.*pdf" ' will look in an absolute folder
sFilter = "Adobe pdf (*.pdf)|*.pdf|All files (*.*)|*.*|Microsoft Word (*.doc;*.docx)|*.doc;*.docx|Image files (*.gif;*.png;*jpg;*.bmp)|*.gif;*.png;*jpg;*.bmp|Html files (*.htm;*.html;*.mht)|*.htm;*.html;*.mht|"
rep = GetFileDlgEx(sIniDir,sFilter)
MsgBox rep

VBSEdit program installs a COM library VBSEdit Toolkit, which allows Open File dialogs.
From VBSEdit help:
Dialog boxes
OpenFileDialog method
Prompt the user to open a file
toolkit.OpenFileDialog ([initialFolder,[filters,[multiselect,[title]]]])
'Opens a single file
Set toolkit = CreateObject("VbsEdit.Toolkit")
files=toolkit.OpenFileDialog("c:\scripts\","Text Files (*.txt)|*.txt",False,"Open a text file")
If UBound(files)>=0 Then
WScript.Echo files(0)
Else
Wscript.Quit
End If
'Opens multiple files
Set toolkit = CreateObject("VbsEdit.Toolkit")
files=toolkit.OpenFileDialog("c:\scripts\","Text Files (*.txt)|*.txt",True,"Open a text file")
If UBound(files)>=0 Then
For Each filepath In files
WScript.Echo filepath
Next
Else
Wscript.Quit
End If
SaveFileDialog method
Prompt the user to save a file
toolkit.SaveFileDialog ([initialFolder,[initialFilename,[filters,[title]]]])
Set toolkit = CreateObject("VbsEdit.Toolkit")
filepath = toolkit.SaveFileDialog("c:\scripts","test.txt","Text Files (*.txt)|*.txt")
If Not(IsNull(filepath)) Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(filepath,True)
objFile.WriteLine Date
objFile.Close
Else
Wscript.Quit
End If
SelectFolder method
Prompt the user to select a folder
toolkit.SelectFolder ([initialDir,[title]])
Set toolkit = CreateObject("VbsEdit.Toolkit")
myfolder=toolkit.SelectFolder("c:\scripts\","Please select a folder")
If Not(IsNull(myfolder)) Then
WScript.Echo myfolder
Else
Wscript.Quit
End If
…
(Actually, folder selection dialogs can be opened without VBSEdit toolkit, with BrowseForFolder method of Shell.Application object.)

Found this answer HERE
Set WshShell=CreateObject("Wscript.Shell")
WshShell.BrowseForFolder(0, "Please select the folder.", 1, "")

Related

How to open two types of documents in one folder?

I frequently run a macro on folders that contain .doc and .docx files. Currently, my macro is only able to edit one type of file and then I have to change my macro from .doc to .docx (or vice versa) and run again.
How could I get both file types in one go?
The current code.
'UpdateDocuments
Sub UpdateDocuments()
Dim file
Dim path As String
'Path to your folder.
'make sure to include the terminating "\"
‘Enter path.
path = "C:\Users\emckenzie\Documents\TEMP PLOT\macro practice\Andria footer change\"
'Change this file extension to the file you are opening
file = Dir(path & "*.docx")
Do While file <> ""
Documents.Open FileName:=path & file
'This is the call to the macro you want to run on each file the folder
'Enter macro.
Call Permit2hundred
' Saves the file
ActiveDocument.Save
ActiveDocument.Close
'set file to next in Dir
file = Dir()
Loop
End Sub
To answer your question:
Use a wildcard like * or ? in this line: fileExtension = "*.doc?"
You can read more about wildcard characters here
Some suggestions on your code:
Assign variable types when you're defining them
Indent your code (You can use www.rubberduckvba.com)
Define your variables close to where you first use them (matter of preference)
When working with documents, assign them to a document variable and refer to that variable instead of ActiveDocument
Use basic error handling
Additional tip:
When calling this procedure Permit2hundred you could pass the targetDocument variable like this:
'This is the call to the macro you want to run on each file the folder
'Enter macro.
Permit2hundred targetDocument
' Saves the file
targetDocument.Save
And the definition of that procedure could be something like this:
Private Sub Permit2hundred(ByVal targetDocument as Document)
'Do something
End Sub
This is the refactored code:
Public Sub UpdateDocuments()
' Add basic Error handling
On Error GoTo CleanFail
'Path to your folder.
'make sure to include the terminating "\"
'Enter path.
Dim folderPath As String
folderPath = "C:\Users\emckenzie\Documents\TEMP PLOT\macro practice\Andria footer change\"
'Change this file extension to the file you are opening
Dim fileExtension As String
fileExtension = "*.doc?"
' Get files in folder
Dim fileName As String
fileName = Dir(folderPath & fileExtension)
' Loop through files in folder
Do While file <> vbNullString
Dim targetDocument As Document
Set targetDocument = Documents.Open(fileName:=folderPath & file)
'This is the call to the macro you want to run on each file the folder
'Enter macro.
Permit2hundred
' Saves the file
targetDocument.Save
targetDocument.Close
'set file to next in Dir
file = Dir()
Loop
CleanExit:
Exit Sub
CleanFail:
MsgBox "Something went wrong. Error: " & Err.Description
GoTo CleanExit
End Sub
Let me know if it works
I prefer to display a file picker dialog and then select what I want. I am then able to choose a doc or docx file without having to alter my code. The Filter property determines the file types allowed. Note that this code clears the filter when it ends, otherwise that is the filter Word will use from that point on, even for manually initiated (non-programmatic) requests of File Open.
This example is setup to allow multiple selections. You can change the AllowMultiSelect to False and then the code will run with only one file at a time.
Dim i As Integer, selFiles() As String
Dim strFolderPath As String, Sep As String
Sep = Application.PathSeparator
Erase selFiles
'Windows Office 2019, 2016, 2013, 2010, 2007
With Application.FileDialog(msoFileDialogFilePicker)
.Title = "Select the files to update"
.InitialFileName = curDir
.AllowMultiSelect = True
.Filters.Clear
.Filters.Add "All Word Files", "*.docx; *.docm; *.doc", 1
If .Show = 0 Then
Exit Sub
End If
ReDim Preserve selFiles(.SelectedItems.Count - 1)
strFolderPath = Left(.SelectedItems(1), InStrRev(.SelectedItems(1), Sep))
For i = 0 To .SelectedItems.Count - 1
selFiles(i) = .SelectedItems(i + 1)
Next
.Filters.Clear
End With

Insert an image file in a MAC Word Userform

I am not a programmer so not sure what to do here. I would like an option of adding an image file in a Microsoft Word document userform for MAC. I had used a code earlier which works perfectly in Windows but it doesnt work for MAC and gives a 5948 error. I had added a field for the image in the userform with a button to add the image and the final submit button. The add button should allow the user to insert any size image from the local folder.
The code I was using is given below:
Dim ImagePath As String
Private Sub CMDAddImage_Click()
Dim objFileDialog As Office.FileDialog
Set objFileDialog = Application.FileDialog(MsoFileDialogType.msoFileDialogFilePicker)
With objFileDialog
.AllowMultiSelect = False
.ButtonName = "File Picker"
.Title = "File Picker"
If (.Show > 0) Then
End If
If (.SelectedItems.Count > 0) Then
Call MsgBox(.SelectedItems(1))
ImagePath = .SelectedItems(1)
End If
End With
Image1.Picture = LoadPicture(ImagePath)
End Sub
And the code in submit button was:
Dim objWord
Dim objDoc
Dim objShapes
Dim objSelection
'Set objSelection = ActiveDocument.Sections
'objSelection.TypeText (vbCrLf & "One Picture will be inserted here....")
ActiveDocument.Bookmarks("Field04").Select
Set objShapes = ActiveDocument.InlineShapes
objShapes.AddPicture (ImagePath)
End
End Sub
Can someone please help me edit the code for mac. In mac it does not allow to add the file.
You should check out the suggestion made by #JohnKorchok in a comment to your previous question - insert an image Content Control in your document instead, and throw away the VBA.
But if you need to keep using VBA and a UserForm...
Application.FileDialog is not available on Mac.
Application.GetOpenFileName is not avaialble from Word (it's an Excel thing).
Application.Dialogs does not do the same thing as GetOpenFileName so the user experience will be rather different, but at its simplest, you can use it like this:
With Application.Dialogs(wdDialogFileOpen)
' .Display = -1 for "OK" ("Open" in this case)
' .Display = 0 for "Cancel"
' (THere are other possible return values
' but I do not think they are applicable here)
If .Display = -1 Then
ImagePath = .Name
End If
End With
or if you prefer, the lengthier
Dim dlg As Word.Dialog
Set dlg = Application.Dialogs(wdDialogFileOpen)
With dlg
If .Display = -1 Then
ImagePath = .Name
End If
End With
Set dlg = Nothing
However, this dilaog does not let you specify file types or any kind of filtering, a starting folder etc. Attempts to set Finder search criteria via something like
.Name = "(_kMDItemFileName = ""*.jpg"")"
.Update
before the .Display either can't work or need different syntax.
Further, the Apple dialog may start with its
own filtering set up so the user will have to click Options to enable All Files. You don't know what file type the user will choose so you will need to deal with that.
An alternative is to invoke Applescript. For this, it appears that you can still use the VBA MacScript command, which means that you can put all the script in your VBA file. If that does not work, then unfortunately you have to use AppleScriptTask which would require you to work some more on the Script and install the script in the correct folder on every Mac where you need this feature.
Here's the code I used - you would probably need to wrap everything up in another function call and use conditional compilation or other tests to call the correct routine depending on whether the code is running on Mac or Windows
Private Sub CMDAddImage_Click()
Dim s As String
Dim sFileName As String
On Error Resume Next
s = ""
' set this to some other location as appropriate
s = s & "set thePictureFoldersPath to (path to pictures folder)" & vbNewLine
s = s & "set applescript's text item delimiters to "",""" & vbNewLine
s = s & "set theFile to ¬" & vbNewLine
' add the image file types you want here
s = s & "(choose file of type {""png"",""jpg""} ¬" & vbNewLine
s = s & "with prompt ""Choose an image to insert."" ¬" & vbNewLine
s = s & "default location alias thePictureFoldersPath ¬" & vbNewLine
s = s & "multiple selections allowed false) as string" & vbNewLine
s = s & "set applescript's text item delimiters to """"" & vbNewLine
' choose file gives as an AFS path name (with colon delimiters)
' get one Word 2016/2019 will work with
s = s & "posix path of theFile"
sFileName = MacScript(s)
If sFileName <> "" Then
' Maybe do some more validation here
ImagePath = sFileName
Image1.Picture = LoadPicture(ImagePath)
End If
End Sub

Open only files with HTML extension from folder(path) without giving File names

Open all files of only 1extension in particular path without giving file names.Since i have lot of html files in 1 folder with different file names but same extension(.html)
I can open directly with this code but need to give file name. I have multiple files with different names with same(.html) extension which makes very difficult to open those files 1by1 and giving entries to submit
Set web = CreateObject("Shell.Application")
web.Open ("C:\Users\hp\Desktop\mani\hi.html")
Set web = Nothing
Use the Dir command to cycle through all *.html files in that folder.
dim fn as string, fp as string, fm as string
dim web as object
Set web = CreateObject("Shell.Application")
fp = "C:\Users\hp\Desktop\mani\"
fm = "*.html"
fn = Dir(fp & fm)
do while cbool(len(fn))
web.Open fp & fn
'do something to the file here
'close the open file here
fn = Dir
loop
or you could have the user pick the wanted file(s) and process them one by one:
Sub PickHTMLFile()
With Application.FileDialog(msoFileDialogFilePicker)
.Filters.Add "Html files", "*.html", 2 ' add a filter #2
.FilterIndex = 2 ' set initial file filter to the added one #
.Show
If .SelectedItems.Count > 0 Then
Dim f As Variant
For Each f In .SelectedItems 'loop through selected items
'do your job here, as for example:
MsgBox "Selected item's path: " & f 'show the current item path
With CreateObject("Shell.Application")
.Open f
End With
Next
Else
MsgBox "user canceled file picker!"
End If
End With
End Sub

how to unzip a attachment in outlook and save it to a foldeer using vba

currently i have an Email that comes in and my vba code will save the file to a folder, however since this code was made they now send me the file in a zip file. This of course breaks the code and i have to resend it in a non zip file to make it work. Here is a sample of what I am currently using:
If Left(objItem.Subject, 28) = "xxxxx report Toolbox" Then
For Each Atmt In objItem.Attachments
FileName = "O:\Automated Reports\toolbox.xlsx"
Atmt.SaveAsFile FileName
modify_file
Debug.Print "success CSAT file"
Open "O:\Automated Reports\toolboxDate.JW" For Output As #1
Write #1, Right(objItem.Subject, 5)
Close #1
Next Atmt
End If
As i stated before this code woks fine for just saving the file when it is not a .zip file. I need it to unzip the file and save it to the O: drive. I have tried to use some shell.application objects but i didn't quite get that to work. Thanks for any help ahead of time
'Create new blank zip.
Set Ag=Wscript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Ag(0), 8, vbtrue)
BlankZip = "PK" & Chr(5) & Chr(6)
For x = 0 to 17
BlankZip = BlankZip & Chr(0)
Next
ts.Write BlankZip
'Unzip
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set SrcFldr=objShell.NameSpace(Ag(1))
Set DestFldr=objShell.NameSpace(Ag(0))
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Msgbox "Finished"
'Zip
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set DestFldr=objShell.NameSpace(Ag(1))
Set SrcFldr=objShell.NameSpace(Ag(0))
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Msgbox "Finished"

Check if a filename without extension exists

I have the file name with the entire path of the file except the file extension.
Example: "C:\temp\FileNameWithoutExtension". Now I want to check if this file exists? I don't care about the file extension.
When I have the entire file name including file extension I was using following code to see if the file exists.
Set oFSO = CreateObject("Scripting.FileSystemObject")
FileExists = oFSO.FileExists(FileName)
Thanks for help.
It would be nice if FileExists handled wildcards but it does not. Would something like this help?
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\temp")
Set objFiles = objFolder.Files
For Each objSingleFile in objFiles
If objSingleFile.Name Like "FileNameWithoutExtension*" Then
' The file name starts with FileNameWithoutExtension
MsgBox "Are you looking for me?: " & objSingleFile.Name
End If
Next
This is making assumption about the location you are searching and it is not recusrive but the basics are here for you to look at. This is not the only approach.
Try this
Sub FileExist()
Dim file As String, fileName As String
fileName = "C:\temp\abc" & "*"
file = Dir(fileName)
If file = "" Then
MsgBox "File doesn't exist"
Else
MsgBox "file found"
End If
End Sub