Open the file and save as another name - vba

I want to create a new word file called "xxx_def_xxx" from selected word file called "xxx_docu_xxx".
So I select a file from dialog -> do something -> SaveAs with new file name.
It does work, but I'm getting "run time error 4160: Bad file name" if I select the file created from others, i.e., if the author is not me but another person.
I was struggling with this problem for couple of days but couldn't solve it.
Any help will be really thankful!
Private Sub CommandButton1_Click()
Dim fileOpen As FileDialog
Dim docuName As String, defName As String
Dim docu As Document
Set fileOpen = Application.FileDialog(FileDialogType:=msoFileDialogOpen)
With fileOpen
.Filters.Clear
.Filters.Add "Word Documents", "*.docx*"
.Title = "Select the docu"
.AllowMultiSelect = False
If .Show = -1 Then
docuName = .SelectedItems(1)
Else
Exit Sub
End If
End With
Set docu = Documents.Open(docuName)
'do something: remove or edit some texts in the file
defName = Replace(docu.Name, "docu", "def")
docu.SaveAs docu.Path & "\" & defName
docu.Saved = True
docu.Close
End Sub

Related

Select folder using browse button in VBA

I have a requirement where I need to select a folder instead of a file, while clicking a browse button.
The code to select a file, while clicking the browse button will be as below.
Case "Browse"
DlgText "path", GetFilePath(,"*.*","C:\","Open sheet")
How to change this to select a folder, instead of a file.
Thanks in advance
Please, try the next way:
Case "Browse"
Dim folderPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select the necessary folder!"
.Show
.AllowMultiSelect = False
If .SelectedItems.Count = 0 Then 'If no folder is selected, abort
MsgBox "You did not select any folder..."
Exit Sub
End If
folderPath = .SelectedItems(1)
End With
'your existing code...
Edited:
If you work in Windows OS, even if ERStudio, which I am not fammiliar to, does not expose such a method, please try the next way, using VBScript objects:
Case "Browse"
Dim objSh As Object, objFold As Object, strStartFolder As String, strFolder As String
strStartFolder = "C:\" 'you can use here what starting folder you want
Set objSh = CreateObject("Shell.Application")
Set objFold = objSh.BrowseForFolder(0, "Select The necessary Folder", 0, strStartFolder)
If IsObject(objFold) Then strFolder = objFold.Self.Path
MsgBox strFolder 'use it where necessary and comment this testing line...
'your existing code...

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

MS Access: Upload multiple files from one button

I am trying to upload multiple files at once into an access database via the use of a button. However only one file will upload at a time.
When the button is clicked it calls a sub procedure. My code is below:
Private Sub btnImport_Click()
'Calls the procdure that imports raw files
Call Module1.ImportRawFiles
End Sub
Public Sub ImportRawFiles()
Dim oFileDiag As Office.FileDialog
Dim path As String: path = ""
Dim oFSO As New FileSystemObject
Dim FileSelected As Variant
Set oFileDiag = Application.FileDialog(msoFileDialogFilePicker) ''Picks file to import
oFileDiag.AllowMultiSelect = True ''Allows multiple files to be selected
oFileDiag.Title = "Please select the reports to upload"
oFileDiag.Filters.Clear
oFileDiag.Filters.Add "Excel Spreadsheets", "*.xlsx, *.xls" ''Only allows xlsx and xls file types to upload
If oFileDiag.Show Then
For Each FileSelected In oFileDiag.SelectedItems
Form_Homepage.txtFileName = FileSelected
Next
End If
If Nz(Form_Homepage.txtFileName, "") = "" Then
MsgBox "No files selected please select a file"
Exit Sub
End If
If oFileDiag.SelectedItems.Count > 0 Then path = oFileDiag.SelectedItems(1)
If Len(path) > 0 Then
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, oFSO.GetFileName(Form_Homepage.txtFileName), path, 1
MsgBox "The " & oFSO.GetFileName(Form_Homepage.txtFileName) & " file has been uploaded"
Else
MsgBox "File not found"
End If
Does anyone know why only one file is uploading?
You are looping through all selected files to assign Form_Homepage.txtFileName but then not doing anything else in that same loop:
If oFileDiag.Show Then
For Each FileSelected In oFileDiag.SelectedItems
Form_Homepage.txtFileName = FileSelected
Next
End If
So by end of the loop, the last selected file is assigned, ignoring all the others, then your later logic statements only perform on that one file.
One solution would be to move your action logic up to the same loop. So move your IF statements into the assignment loop, that way they operate on each iterative assignment of your variable.

Open Windows Explorer from Outlook to choose template [duplicate]

This question already has answers here:
Filepicker VBA to select file and store the file name not working
(2 answers)
Closed 3 years ago.
I am trying to write a macro that allows a user to select a .oft from a directory. I have been able to get a simple macro working that will open a specific .oft and modify the "from" field - this is what I have so far.
Sub EmailTemplateW10()
Set msg = Application.CreateItemFromTemplate("c:\test\test.oft")
msg.SentOnBehalfOfName = "user#domain.com"
msg.Display
Set msg = Nothing
End Sub
That works great, but there are numerous .oft files in the directory I am working with. I did find some articles that talk about setting up a toolbar with drop-downs and creating a macro for each .oft in the directory. I assume there has to be a better way than making a macro for each template.
I tried using this :
Sub EmailTemplateW10()
Set msg = Application.CreateItemFromTemplate(Demo)
msg.SentOnBehalfOfName = "user#domain.com"
msg.Display
Set msg = Nothing
End Sub
Function Demo()
Call Shell("explorer.exe" & " " & "C:\test\", vbNormalFocus)
End Function
Windows Explorer will come up - but the macro throws an error and stops when you acknowledge the error.
Is there perhaps some way to have the user select the file through explorer.exe and save the path of the selected file to a variable, and then pipe that into .CreateItemFromTemplate?
After some digging around I got this to work. I am obviously a VBA noob so i take no credit for the code - I was just able to mash it together and get it to work. Maybe someone in the future will find it helpful.
Public Function aBrowseForFile(aStartFolder As String) As String
On Error GoTo Err_txtBrowseForFile
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False
Dim fDialog As Office.FileDialog
Dim varfile As Variant
Dim strPath As String
Dim strFilter As String, strFileName As String
Dim Main_Dir As String, DefFolder As String
Set fDialog = xlApp.Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.InitialView = msoFileDialogViewThumbnail
.AllowMultiSelect = False
.Title = "Please select one or more files"
.InitialFileName = aStartFolder
.InitialView = msoFileDialogViewThumbnail
.Filters.Clear
.Filters.Add "all files", "*.*"
If .Show = True Then
aBrowseForFile = .SelectedItems(1)
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
Exit_txtBrowseForFile:
Exit Function
Err_txtBrowseForFile:
MsgBox Err.Description, vbCritical, "MyApp"
Resume Exit_txtBrowseForFile
End Function
Sub EmailTemplateW10()
Dim MyFileURL As String
MyFileURL = aBrowseForFile("C:\users\")
Set msg = Application.CreateItemFromTemplate(MyFileURL)
msg.SentOnBehalfOfName = "user#domain.com"
msg.Display
Set msg = Nothing
End Sub

Issue using FileDialog Application

I have a bit of code which I am trying to improve but having some issues.
The code is currently:
Sub TestListFilesInFolder()
'Workbooks.Add ' create a new workbook for the file list
' add headers
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFolderPicker) ' Tried using a FileDialog Application but had no luck
With Range("A1")
.Formula = "Folder contents:"
.Font.Bold = True
.Font.Size = 12
End With
Range("A3").Formula = "Old File Path:"
Range("B3").Formula = "File Type:"
Range("C3").Formula = "File Name:"
Range("D3").Formula = "New File Path:"
Range("A3:H3").Font.Bold = True
ListFilesInFolder "L:\Pictures\A B C\B526 GROUP", True
' ListFilesInFolder fd, True ' I tried replacing the above line with this line but get an error
' list all files included subfolders
End Sub
Line 5 and 6 is a part I have added in where I am trying to get a file dialog to open where the user can choose the folder for the code to work on.
Also The commented out line near the bottom starting ListFilesInFolder is the one I tried inserting to replace the line above it.
The start of the next bit of code is:
Sub ListFilesInFolder(SourceFolderName As String, IncludeSubfolders As Boolean)
So it uses the folder and subfolders of that folder defined in the first sub.
Any help on this would be appreciated.
Regards,
Sam
You're passing fd as the first parameter to your ListFilesInFolder sub. This sub accepts a String as the first parameter, not a FileDialog.
Here's some sample code that, when executed, will open a file dialog and let the user select a folder. Once selected, it will print the path of the folder to B2. If no folder is selected (e.g. dialog is closed or canceled), B2 will contain the text No item selected.
I think you should create a new workbook and play around with this macro. Set a break point and walk through it, see what it's actually doing. Then you can alter it to make it work for your specific needs.
Public Sub SelectExportDestinationPath()
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then
sItem = "No item selected"
Else
sItem = .SelectedItems(1)
End If
End With
'if trailing slash is not found, add it
If Len(sItem) > 0 And InStr(Len(sItem), sItem, Application.PathSeparator, vbCompareText) = 0 Then
sItem = sItem & Application.PathSeparator
End If
Sheet1.Cells(2, 2).Value = sItem
Set fldr = Nothing
End Sub
make sure you have the appropriate reference picked:
Press Alt+F11 to open the VB Editor. In that window, choose menu items Tools -> References..., then look down the list for Microsoft Office XXX Object Library
It's 11.0 for Access 2003, 10.0 for Access 2002; 9.0 for Access 2000, 8.0 for Access 97 -- pick the right one.
Put a check mark in the box next to that reference, then close the dialog.
or, use the actual values, not the mso values
msoFileDialogOpen=1
msoFileDialogSaveAs=2
msoFileDialogFilePicker=3
msoFileDialogFolderPicker=4