2009-12-24 1 views
4

Я хотел бы обновить значения в текущем листе в текущем документе независимо от имени файла excel.Способ обновления активного листа из активной книги Excel с помощью C#?

В VB6.0 мы могли бы сделать

Set AppExcel = GetObject(, "Excel.Application") 
Set SheetExcel = AppExcel.ActiveWorkbook.ActiveSheet 

Как я когда-либо пытался сделать то же самое в C#.

Есть ли способ сделать то же самое в C#.

+0

как об этом: http://msdn.microsoft.com/en-us/library/ms173186%28VS.80%29.aspx – whunmr

+0

Это запустило бы другой экземпляр Excel, однако у меня будет необходимый лист open aready. – Thunder

ответ

4
using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Reflection; 

public class MyClass 
{ 
    public static void Main() 
    { 
     object xlApp = Marshal.GetActiveObject("Excel.Application"); 
     Type t = xlApp.GetType(); 

     t.InvokeMember("Quit", BindingFlags.InvokeMethod, null, xlApp, null); 

    } 
} 

Я изменил код, основанный на примере данного here.

Сказав это, я думаю, что вы можете написать код в vb.net (и использовать GetObject) и использовать библиотеку C#.

ИЛИ

Вы можете передать Microsoft.VisualBasic.dll.
И позвоните по телефону GetObject.

EDIT: Зачем вам это нужно? Не создала бы помощь Excel Addin?

Если вы должны написать код в C# в любом случае, позаботьтесь об освобождении COM экземпляров, которые были созданы с помощью Marshal.ReleaseComObject

edit2: Для того, чтобы получить ссылку на ActiveSheet, вы могли бы написать

object sheet = t.InvokeMember("ActiveSheet", BindingFlags.GetProperty, null, xlApp, null); 

Опять же, я предлагаю вам не проехать по этому маршруту.
Напишите код в VB6, чтобы сделать то, что вам нужно & назовите его C#/vb.net.

+0

О, это хорошо, но все еще непонятно. Как мы можем получить доступ к листам с помощью предоставленного кода. – Thunder

+0

Быть обратно в VB - это решение, но было бы гораздо лучше сделать это в управляемом коде C# – Thunder

2

Вот пример консольного приложения, которое использует Excel Automation для доступа к ActiveSheet.

using Microsoft.Office.Interop.Excel; 
using System.Reflection; 

namespace ExcelAutomationConsole 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      _Application excelApp = null; 
      try 
      { 
       excelApp = new Application(); 
       excelApp.Visible = true; 

       Missing missing = Missing.Value; 
       excelApp.Workbooks.Add(missing); 
       // or 
       //excelApp.Workbooks.Open("file.xlsx", missing, missing, missing, missing, 
       //      missing, missing, missing, missing, 
       //      missing, missing, missing, missing, 
       //      missing, missing); 

       Worksheet sheet = excelApp.ActiveWorkbook.ActiveSheet as Worksheet; 
       Range r = sheet.Cells[1, 1] as Range; 
       r.FormulaR1C1 = "Test"; 
      } 
      finally 
      { 
       excelApp.Quit(); 
      } 
     } 
    } 
} 
+0

это прекрасно, но он также создает новый (excelApp = new ApplicationClass(); ) документ excel. Когда-либо я хочу использовать существующий лист excel, который открывается пользователем и активен в окне, не создавая новый ! – Thunder

+0

Также вы не должны использовать ApplicationClass, а Application вместо этого. Вывод msdn: «Этот класс ... не предназначен для непосредственного использования из вашего кода». http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.applicationclass(office.11).aspx – Mathias

+0

Спасибо за ссылку Матиас, я обновил ответ – bendewey

4

Короче говоря, ответ, абсолютно, да.

Но так вы знаете, ваш подход с использованием 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 метод. Для этого вам необходимо будет:

  1. Получить дескриптор окна активного приложения, вызвав функцию Windows API GetForegroundWindow.
  2. Итерируйте все текущие процессы Excel с помощью Process.GetProcessesByName("Excel") и сравните Process.MainWindowHandle для каждого выполняемого процесса Excel с дескриптором окна, который вы получили ранее, используя API GetForegroundWindow. Предполагая, что у вас есть соответствие, вы подтвердили, что приложение Excel является активным в настоящее время приложением. Если совпадение не найдено, то приложение Excel в настоящее время не имеет фокуса, и вы можете сообщить об этом пользователю.
  3. После того, как вы подтвердили, что активное окно представляет собой запущенное приложение Excel, вы можете использовать обработчик окна, который вы получили, используя API GetForegroundWindow, чтобы получить объект приложения Excel, которым вы можете управлять. Сделайте это, см. Статью Getting the Application Object in a Shimmed Automation Add-in Эндрю Уайтчепеля, начиная с раздела, следующего за заголовком «Чтобы получить объект приложения Excel, вот что мы будем делать». Это сложная тема, но описание в статье превосходно, и пример кода отлично работает. В вашем случае, однако, вам нужно будет заменить первую строку кода int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle; дескриптором окна активного окна, которое вы обнаружили ранее. Другими словами, что-то вроде этого: int hwnd = theHwndOfTheActiveWindowYouFoundEarlier.

Я понимаю, что это много, чтобы переварить, но если вы последуете этим шагам, он будет работать нормально. Самая сложная часть - код Эндрю Уайтчепеля, но это будет работать как есть, кроме необходимости изменить первую строку. Удачи!

- Майк

+0

Привет, Даже если есть несколько приложений excel, работающих под управлением My logic, нужно использовать приложение, которое в настоящее время подсвечивается, то есть текущий активный (имеющий фокус). – Thunder

+0

Привет, Гром, см. Мой обновленный ответ в разделе «Последующий ответ», выше. –

Смежные вопросы