Ошибка при обращении к файлу по локальной сети средствами Vba Ms Office Xp через Ie
При запуске файла "doc" (созданного в MS Office XP) с макросами, написанными на Visual Basic в операционной системе Windows 2000 возникает ошибка "Path/File error". Файл "doc" запускается по локальной сети через Internet Explorer (IE) и при запуке средствами VBA производится попытка прочитать содержимое файл типа "txt" из сетевой директории, доступ к которой на чтение "doc" и "txt" файла есть. На всех машинах установлена операционная система Windows 2000. В IE можно зайти с машины, где запускается файл "doc" в сетевую директорию и просмотреть файл "txt". Оба файла "doc" и "txt" расположены на удаленном сервере в локальной сети. Путь к файлу "doc" следующий: "\\lib\SemHR\". Путь к файлу "txt" следующий: "\\lib\SemHR\SystemFiles". Политика безопасности в программах "Internet Explorer" и "Microsoft Word" стоит средняя. Это приводит к появлению при запуске файла "doc" предупреждения и выбора типа "Запустить/Не запустить" файл. Файл загружается при выборе меню "Запустить". При изменении политики безопасности в обеих программах на самую низкую вышеуказанная ошибка все равно появляется. Программный код, с помощью которого производится считывание содержимого файла следующий (он запускается автоматически при загрузке файла "doc"):
Dim nameOfTxtFile As String
nameOfTxtFile = "\\lib\SemHR\SystemFiles\course.txt"
// Ошибка ("Path/File error") возникает в следующей строке!
Open nameOfTxtFile For Input Access Read As #1
Do While Not EOF(1)
// Здесь процедура считывания файла, корректно работающая в случае присутствия на локальной машине файлов "doc" и "txt", а также указанием новых не сетевых путей к ним.
Loop
Close #1
Уважаемые коллеги, обращаюсь к вам за помощью ...
1. Мои эксперименты не привели к появлению именно такого сообщения об ошибке, поэтому укажите, пожалуйста, код ошибки.
2. Какая версия Office используется на клиентских машинах?
3. Попробуйте вместо фиксированного дескриптора файла (#1) использовать дескриптор, полученный с помощью функции [COLOR=blue]FreeFile[/COLOR]:
hFile = FreeFile
Open nameOfTxtFile For Input Access Read As hFile
Спасибо вам за ответ.
1,3. Код ошибки, к сожалению, я не зафиксировал. Собираюсь завтра (01.04.06) проверить работоспособность дескриптора FreeFile. В этот же день (примерно к 17:00) я напишу о результатах его применения в решении моей задачи и укажу код ошибки.
2. На клиентских машинах установлена программа MS Office 2002.
Еще раз большое спасибо за подсказку!
На клиентских машинах установлена программа MS Office 2002.
Это Вы так называете Office XP или это официальное название? Мне что-то не встречался такой вариант.
Важным дополнение к моему вопросу может быть следующее:
если зайти на клиентскую машину под паролем администратора, имеющего доступ на чтение и запись в соответствующей сетевой папке "\\lib\SemHR\", то никаких проблем при работе скрипта не возникает. Но при отсутствии прав у пользователя на запись информации в этой папке возникает вышеуказанная ошибка. В самом скрипте нет команд записи. Обращение к сетевому файлу "txt" осуществляеться только один раз для считывания информации из него.
---------------------------
Run-time error '75':
Path/File access error
---------------------------
... если зайти на клиентскую машину под паролем администратора, имеющего доступ на чтение и запись в соответствующей сетевой папке "\\lib\SemHR\", то никаких проблем при работе скрипта не возникает. Но при отсутствии прав у пользователя на запись информации в этой папке возникает вышеуказанная ошибка. В самом скрипте нет команд записи. Обращение к сетевому файлу "txt" осуществляеться только один раз для считывания информации из него.
... при тестировании скрипта с дескриптором FreeFile на клиентской машине с правами только на чтение сетевой папки возникает прежняя ошибка.
1. Хотелось бы увидеть весь текст макроса или, по крайней мере, ту часть, что предшествует оператору открывания файла "txt".
2. Для более-менее корректного моделирования ситуация нужны "сетевые" подробности.
2.1. Ваша сеть представляет собой домен или одноранговую сеть?
2.2. Какая ОС используется на сервере, и какая файловая система - на диске с данным сетевым ресурсом?
2.3. Каким образом регулируются права доступа клиентов к ресурсу:
- разрешения настроены с помощью вкладки "Доступ";
- разрешения настроены с помощью вкладки "Безопасность";
- первое и второе сочетаются (как именно).
2.4. Используется ли для предоставления доступа к данному сетевому ресурсу DFS?
3. Используется ли на рабочих станциях антивирус DrWeb версии 4.33?
На ваши вопросы постараюсь ответить до 5 апреля (включительно). Т.е. вечером 5 апреля к 21:00.
Макрос, над который я пытаюсь внедрить является компонентом написанной мною тестовой системы для студентов.
В момент создания тестовой системы системный администратор негативно относился к запускаемым на факультетских машинах файлам типа "exe".
Поэтому я решил создать программу, запускаемую средствами "MS Office" через броузер "Internet Explorer".
Мой макрос размещен в следующем месте проекта (в структуре макросов): "Project/Modules/Module1".
Его код следующий:
-------------------------------------
' Создание общедоступных (глобальных) переменных
Public FIO, currentFormEducation, questionAnswers(20, 20, 20), currentDirectory As String
Public currentTrueAnswers(20, 20, 20), numberCurrentAnswers(20, 20), numberCurrentQuestions(20), currentQuestion, currentTheme As Integer
Public maxTrueAnswers, numberTrueAnswers, numberFalseAnswers, numberPossibleFalseAnswers As Integer
Public numberAskedThemes, NumberThemes(50) As Integer
Public mark As Integer
Public courseFile(50) As String
Public answers(20, 20, 20) As Boolean
Sub autoopen()
' Установка нулевых значений на глобальные переменные
Dim i, j, k As Integer
numberAskedThemes = 0
FIO = ""
currentFormEducation = ""
currentQuestion = 0
For i = 0 To 20
For j = 0 To 20
numberCurrentAnswers(i, j) = 0
For k = 0 To 20
currentTrueAnswers(i, j, k) = 0
answers(i, j, k) = False
questionAnswers(i, j, k) = ""
Next k
Next j
Next i
' Переключение на русский язык
Selection.LanguageID = wdRussian
Selection.LanguageID = wdRussian
Selection.NoProofing = False
Application.CheckLanguage = False
Application.Keyboard (1049)
' Выход из режима с конструктором
CommandBars("Control Toolbox").Visible = False
' Считывание информации из файла
Dim Directory, inputData As String
Dim courseName(50), lecturerName(50) As String
Dim controlQuantity(50), numberFiles As Integer
Dim controlQuantityPermit As Boolean
For i = 1 To 50
controlQuantity(i) = 0
Next i
controlQuantityPermit = True
numberFiles = 0
'!!!_Проверка наличия файла с курсом на диске (к сожалению, данный кусок кода (выделенный значками "'") в ситуации появления ошибки "Run-time error '75': Path/File access error" ищет текстовые файлы на диске "C:" клиентской машины (на которой запускается макрос))
' Directory = "\\lib\SemHR\SystemFiles"
' currentDirectory = "\\lib\SemHR"
' Dim fileExist As Boolean
' fileExist = False
' Set fs = Application.FileSearch
' With fs
' .LookIn = Directory
' .FileName = "*.txt"
' If .Execute > 0 Then
' fileExist = True
' End If
' For i = 1 To .FoundFiles.Count
' courseFile(i) = .FoundFiles(i)
' Next i
' numberFiles = .FoundFiles.Count
' End With
courseFile(1) = "\\lib\SemHR\SystemFiles\course.txt"
'!!!_Количество текстовых файлов я сделал равным 1, так как их поиск не работает корректно (код выше, отмеченный знаками "'")
numberFiles = 1
'!!!_Здесь происходит начало работы с дескриптором "FreeFile"
Dim hFile As Long
hFile = FreeFile
' Проверка наличия исходных файлов
If fileExist = True Then
' Проверка количества исходных файлов
If numberFiles <= 50 Then
For i = 1 To numberFiles
NumberThemes(i) = 0
'!!!_Здесь происходит считывание файла "txt"
Open courseFile(i) For Input Access Read As hFile
Do While Not EOF(1)
Line Input #1, inputData
controlQuantity(i) = controlQuantity(i) + 1
' Определение максимального количества тем для тестирования
If InStrRev(inputData, "&", , 1) <> 0 Then
NumberThemes(i) = NumberThemes(i) + 1
End If
' Вычленение названия курса и ФИО преподавателя
If controlQuantity(i) = 1 Then
symbolPosition = InStrRev(inputData, "^", , 1)
inputData = Right(inputData, Len(inputData) - symbolPosition)
courseName(i) = inputData
End If
If controlQuantity(i) = 2 Then
symbolPosition = InStrRev(inputData, "^", , 1)
inputData = Right(inputData, Len(inputData) - symbolPosition)
lecturerName(i) = inputData
End If
Loop
Close hFile
Next i
' Проверка наличия
For i = 1 To 50
If controlQuantity(i) > 2000 Then
controlQuantityPermit = False
End If
Next i
If controlQuantityPermit = True Then
' Загрузка формы приветствия
Load GreetingForm
' Начальная установка формы обучения
GreetingForm.FormEducation.AddItem "Студент(ка) 3 курса"
GreetingForm.FormEducation.AddItem "Студент(ка) 4 курса"
GreetingForm.FormEducation.AddItem "Студент(ка) 5 курса"
GreetingForm.FormEducation.AddItem "Аспирант(ка) 1 г/о"
GreetingForm.FormEducation.AddItem "Аспирант(ка) 2 г/о"
GreetingForm.FormEducation.AddItem "Аспирант(ка) 3 г/о"
GreetingForm.FormEducation.AddItem "Отличная от предложенных"
GreetingForm.FormEducation.ListIndex = 0
' Начальная установка названия курса
For i = 1 To numberFiles
GreetingForm.TestCourseName.AddItem courseName(i) & " (составитель " & lecturerName(i) & ")"
Next i
GreetingForm.TestCourseName.ListIndex = 0
' Начальная установка количество тем для выбора
For i = 1 To NumberThemes(1)
GreetingForm.ThemesNumber.AddItem i
Next i
GreetingForm.ThemesNumber.ListIndex = 0
' Показать форму приветствия
GreetingForm.Show
NumberThemes(0) = NumberThemes(1)
Else
MsgBox "Корректное прочтение исходных файлов невозможно, так как один из исходных файлов с вопросами содержит слишком большое количество информации (более 2000 строк)!"
ActiveWindow.Close (0)
End If
Else
End If
Else
MsgBox "Прохождение теста невозможно, так как отсутствует один из исходных файлов!"
ActiveWindow.Close (0)
End If
End Sub
-------------------------------------
Добрый день, Dmitrii.
Спасибо Вам за поддержку!
Ваши мудрые подсказки и вопросы помогли мне решить задачу.
Проблема заключалась в том, что на папку "\\lib\SemHR" не было добавлено разрешение общего доступа типа "Все" на чтение.
В результате только у пользователей с добавленными доступами на чтение, а ими являлись те, кто имел полный доступ к этой папке, тест (файл "doc" с макросами) запускался без ошибок.
Соответственно, когда было добавлено разрешение общего доступа "Все" на чтение папки "\\lib\SemHR", то файл "txt" успешно прочитался из поддиректории "\\lib\SemHR\SystemFiles\".
Ответы на ранее заданные вопросы от Dmitrii следующие:
2.2. Какая ОС используется на сервере, и какая файловая система - на диске с данным сетевым ресурсом?
Ответ: На серверной машине используется операционна система (ОС) Windows 2000 server (W 2K Server). На машине с данным сетевым ресурсом установлена операционная система "Windows 2000 Professional". Файловая система на диске с данным сетевым ресурсом - FAT32.
2.3. Каким образом регулируются права доступа клиентов к ресурсу:
- разрешения настроены с помощью вкладки "Доступ";
Ответ: Все сетевые папки имеют общий доступ для всех пользователей (здесь-то и была допущена при администрировании ошибка, так как на папку "\\lib\SemHR" не все имели общий доступ).
- разрешения настроены с помощью вкладки "Безопасность";
Ответ: Для ВСЕХ с сетевой папкой разрешено производить следующие операции: 1) получать "список содержимого папки"; 2) осуществлять ее "чтение и выполнение"; 3) осуществлять "чтение".
- первое и второе сочетаются (как именно).
Ответ: Ответ приведен выше.
2.4. Используется ли для предоставления доступа к данному сетевому ресурсу DFS?
Ответ: Не используется.
3. Используется ли на рабочих станциях антивирус DrWeb версии 4.33?
Ответ: Dr. Web Antivirus сетевая версия №4.33
Желаю всем коллегам удачи!
Огромное спасибо Dmitrii за помощь в решении моего вопроса!!!
Dim i, j, k As Integer
При таком описании переменных только k будет иметь тип Integer, остальные же - тип Variant
Пользуясь случаем, также хотел бы выразить свою благодарность Dmitrii, за помощь в решении многих вопросов, включая и этот.
Спасибо Вам за мое просвящение.
У меня есть к Вам следующий встречный вопрос:
каким удобным образом (т.е. используя по возможности минимальное количество печатных символов) можно объявить переменные i, j и k, назначив им всем при этом тип Intеger?
На мой взгляд, здесь есть несколько вариантов решения, например :
Dim i%, j%, k%
MsgBox TypeName(i) & vbNewLine & _
TypeName(j) & vbNewLine & _
TypeName(k)
End Sub
или :
Private Sub Test_Variable()
MsgBox TypeName(i) & vbNewLine & _
TypeName(j) & vbNewLine & _
TypeName(k)
End Sub
Причём, в последнем случае все переменные, имена которых начинаются с i, j и k, будут иметь тип Integer, в т.ч. и inputData, которую Вы изначально предполагали использовать как строковую переменную. Впрочем, при желании это можно исправить, тем более, что Вам предстоит “корректировка” типа большинства переменных (19 из 32)
P.S. Термин встречный вопрос означает, что я имел наглость пытать Вас, задавая свои вопросы, чего я вроде бы не делал …
Мне очень понравился следующий способ объявления переменных: Dim i%, j%, k%
Он значительно экономичнее ранее используемого мною. Новый прием я обязательно буду использовать в своей дальнейшей практике.
Второй способ задания переменных мне сложно будет использовать в практике, поскольку мой стиль программирования основан на отражении личностных особенностей переменных в ее названии.
Большое спасибо за ценные знания, уважаемые учителя!
P.S.
Прошу прощения за свою терминологическую ошибку, допущенную в форуме. Мною была выбрана весьма ошибочная форма задания вопроса. Приношу свои извенения.
% - Integer
& - Long
! – Single
@ - Currency
# - Double
$ - String (только для строк переменной длины)
Тогда как второй вариант, предоставляет немного больше свободы :
DefBool - Boolean
DefByte - Byte
DefInt - Integer
DefLng - Long
DefCur - Currency
DefSng - Single
DefDbl - Double
DefDate - Date
DefStr - String
DefObj - Object
DefVar - Variant
Что касается осмысленных имён переменных, то использование инструкции Def… это позволяет, хотя для этого и придётся пойти на небольшой компромисс, например :
…
strDirectory
strInputData
intMaxTrueAnswers
intNumberTrueAnswers
Окончательное же решение, безусловно, остаётся только за Вами.
За последние дни я получил от Вас очень много ценных идей и практических знаний. С помощью Dmitrii мне удалось решить проблему, над которой я бился 5 месяцев. Pashulka исправил мои будущие ошибки. Теперь у меня "чешутся руки" дописать последний компонент к тестовой системе, позволяющий преподавателям быстро создавать файл "txt". Постараюсь успеть к запланированной проверки знаний у студентов в конце весенного учебного семестра этого года.
Желаю Dmitrii и Pashulka крепкого здоровья, большого семейного счастья и достойного признания со стороны работодателей Ваших глубоких знаний и умений!
'!!!_Количество текстовых файлов я сделал равным 1, так как их поиск не работает корректно (код выше, отмеченный знаками "'")
Проверил этот фрагмент кода у себя. Всё работает нормально. А какая ошибка возникает?
Впрочем, могу предложить свою редакцию данной процедуры:
Set fs = Application.FileSearch
With fs
.LookIn = Directory
.Filename = "*.txt"
If .Execute > 0 Then
fileExist = True
numberFiles = .FoundFiles.Count
ReDim courseFile(1 To numberFiles)
For i = 1 To numberFiles
courseFile(i) = .FoundFiles(i)
Next i
End If
End With
1. Думаю, запускать цикл имеет смысл лишь тогда, когда результат поиска положителен.
2. Зачем лишний раз использовать выражение [COLOR=blue].FoundFiles.Count[/COLOR], если уже имеется переменная для хранения значения количества найденных файлов.
3. Советую воспользоваться возможностью применения массивов динамической размерности:
Замечу, что в таком случае массив courseFile можно объявить так: [COLOR=blue]Dim courseFile() As String[/COLOR].
Так Вы будете застрахованы от ошибки переполнения массива courseFile, если файлов искомой спецификации будет найдено больше, чем первоначально планировалось.
Имя файла "txt" в моей задаче отражает название курса с характерными для него темами, вопросами и ответами. Тест уже адаптирован под работу с несколькими такими файлами. Поэтому я обязательно буду использовать код, осуществляющий поиск всех доступных файлов "txt" в папке \\lib\SemHR\SystemFiles.
В переменную numberFiles планируется сохранять информацию о количестве исходных файлов "txt". Значение для нее будет браться из выражения ".FoundFiles.Count". Мне очень понравилась возможность динамического объявления массива courseFile. В настоящее время и ближайшие 1-2 года планируется использовать для тестирования от 1 до 5 файлов "txt" одновременно. Однако мне сложно предвидеть судьбу данного теста через 2 года.
Ваш, Dmitrii, код динамического объявления переменной дает мне больше возможности контролировать размер массива с названиями файлов "txt", чем использованный мною ранее код.
Профессионалы, спасибо Вам за то, что Вы есть!