Короче говоря, ответ, абсолютно, да.
Но так вы знаете, ваш подход с использованием GetObject для получения существующего приложения Excel может быть подвержен ошибкам. Если работает только одно приложение Excel, то «GetObject» будет работать нормально. Если в настоящее время открыто более одного приложения Excel, то вы не можете контролировать, какое приложение Excel будет возвращено из функции «GetObject» - возвращенный экземпляр Excel может быть не тем, который вам нужен.
Возможно, вам стоит подумать о создании управляемой надстройки COM, которая запускает в пределах самого приложения Excel и, тем не менее, никогда не возникает проблем, связанных с «каким» экземпляром приложения Excel он контролирует. Для этого вы можете начать, взглянув на статью How to build an Office COM add-in by using Visual C# .NET.
Если вам известен идентификатор процесса или дескриптор главного окна (a.k.a. «Hwnd») экземпляра приложения Excel, который вы хотите контролировать, то вы можете получить для этого точного экземпляра. Чтобы узнать, как это сделать, вы можете прочитать обсуждение Эндрю Уайтчепеля по теме here.Раздел, который вам интересен, начинается с строки, следующей за заголовком «Чтобы получить объект приложения Excel, вот что мы будем делать». Обсуждение немного сложное, но если вы следуете его коду в письме, оно работает точно так, как описано.
Если вы хотите перейти к подходу «GetObject», то следующий пример кода использует раннее связывание, чтобы получить активный лист текущего приложения Excel. Она предполагает, что у вас есть «используя» заявление using Excel = Microsoft.Office.Interop.Excel
, а также using System.Runtime.InteropServices
в верхней части коды модуля:
// Note:
// using System.Runtime.InteropServices;
// using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excelApp =
Marshal.GetActiveObject("Excel.Application");
object activeSheet = excelApp.ActiveSheet;
Если вы использовали позднее связывание, то это может выглядеть следующим образом:
// Note:
// using System.Runtime.InteropServices;
object excelApp =
Marshal.GetActiveObject("Excel.Application");
object activeSheet =
excelApp
.GetType()
.InvokeMember(
"ActiveSheet",
BindingFlags.GetProperty,
null,
excelApp,
null);
Надеется, что это помогает ...
Последующих меры ответ:
Привет, Даже если работает несколько приложений excel Моя логика заключается в использовании приложения, которое в настоящее время подсвечивается, т.е. текущего активного (с фокусом).
Ах, вы должны были сказать ... Сохраняйте вопрос гласит, что вы хотели бы, чтобы дублировать поведение метода GetObject
, как вызывается из VB 6.0. Для этого ответы, которые вы получили здесь, все правильно ответили.
Итак, во-первых, имейте в виду, что то, что вы сейчас задаете, хорошо за пределами capabilites of VB 6.0's GetObject
метод. Для этого вам необходимо будет:
- Получить дескриптор окна активного приложения, вызвав функцию Windows API GetForegroundWindow.
- Итерируйте все текущие процессы Excel с помощью Process.GetProcessesByName("Excel") и сравните Process.MainWindowHandle для каждого выполняемого процесса Excel с дескриптором окна, который вы получили ранее, используя API GetForegroundWindow. Предполагая, что у вас есть соответствие, вы подтвердили, что приложение Excel является активным в настоящее время приложением. Если совпадение не найдено, то приложение Excel в настоящее время не имеет фокуса, и вы можете сообщить об этом пользователю.
- После того, как вы подтвердили, что активное окно представляет собой запущенное приложение Excel, вы можете использовать обработчик окна, который вы получили, используя API GetForegroundWindow, чтобы получить объект приложения Excel, которым вы можете управлять. Сделайте это, см. Статью Getting the Application Object in a Shimmed Automation Add-in Эндрю Уайтчепеля, начиная с раздела, следующего за заголовком «Чтобы получить объект приложения Excel, вот что мы будем делать». Это сложная тема, но описание в статье превосходно, и пример кода отлично работает. В вашем случае, однако, вам нужно будет заменить первую строку кода
int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;
дескриптором окна активного окна, которое вы обнаружили ранее. Другими словами, что-то вроде этого: int hwnd = theHwndOfTheActiveWindowYouFoundEarlier
.
Я понимаю, что это много, чтобы переварить, но если вы последуете этим шагам, он будет работать нормально. Самая сложная часть - код Эндрю Уайтчепеля, но это будет работать как есть, кроме необходимости изменить первую строку. Удачи!
- Майк
как об этом: http://msdn.microsoft.com/en-us/library/ms173186%28VS.80%29.aspx – whunmr
Это запустило бы другой экземпляр Excel, однако у меня будет необходимый лист open aready. – Thunder