【问题标题】:Excel addin: Cell absolute positionExcel插件:单元格绝对位置
【发布时间】:2012-02-12 06:24:31
【问题描述】:

如何找到某个单元格的绝对坐标(以像素为单位)?

我正在开发 Office 2010 插件(功能区 UI),我在功能区的新菜单中添加了一个新按钮,当按下该按钮时,我想获取该单元格的屏幕位置。问题是

Globals.ThisWorkbook.Application.ActiveCell . Top / Left

只给出相对于电子表格A1角的位置,而我想要相对于屏幕0,0的位置。

我找到了这个:How to get screen X and Y of an Excel 2003 cell in C#,但它适用于 Office 2003,我不完全理解答案。

我使用 C# 进行开发,但 VB 也可以。

谢谢!

【问题讨论】:

  • 仅供参考,您链接到的代码无济于事,因为它用于确定屏幕顶部 XL 2003 和早期工具栏的高度。
  • 这就是我的意思,不要因为我没有到处看过而自欺欺人。
  • @cdavid 有点晚了,但看看这是否适合你没有问题:stackoverflow.com/a/29354020/904156

标签: c# vb.net excel excel-addins


【解决方案1】:

我找到了this post,其中包含下面使用的 API 调用。我还提醒您,您可以使用 Application.Commandbars("Ribbon").Height 获取功能区的高度。所以,在 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

【讨论】:

  • 谢谢! @Doug代码还不错,但据我所知,它仍然存在一些问题-它没有考虑Excel在屏幕上的位置,以及公式栏的大小和标题(A、B、C ... 1、2、3)。对于应用程序,我找到了appTop = Globals.ThisWorkbook.Application.Top,但我仍在考虑如何获取公式栏大小和标题大小(如果有)。非常感谢您的帮助。
  • 我已经修改(破解)代码来解决这个问题。不知道是不是最好的办法。查看修改。
  • 编辑栏的一个很好的主意。不幸的是,同样的事情不适用于标题。而且你也不能使用UsableHeight / UsableWidth。我会将您的回复标记为答案并自己尝试。如果您对更多细节感兴趣,我也发布了相同的问题here
  • 哎呀,我一起测试了它们,但没有意识到标题不起作用。感谢您的接受,祝您好运。
【解决方案2】:

我发现它可以在没有任何黑客的情况下工作:

    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.");
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2013-06-07
    • 2017-04-01
    • 1970-01-01
    相关资源
    最近更新 更多