Error 53 when opening CSV file on mac - vba

When I try and open a CSV file, I get:
Error 53: File not found
I get the error on the 4th line, Open FilePath For Input As #1
What am I doing wrong?
It is my first time opening a CSV, please be indulgent with my code.
Sub opentextfile()
Dim FilePath As String
FilePath = "/Users/christinekelly/Desktop/authors.csv"
file1 = FreeFile
Open FilePath For Input As #file1
row_number = 0
Do Until EOF(1)
Line Input #file1, LineFromFile
LineItems = Split(LineFromFile, ",")
ActiveCell.Offset(row_number, 0).Value = LineItems(2)
ActiveCell.Offset(row_number, 1).Value = LineItems(1)
ActiveCell.Offset(row_number, 2).Value = LineItems(0)
Number = row_number + 1
Loop
Close #file1
End Sub

So from looking at #Rebekare's answer to this question this is what worked for me.
I went to the file in question test.csv and opened the immediate window and typed ?ThisWorkbook.Path and got HDD:Users:USER:Desktop.
I then used the suggested concatenatation of this path with Application.PathSeparator & filename i.e.
FilePath = "HDD:Users:USER:Desktop" & Application.PathSeparator & "test.csv"
This is a useful approach as you get the actual file path syntax and then yield the path separator decision to the Application.
Following on from #Mat'sMug suggestion, I found this, which opens the file dialog, and you select the file you want the full path of and it is returned via the message box.
Sub PathofFile()
OpenFile = Application.GetOpenFilename()
MsgBox OpenFile
End Sub
Within that same link was a suggestion for using the Dir function to test if the filepath is valid. If valid you get the filename back, if not you get an error which you can use to determine your next action e.g. the following returns "test.csv" if it exists at that filepath.
MsgBox Dir("HDD:Users:USER:Desktop:test.csv")
If you are doing other operations with the file you might want to add a test to to see if the file is open first, using Microsoft's IsFileOpen function. An example as follows:
Sub Test
If Not IsFileOpen(FilePath) Then
Set wb = Workbooks.Open(FilePath)
End If
End Sub
Function IsFileOpen(filename As String)
Dim filenum As Integer, errnum As Integer
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open filename For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
' No error occurred.
' File is NOT already open by another user.
Case 0
IsFileOpen = False
' Error number for "Permission Denied."
' File is already opened by another user.
Case 70
IsFileOpen = True
' Another error occurred.
Case Else
Error errnum
End Select
End Function

Related

Excel vba On Error GoTo different handlers, depending on an error

I have excel vba code that opens different files on makes use of them. An error can occur because there is no file where excel loos for it. I want to create a MsgBox on such errors with a message which specific file is absent.
Now I can only
On Error GoTo ErrorHandler
ErrorHandler:
MsgBox("File is absent")
But I can't specify which exactly file is absent. Is there a way to achieve it through error handler? Maybe through some additional variable?
EDIT: I open files through
Workbooks.Open Filename:=...
But I'm curious about what one should do if the case is
Dim fileTitle As String
filetitle=Dir()
as well.
Rather than hard-coding the file path via:
Workbooks.Open Filename:=...
Use a variable to represent the file path/name:
Dim fileName As String
fileName = "C:/path/to/my/file.xlsx"
Then, check to make sure it exists before you attempt to open it:
If FileIsAccessible(fileName) Then
' Do stuff
Else
MsgBox fileName & " doesn't exist or cannot be opened"
Exit Sub
End If
Use a custom function like
Function FileIsAccessible(path$) As Boolean
Dim FF As Long
On Error GoTo EarlyExit
FF = FreeFile
'Does file exist?
' Raises Error 53 if file not found
Open path For Input Access Read As FF
Close FF
'If file exist, is it accessible?
' Raises error 70 if file is locked/in-use
FF = FreeFile
Open path For Binary Access Write As FF
Close FF
EarlyExit:
FileIsAccessible = (Err.Number = 0)
End Function
You still have access to your variables in error handler, so you know within which file error happen:
Sub ...
Dim filename As String
On Error GoTo ErrorHandler
filename = Dir(...)
While filename>""
Set wb = Workbooks.Open(filename)
...
filename=Dir
Wend
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & " File: " & filename
End Sub
Two ways to go about this. First, as you suggested, (which is also the easier of the two), you can make a variable that will carry the file name that you reassign after each file successfully loads. That name can then be passed into your message box in the event of a failure. If all you need to do is pass this name, this is the better solution.
The second option would be to create multiple error handlers. I would only recommend this if you need more customization with regard to how the error is handled, like wanting a different message to be displayed based on which type of file was missing. This option would make your code a good bit messier (as you would need to reassign the On Error GoTo ... statement multiple times, but its worth considering if you need a more complex solution.
Give this a try and tweak it as per your requirement. This will give you a starting point to deal with error handling....
Assuming you are trying to open a file abc.xlsx which is located at your Desktop and if this file isn't found on Desktop, the error handling will be triggered.
Don't forget to use Exit Sub before Error Handling label so that it is not executed if the file was found.
Dim wb As Workbook
Dim FilePath As String
FilePath = Environ("UserProfile") & "\Desktop\abc.xlsx"
On Error GoTo ErrorHandler
Set wb = Workbooks.Open(FilePath)
'Other stuff here if file was found and opened successfully
'
'
'
'
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbNewLine & Err.Description, vbCritical, "File Not Found!"

VBA Script to check if text file is open or not

I am checking if a file is open or not that is a .txt file
Private Sub CommandButton1_Click()
Dim strFileName As String
' Full path and name of file.
strFileName = "D:\te.txt"
' Call function to test file lock.
If Not FileLocked(strFileName) Then
' If the function returns False, open the document.
MsgBox "not open"
Else
MsgBox "open"
End If
End Sub
Function FileLocked(strFileName As String) As Boolean
On Error Resume Next
' If the file is already opened by another process,
' and the specified type of access is not allowed,
' the Open operation fails and an error occurs.
Open strFileName For Binary Access Read Write Lock Read Write As #1
Close #1
' If an error occurs, the document is currently open.
If Err.Number <> 0 Then
' Display the error number and description.
MsgBox "Error #" & Str(Err.Number) & " - " & Err.Description
FileLocked = True
Err.Clear
End If
End Function
It turns out .txt when opened using notepad doesn't lock the file, so it can not be known if a .txt file is open or not. And hence, if that .txt file is opened in Wordpad or Sakura, etc., your code should work or at least other code from the net should work.
I found that if a text file is opened using FileSystemObject, then the file is not locked and can still be edited by other users. As a potential workaround, you could make a file with a single bit to indicate when the other file is in use, and include checking that bit in your code. Here's my code as a rough example:
'FSO parameters
Const ForAppending = 8
Const ForReading = 1
Const ForWriting = 2
Sub WriteToFile()
Set fso = CreateObject("Scripting.FileSystemObject")
'Check the current lock bit (1 is locked, 0 is unlocked)
Set FileLock = fso.OpenTextFile("C:\FileLock.txt", ForReading)
Dim LockBit As Integer
LockBit = FileLock.ReadAll
FileLock.Close
'If the bit is 1 (file in use) then wait 1 second and try again (up to 10 times)
For try = 1 To 10
If LockBit = 1 Then
Application.Wait (Now + TimeValue("0:00:1"))
Set FileLock = fso.OpenTextFile("C:\FileLock.txt", ForReading)
LockBit = FileLock.ReadAll
FileLock.Close
Else: GoTo Line1 'when the bit is 0 (file available)
End If
If try = 10 Then
MsgBox "File not available"
Exit Sub
End If
Next try
Line1:
Call LockTheFile(fso, True) 'Change the lock bit to "1" to show the file's in use
Set WriteFile = fso.OpenTextFile("C:\WriteFile.txt", ForWriting)
'Do what you will with the file
MsgBox "Write Successful"
WriteFile.Close
Call LockTheFile(fso, False) 'Change the lock bit to "0" to show the file's available
End Sub
I made this sub separate to make the main code more streamlined
Sub LockTheFile(fso, SetLock As Boolean)
'Write "1" to a lock file to indicate the text file is in use, or "0" to indicate not in use
Set BitFile = fso.CreateTextFile("C:\FileLock.txt", True)
If SetLock = True Then
BitFile.WriteLine "1"
Else
BitFile.WriteLine "0"
End If
BitFile.Close
End Sub

VBA Excel - Macro tells me Word Document is Open even though it is not open

To start off I have a function in VBA Excel that tells me if a Word Document is open or not open. For testing purposes I don't have the Word Document Open and expect 'False' to be returned.
Function IsFileOpen(filename As String) As Boolean
Dim filenum As Integer, errnum As Integer
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open filename For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
' No error occurred.
' File is NOT already open by another user.
Case 0
IsFileOpen = False
' Error number for "Permission Denied."
' File is already opened by another user.
Case 70
IsFileOpen = True
' Another error occurred.
Case Else
Error errnum
End Select
End Function
Called Via:
...
If IsFileOpen("C:/Temp/test.docx") = True Then
MsgBox objWord.ActiveDocument.Name & " already open" 'ERROR FROM PIC HERE
Set objDoc = objWord.ActiveDocument
Else
Set objDoc = objWord.Documents.Open("C:/Temp/test.docx", Visible:=True)
End If
...
However when running the code I get that the Document is open (Returned True from the IsFileOpen function from case 70) yet I get an error on 'objWord.ActiveDocument.Name' that no Document is Open
On Windows 7 Task Manager this is what I have. Word Application is closed but it appears there are background processes open of Word. However I close all documents I don't use so these processes shouldn't be running
I think a better test to check to see if your Word File is open is to use the actual Word Documents collection
So for your example, use something like this:
With objWord
For Each doc In .Documents
If doc.Name = "test.docx" Then
found = True
Exit For
End If
Next doc
If found <> True Then
.Documents.Open FileName:="C:/Temp/test.docx"
Else
.Documents("test.docx").Activate
End If
End With

How to catch error "File not loaded completely"

I have a code which opens a text file. It contains a number of rows that is more than the limit of Excel. When manually opening it, there is a prompt that says "File not loaded completely" but when in macro, I don't see a prompt.
What I want to do is to catch that error. Even when the display alerts of my macro is enabled, still no error is caught.
On Error Goto catch_err
...open text file here
On Error Goto 0
catch_err:
Msgbox err.description
That is the structure of my code.
Why don't you stream the file in and move to the next tab every time you hit 1M rows?
I threw this together for you, excuse the Citrix line in there (I needed it for testing, left it in in case you are on that environment).
Sub BigFile()
Dim myFile As String, textline As String, X As Long
'myFile = "\\Client\C$\Temp\YourBigFile.txt" 'Silly Citrix syntax
myFile = "C:\Temp\YourBigFile.txt" 'Normal syntax
Open myFile For Input As #1
Do Until EOF(1)
X = X + 1
If X = 1000000 + 1 Then
Sheets.Add
X = 1
End If
Line Input #1, textline
Range("A" & X).Formula = textline
Loop
Close #1
End Sub
This way you don't need to test for the error because there won't be one.

Understanding the function of IsFileOpen and outputtext over a simple save with overwrite [duplicate]

This question already has answers here:
Detect whether Excel workbook is already open [closed]
(7 answers)
Closed 8 years ago.
I'm having trouble working out why a bit of code that I found months and months ago (don't know originating website) is doing such a weird thing when trying to save the file...
In the main part of the code that is constantly looping it has the following:
Main Snippit
path = "C:/"
filename = "file.csv"
If Dir(path) = "" Then
FullPath = Environ("USERPROFILE") & "\Desktop\" & filename
Else
FullPath = path & filename
If Dir(FullPath) <> "" Then
isCsvOpen = IsFileOpen(FullPath)
If Not isCsvOpen Then Kill (FullPath)
End If
End If
If Not isCsvOpen Then outputtext delimiteddata, FullPath
It has the following two functions elsewhere in the code:
outputtext()
Function outputtext(text As String, path As String)
Dim MyFile As String, fnum As String
MyFile = path
fnum = FreeFile() ' Get a free file number.
Open MyFile For Output As fnum 'open file for output
Print #fnum, text ' Print when you want the string without quotation marks
Close #fnum
End Function
IsFileOpen()
Function IsFileOpen(filename As String)
Dim filenum As Integer, errnum As Integer
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open filename For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
' No error occurred.
' File is NOT already open by another user.
Case 0
IsFileOpen = False
' Error number for "Permission Denied."
' File is already opened by another user.
Case 70
IsFileOpen = True
Case Else
Error errnum
End Select
End Function
What is the purpose of using IsFileOpen() and outputtext(), surely just saving with overwrite would be sufficient?
To me it looks like it's checking if the file is open, locking it open, then killing the file (unlocking it) and then saving...
Any explination would be much appreciated
A few reasons for such a design...
If the file is open elsewhere, it likely to be open in a non-Read-only mode (which is what is being checked, i.e. whether the file is locked or not). This is especially important over network drives.
If the file is open and your code tries to save it, it will throw an error. So you can either
try to handle the error once it's thrown, or
preempt the problem and throw a controlled error at the user or prompt for further action, etc.
This is a cleaner way to avoid file corruption especially over shared resources.