[[20160801131405]] 『クリックしたコマンドボタンを削除したい』(nonon) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『クリックしたコマンドボタンを削除したい』(nonon)

ユーザーフォーム上のActiveControボタンにコマンドをもたせています。
ボタンをクリックしたらコマンドを実行し、最後にこのボタンを削除したいのですが最初に設定したボタン"CommandButton1"(ここでは“コマンド1”)は、うまくいくのですが、同様のボタンを複数設定している為
"CommandButton2"以降はエラーになります。前半のコマンドは実行しますが、ボタンの削除の段階でエラーになります。
以下の設定です、お知恵をお貸しください。
|
Private Sub コマンド1_Click()
' コマンド1 Macro

ActiveSheet______
ActiveCell.Offset(0, -2)_________
Selection_________
__________________コマンドを記述してます
___________________
__________
With Selection.Validation
____________
.ShowInput = True
.ShowError = True
End With
ActiveSheet.Shapes.Range(Array("コマンド1")).Select
Selection.Delete
Selection.Cut
Application.CutCopyMode = False
ActiveCell.Offset(0, 0).Range("A1").Select
End Sub

Range(Array("コマンド1").Selectに、クリックしたこのボタンのオブジェクト名を入れることは無理でしょうか?

< 使用 Excel:Excel2013、使用 OS:Windows10 >


 まず、テーマの前に、

 ActiveCell.Offset(0, 0).Range("A1").Select 

 セルを選択する必要性があるのかどうか、そういうことは横において
 この構文、どこかにあったコードをサンプルとしてそのまま使われているんでしょうかね?
 感心しない記述方法です。

 基準セル.Offset(0,0) は 基準セルから右に0、下に0動いたセル ということですから基準セルそのものです。
 また、基準とする単一セル.Range("A1") も、そのセルそのものです。

 そうすると、このコードを日本語で表現すると

 アクティブになっているセルからみて右にも下にも移動させないセルに対して、そのセルそのもの

 という、なんだか判じ物のような表現になります。

 ここは、ふつうに ActiveCell.Select としましょう。

 ところで、質問のテーマである コマンドボタン、これは ユーザーフォーム上のボタンのことをいっておられますか?
 コードを見る限り、ユーザーフォーム上のボタンとは関係なく、シート上のコマンドボタンになっています。

 ユーザーフォームのボタンをクリックしたときに、どこの何をどうしたいのですか?

(β) 2016/08/01(月) 14:46


「ActiveCell.Select」の件ありがとうございます。 "コマンド"の一連の処理の中でセルを何度か移動させ処理する必要があり、(0. 0)の記述となってしまいました。
さて、ボタン削除の件ですが、このコマンドを実行後、即ち、"End With"の次に「このコマンドボタンそのもの」(クリックしてこのコマンドを実行したボタン)を削除したいのです。CommandButton1(この場合は、コマンド1)は、うまくいくのですが、別の処理で"Forms.ComanndoButton1"を継続して複数作って削除したいのです。 二つ目以降は、CommandButton2,
CommandButton3……と(当然)なり、削除するボタンのオブジェクト名が指定できません。
(の) 2016/08/01(月) 15:57

 う〜ん・・・

 質問の意図が伝わらなかったようです。

 ・削除するコマンドボタンは ユーザーフォーム上のコマンドボタンですか?
  それともシート上の ActiveXコマンドボタンですか?

 こう聞いています。どちらですか?

 それとも、質問文には ユーザーフォーム とありましたけど、ユーザーフォームは全く関係なく
 最初から、シート上の ActiveXコマンドボタンのことだったのでしょうか?

 そもそも、このプロシジャはどのモジュールに書かれているのですか?
 ユーザーフォームモジュールですか? シートモジュールですか?

(β) 2016/08/01(月) 16:30


 ↑で質問している回答は是非お願いします。

 それとは別に、処理全体の構成が見えないのですが

 ・ユーザーフォームは関係なく、シート上の ActiveXだろうと想像しています。
 ・で、別途の処理で、CommandButtonを複数シート上に生成するコードがあるんだろうと想像しています。
 ・それら、自動生成したActiveXコントロールに コマンド1、コマンド2、コマンド3、・・・という名前を与えていると想像しています。

 という想像なんですけど、その【別途の処理】コードをそのままアップいただけませんか。

 ★本件、削除 ではなく 非表示にしたほうが素直だと、そう思っていまして、その提言をするためにも
  その【別途の処理】コードを拝見したいと思っています。

(β) 2016/08/01(月) 16:39


 これから提言するであろうこととは離れますが、アップされたコードで、

 ActiveSheet.Shapes.Range(Array("コマンド1")).Select 
 Selection.Delete

 これは、ふつうは

 ActiveSheet.Shapes.Range("コマンド1").Delete

 それと

 Selection.Cut 
 Application.CutCopyMode = False 

 これって、何をしているのかがわかりません。

 で、

 Private Sub コマンド1_Click() 

 End SUb

 なら、クリックされたコマンドボタンの名前は "コマンド1" ですし

 Private Sub CommandBitton2_Click() 

 End SUb

 なら、クリックされたコマンドボタンの名前は "CommandButton2" です。

 ボタン名が知りたいということですけど、ボタン名はプロシジャごとに決まっていますので
 なにが問題なのかがわからないところです。

(β) 2016/08/01(月) 16:52


説明が下手で、質問の意図が伝わらず申し訳ございません。自分自身のやりたいことが正しく伝えきれず情けない思いです。失礼ながら単純に要旨のみお伝えします。
プロシジャはユーザーシートモジュールです。ボタン名は、複数のコマンドボタンを設定した時にすべて「コマンド1」としており、複数のどのボタンも「コマンド1」に見えますが、それぞれ「CommandButton1」「CommandButton2」「CommandButton3」と続きます。そこで、ボタンをクリックしたときにプロシジャにクリックしたボタンの「ボタン名(オブジェクト名)」を記述したいのです。
判りずらい質問で、ご迷惑をおかけします。 これを最後にします。
要するに(たとえは悪いですが)クリックした(オブジェクト名の分からない)ボタンに“自殺して”自ら消えてほしいのです。
(nonon) 2016/08/01(月) 19:59

 >>これを最後にします。 

 ん? 意味がちょっと・・・
 別途の処理でコマンドボタンを生成しているプロシジャがあるはずで、そのコードをアップしてくださいとお願いしたんですけど?

 なので、直接の回答ではなく、私からの【提言】という形で2つほど。

 ●現行通り、シートの ActiveX CommandButton で処理するケース。

 いくつのコマンドボタンがあるのかわかりませんけど、CommandButton1〜CommandButton4 の 4個だとします。

 1)コマンドボタンの自動生成はやめます。手動で、準備として シート上に CommandButton1〜CommandButton4を挿入。
  (名前は CommandButton● にしてレスしますが、もちろん、それぞれに異なる名前 "コマンド1" 等を付けておいてもOKです)
 2)シートモジュールには 

 Private Sub CommandButton1_Click()

    '現状通りのCommandButton1 用の処理コード

    CommandButton1.Visible = False

 End Sub

 Private Sub CommandButton2_Click()

    '現状通りのCommandButton2 用の処理コード

    CommandButton2.Visible = False

 End Sub

 Private Sub CommandButton3_Click()

    '現状通りのCommandButton3 用の処理コード

    CommandButton3.Visible = False

 End Sub

 Private Sub CommandButton4_Click()

    '現状通りのCommandButton4 用の処理コード

    CommandButton4.Visible = False

 End Sub

 こんなように、End Sub の前に、当該コマンドボタンを非表示にします。

 3)【別途の処理】は、消してください。かわりに、標準モジュールに。(シートモジュールでもいいですが)

 Sub 別途の処理()
    Dim ctrl As Object

    For Each ctrl In Sheets("Sheet1").OLEObjects    '★シート名は実際のものに
        If TypeOf ctrl.Object Is MSForms.CommandButton Then ctrl.Visible = True
    Next

 End Sub

 つまり、マクロ内で コマンドボタンの削除も生成も行いません。

 ●ActiveX CommandButton処理ではなく フォームツールのボタンにして、そこに標準モジュール(シートモジュールでもいいですが)に書いたマクロを登録。
  この形にしておけば、Application.Caller で、ボタン名が取得できます。

  各ボタン処理コード、別途の処理コード ともに、少し、ActiveX用コードとはかえなければいけませんが
  今回のテーマ、(各ボタン処理のコード詳細がみえないのですが)こちらのほうがいいかもしれません。

(β) 2016/08/01(月) 20:21


 そもそもが、

 >>ボタン名は、複数のコマンドボタンを設定した時にすべて「コマンド1」としており、複数のどのボタンも「コマンド1」に見えますが

 ちょっと誤解しておられるように思いますね。
 ほんとうに ActiveX で CommandButton1,CommandButton2 等であれば、それら名前を同じものにすることはできません。
 やろうとすると、エラーになります。

 もしかして、【名前】ではなく【キャプション】を "コマンド1" にしているだけなのでは?

 ★このあたりも確かめたかったのでコードアップをお願いしているんです。

 キャプションは、名前ではありません。名前はあくまで CommandButton1,CommandButton2 等。
 (もちろん、これら初期設定値を、"コマンド1"、"コマンド2" 等に変更することはできますよ。ただしユニークな名前)

 ですから、CommandButton1 であれば キャプションが "コマンド1" であっても、シートモジュールに記載すべきプロシジャは
 Private Sub コマンド1_Click() ではなく Private Sub CommandButton1_Click() です。

 で、CommandButtonの数だけ、このプロシジャが必要です。(クラス処理をして 見かけ上1つのプロシジャにもできますが)
 逆にいえば、CommandButtonごとにプロシジャがわかれていますので、それぞれのボタン名は明確にわかるわけです。

 もし、ボタンは複数あるけど、それを受けるプロシジャは1つにしておきたい。
 でも、どのボタンがおされたのかは把握したいということであればコメント済みですけど フォームツールボタンを
 使うことになります。

 ■以下は読み飛ばしてください。

 >>ユーザーフォーム上のActiveControボタンにコマンドをもたせています。 

 こう書いておられましたけど、ユーザーフォームとは、何の関係もない処理ですね。

 >>プロシジャはユーザーシートモジュールです。

 ユーザーシートモジュール というモジュールはありません。
 ユーザーフォームモジュールやシートモジュールはありますが。

(β) 2016/08/01(月) 20:35


 コメントしたように、わからないことだらけなんですが、仮に

 >>Forms.ComanndoButton1

 これが何かの勘違いで、シート上のボタンが、ActiveXではなくフォームツールのボタン(ボタン 1 とか)だとすると

 シートモジュールでも標準モジュールでもいいのですが、

 Sub 同じマクロ()
    MsgBox Application.Caller
    ActiveSheet.Shapes(Application.Caller).Delete
 End Sub

 こんなコードを書いておいて(Private Sub 同じマクロ() は だめですよ)
 シート上のボタンにすべて同じマクロをマクロ登録。

 で、シート上のボタンをクリックしてみてください。

 (でも、コメントした通り、削除は運用面で困ることになると思いますが)

(β) 2016/08/02(火) 11:22


昨夜、お教えいただいた「フォームツールのボタンにして、そこに標準モジュールに書いたマクロを登録。この形にしておけば、Application.Caller で、ボタン名が取得できます」との対応を実行、ボタンを作り出す処理の経過中にActivexCommandButtonを作るのを止めてフォームツールのボタンにしました。結果、やりたかった通りの結果が得られました。
本日は、またまたご親切に
  Sub 同じマクロ()
  MsgBox Application.Caller
    ActiveSheet.Shapes(Application.Caller).Delete
   End Sub
を、御教示いただきありがとうございます。早々に、元々エラーになり困っていた
  --------
  ActiveSheet.Shapes.Range(Array("コマンド1")).Select
    Selection.Delete
  --------
を、次の通り記述し直しすべてうまくいきました。「今まで何を苦労していたのか」との思いです。
  ActiveSheet.Shapes(Application.Caller).Delete    
本当に、ありがとうございました。 質問下手で、正しく伝えることができずご迷惑をおかけいたしました。
心より感謝申し上げます。

  

(nonon) 2016/08/02(火) 13:08


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.