Открыть книгу Excel.Application монопольно

1. unichkin 1604 07.05.17 18:31 Сейчас в теме
Хочу программно открывать книгу экселя таким образом, чтобы пользователь при попытке открыть ту же книгу видел сообщение, что она на данный момент занята - т.е. также как это штатно происходит.
Понимаю, что ответ где-то на MSDN но ниасилю никак..
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
24. spectre1978 61 12.05.17 09:07 Сейчас в теме +2 $m
(21) Любой совместный доступ достаточно сложная тема... Судя по тому, что здесь пишут, поведение экселя еще и меняется в зависимости от непонятных причин, например я на вируалке с XP и Office 2007 так и не поймал вашу багу. А у вас она есть. Отсюда печальный вывод - даже если вы добьетесь сносной работы в одной системе, еще не факт что это будет работать на другой.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
5. spectre1978 61 09.05.17 17:08 Сейчас в теме
(1) Так никаких дополнительных телодвижений вроде бы и не надо, это штатное поведение! Может быть, на тот момент когда вы тестируете второе открытие, у вас книга просто закрыта уже? Поставьте какую-нибудь длительно выполняющуюся манипуляцию (типа цикла от одного до ста тысяч с сообщением счетчика) после Workbooks.Open и проверьте открытие, пока этот цикл будет бежать.
8. unichkin 1604 09.05.17 23:42 Сейчас в теме
(5) По-идее да.. Но не работает. Если просто использовать open:
1) Открываю книгу программно
2) Открываю ее-же под текущим пользователем - ожидаю что эксель ругнется, мол она уже открыта - но этого не происходит.
И далее:
3) Под пользователем меняю что-нибудь, сохраняюсь
4) Ранее программно инициализированная книга при попытке чтения листа выбрасывает исключение.
10. spectre1978 61 10.05.17 12:29 Сейчас в теме
(8) а какая версия Excel? У меня на 2007 вчера не получилось воспроизвести такое поведение. После того как книга открыта через OLE - открытие в самом Excel удается сделать только на чтение. Кстати - обращаю внимание - на чтение. Т.е. изменений внести не получится, пока OLE не освободит книгу.
7. alxarz 32 09.05.17 21:46 Сейчас в теме
(1) а что если при открытии защитить книгу паролем, а после работы либо убираем, либо ставим какой был...
9. unichkin 1604 09.05.17 23:43 Сейчас в теме
(7) Нет, пользователь должен иметь возможность открыть книгу и внести свои изменения. Но только с предупреждением - что она уже и так открыта. Пароль 123 тоже не хочу. Но сама идея неплохая..
12. lefthander 10.05.17 12:53 Сейчас в теме
(9)А вот это не получится, если книга не в совместном использовании. Открытая по ОЛЕ книга залочена на изменения, только копию можно открыть на редактирование.
19. alxarz 32 11.05.17 08:57 Сейчас в теме
(9)
Нет, пользователь должен иметь возможность открыть книгу и внести свои изменения.
в теме написано "монопольно", в тексте вопроса тоже про внесение изменений ничего :)
20. unichkin 1604 11.05.17 22:44 Сейчас в теме
(19) написано "программно открывать книгу экселя таким образом, чтобы пользователь при попытке открыть ту же книгу видел сообщение, что она на данный момент занята - т.е. также как это штатно происходит. ". И в (9) я дальше пишу - "Но только с предупреждением - что она уже и так открыта". Т.е. если открыта - выкатывать штатное окно с кнопкой "уведомить" - когда файл освободиться. И если в 1С разрываем с экселем соединение, можно править.
Даже не думал, что тут такие сложности будут. В итоге думаю что не буду загоняться на этом, но еще поковыряю на выходных - если что придумается отпишусь.
11. lefthander 10.05.17 12:52 Сейчас в теме
(1)Процедуру открытия книги можно посмотреть? Такое подозрение что после считывания данных книга успешно закрывается и потому доступна для редактирования.
13. spectre1978 61 10.05.17 15:31 Сейчас в теме
(11) я вчера предположил ровно то же - см. (5). Потому как если ее все же оставлять открытой в OLE, то никак не получается воспроизвести описанный автором косяк.
2. unichkin 1604 07.05.17 18:33 Сейчас в теме
Вроде это должно помочь https://msdn.microsoft.com/en-us/library/office/ff198339.aspx, но либо не так использую, либо не то.. В примерах на VB это enumeration, которому присваивают одно из значений XlSaveConflictResolution, в 1С - это число, причем дает установить либо 0 либо 1, вероятно что-то не так делаю.
3. unichkin 1604 07.05.17 18:43 Сейчас в теме
Увидел параметр Notify в методе open, но отрабатывает через раз.. Может еще что надо указать?
4. AlexanderP 42 09.05.17 15:14 Сейчас в теме
А Excel по умолчанию открывается не в режиме для записи? Мне кажется, параметр ReadOnly для метода Open как раз нужен, чтобы указать обратное. Notify, похоже, требуется для открытия файла, который может быть уже занят. Если = true, то в случае освобождения получим оповещение.
6. spectre1978 61 09.05.17 17:44 Сейчас в теме
но там есть нюанс: если вы тестируете это все под одним пользователем Windows, открыв файл в Excel и затем открыв его же в своей программе, то файл на самом деле не открывается повторно, а происходит обращение к уже открытому пользователем. С теми же правами, с какими у пользователя было открыто. Если вас такое поведение не устраивает, то вам в вашей программе перед открытием файла нужно проверить, открыт ли он сейчас в экселе, и если да, то что-нибудь сделать. Например, поругаться на пользователя, чтобы он его закрыл.
14. unichkin 1604 10.05.17 20:04 Сейчас в теме
1. Создаю на раб. столе файл xlsx, закрываю его
2. Выполняю такой код:

// Инициализация основного объекта EXCEL.Application: Открытие соединения.
	Приложение = Новый COMОбъект("EXCEL.Application");
	Приложение.Visible       = Ложь;
	Приложение.DisplayAlerts = Ложь;

	ПутьКФайлу = "C:\Users\User\Desktop\Лист Microsoft Excel.xlsx";
	
	Книга = Приложение.WorkBooks.Open(ПутьКФайлу);


Торможусь по точке останова после создания книги.
3. Открываю файл - без всяких сообщений\предупреждений открывается, дает себя редактировать.
4. Если после редактирования обратиться к листам книги - будет исключение
Вывод: надо открыть файл программно таким образом, чтобы пользователь при открытии получил стандартное сообщение Excell, что файл уже открыт. А вот как-ума не дам.. Остается на откуп пользователю отдать - мол, следите чтобы открыт не был, иначе ошибка.
16. VmvLer 10.05.17 23:44 Сейчас в теме +3 $m
(14)

Приложение = Новый COMОбъект("EXCEL.Application");

Приложение.Visible = Ложь; 
Приложение.DisplayAlerts = Ложь; 

ПутьКФайлу = "C:\Users\User\Desktop\Лист Microsoft Excel.xlsx"; 

Книга = Приложение.WorkBooks.Open(ПутьКФайлу);


Торможусь по точке останова после создания книги.


далее использовать метод книги

ChangeFileAccess(Mode, WritePassword, Notify) - изменяет статус доступа. Новый статус задается параметром Mode, который может принимать одно из двух значений: xlReadWrite и xlReadOnly. Если файл снабжен паролем и получает статус для записи и чтения, то второй параметр WritePassword задает пароль на запись. Если булевый параметр Notify имеет значение True, то пользователь получает уведомление, когда файл недоступен.

согласно

https://msdn.microsoft.com/ru-ru/library/microsoft.office.tools.excel.workbook.changefileaccess.aspx

Если файл открыт в режиме только для чтения, у вас монопольный доступ к файлу.

значения xlReadWrite и xlReadOnly: 2 и 3 соответственно
http://forum.infostart.ru/forum9/topic70485/

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

Если Книга.ReadOnly Тогда
        тСообщить = "Файл открылся только для чтения";
        Mode =  2;    // xlReadWrite;
        Notify = Истина;   // в 1С True=-1 для Excel, проверить со значением -1
        // пытаемся получить полный доступ к файлу
        Попытка
             Книга.ChangeFileAccess(Mode, , Notify);
        Исключение
             тСообщить = тСообщить + Символы.ПС + ОписаниеОшибки();
        КонецПопытки;
Иначе
        тСообщить = "Файл открылся с полным доступом, значит пока не блокирован";
КонецЕсли; 
  
// после отладки убрать, т.к.  команда Книга.ChangeFileAccess(Mode, , Notify) должна выдать интерактивное сообщение в Excel при "захвате" книги другим пользователем;
Сообщить(тСообщить );  

Приложение.DisplayAlerts = Истина;   // включаем снова вывод предупреждений
Показать
unichkin; +1 Ответить
17. unichkin 1604 11.05.17 07:20 Сейчас в теме
(16)
Книга.ReadOnly
- за это спасибо. Но ChangeFileAccess не отрабатывает как должен, вероятно еще какие-то параметры нужны. Сама фраза "Если файл открыт в режиме только для чтения, у вас монопольный доступ к файлу." - что-то со скрипом верится. По крайней мере ваш пример этого не доказывает - все работает точно также, как и без ChangeFileAccess. Буду курить, спасибо за развернутый комментарий.
15. BackinSoda 10.05.17 20:15 Сейчас в теме
Не знаю как у Вас, а у нас при попытке открыть тот же файл эксель, он просто активизирует/разворачивает окно с открытым файлом, и никакого стандартного сообщения не выходит
18. VmvLer 11.05.17 08:45 Сейчас в теме
может сместить оператор

Приложение.DisplayAlerts = Ложь; 

за пределы проверки монопольного доступа методом, т.е.

Если Книга.ReadOnly Тогда
....
КонецЕсли;

Приложение.DisplayAlerts = Ложь;  // После проверки и системных предупреждений экзел - запрещаем вывод предупреждений
...
.... // выполняем действия с книгой

Приложение.DisplayAlerts = Истина;   // включаем снова вывод предупреждений
....
Показать
21. unichkin 1604 11.05.17 22:48 Сейчас в теме
(18) Я пробовал тоже с ним играться, не то. Попробуйте кстати включить DisplayAlerts и посмотреть на окно Excell, которое при этом создается. Оно какое-то куцое все, обрезанное. Я так подозреваю что программное открытие не задействует ряд процессов, один из которых и отвечает за отслеживание занятости файла. Видимо ради скорости\гибкости это все на программисте - раз уж открываешь программно, то дальше флаг тебе в руки. В принципе верно.. Но пока докопаешься до этих глубин, руки сотрешь до плеч)
24. spectre1978 61 12.05.17 09:07 Сейчас в теме +2 $m
(21) Любой совместный доступ достаточно сложная тема... Судя по тому, что здесь пишут, поведение экселя еще и меняется в зависимости от непонятных причин, например я на вируалке с XP и Office 2007 так и не поймал вашу багу. А у вас она есть. Отсюда печальный вывод - даже если вы добьетесь сносной работы в одной системе, еще не факт что это будет работать на другой.
25. unichkin 1604 13.05.17 23:01 Сейчас в теме
Не буду больше возиться с этим, (21) прав - трата времени. То что воспроизведется у меня - не факт что взлетит на раб. машине, лишняя головная боль.
22. spectre1978 61 11.05.17 22:49 Сейчас в теме
Если структура книги достаточно простая, то возможно, для вашего применения более удачным вариантом будет через ADO в программе работать - тогда это будет без вариантов другой ole-сервер, к тому же inproс, соответственно у Экселя гарантированно отпадёт охота подключаться на запись к уже открытой книге.
23. unichkin 1604 11.05.17 23:11 Сейчас в теме
(22)
Если структура книги достаточно простая, то возможно, для вашего применения более удачным вариантом будет через ADO в программе работать - тогда это будет без вариантов другой ole-сервер, к тому же inproс, соответственно у Экселя гарантированно отпадёт охота подключаться на запись к уже открытой книге.

Сложная структура... К тому же много сил уже на эксель потратил. Да и с ADO 100% новые грабли будут. Так что не в этот раз)
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот