|
▼吉 さん:
こんばんわ
書いているうちに文が長くなってしまいました。
■で区切られた下は時間がある時にでも読んでください^^
>下記のコードで正常に『Test』メニューが表示され、又、リセットも
>正常に出来ました。
今度は予想が当たったようです^^
実はちょっとカラクリがありまして「正常」とは言えないんです。
>上記をどのように、Worksheet_BeforeRightClickイベントへ組み込めば、
>良いのでしょうか?
とりあえず組み込んだコードです。
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Dim i As Long
With Application
For i = 1 To .CommandBars.Count
With .CommandBars(i)
If .Name = "Cell" Then
.Reset
If Target.Count = 1 And Target.Column = 5 Then
With .Controls.Add
.Caption = "最終行にコピー(&B)"
.OnAction = "EndCopy"
.BeginGroup = True
End With
End If
End If
End With
Next i
End With
End Sub
ただこのコードにはちょっと問題がありまして・・・
というのもエクセルの中には「Application.CommandBars("cell")」が
デフォルトで”2つ”あります。
下記コードを試してみてください
(エクセルで使用されているCommandBar全ての各項目情報を
表示します、たぶん100件ぐらい出るはずです)
Sub test()
Dim i As Long
With Application
For i = 1 To .CommandBars.Count
With .CommandBars(i)
Cells(i, 1) = .Index
Cells(i, 2) = .Name
Cells(i, 3) = .NameLocal
End With
Next i
End With
End Sub
環境によって違うと思うのですが、20行目台あたりに
”Cell”、”Column”、”Row”がそれぞれ2つあると思います。
これが意味するのは、
上は、シートの表示状態が”標準”時のコマンドバー、
下は、”改ページプレビュー”時のコマンドバー
ということになります。
なので、もしかしたら”改ページプレビュー”の”Cell”が認識されているのかも?
と当たりをつけて前回のようなテストコード作成しました。
つまりCommandBarの.Name が "Cell"のもの全てに.Controls.Addしてみたという訳です。
”改ページプレビュー”でも追加されていると思うので確認してみてください。
(吉 さんの最初のコードもそのPCでは”改ページプレビュー”で機能しているはずです)
という訳で、「”改ページプレビュー”にも追加される」のを承知の上で、
問題ないようでしたら使用してください。
ただ通常、Application.CommandBars("cell")で指定してやるとIndex順位が上の
”標準”時のコマンドバー、が選択されるはずですが、”改ページプレビュー”時のが
選択されるということはCommandBarのIndex順位が狂っている、
早い話、エクセルがバグってる可能性が高いので再セットアップされることをお奨めします。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
>初心者なためコードの意味がいまいち呑み込めません。
>宜しければ、ご教授をよろしくお願いします。
ではちょっと解説を^^
>For〜Nextステートメントで、CommandBars.Count(コマンドバーの数?)
そうです。
コマンドバーの数が100個なら
For i = 1 To 100
ということになります。
>If .Name = "Cell" Then(コマンドバーの数の名前がCellであれば・・・ですよね?)
たぶんこちらがよく分かっていないのでは?
If CommandBars(i).Name = "Cell" Then の
CommandBars(i) は Index が i の CommandBarsということで、
その Name が "Cell" ならば、ということになります。
で、たぶん Index がちょっと引っかかると思うので、
分かりやすくシートを例にすると(デフォルトのブック状態)
1. Worksheets("Sheet1").Select
2. Worksheets(1).Select
1.と2.は同じ動作をします。
1.はシートの名前で、2.はシートの Index番号でシートを指定しています。
シートの名前を変えると1.はエラーになりますが、2.は問題ありません。
逆に、"Sheet2"を削除すると"Sheet3"の Index番号が2になるので
3. Worksheets("Sheet3").Select
4. Worksheets(3).Select
3.は問題ありませんが4.がエラーになります。
つまり、(言い回しが合っているかは分かりませんが・・・)
Index番号はオブジェクトが作成された順に欠番なしで割り当てられている
ということです。
この理屈が分かれば、
例えば、不特定枚数のシートの中で有るか無いか分からない"test"という名前のシートを探し、
該当するシートが有ればセルのA1に”OK”と表示することができます
For i = 1 To ThisWorkbook.Worksheets.Count
If Worksheets(i).Name = "test" Then
Worksheets(i).Range("A1").Value = "OK"
End If
Next i
これと同じ事をCommandBarでしたということです。
ついでに吉 さんのコードについて少し・・・
>Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
> If Target.Count = 1 And Target.Column = 5 Then
> Application.CommandBars("cell").Reset
> With Application.CommandBars("cell").Controls.Add
> .Caption = "最終行にコピー(&B)"
> .OnAction = "EndCopy"
> .BeginGroup = True
> End With
> Else
> Application.CommandBars("cell").Reset
> End If
>End Sub
これは条件を満たしていてもいなくても
> Application.CommandBars("cell").Reset
が実行されているのでIf文の中に入れる必要はないと思います。
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Application.CommandBars("cell").Reset
If Target.Count = 1 And Target.Column = 5 Then
With Application.CommandBars("cell").Controls.Add
.Caption = "最終行にコピー(&B)"
.OnAction = "EndCopy"
.BeginGroup = True
End With
End If
End Sub
あと、
> Dim R, C As Integer
もそうですが
> Dim C, R As Long
これは
Dim C
Dim R As Long
としているのと同じです。
これで確認してみてください
MsgBox "Cのデータ型は" & TypeName(C) & " Rのデータ型は" & TypeName(R)
なので共にLong型にしたい場合は
Dim C As Long, R As Long
のようにします。
なんだかダラダラと長文になってしまいスイマセン
意味が分からないところがあれば、また気軽に質問してください^^
|
|