This is my current code
Public Sub OpenFiles()
'Set LiveDealSheet file path
'Check if LiveDealSheet is already open
LDSP = "C:\Users\DCHEUNG\Desktop\Programing\LiveDealSheet.xlsm"
IsOTF = IsWorkBookOpen(LDSP)
'Set quick workbook shortcut
Set TWB = ThisWorkbook
If IsOTF = False Then
Set LDS = Workbooks.Open(LDSP)
Else
Workbooks("LiveDealSheet.xlsm").Activate
Set LDS = ActiveWorkbook
End If
End Sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
'i was just browsing through the online library and I found that "Open FileName For..."
'have a lot of keywords. If I only want to open the file and copy stuff out to
'another workbook do I use "Open FileName for Input Read As #ff"?
'Then when I actually open the file in OpenFiles() I change
'"Set LDS = Workbooks.Open(LDSP)" to "Set LDS = Workbooks.Open(LDSP) (ReadOnly)"
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
The file I am trying to open is a shared file. When no is it using, or when I already opened the file, this code works fine. But whenever another user already open a file, this code stops.
I know for a fact that even if another use is using the file, I can still open it in Read-Only mode. So my question is how to include that code in here, and hopefully without the pop-up asking if you want to open in Read-Only mode.
Sorry if this is a dumb question, but I am totally new to coding.
First of all thanks for you input. I have solve the problem on my own with some trial and error.
changed the code to the following
Public Sub OpenFiles()
'Set LiveDealSheet file path
'Check if LiveDealSheet is already open
LDSP = "Z:\LiveDealSheet.xlsm"
IsOTF = IsWorkBookOpen(LDSP)
'Set quick workbook shortcut
Set TWB = ThisWorkbook
If IsOTF = False Then
Set LDS = Workbooks.Open(LDSP)
Debug.Print "Stage 1 Success"
changed everything in this else statement
Else
On Error Resume Next
Set LDS = Workbooks("LiveDealSheet.xlsm")
If LDS Is Nothing Then Workbooks.Open FileName:=LDSP, ReadOnly:=True, IgnoreReadOnlyRecommended:=True
End If
End Sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
I would replace all the scripted above with this:
Public Sub OpenFiles()
On Error GoTo not_open
Workbooks("C:\Users\DCHEUNG\Desktop\Programing\LiveDealSheet.xlsm").Activate
Exit Sub
not_open:
Workbooks.Open FileName:="C:\Users\DCHEUNG\Desktop\Programing\LiveDealSheet.xlsm", ReadOnly:=True
Err.Clear
Resume Next
End Sub
I had the same issue and was helped somewhat by the existing posts, here. However, there was still a gap between the recommendations and reality. So, I'll try to share my lessons learned.
In my case, I needed Workbooks.Open to open the most recent file in a shared folder. This file is often referenced by other users and is therefore frequently open by other users. Below is my first pass to give the VBA code "permission" to open the file as "read only."
' OPEN SOURCE-FILE IN READ-ONLY MODE (argument key below)
Workbooks.Open _
Filename:=strFilename, _
UpdateLinks:=0, _
ReadOnly:=True, _
IgnoreReadOnlyRecommended:=True, _
Notify:=True
This actually works EXCEPT for when excel creates a temporary file in the source folder (the temp file will, therefore, always be the newest file in the folder). To handle that exception, I needed to truncate the temp characters: "~$". I have done that with
Right([your_string], integer_length_of_string)
See in context below.
For Each objFile In myFolder.Files
If InStr(1, objFile.Name, ".xlsm") And objFile.DateLastModified > dateFile Then
dateFile = objFile.DateLastModified
windowName = objFile.Name
If InStr(1, windowName, "~$") Then
fileNameLen = Len(objFile.Name) - 2
windowName = Right(objFile.Name, fileNameLen)
strFilename = myDir & "\" & windowName
End If
strFilename = myDir & "\" & windowName
End If
Next objFile
Related
I am trying to loop through all files in a folder, open them and remove document info. I am having trouble dealing with files that cannot be opened or when opened have a pop us regarding disabling macros. I tried to solve this using on error resume next and on error goto 0. But then I get a runtime failure because my workbook object (wb) has not been set when I was trying to close files that did open.
I have read the documentation on "On Error Resume Next" & "On error goto 0" but I do not believe I am using them correctly here.
Any help is greatly appreciated, Thanks.
Option Explicit
Sub test_Scrubber_New()
Dim directory As String, fileName As String, i As Variant, wb As Workbook
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'directory = "C:\Users\bayli\Desktop\Files for Testing\"
directory = "C:\Users\bayli\Desktop\excel files\"
fileName = Dir(directory & "*.xl??")
i = 0
Do While fileName <> ""
On Error Resume Next
Set wb = Workbooks.Open(directory & fileName)
On Error GoTo 0
'remove info
ActiveWorkbook.RemoveDocumentInformation (xlRDIAll)
wb.Close True
i = i + 1
fileName = Dir()
Application.StatusBar = "Files Completed: " & i
Loop
Application.StatusBar = False
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Complete"
End Sub
I updated my code to include: If Not wb Is Nothing Then remove the info as #PatricK suggested and it is working however it keeps stopping with a pop up about updating links. If I click "Do not update" my code continues working as needed but is there a way to handle this problem. I am looping through over 5k files so as you can imagine it is taking a while. The time it is taking is not a problem but currently I am sitting here having to click "dont update" quite a few times. I thought Application.DisplayAlerts = False would prevent these pop ups however it is not.
OK, so there are a couple questions here. First, regarding the error handling. When you're using inline error handling (On Error Resume Next), the basic pattern is to turn off the automatic error handling, run the line of code that you want to "catch" the error for, then test to see if the Err.Number is zero:
On Error Resume Next
ProcedureThatCanError
If Err.Number <> 0 Then
'handle it.
End If
On Error GoTo 0
The rest of the questions deal with dialogs you can encounter when you're opening workbooks. Most of this is documented on the MSDN page for Workbook.Open, but you'll want to change the Application.AutomationSecurity property to deal with the macro prompts as appropriate. For the updates, you should pass the appropriate UpdateLinks parameter. I'd also recommend specifying IgnoreReadOnlyRecommended, Notify, and CorruptLoad. Something like this should work (untested), or at least get you a lot closer:
Sub TestScrubberNew() 'Underscores should be avoided in method names.
Dim directory As String, fileName As String, i As Variant, wb As Workbook
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim security As MsoAutomationSecurity
security = Application.AutomationSecurity
Application.AutomationSecurity = msoAutomationSecurityForceDisable
directory = "C:\Users\bayli\Desktop\excel files\"
fileName = Dir(directory & "*.xl??")
i = 0
Do While fileName <> vbNullString
On Error Resume Next
Set wb = Workbooks.Open(fileName:=directory & fileName, _
UpdateLinks:=0, _
IgnoreReadOnlyRecommended:=True, _
Notify:=False, _
CorruptLoad:=xlNormalLoad)
If Err.Number = 0 And Not wb Is Nothing Then
On Error GoTo 0
wb.RemoveDocumentInformation xlRDIAll
wb.Close True
i = i + 1
Application.StatusBar = "Files Completed: " & i
fileName = Dir()
Else
Err.Clear
On Error GoTo 0
'Handle (maybe log?) file that didn't open.
End If
Loop
Application.AutomationSecurity = security
Application.StatusBar = False
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Complete"
End Sub
I am trying to write a macro that retrieves data from an ALV grid in SAP GUI. Everything is working fine up until the data exports. When exporting data from ALV grid to an .xlsx file, the file will automatically open after it exports.
I need my script to wait for the export to open, and then copy the data from the newly opened export file to the .xlsm file that the script is coming from.
If I try to activate the export.XLSX file immediately following the command to export the file in SAP GUI, I get a "subscript out of range" error. I thought maybe I could loop the activate command until it stops erroring (while the export.xlsx file is opening) but that causes excel to crash. What should I do?
Function funcLSAT(strEnv)
Dim wkbExport As Workbook
Dim strError As String
If Not IsObject(SapGuiApp) Then
Set SapGuiApp = CreateObject("Sapgui.ScriptingCtrl.1")
End If
If Not IsObject(Connection) Then
Set Connection = SapGuiApp.OpenConnection(strEnv, True)
End If
Set session = Connection.Children(0)
session.findById("wnd[0]/tbar[0]/okcd").Text = "[TCODE]"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/usr/cntlG_CC_MCOUNTY/shellcont/shell").pressToolbarContextButton "&MB_EXPORT"
session.findById("wnd[0]/usr/cntlG_CC_MCOUNTY/shellcont/shell").selectContextMenuItem "&XXL"
session.findById("wnd[1]/usr/ctxtDY_PATH").Text = "[filepath]"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").Text = "export.xlsx"
session.findById("wnd[1]/tbar[0]/btn[11]").press
Set session = Nothing
Set Connection = Nothing
Set SapGuiApp = Nothing
Do
On Error Resume Next
Windows("export.XLSX").Activate
Loop Until (Err.Number = 0)
On Error GoTo 0
Range("A2:AS2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
End Function
I had the same issue time ago when my macro had to wait for a .txt to be created and then continue so I found this:
Dim Directory As String, File As String
Directory = ActiveWorkbook.Path & "\" 'path for the file
File = Directory & "datos.txt" 'name of the file along with the path
FindIt = Dir(File)
While Len(FindIt) = 0
FindIt = Dir(File)
Wend
Hope it helps.
Here is what I do to export as XSLX, copy over the sheet, and close.
Application.wait does not do what you would want it to do here. Application.wait does not release Excel and so the SAP file never opens. Setting a timer will release Excel so the file will load.
It may not be the most well written, but it works. First, do a function to be able to see if the files are open or not. Then, set a timer of 0.5 seconds or so to put on a loop. You could do a longer timer and probably wouldn't have to loop, but done with a short time keeps Excel from being released any longer than it has to. Once the file locked on to, it will copy over the contents and close the file, and will exit the loop. Then I also kill the file because, on next run, it needs to be gone if the first run the isfile open is going to pick up the old file. This is written to where it's supposed to grab the workbook if it's opened in another instance—though, I haven't tested that. The way my VBA workbook loads, SAP files end up loading in the same instance. Good Luck!
Function IsFileOpen(FileName As String)
Dim iFilenum As Long
Dim iErr As Long
On Error Resume Next
iFilenum = FreeFile()
Open FileName For Input Lock Read As #iFilenum
Close iFilenum
iErr = Err
On Error GoTo 0
Select Case iErr
Case 0: IsFileOpen = False
Case 70: IsFileOpen = True
Case Else: Error iErr
End Select
End Function
Dim xlfile as string, xldir as string
Dim PauseTime, Start
Dim control As Long
Dim xlapp As Object
Dim wb as workbook
xldir= "Your file folder path here"
control = 0
xlfile = "Your filename here"
Do Until control = 5
PauseTime = 0.5 ' Set duration.
Start = Timer ' Set start time.
Do While Timer < Start + PauseTime
DoEvents ' Yield to other processes.
Loop
If control = 1 And IsFileOpen(xldir & xlfile) = False Then
Exit Do
End If
If IsFileOpen(xldir & xlfile) = True Then
Set xlapp = GetObject(xldir & xlfile).Application
If control = 0 Then
Workbooks(xlfile).Sheets(1).Name = Left(xlfile, Len(xlfile) - 5)
Workbooks(xlfile).Sheets(Left(xlfile, Len(xlfile) - 5)).Copy
before:=ThisWorkbook.Sheets(1)
ThisWorkbook.Activate
control = 1
End If
For Each wb In Application.Workbooks
If wb.Name = xlfile Then
wb.Close
End If
Next wb
End If
Loop
control = 0
kill(xldir&xlfile)
I used some code from Close an opened PDF after opening it using FollowHyperlink to create the following code to open a pdf file and rename it. The code runs fine but only if I break execution at MsgBox "Break Here" and step into it with the F8 key. Any ideas on why it won't execute automatically?
Sub OpenPDF()
'Opens PDF Scaned file & saves it to another folder
'***ErrorHandler***
On Error Resume Next
'***Declare Objects****
Dim objectWMI As Object
Dim objectProcess As Object
Dim objectProcesses As Object
Dim Path As String
Dim MyDir As String
'***Opens a new workbook if there are no active workbooks***
'***There must be an active workbook for FollowHyperlink to function***
nowbs = Application.Workbooks.Count
If nowbs = 1 Then
Application.Workbooks.Add
Else
End If
'***Saves current Excel path
MyDir = CurDir
'***Sets path to Ricoh Scans
PDFDir = "S:\Ricoh Scans"
ChDir PDFDir
'***Gets filename for PDF scan
Path = Application.GetOpenFilename(filefilter:="PDF file (*.pdf), *.pdf")
'***Opens PDF file***
ActiveWorkbook.FollowHyperlink Path
'***Sets Excel as active application
AppActivate "Microsoft Excel"
'***Prompts for PO number****
MyPONum = InputBox("Enter PO Number", "PO Editor", "30500")
'***If user selects Cancel on inputbox then xl closes Acrobat and exits sub
If MyPONum = vbNullString Then
GoTo EndAll
Else
End If
'***Replaces scanned filename with inputbox filename
PathLen = Len(Path)
OldName = Mid(Path, 16, PathLen - 19)
NewName = "S:\Materials Management\Purchase Orders\PO " & MyPONum & ".pdf"
EndAll:
'***Set Objects***
Set objectWMI = GetObject("winmgmts://.")
Set objectProcesses = objectWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'Acrobat.exe'") '< Change if you need be ** Was AcroRd32.exe**
'
'
'Code executes fine up to here but must Ctrl + Break at this line
'and F8 step thru balance of code or it will not work
'
'
MsgBox "Break Here"
'***Terminate all Open PDFs***
For Each objectProcess In objectProcesses
Call objectProcess.Terminate
Next
'***Clean Up***
Set objectProcesses = Nothing
Set objectWMI = Nothing
'***Renames scanned file and moves it to Materials Management folder***
Name Path As NewName
'***Resets current directory
ChDir MyDir
End Sub
Thanks to all for your input. I'm not a programmer and as I said I used code that had been posted elsewhere on this site. It was a timing issue and this edit works.
'***Terminate all Open PDFs***
For Each objectProcess In objectProcesses
objectProcess.Terminate
Next
'***Clean Up***
Set objectProcesses = Nothing
Set objectWMI = Nothing
'***************
Application.Wait (Now + TimeValue("00:00:02"))
'***Renames scanned file and moves it to Materials Management folder***
Name Path As NewName
'***Resets current directory
ChDir MyDir
End Sub
I Have created a user form that will open an excel file open & hide the excel. When closing the user form will save & close the excel file. However, there are two types of users of the excel file.
Editors - Those who are entering data into the file
Viewers - Those who are viewing a file.
The folder which has the excel file only allow "Editors" to save. (Others have no permission to write). Therefore, I have to avoid save part if the user has no wright permission to the folder. Any ideas? My code for the close event of user form is here.
Private Sub UserForm_QueryClose (Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
If ws.AutoFilterMode Then ws.AutoFilterMode = False
ws.Columns("F:H").Copy
ws.Activate
ws.Range("F1").Select
Application.DisplayAlerts = False
Selection.PasteSpecial Paste:=xlPasteValues
Application.DisplayAlerts = True
Application.CutCopyMode = False
Application.Visible = True
ActiveWorkbook.CheckCompatibility = False
ThisWorkbook.Close savechanges:=True
ActiveWorkbook.CheckCompatibility = True
End If
End Sub
Ws Denoted the declared name for the worksheet.
Edit
I have tried & found an alternative method to overcome the situation. However, this is not the solution & is a dirty method to get the result. Please see below code.
Private Sub UserForm_QueryClose (Cancel As Integer, CloseMode As Integer)
On Error Resume Next
If CloseMode = vbFormControlMenu Then
If ws.AutoFilterMode Then ws.AutoFilterMode = False
ws.Columns("F:H").Copy
ws.Activate
ws.Range("F1").Select
Application.DisplayAlerts = False
Selection.PasteSpecial Paste:=xlPasteValues
Application.DisplayAlerts = True
Application.CutCopyMode = False
Application.Visible = True
ActiveWorkbook.CheckCompatibility = False
ThisWorkbook.Save
ThisWorkbook.Close savechanges:=False
ActiveWorkbook.CheckCompatibility = True
End If
End Sub
On above code I have tracked error generated during the save process of viewers & jump to next line by using
on error resume next.
The answer above from Macro Man, while succinct and useful, will not work in an environment where folder access is managed by user groups instead of user names. As many corporate environments - including my own - use this method to manage folder access, I have posted below a solution that will assess a user's actual permissions to a folder. This will work whether the user has been granted individual or group access to a folder.
Private Function TestWriteAccess(ByVal StrPath As String) As Boolean
Dim StrName As String, iFile As Integer, iCount As Integer, BExists As Boolean
'Set the initial output to False
TestWriteAccess = False
'Ensure the file path has a trailing slash
If Right(StrPath, 1) <> "\" Then StrPath = StrPath & "\"
'Ensure the path exists and is a folder
On Error Resume Next
BExists = (GetAttr(StrPath) And vbDirectory) = vbDirectory
If Not BExists Then GoTo Exit_TestWriteAccess 'Folder does not exist
'Set error handling - return False if we encounter an error (folder does not exist or file cannot be created)
On Error GoTo Exit_TestWriteAccess
'Get the first available file name
Do
StrName = StrPath & "TestWriteAccess" & iCount & ".tmp"
iCount = iCount + 1
Loop Until Dir(StrName) = vbNullString
'Attempt to create a test file
iFile = FreeFile()
Open StrName For Output As #iFile
Write #iFile, "Testing folder access"
Close #iFile
TestWriteAccess = True
'Delete our test file
Kill StrName
Exit_TestWriteAccess:
End Function
In researching file access, I also stumbled upon Check Access Rights to File/Directory on NTFS Volume by Segey Merzlikin on FreeVBcode.com; this solution is overkill for my needs (and OP's) but will return the exact access rights that a user has to a particular file.
This checks the access list of the workbook's folder to see if the user's name appears in the list. If it does, then save the file.
If Instr(1, Environ("USERNAME"), CreateObject("WScript.Shell").Exec("CMD /C ICACLS """ & _
ThisWorkbook.Path & """").StdOut.ReadAll) > 0 Then ThisWorkbook.Save
It does this by opening a command prompt, running the ICACLS command through it and reading the output from that command. Then it uses the InStr() method to see if the username appears in that output.
I have this code. It is supposed to check if a file exists and open it if it does. It does work if the file exists, and if it doesn't, however, whenever I leave the textbox blank and click the submit button, it fails. What I want, if the textbox is blank is to display the error message just like if the file didn't exist.
Runtime-error "1004"
Dim File As String
File = TextBox1.Value
Dim DirFile As String
DirFile = "C:\Documents and Settings\Administrator\Desktop\" & File
If Dir(DirFile) = "" Then
MsgBox "File does not exist"
Else
Workbooks.Open Filename:=DirFile
End If
something like this
best to use a workbook variable to provide further control (if needed) of the opened workbook
updated to test that file name was an actual workbook - which also makes the initial check redundant, other than to message the user than the Textbox is blank
Dim strFile As String
Dim WB As Workbook
strFile = Trim(TextBox1.Value)
Dim DirFile As String
If Len(strFile) = 0 Then Exit Sub
DirFile = "C:\Documents and Settings\Administrator\Desktop\" & strFile
If Len(Dir(DirFile)) = 0 Then
MsgBox "File does not exist"
Else
On Error Resume Next
Set WB = Workbooks.Open(DirFile)
On Error GoTo 0
If WB Is Nothing Then MsgBox DirFile & " is invalid", vbCritical
End If
I use this function to check for file existence:
Function IsFile(ByVal fName As String) As Boolean
'Returns TRUE if the provided name points to an existing file.
'Returns FALSE if not existing, or if it's a folder
On Error Resume Next
IsFile = ((GetAttr(fName) And vbDirectory) <> vbDirectory)
End Function
For checking existence one can also use (works for both, files and folders):
Not Dir(DirFile, vbDirectory) = vbNullString
The result is True if a file or a directory exists.
Example:
If Not Dir("C:\Temp\test.xlsx", vbDirectory) = vbNullString Then
MsgBox "exists"
Else
MsgBox "does not exist"
End If
A way that is clean and short:
Public Function IsFile(s)
IsFile = CreateObject("Scripting.FileSystemObject").FileExists(s)
End Function
Function FileExists(ByRef strFileName As String) As Boolean
' TRUE if the argument is an existing file
' works with Unicode file names
On Error Resume Next
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
FileExists = objFSO.FileExists(strFileName)
On Error GoTo 0
End Function
To make the function run faster, objFSO can be made a global variable and the code can be modified and saved in a module like this:
Option Explicit
Dim objFSO As Object
Function FileExists(ByRef strFileName As String) As Boolean
' TRUE if the argument is an existing file
' works with Unicode file names
On Error Resume Next
If objFSO Is Nothing Then Set objFSO = CreateObject("Scripting.FileSystemObject")
FileExists = objFSO.FileExists(strFileName)
On Error GoTo 0
End Function
For strFileName to be a unicode string, you can, for example, either get it from a cell value or define it in a special way, as Excel's VBE doesn't save string constants in Unicode. VBE does support Unicode strings already saved in string variables. You're gonna have to look this up for further details.
Hope this helps somebody ^_^
Maybe it caused by Filename variable
File = TextBox1.Value
It should be
Filename = TextBox1.Value
Speed of Various FileExists Methods
I needed to check file existence for many of my projects, so I wanted to determine the fastest option. I used the micro timer code (see Benchmarking VBA Code) to run the File Exist functions below the table against a local folder with 2865 files to see which was faster. Winner used GetAttr. Using FSO method for Test 2 was a bit faster with the object defined as a global than not, but not as fast as the GetAttr method.
------------------------------------------------------
% of Fastest Seconds Name
------------------------------------------------------
100.00000000000% 0.0237387 Test 1 - GetAttr
7628.42784145720% 1.8108896 Test 2 - FSO (Obj Global)
8360.93687615602% 2.0522254 Test 2 - FSO (Obj in Function)
911.27399562739% 0.2163246 Test 3 - Dir
969.96844814586% 0.2302579 Test 4 - Dir$
969.75108156723% 0.2302063 Test 5 - VBA.Dir
933.82240813524% 0.2216773 Test 6 - VBA.Dir$
7810.66612746275% 1.8541506 Test 7 - Script.FSO
Function FileExistsGA(ByVal FileSpec As String) As Boolean
' Karl Peterson MS VB MVP
Dim Attr As Long
' Guard against bad FileSpec by ignoring errors
' retrieving its attributes.
On Error Resume Next
Attr = GetAttr(FileSpec)
If Err.Number = 0 Then
' No error, so something was found.
' If Directory attribute set, then not a file.
FileExistsGA = Not ((Attr And vbDirectory) = vbDirectory)
End If
End Function
Function FSOFileExists(sFilePathNameExt As String) As Boolean
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
FSOFileExists = fso.FileExists(sFilePathNameExt)
Set fso = Nothing
End Function
Function FileExistsDir(sFilePathNameExt As String) As Boolean
If Len(Dir(sFilePathNameExt)) > 0 Then FileExistsDir = True
End Function
Function FileExistsDirDollar(sFilePathNameExt As String) As Boolean
If Len(Dir$(sFilePathNameExt)) > 0 Then FileExistsDirDollar = True
End Function
Function FileExistsVBADirDollar(sFilePathNameExt As String) As Boolean
If Len(VBA.Dir$(sFilePathNameExt)) > 0 Then FileExistsVBADirDollar = True
End Function
Function FileExistsVBADir(sFilePathNameExt As String) As Boolean
If Len(VBA.Dir(sFilePathNameExt)) > 0 Then FileExistsVBADir = True
End Function
Public Function IsFileSFSO(s)
IsFileSFSO = CreateObject("Scripting.FileSystemObject").FileExists(s)
End Function
I realize that this does not fully answer the OP, but is provides information on which of the answers provided seems to be most efficient.
I'll throw this out there and then duck.
The usual reason to check if a file exists is to avoid an error when attempting to open it. How about using the error handler to deal with that:
Function openFileTest(filePathName As String, ByRef wkBook As Workbook, _
errorHandlingMethod As Long) As Boolean
'Returns True if filePathName is successfully opened,
' False otherwise.
Dim errorNum As Long
'***************************************************************************
' Open the file or determine that it doesn't exist.
On Error Resume Next:
Set wkBook = Workbooks.Open(fileName:=filePathName)
If Err.Number <> 0 Then
errorNum = Err.Number
'Error while attempting to open the file. Maybe it doesn't exist?
If Err.Number = 1004 Then
'***************************************************************************
'File doesn't exist.
'Better clear the error and point to the error handler before moving on.
Err.Clear
On Error GoTo OPENFILETEST_FAIL:
'[Clever code here to cope with non-existant file]
'...
'If the problem could not be resolved, invoke the error handler.
Err.Raise errorNum
Else
'No idea what the error is, but it's not due to a non-existant file
'Invoke the error handler.
Err.Clear
On Error GoTo OPENFILETEST_FAIL:
Err.Raise errorNum
End If
End If
'Either the file was successfully opened or the problem was resolved.
openFileTest = True
Exit Function
OPENFILETEST_FAIL:
errorNum = Err.Number
'Presumabley the problem is not a non-existant file, so it's
'some other error. Not sure what this would be, so...
If errorHandlingMethod < 2 Then
'The easy out is to clear the error, reset to the default error handler,
'and raise the error number again.
'This will immediately cause the code to terminate with VBA's standard
'run time error Message box:
errorNum = Err.Number
Err.Clear
On Error GoTo 0
Err.Raise errorNum
Exit Function
ElseIf errorHandlingMethod = 2 Then
'Easier debugging, generate a more informative message box, then terminate:
MsgBox "" _
& "Error while opening workbook." _
& "PathName: " & filePathName & vbCrLf _
& "Error " & errorNum & ": " & Err.Description & vbCrLf _
, vbExclamation _
, "Failure in function OpenFile(), IO Module"
End
Else
'The calling function is ok with a false result. That is the point
'of returning a boolean, after all.
openFileTest = False
Exit Function
End If
End Function 'openFileTest()
Here is my updated code. Checks to see if version exists before saving and saves as the next available version number.
Sub SaveNewVersion()
Dim fileName As String, index As Long, ext As String
arr = Split(ActiveWorkbook.Name, ".")
ext = arr(UBound(arr))
fileName = ActiveWorkbook.FullName
If InStr(ActiveWorkbook.Name, "_v") = 0 Then
fileName = ActiveWorkbook.Path & "\" & Left(ActiveWorkbook.Name, InStr(ActiveWorkbook.Name, ".") - 1) & "_v1." & ext
End If
Do Until Len(Dir(fileName)) = 0
index = CInt(Split(Right(fileName, Len(fileName) - InStr(fileName, "_v") - 1), ".")(0))
index = index + 1
fileName = Left(fileName, InStr(fileName, "_v") - 1) & "_v" & index & "." & ext
'Debug.Print fileName
Loop
ActiveWorkbook.SaveAs (fileName)
End Sub
You should set a condition loop to check the TextBox1 value.
If TextBox1.value = "" then
MsgBox "The file not exist"
Exit sub 'exit the macro
End If
Hope it help you.