• ベストアンサー

エクセルの右クリック(BeforeRightClick)について

Excel2007 VBAにてWorksheet_BeforeRightClickを使用しています。 列セル(行セル)の全選択をして、右クリックでセルの書式設定を一括で出来ますが、 BeforeRightClickに引っかかってしまいます。 そこで、セル以外を選択されているかを調べる方法はあるのでしょうか? Target.Addressも試しました。 これだと、セル以外を選択時「$D:$D」、1つのセル選択時「$D2」などと返って来ます。 前者は数字が含まれていませんので特定のセルではありませんが、 列位置によっては文字数が変わってしまいます。 後者はセルを指定されている時ですが、範囲ではありません。 説明が分かりにくいかも知れませんが、 列セルの全選択時はBeforeRightClickを無視、 1つのセル選択時はセルの行位置を取得、 複数のセル選択時は選択セルの開始行位置を取得したい訳です。 どなたか御存知でしたら教えて下さい。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • ja7awu
  • ベストアンサー率62% (292/464)
回答No.2

こんな感じで如何でしょうか。 Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)   If Selection.Rows.Count = Cells.Rows.Count Or _       Selection.Columns.Count = Cells.Columns.Count Then     Cancel = True   Else     MsgBox "列 Or 行 選択状態以外で右クリックされました。"   End If End Sub

kiki_s
質問者

お礼

直接比較だけなんですね。 VBなら、基本的な部分は理解出来るのですが(仕事で) VBAは今回初めてなので、なかなか難しいところがあります。 似た言語でも環境が違うと全く別物です。 まぁ、仕事とはいっても今回のエクセルは社内用なので適当です(^^;; 元々、誰かが作ったマクロがあったのですが、 全てのセルにマクロが埋め込まれていて、キー操作毎にマクロが走るため、 動作が異様に遅いという欠点がありました。 (数千セル以上にマクロがある) そこで、勉強も兼ねてマクロを変更しようと試みたのですが、 とてもとても、さわれるものではないと分かり、 これなら1から作る方が早いと考え、VBかVBAか悩んだあげく、 エクセルなら全てのマシンに入っているのでVBAで組み上げる事にした訳です。 もっともっと努力しないと駄目ですね。 ありがとうございました。

その他の回答 (3)

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

こんにちは。 > 複数のセル選択時は選択セルの開始行位置を取得したい訳です。 例えば、A5:C10, D1:D5, F15:F20 などと複数のセル範囲が選択されている ときに、右クリックされた場合の開始行とは? 開始行の定義によって返すべき行番号は異なりますよ。この辺も考慮して みて下さい。  # もう一例) A5:A10、C:C のときは? 察するに、Target.Areas.Count > 1 の場合は終了させてしまえば、  ・ひとつのセルを選択している時  ・ひとつのセル範囲(例:A1:C10)を選択している時 ともに、Target.Cells(1).Row で先頭セルの行番号は取得できます。 こんな感じ。IF のネストが深くなるのでベタ書きです。 Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)   ' // 終了条件::   If Target.Areas.Count > 1 Then Exit Sub   If Target.Rows.Count = Me.Rows.Count Then Exit Sub   If Target.Columns.Count = Me.Columns.Count Then Exit Sub   ' // メインとなる処理   MsgBox Target.Cells(1).Row End Sub

kiki_s
質問者

お礼

>例えば、A5:C10, D1:D5, F15:F20 などと複数のセル範囲が選択されているときに、 >右クリックされた場合の開始行とは? 離れたセルの複数範囲選択は今のところ考えていません。 (最終的には機能として利用したいところですが) 列は関係なく、必要な情報としては行だけです。 あくまで連続したセルを指定するだけです。 1行に必要とする複数のデータを書き込んで別シートにコピーするだけの動作です。 例えば、範囲指定をD8:D19としてもA8:M19としても、 取得する情報は「開始:8行」「終了:19行」となります。 入力側のシートは1行ですが、コピー先は複数行ありますので、 入力側の現在セル位置情報(行のみの値)を元に計算でコピー先セルに複写しています。 この計算(基準+オフセット)が面倒でした(^^;; >こんな感じ。IF のネストが深くなるのでベタ書きです。 なるほど、単純に比較だけと考えれば良い訳ですね。 「小さい」か「同じ」だけだとは・・・ 参考にさせて頂きます。 ありがとうございました。

  • onlyrom
  • ベストアンサー率59% (228/384)
回答No.3

回答ではないのでなんですが。。 VBAに馴染みのない質問者にはちょっぴりためになるかも。(^^;;; '----------------------------------------------  Sub test()  Dim Absolute_Reference  Dim Relative_Reference  Absolute_Reference = Selection.Address  Relative_Reference = Selection.Address(False, False)  MsgBox Absolute_Reference & " @ " & Relative_Reference End Sub '--------------------------------------------- 以上。  

kiki_s
質問者

お礼

範囲選択については「Selection.Cells.Address」から文字列を分解して開始、終了アドレスを取得していますが、 こんなに短いコードで同じ事が出来るのですね。 ホント、もの凄く「ため」になりました。 ありがとうございました。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.1

InStr() 関数で単一セルか範囲が選択されているのかを確認し、範囲であれば Split() 関数を使って分割。 $D:$D → [:] の前後の文字 [$D] と [$D] が一致したら BeforeRightClick を終了する。 そうでなければ開始アドレスを取得する。 Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) Dim tmp As Variant Dim ADR As Range Set ADR = Target If InStr(Selection.Address, ":") > 0 Then tmp = Split(Selection.Address, ":") On Error Resume Next If tmp(0) = tmp(1) Then Exit Sub Else Set ADR = Range(tmp(0)) End If End If Cancel = True '右クリックメニューの抑止 'MsgBox ADR.Address MsgBox ADR.Row End Sub

kiki_s
質問者

お礼

標準モジュールで似た事をしている部分があります。 えらく長ったらしいコードになっていますが(^^;; このコード量で行アドレスが取得出来るのですね。 よく考えられていると感心しました。 参考にさせて頂きます。 ありがとうございました。

関連するQ&A