Доброго времени суток!
Подскажите, плз, что-нибудь по такой проблеме: закачиваются данные из Excel по OLE. Файл открывается и считывается стандартно (откуда — в данном случае не принципиально, Deplhi, VB — все равно):
ObjExcel.Workbooks.Open(...)
ObjExcel.Workbook(имя).Worksheet(1).Cells(...)
Если в процессе загрузки открыть любой другой файл excel, то вместе с ним открывается окно с тем файлом, из которого грузятся данные, что уже не очень гуд. А если потом закрыть excel, то приложение загрузки теряет файл, что совсем уже плохо. Можно ли как-то открыть файл по OLE так, чтобы это соединение вообще не имело отношения к тому, что открывается параллельно? Спасибо.
Здравствуйте, EvgeniyM, Вы писали:
EM>Подскажите, плз, что-нибудь по такой проблеме: закачиваются данные из Excel по OLE. Файл открывается и считывается стандартно (откуда — в данном случае не принципиально, Deplhi, VB — все равно): EM>ObjExcel.Workbooks.Open(...) EM>ObjExcel.Workbook(имя).Worksheet(1).Cells(...) EM>Если в процессе загрузки открыть любой другой файл excel, то вместе с ним открывается окно с тем файлом, из которого грузятся данные, что уже не очень гуд. А если потом закрыть excel, то приложение загрузки теряет файл, что совсем уже плохо. Можно ли как-то открыть файл по OLE так, чтобы это соединение вообще не имело отношения к тому, что открывается параллельно?
Попробуйте
ObjExcel.IgnoreRemoteRequests = True
только его надо очень аккуратно восстанавливать перед закрытием объекта Application
ObjExcel.IgnoreRemoteRequests = False
иначе файлы перестанут открываться "из shell", а только через File->Open, пока не уберете соответствующую галочку
В интерфейсе это Сервис->Параметры->Общие — CheckBox Игнорировать DDE-запросы от других приложений
Здравствуйте, EvgeniyM, Вы писали:
EM>Доброго времени суток! EM>Подскажите, плз, что-нибудь по такой проблеме: закачиваются данные из Excel по OLE. Файл открывается и считывается стандартно (откуда — в данном случае не принципиально, Deplhi, VB — все равно): EM>ObjExcel.Workbooks.Open(...) EM>ObjExcel.Workbook(имя).Worksheet(1).Cells(...) EM>Если в процессе загрузки открыть любой другой файл excel, то вместе с ним открывается окно с тем файлом, из которого грузятся данные, что уже не очень гуд. А если потом закрыть excel, то приложение загрузки теряет файл, что совсем уже плохо. Можно ли как-то открыть файл по OLE так, чтобы это соединение вообще не имело отношения к тому, что открывается параллельно?
Excel как Application имеет кучу событий. Нужно прицепиться к событиям Excel (например, на закрытие документов) и использовать/отслеживать их.
Например, если не нужно выходить из Excel, то тогда нужно скрыть его видимость. И т.п. Примерный иллюстрирующий код:
Dim WithEvents ExcelApp As Excel.Application
Const workbookname As String = "c:\tmp\x.xls"Private Sub Form_Load()
Set ExcelApp = CreateObject("Excel.application")
ExcelApp.Workbooks.Open workbookname
End Sub
Private Sub ExcelApp_WorkbookBeforeClose(ByVal Wb As Excel.Workbook, Cancel As Boolean)
Dim wb2 As Excel.Workbook
If ExcelApp.Visible Then' я не большой спец в Excel, возможно, существуют другие способы определить что именно наш документ закрываетсяIf UCase(Wb.FullName) = UCase(workbookname) Then
Cancel = True
ExcelApp.Visible = False' Закрываем все остальные документы, потому что по Cancel = True закрытие прекратитсяFor Each wb2 In ExcelApp.Workbooks
If Not wb2 Is Wb Then wb2.Close
Next
End If
End If
End Sub' это только для отладки - показать ExcelPrivate Sub Form_Click()
ExcelApp.Visible = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim ea2 As Excel.Application, wb2 As Excel.Workbook
Set ea2 = ExcelApp ' запоминаем наш экземплярSet ExcelApp = Nothing' убираем отслеживание за событиямиIf ea2.Workbooks.Count = 1 Then' Закрываем приложение
ea2.Visible = False
ea2.Quit
Else' Закрываем только свой документ For Each wb2 In ea2.Workbooks
' я не большой спец в Excel, возможно, существуют другие способы определить наш документIf UCase(wb2.FullName) = UCase(workbookname) Then
wb2.Close
Exit For
End If
Next
End If
End Sub
Vi2>Excel как Application имеет кучу событий. Нужно прицепиться к событиям Excel (например, на закрытие документов) и использовать/отслеживать их.
Это было бы очень здорово, но я одного не понял: а как, собственно, к ним прицепиться? Я так понимаю, должен быть набор процедур в вызывающем приложении, которые будут перехватывать соответствующие события excel. А как задать для объекта Excel.Application, что именно эта процедура должна обрабатывать данное событие?
Спасибо, мысль интересная. Хотя в этом случае пропадет возможность параллельно открывать другие excel-файлы, а ради этого, в общем, все и затевается. Но как крайний вариант пойдет.
EM>Хотя в этом случае пропадет возможность параллельно открывать другие excel-файлы, а ради этого, в общем, все и затевается. Но как крайний вариант пойдет.
Нет, это совсем не так. Когда Вы запускаете Application и устанавливаете для нее IgnoreRemoteRequests = True
то именно этот экземпляр становится закрытым для других файлов. Когда пользователь будет щелкать по файлам xls, для первого из них будет создан другой экземпляр, а Ваш будет спокойно отрабатывать.
То, о чем я предупреждала — это то, что если Ваш экземпляр завершит работу и будет закрыт, то это свойство станет True по умолчанию, и тогда файлы перестанут закрываться. Если экземпляр вывалится в результате сбоя, то скорее всего будет все нормально.
Вы можете это проверить, запустив Application, установив ему это свойство в True, и если Вы откроете еще Excel, то Сервис->Параметры->Общие CheckBox игнорировать DDE запросы от других приложений будет сброшен. Главное, восстановить это свойство перед выходом из Excel
Здравствуйте, Elena_, Вы писали:
E_>То, о чем я предупреждала — это то, что если Ваш экземпляр завершит работу и будет закрыт, то это свойство станет True по умолчанию, и тогда файлы перестанут закрываться.
Точно, именно так все и оказалось, я в прошлый раз поленился проверять ... Причем если приложение валится аварийно, то этот параметр действительно не сохряняется. Спасибо огромное!
E_>только его надо очень аккуратно восстанавливать перед закрытием объекта Application E_>
E_>ObjExcel.IgnoreRemoteRequests = False
E_>
обнаружилась неприятная плюшка с этим IgnoreRemoteRequests.
При выставлении его в True и использовании листа Excel как OLE Item, происходит падение приложения при нажатии F1 в активном листе Excel (справка вызывается). Падает внутри Excel.EXE, глубже копнуть не удалось.
Здравствуйте, Lyvra, Вы писали:
L>обнаружилась неприятная плюшка с этим IgnoreRemoteRequests. L>При выставлении его в True и использовании листа Excel как OLE Item, происходит падение приложения при нажатии F1 в активном листе Excel (справка вызывается). Падает внутри Excel.EXE, глубже копнуть не удалось.
Здрям
E_>А код не приведете?
проблемы вычленить не удалось — без моего приложения она не повторяется. Но похоже IgnoreRemoteRequests только уменьшает вероятность падения (падает все равно).
Падение происходит при нажатии F1 в активном окне встроенного Excel, мое окно начинает изменять размер (этот help Excel 2000 шалит) и Excel рушится (Exception).
Т.к. все упало в exe-COM-сервере, мое приложение можно спокойно остановить, но информации о причинах ошибки в Excel нет.
Пока все вылечилось перелинковкой приложения к статическому MFC..., будет время — постараюсь покопать
Только приложение скомпайлено для VC 7.1. Запускаем ехе, он откроет "Test1.xlt" лежащий в той же директории. Теперь двойной клик на ячейке Excel и нажимаем клавишу "F1". Если сразу не упал — закрываем хелп и по новой -)
Проблема проявляется только в случае наличия ActiveX (ComboBox) на листе Excel.
Если кто подскажет как победить — благодарность моя будет широка!!!
Здравствуйте, Lyvra, Вы писали:
L>вот код — http://www.rsdn.ru/File/24144/test2003.rar
L>Только приложение скомпайлено для VC 7.1. Запускаем ехе, он откроет "Test1.xlt" лежащий в той же директории. Теперь двойной клик на ячейке Excel и нажимаем клавишу "F1". Если сразу не упал — закрываем хелп и по новой -)
L>Проблема проявляется только в случае наличия ActiveX (ComboBox) на листе Excel.
Я попробовала раз 50 нажать, все нормально, вылезает установленный у меня Assistant для Office и ничего не вываливается — может быть, просто надо что-то в Office переустановить?
Это в Debug, я его у себя пересобрала
Release вываливается сразу, просто еще ничего не появляется, я не смотрела, почему.
у меня есть 2 вопроса, на которые я так и не нашел ответ, может вы _Elena подскажите
1) Как програмно (VB, etc) выйти из редактирования ячейки.
Никакой внешний Range::Select в это время не проходит, также как и нажатие на меню внешнего приложения (см. test2003.rar)
2) Возможно ли подключить загруженный _WorkBook* как IOleObject*. В многострадальном test2003.rar все наоборот — полчаем WorkBook* из IOleObject*.
Проблема в том что хочется отловить сообщение об открытии кники в Excel::Application, но её нет, пока книга не откроется .
Я просто не уверен такой код до загрузки в 100% предоставит мне тот же _Application, что и от загруженной книги.