Vba ошибка файл уже открыт

I am trying to read data from another spreadsheet in the same folder as my currently opened workbook, whenever I run this code I get the error file already open. Is there something wrong with my syntax or anything that might stop this from happening?

Here is the code.

Sub ReadFile()
    Infile = ThisWorkbook.Path & "\smallDataset.csv"
    Open Infile For Input As #1
        Input #1, a, b
        Close #1
        Debug.Print (a & " " & b)
End Sub

Thanks.

asked Dec 27, 2017 at 0:48

Colours's user avatar

3

Try the following code to make sure there is no file open with handle #1

Sub ReadFile()
    InFile = ThisWorkbook.Path & "\smallDataset.csv"
    Close #1
    Open InFile For Input As #1
        Input #1, a, b
        Close #1
        Debug.Print (a & " " & b)
End Sub

Or you use Freefile to get the next number

Sub ReadFile
FileNumber = FreeFile

InFile = ThisWorkbook.Path & "\smallDataset.csv"

    Open InFile For Input As FileNumber
        Input #FileNumber, a, b
        Close #FileNumber
        Debug.Print (a & " " & b)
End Sub

answered Dec 27, 2017 at 8:54

Storax's user avatar

StoraxStorax

11.2k3 gold badges16 silver badges33 bronze badges

I am also experiencing the errors which you have, these are the probable causes of the said error.

1) The CSV is open along with the Excel file
2) Your code has memory leaks

To resolve number 1

  • Try running the VBA code when the CSV is not opened

To resolve number 2

  • Try to use close the CSVobject after you have written your data inside it.

I’m not sure about your full code, but please check if you have something like Excel.Close or Excel.Quit.

answered Dec 27, 2017 at 1:54

Mr.J's user avatar

Mr.JMr.J

4302 gold badges10 silver badges30 bronze badges

daggg

2 / 2 / 0

Регистрация: 29.08.2017

Сообщений: 13

1

13.10.2017, 00:35. Показов 1926. Ответов 9

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Доброго времени суток многоуважаемые форумчане!
Я конечно понимаю уже существуют похожие темы, вроде написан код правильно и команду Close #1 предусмотрел в конце цикла, но все равно компилируется Ошибка: file already open.
В чем дело не понятно((((???

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Sub DoWhileDemol()
Dim LineCt As Long
Dim LineOfText As String
Open "F:\.........\text01.txt" For Input As #1
LineCt = 0
Do While Not EOF(l)
Line Input #1, LineOfText
Range("Al").Offset(LineCt, 0) = UCase(LineOfText)
LineCt = LineCt + 1
Loop
Close #1
End Sub



0



Эксперт MS Access

26792 / 14471 / 3192

Регистрация: 28.04.2012

Сообщений: 15,782

13.10.2017, 00:55

2

Ошибка здесь: Do While Not EOF(l). Надо: Do While Not EOF(1)



0



2 / 2 / 0

Регистрация: 29.08.2017

Сообщений: 13

13.10.2017, 01:30

 [ТС]

3

mobile,
Do While Not EOF(l). Надо: Do While Not EOF(1) — Исправил косяк,
Но ошибка все равно никуда не пропала



0



shanemac51

Модератор

Эксперт MS Access

11489 / 4732 / 764

Регистрация: 07.08.2010

Сообщений: 13,746

Записей в блоге: 4

13.10.2017, 06:46

4

может ваш файл уже открыт в другой версии вашей процедуры(без строки ckjse #1) или в блокноте
попробуйте добавить строку

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub DoWhileDemol()
Dim LineCt As Long
Dim LineOfText As String
''''''''''
reset
 
Open "F:\.........\text01.txt" For Input As #1
LineCt = 0
Do While Not EOF(l)
Line Input #1, LineOfText
Range("Al").Offset(LineCt, 0) = UCase(LineOfText)
LineCt = LineCt + 1
Loop
Close #1
End Sub



1



SoftIce

es geht mir gut

11267 / 4749 / 1183

Регистрация: 27.07.2011

Сообщений: 11,439

13.10.2017, 07:11

5

Используйте функцию FreeFile

Функция FreeFile

FreeFile([RangeNumber])

Функция FreeFile используется для возвращения незанятого номера(не задействованного для открытия другого файла) файла, который можно использовать при открытии файла инструкцией Open. Рекомендуется всегда использовать эту функцию при открытии файла во избежание различных проблем
Возвращаемое значение

Возвращает значение типа Integer в диапазоне от 1 до 511, представляющее следующий номер файла, доступный для использования с инструкцией Open
Параметры

RangeNumber


Необязательный аргумент типа Variant, указывающим диапазон, из которого возвращается следующий свободный номер файла. Значение 0 (используется по умолчанию) задает возвращение номера файла из диапазона 1 – 255 включительно. Значение 1 задает возвращение номера файла из диапазона 256 – 511

Пример

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
' Используем функцию FreeFile
' для определения следующего свободного номера файла
' В цикле последовательно открываются для вывода данных
' пять файлов, в каждый из которых записываются
' некоторые данные
Dim MyIndex, FileNumber
For MyIndex = 1 To 5 ' Выполняет цикл 5 раз
 FileNumber = FreeFile ' Определяем свободный номер файла
' Создаем файл
 Open "TEST" & MyIndex For Output As #FileNumber 
 Write #FileNumber, "Пример." ' выводим текст
 Close #FileNumber ' закрываем файл
Next MyIndex



0



Burk

1840 / 1156 / 353

Регистрация: 11.07.2014

Сообщений: 4,097

13.10.2017, 08:07

6

daggg, не уверен, что freefile поможет. у меня открыто много файлов, фри выдает 1. Поэтому не будет проверки на уже существующий файл. Для своих программ я написал такую функцию для проверки существования файла. Sname строка с именем файла. Истина, если уже загружен, иначе Ложь

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Public Function IsWbExist(Sname As String) As Boolean
Dim W As Object
IsWbExist = True
On Error GoTo WbFal
Set W = Workbooks(Sname)
GoTo Final
WbFal:
IsWbExist = False
Final:
On Error GoTo 0
End Function



0



es geht mir gut

11267 / 4749 / 1183

Регистрация: 27.07.2011

Сообщений: 11,439

13.10.2017, 08:13

7

Цитата
Сообщение от Burk
Посмотреть сообщение

фри выдает 1

Вы не о тех файлах пишите.
Речь идет только о файлах открытых инструкцией Open



0



1840 / 1156 / 353

Регистрация: 11.07.2014

Сообщений: 4,097

13.10.2017, 08:14

8

daggg, да и открывать, если его нет, нужно без #Number. Sname без полного пути к файлу, только его имя



0



SoftIce

es geht mir gut

11267 / 4749 / 1183

Регистрация: 27.07.2011

Сообщений: 11,439

13.10.2017, 08:20

9

Цитата
Сообщение от Burk
Посмотреть сообщение

открывать, если его нет, нужно без #Number

Не понял, если честно. Можете пояснить?

Добавлено через 3 минуты
Короче

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
Sub DoWhileDemol()
Dim LineCt As Long, ff as integer
Dim LineOfText As String
ff=FreeFile
Open "F:\.........\text01.txt" For Input As #ff
LineCt = 0
Do While Not EOF(ff)
Line Input #ff, LineOfText
Range("A1").Offset(LineCt, 0) = UCase(LineOfText)
LineCt = LineCt + 1
Loop
Close #ff
End Sub



0



1840 / 1156 / 353

Регистрация: 11.07.2014

Сообщений: 4,097

13.10.2017, 09:52

10

SoftIce, я пишу только о файлах, которые у меня открыты инструкцией Open



0



Run-time Error 55 File already open. This is one of the common error in file handling. It is difficult to avoid if you handle multiple files and use direct file numbers

Sub TextFile_Write_Error()

‘ —————————————————————
‘ Written By Shanmuga Sundara Raman for http://vbadud.blogspot.com
‘ —————————————————————

‘ ————————
‘ Code with Errors
‘ ————————
Open «d:\VBADudExamples\TextFile1.txt» For Output As #1 ‘ Open file for output.

Print #1, «TextFile1»

Open «d:\VBADudExamples\TextFile2.txt» For Output As #1 ‘ Open file for output.

Close #1 ‘ Close file.

Close #1 ‘ Close file.

‘ ————————
‘ Workaround for the Errors
‘ ————————
‘ Use FreeFile to get a file number that is not used

iF1 = FreeFile ‘ Returns an Integer representing the next file number available for use by the Open statement.
Open «d:\VBADudExamples\TextFile1.txt» For Output As #iF1 ‘ Open file for output.

Print #iF1, «TextFile1»

iF2 = FreeFile
Open «d:\VBADudExamples\TextFile2.txt» For Output As #iF2 ‘ Open file for output.

Close #iF2 ‘ Close file.

Close #iF1 ‘ Close file.

‘ ————————————————
‘ Excel VBA, Run-time Error 55, File already open
‘ ————————————————

End Sub

Активизирует подпрограмму обработки ошибок и указывает положение подпрограммы в процедуре; используется также для отключения подпрограммы обработки ошибок.

  • On Error GoTo строка — Активизирует подпрограмму обработки ошибок, начало которой определяется обязательным аргументом строка, значением которого может быть любая метка строки или номер строки. Если возвращается ошибка выполнения, управление передается на указанную строку и запускается обработчик ошибок. Аргумент строка должен определять строку в той же процедуре, в которой находится инструкция On Error; в противном случае возникает ошибка компиляции.
  • On Error Resume Next — Указывает, что возникновение ошибки выполнения приводит к передаче управления на инструкцию, непосредственно следующую за инструкцией, при выполнении которой возникла ошибка. Рекомендуется при доступе к объектам использовать эту форму инструкции, а не On Error GoTo.
  • On Error GoTo 0 — Отключает любой активизированный обработчик ошибок в текущей процедуре.

Замечания

Если не выполнена инструкция On Error, то любая ошибка выполнения является фатальной; это означает, что выводится сообщение об ошибке и выполнение программы прекращается.

«Включенным» обработчиком ошибок называют подпрограмму, которая указана в инструкции On Error; «активным» обработчиком ошибок является включенный обработчик ошибок, который обрабатывает текущую ошибку. Если ошибка возникает в самом обработчике ошибок (в промежутке между возникновением ошибки и выполнением инструкции Resume, Exit Sub, Exit Function или Exit Property), то обработчик ошибок, определенный в текущей процедуре, не может обработать ошибку. Управление в этом случае возвращается в вызывающую процедуру; если в вызывающей процедуре включен обработчик ошибок, то обработка ошибки передается ему. Если этот обработчик ошибок является в данный момент активным, т.е. уже обрабатывает ошибку, то управление снова передается назад в вызывающую процедуру и т.д. до тех пор, пока не будет найден включенный, но не активный обработчик ошибок. Если включенный, но неактивный обработчик ошибок найден не будет, ошибка становится фатальной в том месте программы, в котором она впервые возникла. При каждой передаче управления обработчиком ошибок в вызывающую процедуру эта процедура становится текущей. После завершения обработки ошибки обработчиком в любой процедуре возобновляется выполнение текущей процедуры с той ее части, которая указана в инструкции Resume.

Подпрограмма обработки ошибок не может быть процедурой Sub или Function. Эта подпрограмма должна быть частью программы, которая отмечается с помощью метки строки или номера строки.

Для определения причины ошибки в подпрограммах обработки ошибок используют значение свойства Number объекта Err. Необходимо обеспечить в подпрограммах обработки ошибок проверку или сохранение существенных значений свойств объекта Err перед тем, как может возникнуть новая ошибка или перед вызовом процедуры, в которой может возникнуть новая ошибка. Значения свойств объекта Err описывают последнюю ошибку. Текст сообщения об ошибке, соответствующего коду ошибки Err.Number содержится в свойстве Err.Description.

Конструкция On Error Resume Next задает продолжение выполнения с инструкции, непосредственно следующей за инструкцией, которая привела к ошибке выполнения, или с инструкции, непосредственно следующей за вызывающей инструкцией в процедуре, содержащей конструкцию On Error Resume Next. Это позволяет продолжить исполнение программы несмотря на ошибку выполнения. Это позволяет также встроить подпрограмму обработки ошибок в процедуру, а не передавать управление в другую часть процедуры. Конструкция On Error Resume Next становится неактивной при вызове новой процедуры, поэтому для внутренней обработки ошибок необходимо выполнять инструкцию On Error Resume Next в каждой вызываемой процедуре.

При обработке ошибок, возникающих при доступе к другим объектам, рекомендуется использовать конструкцию On Error Resume Next, а не конструкцию On Error GoTo. Проверка объекта Err после каждого взаимодействия с другим объектом позволяет устранить неопределенность в том, при доступе к какому объекту возникла ошибка. Это позволяет всегда точно знать, какой объект поместил значение кода ошибки в свойство Err.Number, а также в каком объекте возникла ошибка (эта информация содержится в свойстве Err.Source).

Конструкция On Error GoTo 0 отключает обработку ошибок в текущей процедуре. Эта конструкция не задает переход на строку 0 для обработки ошибок, даже если в процедуре имеется строка с номером 0. Если инструкция On Error GoTo 0 не выполнялась, то обработчик автоматически отключается при выходе из процедуры.

Для того, чтобы предотвратить выполнение программы обработки ошибок в тех случаях, когда ошибка не возникла, следует помещать соответствующую инструкцию Exit Sub, Exit Function или Exit Property сразу после подпрограммы обработки ошибки, как в следующем примере:

Sub InitializeMatrix(Var1, Var2, Var3, Var4)
	On Error GoTo ОбработкаОшибок
	. . .
	Exit Sub
ОбработкаОшибок:
	. . .
	Resume Next
End Sub

В этом примере программа обработки ошибок помещена между инструкциями Exit Sub и End Sub, что позволяет отделить ее от части программы, соответствующей нормальному выполнению процедуры. Программу обработки ошибок можно разместить в любом месте процедуры.

Ошибки, которые не были перехвачены, возвращаются в управляющее приложение, если объект был запущен как исполняемый файл. В среде разработчика такие ошибки возвращаются в управляющее приложение только при указании соответствующих параметров. За описанием необходимых значений этих параметров и способов их задания следует обращаться к документации главного приложения. Там же следует проверить, позволяет ли главное приложение создавать классы.

Err.Number = vbObjectError + 1052

Системные ошибки при вызовах библиотек динамической компоновки (DLL) не приводят к возникновению исключений и не перехватываются средствами Visual Basic. При вызове функций из библиотек DLL необходимо проверять, успешно ли возвращается каждое значение (согласно спецификациям API), и в случае неудачи проверять значение свойства LastDLLError объекта Err.

Пример

В начале этой программы инструкция On Error GoTo определяет положение подпрограммы обработки ошибок в процедуре. В данном примере попытка удалить открытый файл приводит к возникновению ошибки с кодом 55. Ошибка обрабатывается в подпрограмме, после чего управление возвращается инструкции, которая привела к возникновению ошибки. Инструкция On Error GoTo 0 отключает перехват ошибок. После этого инструкция On Error Resume Next задает отложенный перехват ошибок, что позволяет точно определить, в каком контексте возникла ошибка, генерируемая в следующей инструкции. Следует отметить, что после обработки ошибки вызывается метод Err.Clear для сброса значений свойств объекта Err.

Sub OnErrorStatementDemo()
	On Error GoTo ErrorHandler			' Включаем программу обработки 
						' ошибок.
	Open "TESTFILE" For Output As #1		' Открываем файл.
	Kill "TESTFILE"				' Попытка удалить открытый 
						' файл.
	On Error Goto 0				' Отключаем перехват ошибок.
	On Error Resume Next			' Откладываем перехват ошибок.
	ObjectRef = GetObject("MyWord.Basic")	' Запускаем несуществующий 
						' объект, а затем проверяем 
						' ошибку механизма управления 
						' программируемыми объектами.
	If Err.Number = 440 Or Err.Number = 432 Then
	' Выводим сообщение для пользователя и очищаем объект Err.
		Msg = "Ошибка при попытке открыть программируемый объект!"
		MsgBox Msg, , "Проверка отложенной ошибки"
		Err.Clear			' Очищаем поля объекта Err.
	End If	
Exit Sub					' Выходим из процедуры, чтобы
						' не попасть в обработчик.
ErrorHandler:					' Обработчик ошибок.
	Select Case Err.Number			' Определяем код ошибки.

Case 55						' "Ошибка "Файл уже открыт".
			Close #1		' Закрываем открытый файл.
		Case Else
	' Здесь размещаются инструкции для обработки других ошибок... 
	End Select
	Resume					' Возобновляем выполнение
						' со строки, вызвавшей ошибку.
End Sub

Обновлено

Вопрос:

В VBA Ms Access я импортирую txt файл, анализируя его по строкам.

Я использую FileDialog, чтобы пользователь мог выбрать файл для импорта, но когда я открываю файл для его чтения, я получаю сообщение об ошибке 55 – файл уже открыт.

Кошка:

Dim openDialog As FileDialog

Set openDialog = Application.FileDialog(msoFileDialogFilePicker)
On Error GoTo DoNothing
With openDialog
.title = "Import"
.AllowMultiSelect = False
.Show
End With

FName = openDialog.SelectedItems.Item(1)
'Close FName

Open FName For Input Access Read As #1
On Error GoTo DoNothing

Вместо этого, если я использую Close Fname, ошибок выполнения не существует, но импорт не работает (код для импорта прав, потому что он работает, когда я жестко кодирую файл имен)

Лучший ответ:

после того, как у вас есть имя файла, откройте обработчик диалогового окна:

Set openDialog = Nothing

Понравилась статья? Поделить с друзьями:
  • Vba отслеживание ошибок
  • Vba ошибка user defined type not defined
  • Vdwit 4514x ошибка f5
  • Vba ошибка trim
  • Vba обработчики ошибок