Добрый день, знатоки. Подскажите возможно ли средствами VBA определить открыт ли уже файл (который я хочу открыть) другим пользователем (ну или мной)? Хочется вместо системного сообщения и прекращения работы макроса выводить свой msgbox и работать по обстановке (занят файл/не занят).
Почитал, поковырялся - пока не нашел. Всем заранее спасибо.
Guest
Гость
25.11.2010 15:42:54
можно через wb.activate и on error resume next
Пользователь
Сообщений: Регистрация: 11.01.2013
25.11.2010 15:43:37
> Хочется вместо системного сообщения и прекращения работы макроса
Почему бы не перехватить ошибку? On Error...
Пользователь
Сообщений: Регистрация: 13.05.2010
25.11.2010 15:47:16
Сергей, недавно подымалась тема с Вашим вопросом, наберите в поиске "UserStatus" (код от уважаемого The_Prist).
<FONT COLOR="CadetBlue">
Пользователь
Сообщений: Регистрация: 22.12.2012
На лицо ужасный, добрый внутри
25.11.2010 15:53:56
Что-то я не понял... Вы что хотите: 1. Не открывая книгу, узнать, не открыта ли она в режиме монопольного доступа кем-то другим? 2. Узнать программно, кем, когда и в каком режиме открыта книга общего доступа?
В любом случае посмотрите, может быть что-нибудь наковыряете для себя из этого: Sub Workbook_UserStatus () 'Свойство UserStatus Property возвращает 2D-массив (1 to 3), содержащий информацию _ о каждом пользователе, открывшем книгу в режиме общего доступа. '1-й столбец - имя пользователя, открывшего книгу в режиме общего доступа, _ 2-й столбец - дата и время, когда этот пользователь открыл книгу, _ 3-й столбец - индикатор режима открытия книги (1 - монопольный, 2 - общий доступ). Debug.Print IIf(Workbooks("personal.xls").UserStatus(1, 3) = 1, "Exclusive", "Shared") End Sub
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Сергей М
Гость
25.11.2010 16:09:31
Да, Не открывая книгу, узнать, не открыта ли она (режим "для чтения" не устраивает). Спасибо за подсказки, щас попробую userstatus
Сергей М
Гость
25.11.2010 16:10:55
{quote}{login=Казанский}{date=25.11.2010 03:43}{thema=}{post}> Хочется вместо системного сообщения и прекращения работы макроса
Почему бы не перехватить ошибку? On Error...{/post}{/quote}
Пробовал, что-то не хочет и всё.
Модератор
Сообщений: Регистрация: 14.09.2012
Контакты см. в профиле
25.11.2010 16:13:59
Option Compare Text 'Если Вы не понимаете, зачем используется эта инструкция, то оставьте её в покое
Private Function WorkbookIsOpen(iName$) As Boolean '***********************************************' ' Дата создания 01/01/2005 ' Автор Климов Павел Юрьевич ' '***********************************************' Dim iBook As Workbook For Each iBook In Workbooks If iBook.Name = iName$ Then WorkbookIsOpen = True Exit Function End If Next WorkbookIsOpen = False End Function
Private Function WorkbookIsOpen(iName$) As Boolean '***********************************************' ' Дата создания 01/01/2005 ' Автор Климов Павел Юрьевич ' '***********************************************' Dim iBook As Workbook For Each iBook In Workbooks If StrComp(iBook.Name, iName$, vbTextCompare) = 0 Then WorkbookIsOpen = True Exit Function End If Next WorkbookIsOpen = False End Function Вариант II. Private Function WorkbookIsOpen(iName$) As Boolean '***********************************************' ' Дата создания 01/01/2005 ' Автор Климов Павел Юрьевич ' '***********************************************' On Error Resume Next WorkbookIsOpen = IsObject(Workbooks(iName$)) End Function
Private Function WorkbookIsOpen(iName$) As Boolean On Error Resume Next WorkbookIsOpen = (TypeOf Workbooks(iName$) Is Workbook) End Function
Private Function WorkbookIsOpen(iName$) As Boolean On Error Resume Next WorkbookIsOpen = (TypeName(Workbooks(iName$)) = "Workbook") End Function
Private Function WorkbookIsOpen(iName$) As Boolean On Error Resume Next WorkbookIsOpen = (VarType(Workbooks(iName$)) = vbObject) End Function
Private Function WorkbookIsOpen(iName$) As Boolean On Error Resume Next WorkbookIsOpen = Len(Workbooks(iName$).Name) > 0 End Function
Private Function WorkbookIsOpen(iName$) As Boolean On Error Resume Next WorkbookIsOpen = Workbooks(iName$).Index > 0 End Function Пример вызова любой из вышеопубликованных авторских функций : Private Sub Test() MsgBox WorkbookIsOpen("Имя_Книги.xls") End Sub
Пользователь
Сообщений: Регистрация: 13.05.2010
25.11.2010 16:25:16
Юрий, а может все-таки пример Дмитрия (The_Prist )? :)
P.S. Там где он девушке (женщине) помог (у меня не находит).
<FONT COLOR="CadetBlue">
Пользователь
Сообщений: Регистрация: 22.12.2012
На лицо ужасный, добрый внутри
25.11.2010 16:49:13
Мужики, я так понял, что книга расшарена и лежит на серваке, но общий доступ в ней не разрешён. Очевидно, что Сергею не хочется ДАЖЕ ПРОБОВАТЬ открывать эту книгу по каким-то причинам (это его дело, по каким) в случае если она уже открыта кем-то другим. Ну, брезгливый он, капример :-) Тогда может прокатить такой вариант: 1. В AutoOpen этой книги прописываете процедуру записи в те её Properties, которые видно даже без открытия файла, какого-нибудь заранее оговоренного свойства (ну, например,комментария). И сразу же там же - сохранение книги. 2. В AutoClose этой книги прописываете удаление этого комментария перед сохранением. 3. В своём Personal пропишите Ёкселю, чтобы попытке открыть любой файл сначала читаел у него комментарий и по нему уже определял, открыт файл кем-то или нет.
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Пользователь
Сообщений: Регистрация: 22.12.2012
На лицо ужасный, добрый внутри
25.11.2010 16:52:34
Дмитрий (The_Prist), а чем это принципиально отличается от тог, что я советовал в 15:53: Sub Workbook_UserStatus () Debug.Print IIf(Workbooks("personal.xls").UserStatus(1, 3) = 1, "Exclusive", "Shared") End Sub
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Сергей М
Гость
25.11.2010 16:55:55
Забил
Dim asUsersAs String asUsers = Workbooks(путь с диском, каталогом).UserStatus
сразу же выдал ошибку 9
Пользователь
Сообщений: Регистрация: 22.12.2012
На лицо ужасный, добрый внутри
25.11.2010 17:10:39
{quote}{login=Сергей М}{date=25.11.2010 04:55}{thema=}{post} Dim asUsersAs String asUsers = Workbooks(путь с диском, каталогом).UserStatus сразу же выдал ошибку 9{/post}{/quote} Ну, этого и следовало ожидать. Ведь в примерах и я и Дмитрий писАли в скобках у Workbooks не Workbooks(путь с диском, каталогом), а имя ОТКРЫТОЙ книги: Workbooks("Книга1.xls") или Workbooks("personal.xls").
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Пользователь
Сообщений: Регистрация: 22.12.2012
На лицо ужасный, добрый внутри
25.11.2010 17:15:07
Сергей, а почему вы не хотите открыть книгу, заблокировав сообщения Application.DisplayAlerts = False, потом проверить её UserStatus и если он вас не устраивает, сразу её закрыть и опять разрешить сообщения?
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Сергей М
Гость
25.11.2010 17:17:08
Проверка нужна перед тем как открывать файл чтобы внести в него изменения (макросом), а если там (в файле) уже кто-то сидит, то макрос может сработать коряво. Вот и хочется не открывать.
Можно сделать вывод что файл НЕ открыт, если выдает ошибку?
Пользователь
Сообщений: Регистрация: 13.05.2010
25.11.2010 17:18:59
Нашел тему, см. внимательно:
<FONT COLOR="CadetBlue">
Пользователь
Сообщений: Регистрация: 22.12.2012
На лицо ужасный, добрый внутри
25.11.2010 17:22:04
У вас что, макрос что-то выполняет по событию Workbook_Open (или по AutoOpen)? Ну тогда первым же действием и встройте в него проверку на то, открыт ли файл уже кем-то другим.
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Сергей М
Гость
25.11.2010 17:29:21
С Workbook_Open работает. После того как Файл открыл Userstatus заработал. Теперь наверно нужно количество юзеров посчитать и про них msgbox написать.
Пользователь
Сообщений: Регистрация: 13.05.2010
25.11.2010 17:33:16
Сергей, Вы по ссылке ходили?! Там все это есть...
-=75575=-
<FONT COLOR="CadetBlue">
Сергей М
Гость
25.11.2010 17:45:08
Да, смотрел. Спасибо.
Вроде получилось (всё-таки с открытием файла, а не без этого). Всем спасибо за участие в решении.
Пользователь
Сообщений: Регистрация: 23.12.2012
26.11.2010 06:39:26
Без загрузки файла в Excel:
Function IsOpen(File$) As Boolean Dim FN% FN = FreeFile On Error Resume Next Open File For Random Access Read Write Lock Read Write As #FN Close #FN IsOpen = Err End Function
Sub Test() Debug.Print IsOpen("C:\Test.xls") End Sub
Пользователь
Сообщений: Регистрация: 16.01.2013
26.11.2010 08:38:40
а где ставится непосредственно этот флаг lock ?
если позволите ..:)
Живи и дай жить..
Пользователь
Сообщений: Регистрация: 23.12.2012
26.11.2010 16:34:02
{quote}{login=слэн}{date=26.11.2010 08:38}{thema=}{post}а где ставится непосредственно этот флаг lock ?{/post}{/quote} Где-то в файловой системе операционки :-)
Сссылки, если кому-то интересно: MSDN: Википедия:
В VBA это операторы Lock и Unlock. Из VBA справки: "it controls access by other processes to all or part of a file opened using the Open statement"
Пример использования:
Пользователь
Сообщений: Регистрация: 23.12.2012
26.11.2010 16:38:18
Эксклюзтвный доступ к папке, файлу или к его части операционная система предоставляет для запросившего процесса. Такой доступ снимается либо по команде Unlock из этого же процесса, либо автоматически через некоторое время после закрытия процесса.
dl
Гость
26.11.2010 16:59:29
{quote}{login=ZVI}{date=26.11.2010 04:38}{thema=}{post} снимается либо по команде Unlock из этого же процесса{/post}{/quote}
а так хотелось бы
если мойфайл lock для места из которого его lock в приложение которое его lock выполнить unlock мойфайл msgbox("ТЕПЕРЬ ТЫ САМ LOCK!")