Excel VBA How to prevent user from hitting cancel in msoFileDialogSaveAs - vba

I am very new to VBA and I am creating a template for my boss. I want to force users to "save as" so that they don't overwrite the template. In other words, I'd like to disable the cancel button when the save as dialog box pops up.
Here is my code:
Dim fPth As Object
Set fPth = Application.FileDialog(msoFileDialogSaveAs)
With fPth
.InitialFileName = CTAPath
.InitialFileName = CTAName & "_CAP DATA"
.Title = "Save with your CTA file"
.InitialView = msoFileDialogViewList
.FilterIndex = 2
If .Show = -1 Then
.Execute
End If
End With
I'm thinking I should create an ELSE statement within the IF statement but I can't figure out what it should be. I've tried searching and I'm not coming up with any solutions.
Thank you!

That's not the way to do this: if the users choose the file itself in the "Save as" filelist, you might end up in the same situation.
I'd advise you to make the file read-only, so nobody can change or overwrite it.

I'm not sure you're able to disable Cancel button, but there is workaround...
You can loop .Show method till user hits Save button ;)
For example:
Sub PreventCancel()
Dim fPth As Object
Set fPth = Application.FileDialog(msoFileDialogSaveAs)
Dim result As Variant
With fPth
.InitialFileName = CTAPath
.InitialFileName = CTAName & "_CAP DATA"
.Title = "Save with your CTA file"
.InitialView = msoFileDialogViewList
.FilterIndex = 2
Do
result = .Show
Loop While result <> True
.Execute
End With
End Sub
[EDIT]
I'd suggest to use Application.GetSaveAsFilename Method (Excel) instead of FileDialog, because it gives you more control over it.
Please, read valuable comments to your question also.

Related

Open the file and save as another name

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

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 catch silent failure of wdDialogFileSaveAs if file is locked?

I created a dialog with three buttons, where the third should save a Word document (Office Pro Plus 2013, BTW) as a PDF file.
Private Sub Button_Dokument_mit_Grafik_als_PDF_speichern_Click()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
With Dialogs(wdDialogFileSaveAs)
.Format = wdFormatPDF
' .Format = 17 '17 = PDF
.Show
End With
Options.PrintDrawingObjects = Grafik
End Sub
If the PDF exists I can choose to overwrite it, which does work in most cases.
If the PDF to be overwritten is already open, in Adobe Reader for instance, then the file isn't saved, as it is locked. I don't get any notification that the file is locked.
How can I catch this and pop up the same message that I get when saving manually within Word?
EDIT:
To explain why my question is different to others that have been answered:
I don't need to check if the file is open in Word already. I'm saving the file as a PDF not as a Word file.
I need to check if the file is open and locked in any other application, such as Adobe Reader, Edge or whatever.
This check is done by Word (and/or the OS?) already, and THIS is the event I need to catch. I don't understand why I need to catch it at all, as the result of the check if the file does exist does come up, but the result of the check if the file is locked seems to be ignored.
The VBA code behaves as if the file has been saved, but it is not, if locked by any application other than Word.
I have no clue which code snippet exactly I would need to grab from Detect whether Excel workbook is already open
Here is what you might be looking for:
Sub SaveAsPdf()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
Dim fDialog As FileDialog
Set fDialog = Application.FileDialog(msoFileDialogSaveAs)
fDialog.Title = "Save a file"
'works only in Word2016 not in word 2013;
'fDialog.InitialFileName = "*.pdf"
'we can use the filterindex property instead
fDialog.FilterIndex = 7
If fDialog.Show = -1 Then
Dim selectedFilePath As String
selectedFilePath = fDialog.SelectedItems(1)
If IsFileInUse(selectedFilePath) Then
MsgBox "The target pdf file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the pdf file and try again.", vbExclamation
Else
ActiveDocument.SaveAs2 selectedFilePath, wdFormatPDF
End If
End If
Options.PrintDrawingObjects = Grafik
End Sub
Private Function IsFileInUse(ByVal filePath As String) As Boolean
On Error Resume Next
Open filePath For Binary Access Read Lock Read As #1
Close #1
IsFileInUse = IIf(Err.Number > 0, True, False)
On Error GoTo 0
End Function
If you would like to use wdDialogFileSaveAs dialog, you can try the below code:
The Display method will display the dialog box without executing the actual functionality. You can validate the result of the display to identify the button clicked and use the execute method to execute the actual functionality.
'Save As Pdf using wdDialogFileSaveAs dialog
'However, it doesn't work as expected.
'The Display method should
Sub SaveAsPdf()
Dim dlg As Dialog
Dim dlgResult As Long
Set dlg = Dialogs(wdDialogFileSaveAs)
With dlg
.Format = wdFormatPDF
dlgResult = .Display
If dlgResult = -1 Then 'user clicks save button;
If .Name <> "" Then
If IsFileInUse(.Name) Then
MsgBox "The target pdf file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the pdf file and try again.", vbExclamation
Else
.Execute
End If
End If
End If
End With
End Sub
Please note that, the above code (wdDialogFileSaveAs dialog) doesn't work as expected in Word 2016 at least in my local enviornment. The Display method executes the actual functionality once the save button is clicked. Also it returns -2 as a dialog result if Save button is clicked.
Thanks to the help of #CSS (see answer and comments above), this is the full currently working code (unless I'd still find any flaws):
Private Sub Button_Dokument_mit_Grafik_als_PDF_speichern_Click()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
Dim dlg As Dialog
Dim dlgResult As Long
Set dlg = Dialogs(wdDialogFileSaveAs)
With dlg
.Format = wdFormatPDF
dlgResult = .Display
If dlgResult = -1 Then 'user clicked save button
If .Name <> "" Then
If IsFileInUse(.Name) Then
MsgBox "The target PDF file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the PDF file and try again.", vbExclamation
Else
.Execute
End If
End If
End If
End With
Options.PrintDrawingObjects = Grafik
End Sub
Private Function IsFileInUse(ByVal filePath As String) As Boolean
On Error Resume Next
Open filePath For Binary Access Read Lock Read As #1
Close #1
IsFileInUse = IIf(Err.Number > 0, True, False)
On Error GoTo 0
End Function
Thanks to #CSS again. :)
You may want to edit your answer, though, so that it does reflect the finally working code. I've given appropriate thanks.

Error when closing a explorer window through a userform

I have a minor issue for one of the features on my userform. If a user clicks the "Browse" button but doesn't click the "Open" button after selecting a file, and instead either closes the window or selects "Cancel", a Run-time error '5': Invalid procedure call or argument is displayed.
Ideally if the user closes the window or selects "Cancel" I would like the user to be returned to the form. I know I'm missing some code but don't know what or where it should go. Below is the code I have;
Private Sub CommandButtonPicture_File_Browse_Click()
Dim FindFile As Office.FileDialog
Dim FoundFile As Variant
Set FindFile = Application.FileDialog(msoFileDialogOpen)
With FindFile
.Filters.Clear
.Filters.Add "Jpegs", "*.jpg;*.jpeg*"
.Filters.Add "Png", "*.png*"
.Filters.Add "Gif", "*.gif*"
.Filters.Add "Bitmaps", "*.bmp*"
.Filters.Add "PDF", "*.pdf*"
.Filters.Add "All Files", "*.*"
.AllowMultiSelect = False
If .Show = True Then
TextBoxPicture_File_Link.Value = .SelectedItems(1)
End If
Me.TextBoxPicture_File_Link = .SelectedItems(1)
End With
End Sub
Please note, the code currently works it adds the file link to text box as intended, it's just the issue discussed above that's a problem.

VBA to Star Basic (OpenOffice), struggling

I have this task to convert recenntly written VBA code to OpenOffice version. I tried to launch it from OpenOffice, but it doesn't work (mostly "unsatisfied query..." error. I am now stuck on Open File Dialog, I can either use VBA compatible open file dialog as mine looks now like that (giving error):
FileToOpen = Application.GetOpenFilename("Please choose a file to import", "Excel Files *.dbf (*.dbf)")
I can also use OpenOffice file dialog box, but couldn't find any information on this.
Thanks in advance
I'm confused on what you're asking, but if you're having trouble creating a file dialog box, this is VBA code that will do it for you. I think this is what you're asking, but I could be wrong.
Private Sub cmdFileDialog_Click()
' This requires a reference to the Microsoft Office 11.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
' Clear the list box contents.
Me.FileList.Value = ""
' Set up the File dialog box.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
' Change allowmultiselect to true if you want them to be able to select multiple files
.AllowMultiSelect = False
' Set the title of the dialog box.
.Title = "Select One or More Files"
' Clear out the current filters, and then add your own.
.Filters.Clear
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
' Loop through each file that is selected and then add it to the list box.
For Each varFile In .SelectedItems
Me.FileList.Value = varFile
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub