Optimize msoFileDialogOpen - vba

I am trying to make this msoFileDialogOpen allow the user to select multiple files. Is there a better way to do this:
Public Sub Function3_FileExplorer()
' Start File Explorer to select file containing data (simple GUI, much
' easier than coding vFileName)
vuserChoiceDataFileNumber = InputBox("Enter the number of files you want to select.")
With Application.FileDialog(msoFileDialogOpen)
Select Case IsNumeric(vuserChoiceDataFileNumber)
Case True
If VarType(vuserChoiceDataFileNumber) = 2 Or 3 Then
iuserChoiceDataFileNumber = CInt(vuserChoiceDataFileNumber)
End If
Case False
MsgBox (vuserChoiceDataFileNumber & " is not an integer.")
.AllowMultiSelect = False
End Select
.Show
End With
Exit Sub
On Error GoTo ErrorHandler
.AllowMultiSelect = True
ErrorHandler:
MsgBox "Error detected" & vbNewLine & "Error" & Err.Number & ": " & _
Err.Description, vbCritical, "Error Handler: Error " & Err.Number
MsgBox "If you want to force the program to run, go to the line below and " & _
"insert a ' mark to comment the line out." & vbNewLine & _
"On Error GoTo ErrorHandler", vbCritical, "Error Handler: Error " & Err.Number
End Sub

Yes, you can make this much simpler by not asking the user how many files they want to open--just let them select as many as they want.
Public Sub Function3_FileExplorer()
' Start File Explorer to select file containing data (simple GUI, much easier than coding vFileName)
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.FilterIndex = 2
If .Show Then
Dim file As Variant
For Each file In .SelectedItems
' do something with the file, for example, open it:
Application.Workbooks.Open (file)
Next file
End If
End With
End Sub

Related

Import Excels with table checking - access 2016

I have googled everywhere but I am unable to find out to do it without rewriting all the code, is there anyway to have this code check whether the file name matches table names and if it does then clear that table and re import or if not then create a new table?
Option Compare Database
Option Explicit
Private Sub btnBrowse_Click()
Dim diag As Office.FileDialog
Dim item As Variant
Set diag = Application.FileDialog(msoFileDialogFilePicker)
diag.AllowMultiSelect = False
diag.Title = "Please select an Excel Spreadsheet"
diag.Filters.Clear
diag.Filters.Add "Excel Spreadsheets", "*.xls, *.xlsx, *.xlsm"
If diag.Show Then
For Each item In diag.SelectedItems
Me.txtFileName = item
Next
End If
End Sub
Private Sub btnImportSpreadsheet_Click()
Dim FSO As New FileSystemObject
If FSO.FileExists(Nz(Me.txtFileName, "")) Then
ImportExcelSpreadsheet Me.txtFileName, FSO.GetFileName(Me.txtFileName)
ElseIf Nz(Me.txtFileName, "") = "" Then
MsgBox "Please select a file!", vbExclamation
Else
MsgBox "File not found!", vbExclamation
End If
End Sub
Public Sub ImportExcelSpreadsheet(Filename As String, TableName As String)
On Error Resume Next
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, TableName, Filename, True
If Err.Number = 3125 Then
If vbOK = MsgBox(Err.Description & vbNewLine & vbNewLine & "Skip column header and continue?", vbExclamation + vbOKCancel, "Error with Excel Column header") Then
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, TableName, Filename, False
MsgBox "Done", vbInformation
End If
Exit Sub
ElseIf Err.Number <> 0 Then
MsgBox Err.Number & ":" & Err.Description, vbCritical
Exit Sub
End If
MsgBox "Upload Complete", vbInformation
End Sub
Thank for any help
You'll have to rewrite some. Without looping through Tables collection and testing against each name, every method seems to involve handling an error. Here is one:
Function TableExists(strTableName As String) As Boolean
On Error Resume Next
TableExists = IsObject(CurrentDb.TableDefs(strTableName))
End Function
Call the function:
If TableExists("YourTableName") = True Then
More examples in How to check if a table exists in MS Access for vb macros

Print to PDF not working

My code is suppose to check cell j2 for an email address and if found, convert that specific tab to pdf and save it in a file path that the user chooses. It works fine on the original workbook I made the macro in. When I copy the code and try running it, it prints to pdf different sheets that don't even have anything in j2 with the incorrect tab name. I keep getting an Run time error 5 Invalid procedure call or argument when i run the code on the print pdf line.
Sub SaveSheetsAsPDF()
Dim DestFolder As String
Dim PDFFile As String
Dim wb As Worksheet
Dim AlwaysOverwritePDF As Boolean
'Speed up macro
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Prompt for file destination
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
DestFolder = .SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
End With
'Create new PDF file name including path and file extension
For Each wb In ThisWorkbook.Worksheets
'Test j2 for a mail address
If wb.Range("J2").Value Like "?*#?*.?*" Then
PDFFile = DestFolder & Application.PathSeparator & wb.Name & "-" & Format(Date, "mmyy") & ".pdf"
'If the PDF already exists
If Len(Dir(PDFFile)) > 0 Then
If AlwaysOverwritePDF = False Then
OverwritePDF = MsgBox(PDFFile & " already exists." & vbCrLf & vbCrLf & "Do you want to overwrite it?", vbYesNo + vbQuestion, "File Exists")
On Error Resume Next
'If you want to overwrite the file then delete the current one
If OverwritePDF = vbYes Then
Kill PDFFile
Else
MsgBox "OK then, if you don't overwrite the existing PDF, I can't continue." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Exiting Macro"
Exit Sub
End If
Else
On Error Resume Next
Kill PDFFile
End If
If Err.Number <> 0 Then
MsgBox "Unable to delete existing file. Please make sure the file is not open or write protected." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Unable to Delete File"
Exit Sub
End If
End If
End If
'Prints PDF
wb.ExportAsFixedFormat Type:=xlTypePDF, FileName:=PDFFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
Next wb
MsgBox "All Files Have Been Converted!"
ResetSettings:
'Resets optimization settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Edit: Also not all worksheets on the workbook will need to converted. So only the sheets that need to be converted will have the email address in J2.

Code that checks if an excel file is open works on one computer (user), but will it work with more computers (users)?

The following code checks if file is open, if not, it opens it and copies something into it. It works fine on my computer. Will it work, when the file is shared and another user opens the file? Will my code detect it?
Sub copy_to_boss()
On Error Resume Next
team = "boss.xlsm"
Set fileBoss = Workbooks(team)
fileIsOpen = Not fileBoss Is Nothing
If fileIsOpen = True Then
MsgBox "The following file is open " & team & " - close it."
Else
MsgBox "I will open the following file " & team
Workbooks.Open Filename:=team
ActiveWorkbook.Worksheets("List1").Cells(1, 1).Value = "10"
End If
End Sub
Try this:
Sub test_LockFile()
Dim sFile As String
Dim sLockFile As String
Dim objFSO As Object
'Trick: Each Excel file in use has a temporary file companion with prefix "~$"
' (e.g. "test.xlsm" ... "$~test.xlsm")
'Define sLockFile
sFile = ThisWorkbook.Name
sLockFile = ThisWorkbook.Path & "\~$" & sFile
'FileSystemObject, late Binding ohne Nutzung von IntelliSense und autom. Konstanten
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Show message if file is locked
If objFSO.FileExists(sLockFile) Then
MsgBox "The file " & sLockFile & " is locked by some user.", vbInformation, sFile & " is locked"
Else
MsgBox "The file is available", vbInformation, sFile
End If
End Sub
You can use something like this to check if the file is in use:
Public Function IsFileLocked(PathName As String) As Boolean
On Error GoTo ErrHandler
Dim i As Integer
If Len(Dir$(PathName)) Then
i = FreeFile()
Open PathName For Random Access Read Write Lock Read Write As #i
Lock i 'Redundant but let's be 100% sure
Unlock i
Close i
Else
Err.Raise 53
End If
ExitProc:
On Error GoTo 0
Exit Function
ErrHandler:
Select Case Err.Number
Case 70 'Unable to acquire exclusive lock
IsFileOpen = True
Case Else
MsgBox "Error " & Err.Number & " (" & Err.Description & ")"
End Select
Resume ExitProc
Resume
End Function

VBA Before Save event - file restriction based on user entry

I have the following WB code which tries to force the user to save the file as a particular file type (.xlsm) and name (the default path & "username-gaplist" --> can be followed by ANY type after this). So far I'm almost got it working down pat, except for 1 issue with the comparison operator in the IF statement.
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim txtFileName As String
Dim yn As Boolean
Dim a As String
a = Application.DefaultFilePath & "\" & Environ("UserName") & "-Gaplist.xlsm"
'1. Check of Save As was used.
If SaveAsUI = True Then
Cancel = True
'2. Call up your own dialog box. Cancel out if user Cancels in the dialog box.
txtFileName = Application.GetSaveAsFilename(Environ("UserName") & "-Gaplist", "Excel Macro-Enabled Workbook (*.xlsm), *.xlsm", , "Save As XLSM file")
'this compares the named file by user to the restriction which is username and gap list, and cancels if non-confmring
If Left(txtFileName, Len(txtFileName)) >= Left(a, Len(txtFileName)) Then
MsgBox Left(txtFileName, Len(txtFileName)) & vbLf & Left(a, Len(txtFileName))
'if user hits cancel (returns value of "False")
If txtFileName = "False" Then
MsgBox "Action Cancelled", vbOKOnly
Cancel = True
Exit Sub
End If
'if an invalid string is entered
Else
MsgBox "Must be saved in following format:" & vbLf & Application.UserName & "-Gaplist" & " " & "(you can add whatever after this)", vbOKOnly, "Retry.."
Cancel = True
Exit Sub
End If
'3. Save the file based on string entered
Application.EnableEvents = False
Application.DisplayAlerts = False
ThisWorkbook.SaveAs Filename:=txtFileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
Application.EnableEvents = True
Application.DisplayAlerts = True
MsgBox "Saved to: " & txtFileName, vbExclamation, Now
End If
End Sub
Like I said, I know that the issue lies in the
Left(txtFileName, Len(txtFileName)) >= Left(a, Len(txtFileName))
and the Cancel function works correctly in this setup, but I tested and this is what happens:
Entered: username-gaplist.xlsm String(fixed): username-gaplist.xlsm
result: GOOD (will overwrite if already saved as display events gets
turned off) Entered: usernam.xlsm String(fixed):
username-gaplist.xlsm result: Good (will give the user's the msgbox
telling them to retry as it doesn't conform)
Entered: username-gaplist323423.xlsm String(fixed):
username-gaplist.xlsm result: Good (will save accordingly to the
specified file path)
Entered: userzzz.xlsm String(fixed): username-gaplist.xlsm result:
BAD - this is allowing the user to save because adding the "z" means that the entered string is > than the fixed string (based on
same length), and it saves this . I would like to fix this
Entered: (user hits cancel) String(fixed): username-gaplist.xlsm
result: Msgbox action cancelled - exits sub
The other thing I could try is to use a "LIKE" operator , but have little experience using this.
Anyone provide any thoughts/suggestions would be great!
THanks
Figured it out.
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim txtFileName As String
Dim yn As Boolean
Dim a As String
a = Application.DefaultFilePath & "\" & Environ("UserName") & "-Gaplist"
'1. Check of Save As was used.
If SaveAsUI = True Then
Cancel = True
'2. Call up your own dialog box. Cancel out if user Cancels in the dialog box.
txtFileName = Application.GetSaveAsFilename(Environ("UserName") & "-Gaplist", "Excel Macro-Enabled Workbook (*.xlsm), *.xlsm", , "Save As XLSM file")
'this compares the named file by user to the restriction which is username and gap list, and cancels if non-confmring
If txtFileName = "False" Then
MsgBox "Action Cancelled", vbExclamation, "Cancelled.."
Cancel = True
Exit Sub
ElseIf Left(WorksheetFunction.Substitute(txtFileName, ".xlsm", ""), Len(a)) = a Then
GoTo ResumeSub
ElseIf Left(WorksheetFunction.Substitute(txtFileName, ".xlsm", ""), Len(a)) <> a Then
MsgBox "Must be saved in the following format: " & Chr(10) & Chr(10) & _
Environ("username") & "-Gaplist" & "(you can enter whatever text after this)" & vbLf & vbLf & _
"Note: Not case sensitive!", vbCritical, "Retry.."
Cancel = True
Exit Sub
End If
'3. Save the file.
ResumeSub:
Application.EnableEvents = False
Application.DisplayAlerts = False
ThisWorkbook.SaveAs Filename:=txtFileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
Application.EnableEvents = True
Application.DisplayAlerts = True
MsgBox "Saved to: " & txtFileName & vbLf & vbLf & Space(15) & Date & " " & Time, vbInformation, "Saved!"
End If
End Sub

VBA msoFileDialogOpen declare filename as Path

I am trying to use msoFileDialogOpen to retrieve the corresponding filename the user selected. Here is my clumsy code so far:
Public Sub Function3_FileExplorer()
' Start File Explorer to select file containing data (simple GUI, much easier than coding vFileName)
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
If .Show Then
Dim file As Variant
For Each file In .SelectedItems
.SelectedItems Path
End If
End With
ErrorHandler:
MsgBox "Error detected" & vbNewLine & "Error" & Err.Number & Err.Line
Err.Description , vbCritical, "Error Handler: Error " & Err.Number
End Sub
When I run this program I get the error message:
Compile error:
Invalid use of property
I think using property .SelectedItems is the right thing to do here but I'm not sure how to take that filename and store it as a variant.
EDIT: the revised code (does this do what I want it to do?)
Public Sub Function3_FileExplorer()
Dim file As Variant
' Start File Explorer to select file containing data (simple GUI, much easier than coding vFileName)
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
If .Show Then
file = .SelectedItems(1)
Path = file
End If
End With
MsgBox file
Exit Sub
ErrorHandler:
MsgBox "Error detected" & vbNewLine & "Error" & Err.Number & _
Err.Description, vbCritical, "Error Handler: Error " & Err.Number
End Sub
This is basically what you want (it's not clear what you really want to do with the file name):
Public Sub Function3_FileExplorer()
Dim file As Variant
' Start File Explorer to select file containing data (simple GUI, much easier than coding vFileName)
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
If .Show Then
file = .SelectedItems(1)
End If
End With
MsgBox file
Exit Sub
ErrorHandler:
MsgBox "Error detected" & vbNewLine & "Error" & Err.Number & _
Err.Description, vbCritical, "Error Handler: Error " & Err.Number
End Sub