Получить адрес ячейки Excel из UDF - PullRequest
3 голосов
/ 03 января 2012

Я создал надстройку автоматизации для Excel, реализованную в виде библиотеки классов ac #, которая содержит оболочку UDF. (Я не использую VSTO) UDF выглядит следующим образом:

string foo(string data){

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

Isесть ли способ для меня неявным образом получить адрес ячейки, где была введена эта формула, без передачи каких-либо дополнительных параметров?Одним из способов было бы подключить прослушиватель событий к книге, как только загрузится надстройка, и записать события при изменении значения ячеек;Но я ищу альтернативу этому.

Спасибо,

Ответы [ 2 ]

4 голосов
/ 03 января 2012

вы можете попробовать 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 голосов
/ 04 января 2012

спасибо Брижешу за то, что он указал мне правильное направление.Я использовал следующее, чтобы получить адрес ячейки:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...