Хочу программно открывать книгу экселя таким образом, чтобы пользователь при попытке открыть ту же книгу видел сообщение, что она на данный момент занята - т.е. также как это штатно происходит.
Понимаю, что ответ где-то на MSDN но ниасилю никак..
24.
spectre1978
6112.05.17 09:07 Сейчас в теме+2 $m
(21) Любой совместный доступ достаточно сложная тема... Судя по тому, что здесь пишут, поведение экселя еще и меняется в зависимости от непонятных причин, например я на вируалке с XP и Office 2007 так и не поймал вашу багу. А у вас она есть. Отсюда печальный вывод - даже если вы добьетесь сносной работы в одной системе, еще не факт что это будет работать на другой.
(1) Так никаких дополнительных телодвижений вроде бы и не надо, это штатное поведение! Может быть, на тот момент когда вы тестируете второе открытие, у вас книга просто закрыта уже? Поставьте какую-нибудь длительно выполняющуюся манипуляцию (типа цикла от одного до ста тысяч с сообщением счетчика) после Workbooks.Open и проверьте открытие, пока этот цикл будет бежать.
(5) По-идее да.. Но не работает. Если просто использовать open:
1) Открываю книгу программно
2) Открываю ее-же под текущим пользователем - ожидаю что эксель ругнется, мол она уже открыта - но этого не происходит.
И далее:
3) Под пользователем меняю что-нибудь, сохраняюсь
4) Ранее программно инициализированная книга при попытке чтения листа выбрасывает исключение.
(8) а какая версия Excel? У меня на 2007 вчера не получилось воспроизвести такое поведение. После того как книга открыта через OLE - открытие в самом Excel удается сделать только на чтение. Кстати - обращаю внимание - на чтение. Т.е. изменений внести не получится, пока OLE не освободит книгу.
(7) Нет, пользователь должен иметь возможность открыть книгу и внести свои изменения. Но только с предупреждением - что она уже и так открыта. Пароль 123 тоже не хочу. Но сама идея неплохая..
(9)А вот это не получится, если книга не в совместном использовании. Открытая по ОЛЕ книга залочена на изменения, только копию можно открыть на редактирование.
(19) написано "программно открывать книгу экселя таким образом, чтобы пользователь при попытке открыть ту же книгу видел сообщение, что она на данный момент занята - т.е. также как это штатно происходит. ". И в (9) я дальше пишу - "Но только с предупреждением - что она уже и так открыта". Т.е. если открыта - выкатывать штатное окно с кнопкой "уведомить" - когда файл освободиться. И если в 1С разрываем с экселем соединение, можно править.
Даже не думал, что тут такие сложности будут. В итоге думаю что не буду загоняться на этом, но еще поковыряю на выходных - если что придумается отпишусь.
(1)Процедуру открытия книги можно посмотреть? Такое подозрение что после считывания данных книга успешно закрывается и потому доступна для редактирования.
(11) я вчера предположил ровно то же - см. (5). Потому как если ее все же оставлять открытой в OLE, то никак не получается воспроизвести описанный автором косяк.
Вроде это должно помочь https://msdn.microsoft.com/en-us/library/office/ff198339.aspx, но либо не так использую, либо не то.. В примерах на VB это enumeration, которому присваивают одно из значений XlSaveConflictResolution, в 1С - это число, причем дает установить либо 0 либо 1, вероятно что-то не так делаю.
А Excel по умолчанию открывается не в режиме для записи? Мне кажется, параметр ReadOnly для метода Open как раз нужен, чтобы указать обратное. Notify, похоже, требуется для открытия файла, который может быть уже занят. Если = true, то в случае освобождения получим оповещение.
но там есть нюанс: если вы тестируете это все под одним пользователем Windows, открыв файл в Excel и затем открыв его же в своей программе, то файл на самом деле не открывается повторно, а происходит обращение к уже открытому пользователем. С теми же правами, с какими у пользователя было открыто. Если вас такое поведение не устраивает, то вам в вашей программе перед открытием файла нужно проверить, открыт ли он сейчас в экселе, и если да, то что-нибудь сделать. Например, поругаться на пользователя, чтобы он его закрыл.
1. Создаю на раб. столе файл xlsx, закрываю его
2. Выполняю такой код:
// Инициализация основного объекта EXCEL.Application: Открытие соединения.
Приложение = Новый COMОбъект("EXCEL.Application");
Приложение.Visible = Ложь;
Приложение.DisplayAlerts = Ложь;
ПутьКФайлу = "C:\Users\User\Desktop\Лист Microsoft Excel.xlsx";
Книга = Приложение.WorkBooks.Open(ПутьКФайлу);
Торможусь по точке останова после создания книги.
3. Открываю файл - без всяких сообщений\предупреждений открывается, дает себя редактировать.
4. Если после редактирования обратиться к листам книги - будет исключение
Вывод: надо открыть файл программно таким образом, чтобы пользователь при открытии получил стандартное сообщение Excell, что файл уже открыт. А вот как-ума не дам.. Остается на откуп пользователю отдать - мол, следите чтобы открыт не был, иначе ошибка.
Приложение = Новый COMОбъект("EXCEL.Application");
Приложение.Visible = Ложь;
Приложение.DisplayAlerts = Ложь;
ПутьКФайлу = "C:\Users\User\Desktop\Лист Microsoft Excel.xlsx";
Книга = Приложение.WorkBooks.Open(ПутьКФайлу);
Торможусь по точке останова после создания книги.
далее использовать метод книги
ChangeFileAccess(Mode, WritePassword, Notify) - изменяет статус доступа. Новый статус задается параметром Mode, который может принимать одно из двух значений: xlReadWrite и xlReadOnly. Если файл снабжен паролем и получает статус для записи и чтения, то второй параметр WritePassword задает пароль на запись. Если булевый параметр Notify имеет значение True, то пользователь получает уведомление, когда файл недоступен.
далее предлагаю отладить такой вариант кода с коленок, проверку синтаксиса и логики не проводил, просто пример:
Если Книга.ReadOnly Тогда
тСообщить = "Файл открылся только для чтения";
Mode = 2; // xlReadWrite;
Notify = Истина; // в 1С True=-1 для Excel, проверить со значением -1
// пытаемся получить полный доступ к файлу
Попытка
Книга.ChangeFileAccess(Mode, , Notify);
Исключение
тСообщить = тСообщить + Символы.ПС + ОписаниеОшибки();
КонецПопытки;
Иначе
тСообщить = "Файл открылся с полным доступом, значит пока не блокирован";
КонецЕсли;
// после отладки убрать, т.к. команда Книга.ChangeFileAccess(Mode, , Notify) должна выдать интерактивное сообщение в Excel при "захвате" книги другим пользователем;
Сообщить(тСообщить );
Приложение.DisplayAlerts = Истина; // включаем снова вывод предупреждений
- за это спасибо. Но ChangeFileAccess не отрабатывает как должен, вероятно еще какие-то параметры нужны. Сама фраза "Если файл открыт в режиме только для чтения, у вас монопольный доступ к файлу." - что-то со скрипом верится. По крайней мере ваш пример этого не доказывает - все работает точно также, как и без ChangeFileAccess. Буду курить, спасибо за развернутый комментарий.
Не знаю как у Вас, а у нас при попытке открыть тот же файл эксель, он просто активизирует/разворачивает окно с открытым файлом, и никакого стандартного сообщения не выходит
за пределы проверки монопольного доступа методом, т.е.
Если Книга.ReadOnly Тогда
....
КонецЕсли;
Приложение.DisplayAlerts = Ложь; // После проверки и системных предупреждений экзел - запрещаем вывод предупреждений
...
.... // выполняем действия с книгой
Приложение.DisplayAlerts = Истина; // включаем снова вывод предупреждений
....
(18) Я пробовал тоже с ним играться, не то. Попробуйте кстати включить DisplayAlerts и посмотреть на окно Excell, которое при этом создается. Оно какое-то куцое все, обрезанное. Я так подозреваю что программное открытие не задействует ряд процессов, один из которых и отвечает за отслеживание занятости файла. Видимо ради скорости\гибкости это все на программисте - раз уж открываешь программно, то дальше флаг тебе в руки. В принципе верно.. Но пока докопаешься до этих глубин, руки сотрешь до плеч)
24.
spectre1978
6112.05.17 09:07 Сейчас в теме+2 $m
(21) Любой совместный доступ достаточно сложная тема... Судя по тому, что здесь пишут, поведение экселя еще и меняется в зависимости от непонятных причин, например я на вируалке с XP и Office 2007 так и не поймал вашу багу. А у вас она есть. Отсюда печальный вывод - даже если вы добьетесь сносной работы в одной системе, еще не факт что это будет работать на другой.
Если структура книги достаточно простая, то возможно, для вашего применения более удачным вариантом будет через ADO в программе работать - тогда это будет без вариантов другой ole-сервер, к тому же inproс, соответственно у Экселя гарантированно отпадёт охота подключаться на запись к уже открытой книге.
Если структура книги достаточно простая, то возможно, для вашего применения более удачным вариантом будет через ADO в программе работать - тогда это будет без вариантов другой ole-сервер, к тому же inproс, соответственно у Экселя гарантированно отпадёт охота подключаться на запись к уже открытой книге.
Сложная структура... К тому же много сил уже на эксель потратил. Да и с ADO 100% новые грабли будут. Так что не в этот раз)