2012-01-03 98 views
3

我创建了一个Excel自动化加载项,实现为包含UDF包装的ac#类库(我不使用VSTO) UDF如下所示:从UDF获取excel单元地址

string foo(string data){ 

    //Do some work on the data passed 
    string result; 
    return(result); 
} 

有没有办法让我隐式地获取输入公式的单元格地址,而不需要传递任何附加参数?一种方法是在插件加载后将事件监听器挂接到工作簿,并在单元格的值发生变化时捕获事件;但我正在寻找替代方案。

感谢,

+0

我不是你在做什么明确的,但在VBA Application.Caller返回调用该UDF它在 – 2012-01-03 05:15:55

回答

4

你可以尝试Globals.ThisAddIn.Application.Caller,它返回一个包含电池的Excel.Range。也许这样得到Excel.Application

public class InteropHelper 
{ 
    public static void GetReferences(ref Microsoft.Office.Interop.Excel.Application _Application, ref Microsoft.Office.Interop.Excel.Workbook _Workbook) 
    { 
     EnumChildCallback cb; 
     // First, get Excel's main window handle. 
     int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle; 

     // We need to enumerate the child windows to find one that 
     // supports accessibility. To do this, instantiate the 
     // delegate and wrap the callback method in it, then call 
     // EnumChildWindows, passing the delegate as the 2nd arg. 
     if (hwnd != 0) 
     { 
      int hwndChild = 0; 
      cb = new EnumChildCallback(EnumChildProc); 
      EnumChildWindows(hwnd, cb, ref hwndChild); 

      // If we found an accessible child window, call 
      // AccessibleObjectFromWindow, passing the constant 
      // OBJID_NATIVEOM (defined in winuser.h) and 
      // IID_IDispatch - we want an IDispatch pointer 
      // into the native object model. 
      if (hwndChild != 0) 
      { 
       const uint OBJID_NATIVEOM = 0xFFFFFFF0; 
       Guid IID_IDispatch = new Guid(
        "{00020400-0000-0000-C000-000000000046}"); 
       Microsoft.Office.Interop.Excel.Window ptr = null; 

       int hr = AccessibleObjectFromWindow(
         hwndChild, OBJID_NATIVEOM, IID_IDispatch.ToByteArray(), ref ptr); 
       if (hr >= 0) 
       { 
        // If we successfully got a native OM 
        // IDispatch pointer, we can QI this for 
        // an Excel Application (using the implicit 
        // cast operator supplied in the PIA). 
        _Application = ptr.Application; 
        _Workbook = _Application.ActiveWorkbook; 
       } 
      } 
     } 
    } 

    [DllImport("Oleacc.dll")] 
    public static extern int AccessibleObjectFromWindow(
      int hwnd, uint dwObjectID, byte[] riid, 
      ref Microsoft.Office.Interop.Excel.Window ptr); 

    public delegate bool EnumChildCallback(int hwnd, ref int lParam); 

    [DllImport("User32.dll")] 
    public static extern bool EnumChildWindows(
      int hWndParent, EnumChildCallback lpEnumFunc, 
      ref int lParam); 


    [DllImport("User32.dll")] 
    public static extern int GetClassName(
      int hWnd, StringBuilder lpClassName, int nMaxCount); 

    public static bool EnumChildProc(int hwndChild, ref int lParam) 
    { 
     StringBuilder buf = new StringBuilder(128); 
     GetClassName(hwndChild, buf, 128); 
     if (buf.ToString() == "EXCEL7") 
     { 
      lParam = hwndChild; 
      return false; 
     } 
     return true; 
    } 
} 
+0

我不使用VSTO的范围。创建我的插件,我已经实现了一个自动化插件作为ac#类库。这就是为什么“Globals.ThisAddIn.Application.Caller”不适合我。或者我错过了一个命名空间声明? – shrikanth 2012-01-03 06:26:01

+0

您可以使用com获取参考Excel.Application – 2012-01-03 06:37:15

0

感谢brijesh指出我在正确的方向。我用下面来获取单元格地址:

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

Excel.Application excelApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); 

Excel.Range target = (Excel.Range)excelApp.get_Caller(System.Type.Missing); 

string cellAddress = target.get_Address(Missing.Value, Missing.Value, 
      Excel.XlReferenceStyle.xlA1, Missing.Value, Missing.Value); 
相关问题