• ベストアンサー

エクセルで描画のコントロール2

KenKen_SPの回答

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.4

EXCEL_VBA さん、Wendy02 さん、koko88okok さん、こんにちは。お邪魔します。 結論としては #1 ご回答で、あえて VBA でやるまでも無い気がしますが、 面白そうなので参加します。私も色々と試してたのですが、気付いたら時間 が経ってしまいました。激しく遅レスですが(´・ω・`) C が分かるとのことなので、細かな解説はしません。 Excel のオートシェープは指定した位置と若干異なる位置に書かれてしまう 場合があるので 100 %正確にプロットすることは不可能です。これは Excel の仕様なのでどうしようもありませんが、0.25ポイント内外程度の誤差を 許容する精度でよければ下記のような方法で実現できそうです。 以下の2つのサンプルでは、マクロを実行し、Msgbox の OK をクリックした 後2秒後のカーソル位置にシェープを書き込んでいます。 もっとも今回のご質問内容は、keybd_event API などで[Alt]キー押下を シミュレートしてやれば、細かな座標表計算が不要だと思いますが.... 一番厄介なのは、ワークシート上でのマウス左クリックの検知でしょうね。 要は WH_MOUSE メッセージをフックすれば良いのですが、Excel ではどう やってもうまくいきそうもありませんでした。  # もともと VB(A) 単独でグローバルフックはできないし。 特別な外部コンポーネントを使用しない方法となると、Userform + DirectInput による方法しかないような気がします。フックより簡単ですよ。 どんなもんでしょう? Option Explicit ' Win32Api Private Declare Function GetDC Lib "user32.dll" ( _   ByVal hWnd As Long) As Long Private Declare Function ReleaseDC Lib "user32.dll" ( _   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 Declare Function GetCursorPos Lib "user32.dll" ( _   ByRef lpPoint As POINTAPI) As Long Private Type POINTAPI   x As Long   y As Long End Type Private Declare Function timeGetTime Lib "winmm.dll" () As Long Private Const LOGPIXELSX = 88 ' x 方向の1論理インチ当たりのピクセル数 Private Const LOGPIXELSY = 90 ' y 方向の1論理インチ当たりのピクセル数 Private mKx   As Double   ' x 方向ピクセル-->ポイント変換係数 Private mKy   As Double   ' y 方向ピクセル-->ポイント変換係数 Private mZoomKx As Double   ' x 方向ウインドウ表示倍率補正係数 Private mZoomKy As Double   ' y 方向ウインドウ表示倍率補正係数 ' ピクセル→ポイント変換係数を求める Private Sub GetPixelToPointKNum()   Dim hDC As Long   hDC = GetDC(0&) ' 0: Desktop Window   If hDC <> 0 Then     mKx = CDbl(72# / GetDeviceCaps(hDC, LOGPIXELSX))     mKy = CDbl(72# / GetDeviceCaps(hDC, LOGPIXELSY))     Call ReleaseDC(0&, hDC)   End If End Sub ' ウインドウ表示倍率による補正係数を求める Private Sub GetFixKnum()   Dim tmp As Double   If mKx * mKy Then Call GetPixelToPointKNum   With ActiveWindow     mZoomKx = CDbl(.Zoom) / 100#     tmp = 72# * CDbl(ActiveSheet.Range("A1").Height) / mZoomKx     mZoomKy = tmp * mZoomKx / tmp   End With End Sub ' カーソル位置にシェープを書き込むサンプル Sub TestMacro1()   Dim Cur As POINTAPI   Dim Shp As Shape   Dim x  As Single   Dim y  As Single   Dim t  As Long   Call GetPixelToPointKNum   Call GetFixKnum   MsgBox "2秒後のカーソル位置にシェープを書き込みます"   t = timeGetTime()   While t + 2000 > timeGetTime()     DoEvents   Wend   Call GetCursorPos(Cur)   With ActiveWindow     x = CDbl((Cur.x - .PointsToScreenPixelsX(0)) * mKx / mZoomKx)     y = CDbl((Cur.y - .PointsToScreenPixelsY(0)) * mKy / mZoomKy)   End With   ActiveSheet.Shapes.AddShape msoShapeRectangle, x, y, 100, 100 End Sub ' カーソル位置のセルにぴったりとくっつけてシェープを書き込むサンプル Sub TestMacro2()   Dim Cur As POINTAPI   Dim Pos As Object ' Range or Shape なので Object   Dim x  As Single   Dim y  As Single   Dim t  As Long   MsgBox "2秒後のカーソル位置付近のセル左角にシェープを書き込みます"   t = timeGetTime()   While t + 2000 > timeGetTime()     DoEvents   Wend   Call GetCursorPos(Cur)   Set Pos = ActiveWindow.RangeFromPoint(Cur.x, Cur.y)   If UCase$(TypeName(Pos)) = "RANGE" Then     x = Pos.Left     y = Pos.Top     ActiveSheet.Shapes.AddShape msoShapeRectangle, x, y, 100, 100   End If End Sub

Excel_VBA
質問者

補足

ご丁寧にありがとうございます。 確かに#1の方法でやるしかないかなぁ?って思いましたが、#1の方法では、入力範囲の制限が出来ないように思いました。 また、早速、動かしてみましたが、四角が書かれるだけでした。多分ヒントとしては、最重要事項だと思うのですが、この例ですと、やはり、インターバルタイマーを使用して、定期的にTestMacroを呼び出す必要があるのでしょうか? もう少し、詳しく教えていただけないでしょうか? 追伸! >C が分かるとのことなので、細かな解説はしません。 どこで、どう間違えれば、私が、C言語が解ると勘違いされるのか?と疑問に思っておりましが、関心カテゴリーが一式選択されていたからなんですね?大変失礼しました。(爆笑+選択した記憶がない) ちゃんと、気になるカテゴリーに変更しておきましたので、今後とも宜しくお願いいたします。

関連するQ&A

  • エクセルで描画のコントロール

    エクセルのセル幅を小さく設定(例:25程度)に設定して、セルの境界線をCADでいうグリッドに見立てて直線を描画したいと考えています。その時の条件としては、あるセル範囲(例:B~H,3~20の間)のセルの境界線の交点(下の例で、┌┐┘└├┬┤┴┼となるところ) ┌─┬─┐ │ │ │ ├─┼─┤ │ │ │ └─┴─┘ のみ直線の始点と終点が選択できて、任意の交点同士で直線が垂直、水平、斜めに引けるようなマクロって作ることが出来ますか? 同時に、表示-ツールバー-図形描画などで表示されるボタンからの勝手な描画も禁止にしたいのですが、どうやっていいのか?てんで、解りません。どなたか?詳しい方がいらっしゃいましたら、教えて頂けないでしょうか?宜しくお願いいたします。

  • エクセルの描画を続けて使うには?

    エクセルの描画ツールを続けて使うにはどうしたら良いのでしょうか? 例えば直線を描く場合、マウスのポインターをオートシェイプに持っていき直線を選びます(又はAlt-uと矢印キーで)。 マウスのポインターが「+」になります。 そして直線をマウスで引きます。 続けて引こうとすると、またマウスで同じ操作をしてポインターを「+」にしないと直線が引けません。 簡単に続けて同じ描画ツールを使う方法はないでしょうか? またショートカットキー等で描画を選択した状態(ポインターが「+」)にできないでしょうか? Officeは2000と2003を使っています。 よろしくお願い申し上げます。

  • Excelの図形描画について

    Excelのセル幅を小さくしてセル枠を方眼用紙のようにし、図形描画機能の図や線をセル枠に沿って配置して作図しています。 また、私はよく図形をコピーし、目的位置のセルをクリックして貼り付けています。 (そのセルが貼り付けられた図形の基点(左上)となることを期待しています。) 困っているのは直線の貼り付けです。 セル枠に関係なく引いた線をコピーした場合は、クリックしたセルの位置に期待通りに貼り付けられるのに、セル枠にぴったり合わせて引いた線の場合は期待通りにいきません。 セル枠にぴったりの線も、クリックしたセル位置に貼り付けるにはどうすればよいのでしょうか。 ちなみに、以前使っていたPC(Win98/Excel2000)では問題ありませんでした。PCを変えたら(WinXP/Excel2000)そのようになってしまったので、どこかの設定ではないかと思うのですが、それが分かりません。 何かアドバイスなどありましたら、お願いします。

  • 矢印を描画するには

    任意の座標間に矢印つきの直線を描画したいのですが、可能でしょうか? イメージとしては、WordやExcel、PowerPointの矢印描画あたりです。

  • Excelの図形描画を一括で消したい。

    Excelの図形描画によるテキストボックスや矢印や直線や円などを一括で削除したいのですが、どうやったらできますか? 行や列やセルでコピーすると、図形描画の図形類もコピーされるのに、行や列やセルを削除しても消えないのです。その場合、図形描画の図形類は点や線に変形してしまうことがあり、クリックして消すことも大変になったりします。 よろしくお願い致します。 当方、Excel2000使用。

  • エクセルの描画ツールについて

    エクセル2003です。(英語版を使用しています) 描画ツールを続けて使う場合(例えば直線を続けて使う場合)、現在はその都度、描画ツールのLINEボタンを選択しています。 いちいち描画ツールのボタンを押さずに描画を続ける方法はないでしょうか? よろしくお願い申し上げます。

  • Excel内で傾きを変えて直線近似したい

    Excel内で,傾きを変えて直線近似をしたいです. たとえば,セルA1からA5に数字の0から4をX座標として入力します. セルB1からB5にはY座標として0から2,4,6,8と入力します. この直線では,当然傾きが2なのですが, この直線をあえて傾きが1になるように直線近似して,その際の切片を求めるなんて やり方ありませんか. 実験の解析で使うのですが・・・. エクセルでの計算に詳しい方,わかる方がいらっしゃいましたら回答よろしくお願いします.

  • Excelが暴走してしまいました

    エクセルで入力中、ある特定の1つのセルに基点が設定されたらしく、普通は左クリックをした状態でマウスを動かして範囲を広げるますが、単にマウスを動かすだけで範囲が広がり(青くなる)、基点のセルの解除もできなくなってしまいました。 結局エクセルを終了させる羽目になってしまいましたが、再度起こったときに対処したいので、この原因と対処方法をご教示ください。 なお、同様の質問があるかどうか検索してみたのですが、キーワードの取り方がまずいせいか、欲しい情報に到達できませんでした。

  • Excel VBA コントロール シフト 矢印

    お世話になります Excel VBAです 以前真似事程度に、ほんの少しだけしてた者です。 以前にも聞いたかもしれないのですが質問させてください。 シート上でコントロールとシフトと矢印キーを同時に押すと データありならあり、なしならなしの その境界線まで範囲選択できると思います。 これと同じことをVBAで実現したいとき、 ループを組んで1つずつ次へ次へと、 境界線を探すしかないのでしょうか? CELLとかレンジとかで 「ここのセルと状態の同じ境界線まで範囲選択」 的な指定は無理でしょうか? ご教示をお願いします。

  • セルの上に図形描画の線が書かれている時に!

    商品の一覧を表す、エクセルの表の内、ある行の商品の注文が中止になったとします。その時の表示の方法として、図形描画の直線で、取り消しラインを引いてあるとします。セルの書式の取り消しを使ってくれれば、簡単にその行を特定できるのでは?と思いますが、書式の取り消しラインは、文字の上しか取り消しラインを引かないので、わかりにくため、描画を使っているそうです。(これは、相手方のルールなので、変更はできないとします。) で、セルの上に図形描画のラインが引かれているセルを特定することって出来るのでしょうか?当然、ラインは、必ずしも水平直角に引かれているとは限りません。どなたか?詳しい方がいらっしゃいましたら、教えて頂けないでしょうか?(もしかして、数学の幾何学のカテゴの方がいいのかなぁ?) さらに、難しことを考えると切りが無いのですが、できれば、複数行にまたがったセル範囲に対して、斜めのラインで消している場合についても教えて頂ければ幸いに存じます。 宜しくお願い致します。