Excel addin: абсолютная позиция ячейки - PullRequest
2 голосов
/ 12 февраля 2012

Как найти абсолютные координаты в пикселях определенной ячейки?

Я разрабатываю дополнение Office 2010 (пользовательский интерфейс ленты) и добавляю новую кнопку в новое меню ленты, и когдакнопка нажата, я хочу получить положение экрана этой ячейки.Проблема в том, что

Globals.ThisWorkbook.Application.ActiveCell . Top / Left

дает только положение относительно угла A1 электронной таблицы, в то время как я хочу положение относительно 0,0 экрана.

Я нашелэто: Как получить экран X и Y ячейки Excel 2003 в C # , но это для Office 2003, и я не до конца понимаю ответ.

Я использую C # для разработки, но VB тоже подойдет.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 17 февраля 2015

Я нашел, что это работает без каких-либо взломов:

    Point GetScreenPositionFromCell(Excel.Range cell, Excel.Application excel)
    {
        var wnd = excel.ActiveWindow;
        if (wnd != null)
        {
            var result = new Point
            {
                X = wnd.PointsToScreenPixelsX((int)cell.Left),
                Y = wnd.PointsToScreenPixelsY((int)cell.Top)
            };

            //cleanup
            Marshal.ReleaseComObject(wnd);
            wnd = null;

            return result;
        }

        throw new Exception("Error retrieving active Excel-window.");
    }
3 голосов
/ 12 февраля 2012

Я нашел это сообщение , которое содержит вызовы API, используемые ниже.Мне также напомнили, что вы можете получить высоту ленты с помощью Application.Commandbars («Лента»). Высота.Итак, в VBA вы должны сделать:

РЕДАКТИРОВАТЬ: В ответ на проблему с панелью формул и высотой заголовков я добавил функцию, которая их скрывает, получает ActiveWindow.Height, затем показывает их и получает новый ActiveWindow.Height.и цифры разницы.Эта функция теперь вызывается в строке ниже, которая складывает высоты перед преобразованием.Я думаю, что это работает, но я не проводил много испытаний.

Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90

Sub CellTopLeftPixels(rng As Excel.Range)
Dim RibbonHeight As Long
Dim TotalTop As Long
Dim TotalLeft As Long

RibbonHeight = Application.CommandBars("Ribbon").Height
TotalTop = (RibbonHeight + GetFormulaBarAndHeadingsHeight + rng.Top) * PixelsPerPointY
TotalLeft = rng.Left * PixelsPerPointX
Debug.Print "Top: "; TotalTop; " Left: "; TotalLeft
End Sub

Function GetFormulaBarAndHeadingsHeight()
Dim ActiveWindowHeightWhenHidden As Long
Dim ActiveWindowHeightWhenShown As Long

Application.DisplayFormulaBar = False
ActiveWindow.DisplayHeadings = False
ActiveWindowHeightWhenHidden = ActiveWindow.Height
Application.DisplayFormulaBar = True
ActiveWindow.DisplayHeadings = True
ActiveWindowHeightWhenShown = ActiveWindow.Height
GetFormulaBarAndHeadingsHeight = ActiveWindowHeightWhenHidden - ActiveWindowHeightWhenShown
End Function

Function PixelsPerPointX() As Double
Dim hdc As Long
Dim PixPerInchX As Long

hdc = GetDC(0)
PixPerInchX = GetDeviceCaps(hdc, LOGPIXELSX)
PixelsPerPointX = PixPerInchX / 72
ReleaseDC 0, hdc
End Function

Function PixelsPerPointY() As Double
Dim hdc As Long
Dim PixPerInchY As Long

hdc = GetDC(0)
PixPerInchY = GetDeviceCaps(hdc, LOGPIXELSY)
PixelsPerPointY = PixPerInchY / 72
ReleaseDC 0, hdc
End Function

72 выше - это точки на дюйм.

Назовите это как:

Sub test()
CellTopLeftPixels ActiveCell
End Sub
...