• ベストアンサー

エクセルの右クリック(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

  • Excelで右クリック禁止が出来ない?

    Excel2010 を使用しています。 設定した範囲(1~10行)のセルを右クリックしたときに出るショートカットメニューを表示しない様な設定にしたく、  Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)   Dim myRowTop As Long , myRowBottom As Long   myRowTop = 1   myRowBottom = 10   If ActiveCell.Row >= myRowTop And ActiveCell.Row <= myRowBottom Then    Application.CommandBars("Cell").Enabled = False   Else    Application.CommandBars("Cell").Enabled = True   End If  End Sub としました。 これで通常問題ないと思いますが、 A1 : F10 を「テーブルとして書式設定」し、この範囲のセルを右クリックしたとき、 ショートカットメニューが表示されてしまいます。 CommandBars([Index]) の Index が違うのかと思い、試してみましたが、直りませんでした。 どなたか詳しい方、どうか教えてください。 よろしくお願いします。

  • エクセルVBAについて

    エクセルVBAについて 下にある、1行目に入力された数値の、選択したセルの数値を、B5セルに表示させるマクロなのですが、1行目が結合していると、うまくB5セルに表示できません。 Private Sub Worksheet_SelectionChange(ByVal Target As Range)  If Target.Count > 1 Then Exit Sub    '●複数セル選択は無視  If Target.Row <> 1 Then Exit Sub    '●1行目以外の選択は無視  If Target.Column > 6 Then Exit Sub   '●F列目以降の選択は無視  If Target.Value = "" Then Exit Sub   '●選択セルが未入力なら無視    Range("B5").Value = Target.Value End Sub このマクロで、結合しているセルをB5に表示させることはできますでしょうか? 1行目で選択するセルは、すべて2つのセルが結合しています。 よろしくお願いいたします。

  • VBA エクセル2000でハイパーリンクをはる

    アクティブなワークシートの特定セル(行位置、列位置 一定)と他のワークシートの不定セル(行位置、列位置 とも、或いは、どちらか、 が変数)間にハイパーリンクをはりたい 実現したいことは至ってシンプルでセル間をジャンプ可能となればOK、です 例えばWorksheet「アクティブ」のCells(固定行位置,固定列位置)と Worksheet「他のシート」のCells(変数行位置,変数列位置)、両変数はその時点でプログラム(マクロ)が獲得済み、間にハイパーリンク(出来たら往復)をはるコードはどういうものになるでしょうか? うまく説明できているか、自信はありませんが何とか教えて頂きたくお願い致します

  • (エクセルVBA)セルを左クリックしたら実行させるには?

    エクセルVBA初心者です。 下のように、同じシート内のコードとして2つのサブプロシージャがある状態なのですが、 シート内のどこかのセルを左クリック→指示(1) シート内のどこかのセルを右クリック→指示(2) のようにするにはどうしたらいいのでしょうか? (この状態だと、右クリックすると選択範囲が変わったことが優先的に認識されて指示(1)のほうが実行されてしまうようです。) 説明不足かもしれませんが、何を説明していいのか分からないので、補足が必要だったら言ってください。すみませんがよろしくお願いします。 --------------------------------------------------------------- Private Sub Worksheet_SelectionChange(ByVal Target As Range) 指示(1) End Sub --------------------------------------------------------------- Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) 指示(2) End Sub ---------------------------------------------------------------

  • Excel2007VBA右クリックの複数回使用

    ●質問の主旨 ワークシートのイベントプロシージャにおいて右クリック Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) を連続で使用するためには以下のコードをどのように書き換えればよいでしょうか? ご存知の方ご教示願います。 ●質問の補足 ExcelのワークシートとVBAでタイムカードを作成しています。 以下のコードでは「出勤打刻」も「退勤打刻」もできません。 「退勤打刻」のコードを削除すると、「出勤打刻」はできます。 「プロシージャ名が適切ではありません」とエラーが返されます。 エラーの意図は分かりますが、「出勤打刻」と「退勤打刻」のクリック方法が違うのも 紛らわしいとも思います。同じクリック方法で統一するにはどうすればよいか悩んでいます。 ●コード '---------------------定数--------------------- Const SYUKIN_DAKOKU_CLMN As Integer = 5 '出勤打刻位置の列番号 Const TAIKIN_DAKOKU_CLMN As Integer = 6 '退勤打刻位置の列番号 Const DAY_CLMN As Integer = 2 '日付欄の列番号 '---------------------出勤打刻--------------------- Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) If Target.Column = SYUKIN_DAKOKU_CLMN Then '出勤打刻の位置 Cancel = True 'コンテキストメニューの抑制 If IsEmpty(Target.Value) Then 'ターゲットが空白のとき If Cells(Target.Row, DAY_CLMN).Value = Day(Date) Then '右クリックしたときの日付が日付欄の日付と等しいとき Target = Time '右クリックしたセルに現在の時間を表示 Target.NumberFormat = "hh:mm" '時間の表示形式は "hh:mm" Else MsgBox "打刻位置が間違っています", vbExclamation, "打刻位置の確認" 'メッセージ表示 Cancel = True 'コンテキストメニューの抑制 End If Else '打刻済みのときはメッセージ表示 MsgBox "すでに打刻しています", vbExclamation, "打刻位置の確認" End If End If End Sub '---------------------退勤打刻--------------------- Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) If Target2.Column = TAIKIN_DAKOKU Then '出勤打刻の位置 Cancel = True 'コンテキストメニューの抑制 If IsDate(Cells(Target.Row, DAY_CLMN)) = True Then '出勤打刻がされていれば If IsEmpty(Target.Value) Then 'ターゲットが空白であれば If Cells(Target.Row, DAY_CLMN).Value = Day(Date) Then '右クリックしたときの日付が日付欄の日付と等しい Target = Time '右クリックしたセルに現在の時間を表示 Target.NumberFormat = "hh:mm" '時間の表示形式は "hh:mm" Else MsgBox "打刻位置が間違っています", vbExclamation, "打刻位置の確認" 'メッセージ表示 Cancel = True 'コンテキストメニューの抑制 End If Else '打刻済みのときはメッセージ表示 MsgBox "すでに打刻しています", vbExclamation, "打刻位置の確認" End If End If End If End Sub

  • エクセルVBAでクリックしたセルのみ書式を変えたいのです。

    Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range) If Target.Row <= 11 And Target.Column <= 11 Then With Selection .Interior.ColorIndex = 3 .Font.ColorIndex = 2 .Font.Bold = True End With End If End Sub これで出来るのですが、問題は別のセルに移動しても書式は変ったままなのです。(当り前ですが) 書式を変えるのはあくまで選択されている間だけにしたいのです。 どのようにすればよいのでしょうか? エクセル97です。

  • クリックされたセルの位置を取得するには?

    テーブルのセルがクリックされた時、そのセルの位置(行番号、列番号)を取得したいと思っています。 セルオブジェクトのプロパティ(?)がよく分からないのですが、どうすれば取得できますか? ご回答よろしくお願いします。

  • エクセルVBA(値または文字の重複削除)

    先日まで何も出来ない状態でしたが、時間が出来たので、 またVBAを触り始めました。 質問はVBAで変数に代入されている値または文字の重複を削除したいのです。 セル範囲を取得し、変数に代入するまではいいのですが、 行列にまたがって範囲選択すると複数のセル位置(数値)が入ってしまいます。 例えば、D8からE9とD12からD13まで選択すると、変数の「セル位置」には「$D$8$E$8$D$9$E$9$D$12$D$13」が代入されますが、 $D$8=$E$8 $D$9=$E$9 数値の部分(内部は文字列ですが)が重なってしまいます。 これを、「$D$8$E$$D$9$E$$D$12$D$13」など数値(文字)のどちらかを削除出来ないものかと悩んでいます。 利用するのは数字の部分だけなので、その処理自体は問題ありません。 IF文でループさせて文字が存在するか見ているだけです。 また、比較自体も必ず偶数行だけですので、最後の「$」が無くても問題はありません。 For 始まり行 = セル開始行 To 入力行数 Step 2 If InStr(セル位置, "$" & Trim(始まり行) & "$") Then Exit For End If Next ただ、重複があるとそれも個数に含まれてしまい、計算がおかしくなります。 選択セル範囲の個数取得にはRange.Addressを使っています。 Dim rg As Range 'セル セル位置 = "" For Each rg In Selection セル位置 = セル位置 + rg.Address Next 縦1列なら大丈夫なのですが、複数列になると問題になります。 列行関係なく選択されたセルの行数が分かればいいだけなんですが・・・ 考え方だけでも構いませんので、よろしくお願いします。

  • 選択セルに計算結果を表示

    エクセルVBAで選択セルに計算結果を表示したいのですが、教えてください。 A列には、ID B・C列には値が入力されています。 下記の構文ですと、行のどこをダブルクリックしても、D列に合計が表示されます。 D列以降のどの行をダブルクリックしても、アクティブなセルに合計を表示したいです。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Cells(Target.Row, 4) = Cells(Target.Row, 2) + Cells(Target.Row, 3) End Sub

  • EXCEL保護シートで、Σを使いたい。

    EXCEL2002のシートに保護をかけた時に、Σがグレーアウトして表示されません。 表示させるには、どのようにすればよいでしょうか? Σを入力するセルは、ロックをかけておらず、タテ(列)の合計を計算させます。 保護されたシートのすべてのユーザーに許可する操作は 「ロックされたセル範囲の選択」「ロックされていないセル範囲の選択」「セルの書式設定」「列の書式設定」「行の書式設定」「行の挿入」「行の削除」「並べ替え」にチェックをいれています。

専門家に質問してみよう