プロが教えるわが家の防犯対策術!

エクセル既存のコマンドをユーザー定義のコマンドボタン等に割り付けたい。

お世話になります。
どなたか教えてください。

他のアプリケーションから画像をキャプチャーし、
それをエクセルに貼り付け、そこにオートシェイプなどを使い修正指示等を描きこむ作業をしています。
少しでも楽にしようと、ユーザーフォーム上に配置したコマンドボタン・ピクチャ等に既存のコマンドを割付て見ました。
オートシェイプ 線 の場合
Application.CommandBars.FindControl(, 130).Execute
これで(上記の作成した)ボタンを左クリックした時に、オートシェイプのツールバー内の“線”コマンドと同じように1本の線がひけました。

ただ、オートシェイプのツールバー内の“線”コマンドを使用した時は、
シングルクリックの時は線を一本描くとコマンドが終了、ダブルクリックの時は線が連続して描けます。
自分で追加したボタンでもこのように動作させる方法は無いでしょうか?
(ダメとは思いつつダブルクリックのイベントに上記コードを記述しましたが、、、やはりダメでした。)

さらにexcel2003の場合は上記コードが動作したのですが、
2007の場合は動作せず、線が描けません。なぜでしょうか?

以上2点かなり調べましたが解らず、行き詰まってしまいました。
どなたか教えてください。
よろしくお願いいたします。

A 回答 (5件)

#2の回答者です。



>ここまで書いてふと思ったのですが、連続実行する為にはPushedプロパティやStateプロパティでどうしても物理的にボタンが押された状態をマクロで再現しないといけないのでしょうか?

考え方は分かるのですが、私の知っている範囲ですが、確かにダイレクトに命令が送れればよいのですが、OLEのセキュリティなのか、拒否されてしまうからです。それ以外にも方法はあるのですが、それは、レジストリを直接操作する方法になると思います。たぶん、今回のコードは、最終的には、UserForm からのオートシェイプのコントロールという所なんだろうとは思うのです。CommandBarsButton 自体は、抜き出しは可能ですし、ハンドルは取れますが、その後の直線のボタンのハンドル自体が取れないですね。そうすると、クリックの命令自体も送れません。

2007の件ですが、FindControl やCommandBars から取るのは、前のメニュー構造ものであって、Ribbon からではありません。Ribbon メニューから、取得したり命令したりする方法は違うのだろうと思います。

何か言い訳めいていますが、こんな所しか回答できません。
別に、コマンド自体をExecute で命令を与えることは可能だとしても、メニューからマウスで行っていることと同じようにするには、今の方法からでは無理だろうと思います。
    • good
    • 0
この回答へのお礼

お礼が遅れてすみません。

なかなか難しいものですね。
レジストリを操作するとなると私の腕ではちょっと無理です。
2003では連続実行できるコマンドを集めてツールバーを作りユーザーフォームの近くに置き、
2007ではどうしましょう?(笑)我慢してもらいます。

2007で直線コマンドが実行できない件は、他の方からアドバイス頂きました。
どうやら直線と直線コネクタが統合されて、ID=130ではなく=1042で動作するようになったようです。
コマンドアイコンの名前が直線だったのですっかり思い込んでいました。

ユーザーフォームのボタンからはコマンドの連続実行はできそうにありませんが、
Wendy02さんにご回答頂き、深い話が聞けて本当に良かったです。

またよろしくお願いいたします。

お礼日時:2010/06/29 22:39

>Excel2003以前のバージョンではボタンのクリックイベントに割り付け、単独の線は引けたのですが、


>Excel2007では質問で書きましたように動作せず、 
>職場の環境は2003,2007が混在している状況ですので仕方が無く
>If CInt(Application.Version) < 12 Then
>Application.CommandBars.FindControl(, 130).Execute
>else
>"別シートにある直線のテンプレートをコピペするコード
>end if

FindControl(, 130) の130は直線ですが、1042 直線コネクタに変えて見てください。
EXCEL 2003,2007 どちらでも直線引けると思います。

Application.CommandBars.FindControl(ID:=1042).Execute
    • good
    • 0
この回答へのお礼

systemproonoさんアドバイスどうもありがとうございます。

おかげさまで2003、2007共にボタンから直線を引く事が出来ました。
私には全く思いつきませんでした。
ここで質問してみてよかったです。

2007のオートシェイプのアイコンを見ていたら直線コネクタがありませんね。
どうやら直線と統合されたと見て良いんでしょうね。
CommandBars Control IDには直線が130番として残っているのですけどね。

とりあえずこれで一つ目の問題はクリアできました。
本当に助かりました。ありがとうございます!
またよろしくお願いいたします。

お礼日時:2010/06/28 19:55

例えば、こんな方法で調べられたらいかがですか?


私の環境(Excel 2007)では 130番のコントロールがそのようですが
(ちなみにこれもオブジェクトブラウザで調べました)   (^_^)

Sub コマンドバーコントロールの一覧表()
  Dim cb0 As CommandBar, cc0 As CommandBarControl, r0 As Long
  Worksheets("Sheet1").Activate
  ActiveSheet.UsedRange.Clear
  Range("A1") = "CB Index"
  Range("B1") = "CB名"
  Range("C1") = "Ctrl Id"
  Range("D1") = "Ctrl Caption"
  r0 = 1
  For Each cb0 In Application.CommandBars
    For Each cc0 In cb0.Controls
      r0 = r0 + 1
      Cells(r0, 1) = cb0.Index
      Cells(r0, 2) = cb0.Name
      Cells(r0, 3) = cc0.ID
      Cells(r0, 4) = cc0.Caption
    Next cc0
  Next cb0
End Sub
    • good
    • 0
この回答へのお礼

お礼が遅れてすみません。
直線コマンドのコントロールIDが130だという事は解っていたのですが、2007では何故か実行できませんでした。”描画モードのロック”のコントロールIDというものがあれば話は早いんですけどね。見つかりませんでした。オブジェクトブラウザは便利ですね。どうもありがとうございます。

お礼日時:2010/06/28 19:46

ご質問は、CommandBarButton のコントロールのことで、Line を引く話なのでしょうか。



>エクセル既存のコマンドをユーザー定義のコマンドボタン等に割り付けたい。
これ自体は、Class で割りつけるか、OnAction に登録すれば済む話です。

しかし、ご質問内容の、クリック自体をマクロでコントロールする方法は、外部のキーボードマクロを使うことは除いて、以前も、やったことがあるのですが、今持って分かりません。

今調べてみたら、Ver.5 のToolBar オブジェクトのToolBarsButton の Pushed プロパティをTrue にすることで、過去には出来ていたようですが。今は、値取得のみで、もう出来ないようです。

この他では、外部のWin32APIを使って行う方法を考えると思いますが、今はOLEオブジェクトなので、コマンドボタンのハンドルが取れなかったのです。ハンドルが取れるのは、ツールバーのみだけです。

今のVBAでは、ボタンモード(.State)は、ダブルクリックした状態ですと、msoButtonUp からmsoButtonDonw にモードが変わりますが、Pushed プロパティ同様に、値を取るだけで、変更できません。

Excel 2007 については、確かに現象は確認はしましたが、こちらも分かりません。
    • good
    • 1
この回答へのお礼

Wendy02さん アドバイスどうもありがとうございます。

質問内容が解りにくくてすみません。
私がやりたいのは、オートシェイプの直線コマンドボタンを押して出来る全ての作業(ダブルクリックして直線を連続で描画できる機能も含む)を自分が作ったボタンで出来ないか?という事です。

Excel2003以前のバージョンではボタンのクリックイベントに割り付け、単独の線は引けたのですが、
Excel2007では質問で書きましたように動作せず、 
職場の環境は2003,2007が混在している状況ですので仕方が無く
If CInt(Application.Version) < 12 Then
Application.CommandBars.FindControl(, 130).Execute
else
"別シートにある直線のテンプレートをコピペするコード
end if

・・・とエクセルのバージョンで動作を分けてあります。

やはり2007で出来ないのは原因不明なんですね。原因不明という事は対処も無理という事ですよね?

あと、ダブルクリック(2003)右クリックメニュー(2007)から出来る、
直線コマンドの連続実行についてですが、
今回の件で調べているうちに、メニューバー内のメニューはStateプロパティにTrueを設定する事で、
ボタンが押された状態にする事が出来るメニューもあるという事が解ったので、今回の直線コマンドも同様に出来るのではないか?と思ったんです。
ここまで書いてふと思ったのですが、連続実行する為にはPushedプロパティやStateプロパティでどうしても物理的にボタンが押された状態をマクロで再現しないといけないのでしょうか?
ボタンが押された状態というのは、現在連続実行のモードだという事を表示しているだけで、連続実行の命令文は別にあるのではないか?ということです。
私のような初心者では知る由もありませんが。。

今回の事は、あるボタンに割り当ててあるコマンドを、別のボタンに同じように割り付けるという事で、
もっと単純な事かと思っていたのですが、難しく意外でした。
でも、出来たら最初に考えたようにマクロを完成させたいと思っていますので、
もし何か解りましたらまたよろしくお願いいたします。

お礼日時:2010/06/25 22:54

初心者は皆さんこのようにしますが、よい方法ではありません。



例えば、人を使って、駅で切符を買ってこさせるのに、
  どこにある自動販売機の左上から何番目のボタンを押せ
と指示するようなものです。

よりよい方法は
  200円の切符を買え。
と指示することです。おわかりでしょうか? この方が簡単で正確ですね。

VBAで、オートシェイプの線などを描画するには
  Worksheets("Sheet1").Shapes.AddShape(Type, Left, Top, Width, Height)
  とします。
  Sheet1 は仮の名で、実際のシート名を使います。
  Type は Excel の MsoAutoShapeType のメンバで、直線なら 183 です。
  Left, Top は描画位置ですからマクロ実行前に描画位置のセルを選択しておいて
  Selection.Left, Selecton.Top とすればよいでしょう。
  Width, Height は大きさですから、とりあえず 10,10 としておいて
  描画後に手で直せばよいでしょう。
  問題は Type(図景番号) の値で、Excel 2007 ではオートシェイプだけで 1~183 あります。
  そんなもの覚える必要はありません。

  Sub オートシェイプの一覧表()
    Dim i0 As Integer, ws0 As Worksheet
    Set ws0 = Worksheets("Sheet1")
    For i0 = 1 To 256
      ws0.Shapes.AddShape i0, 10, ws0.Cells(i0, 1).Top, 10, 10
    Next
  End Sub
  
  といったプログラムで一覧表を作っておけば、行番号が図景番号になります。

この話に限らず、ここでアドバイスしましたら
  『そんな大変なこと覚えられない』
という感想をいただくことがありますが、覚える必要なんかありません。
上級者が初心者と違うのは『何でも知っている』からではなく、
『わからないことを調べる方法を知っている』ことなんです。

Excel VBA について、調べる方法はこうです。
VBAの編集画面でF2キーを押すとオブジェクトブラウザが表示されます。
左上に <すべてのライブラリ> と表示されていたら、Excel に変えた方がよいでしょう。
Worksheet 上に描く図景ですから、まず 『クラス』の中から Worksheet を探します。
すると右側に『Worksheetのメンバ』が表示されますから、
その中から Shapes を探します。
すると下に『Property Shapes As Shapes』と表示され、Shapes に下線が引かれています。
この Shapes をクリックすれば、『クラス』で Shapes が選択されます。

これらクラスなりメンバなりの意味を知るには、知りたい項目をクリックし
F1キーでヘルプを表示します。

長々書きましたが、この方法を使いこなせれば、あなたは上級者です。
    • good
    • 0
この回答へのお礼

mimeuさん アドバイスどうもありがとうございます。

今回、私がやりたいのは
オートシェイプツールバーの直線ボタンを押し下げて出来る作業を全て、自分が作ったユーザーフォーム上のボタン等で出来ないものか?という事です。

確かにmimeuさんのアドバイスのように、
Worksheets("Sheet1").Shapes.AddShape(Type, Left, Top, Width, Height)と書いた方が、
直接的ですし、解りやすいのですが、
このマクロで私が実際にやりたい作業というのは、最初の質問にも書きましたが、
取り込んだ画像にシェイプやテキストボックス等を使って修正指示等を書き込むというものです。
例えば、今回のように直線コマンドを使って立方体のアイソメ図(立体図)を描くとします。

Worksheets("Sheet1").Shapes.AddShape~と直接的に書いた場合
(1)目標の位置に近いところのセルをアクティブにする
(2)コマンドボタンを押す→直線が描画される
(3)目的の位置に線の端末を移動
(4)もう一方の端末を移動
これで目的の線が一本引けます。陰線は描かないものとして、立方体なのでこれを9回繰り返します。
(一本引けたらあとはコピーすれば多少は楽になります)

ツールバーの直線コマンドの場合(これをそのまま割り付けたい)
(1)ボタンをダブルクリックして連続してコマンドが実行できるようにする。
(2)目標とする位置をクリック
(3)もう一端をクリック・・・で一本引けます。×9で完成。
(直線でなくフリーフォームを使えばさらに楽になる)

VBAのコードとしては解りやすくても、
実際にやりたい作業が手間がかかって遅くなってしまうのでは本末転倒だと考えます。

それならマクロなんか組まずに素直にツールバーのボタンを押せば?と思われるかもしれませんが、
ユーザーフォーム上に直線コマンド以外にも、別シートに配置した図形テンプレートの取り込み、
キャプチャー画像取り込みや、シート内容のはき出しなどのマクロを割り付けたボタンを配置してあり、
今回上手くいかない直線コマンドだけ別の場所にボタンがあるというのも使いづらいなぁという事で
今回の質問をさせていただきました。

引き続きどうぞよろしくお願いいたします。

お礼日時:2010/06/25 21:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!