Get the excel cell address from a UDF

心已入冬 提交于 2019-11-29 11:52:22

you can try Globals.ThisAddIn.Application.Caller, it returns an Excel.Range containing the cell. Maybe something like this to get 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;
    }
}

thanks to brijesh for pointing me in the right direction. I used the following to get the cell address:

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);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!