こんにちは。 試作レベルではありますが...
Option Explicit
Private Declare Function GetCursorPos Lib "user32.dll" _ (ByRef lpPoint As POINTAPI) As Long
Private Type POINTAPI x As Long y As Long End Type
Private MoP As POINTAPI
Private Const DPI As Double = 96 Private Const PPI As Double = 72
Sub shape_set() Dim f As Double Dim Lx As Single Dim Ty As Single Dim z As Long Dim r As Range Dim rev
On Error GoTo ErrHandler Call GetCursorPos(MoP) With ActiveWindow z = .Zoom If z = 100 Then ReDim rev(1 To 2) rev(1) = 1 rev(2) = 1 Else Set r = .VisibleRange.Cells(.VisibleRange.Count) rev = rev_zoom(z, r) End If f = PPI * 100 / (DPI * z) Lx = (MoP.x - .PointsToScreenPixelsX(0)) * f * rev(1) Ty = (MoP.y - .PointsToScreenPixelsY(0)) * f * rev(2) End With With ActiveSheet.Shapes(1) .Left = Lx .Top = Ty End With ErrHandler: Set r = Nothing End Sub
Function rev_zoom(ByVal z As Long, ByVal r As Range) Const p As Double = 0.5000001 Dim f As Double Dim ckL As Single Dim ckT As Single Dim x As Long Dim y As Long Dim i As Long Dim v(1 To 2) As Double With ActiveWindow x = .PointsToScreenPixelsX(0) y = .PointsToScreenPixelsY(0) f = DPI * z / (PPI * 100) For i = 1 To r.Column - 1 x = x + Int(Columns(i).Width * f + p) Next i For i = 1 To r.Row - 1 y = y + Int(Rows(i).Height * f + p) Next i f = PPI * 100 / (DPI * z) '1/t ckL = (x - .PointsToScreenPixelsX(0)) * f ckT = (y - .PointsToScreenPixelsY(0)) * f End With v(1) = r.Left / ckL v(2) = r.Top / ckT rev_zoom = v End Function
上記コードの基本部分は芳坂氏のホームページ http://hp.vector.co.jp/authors/VA016119/index.html (>My Personal.xls>CellScreenPos) ここで公開されているコードで勉強させて頂いたものです。
多分..ですけど、ZOOMや列幅行高によって補正しなければならないと思います。 さらにフォント設定も影響するような気がします。 また、上記はウィンドウ分割や枠固定には対応させていません。 (紹介ページは対応しています) それと、A1からVisibleRangeの最終セルまでの範囲で補正値を算出していますから 行位置が大きくなるとレスポンスが悪いです。 また、列幅行高が不揃いだと正確さは望めません。 (この辺でワタシはなげちゃいました...orz) (補正値を算出するのはもっと別のアプローチのほうが良いのかも^ ^;)
参考になれば幸いです。
この記事にはVBAのコードが含まれています。
緑の太文字→注釈 茶色の太文字→条件分岐 赤の太文字→ループ 青の太文字→その他
|