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

Excel VBA を用いて Excelのメニューバーの各項目の enable/disable 状態を変更する事は可能でしょうか?
(「編集」-「貼り付け」の許可/禁止の切り替えなど)
ご存知の方、教えてください。お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

こんにちは。



Office 2003までに限られますが、

'標準モジュール
Sub Test1()
 Call MenuVisible(False) 'Off--False, On--True
End Sub
'
Sub MenuVisible(flg As Boolean)
With Application
 .CommandBars("Worksheet Menu Bar").Controls("編集(&E)") _
   .Controls("貼り付け(&P)").Enabled = flg '編集メニュー
 .CommandBars("Cell").FindControl(, 22).Enabled = flg '右クリックメニュー
 If flg Then
  Application.OnKey "^v"
 Else
  Application.OnKey "^v", "Dummy" 'ショートカットを無効

 End If
 End With
End Sub
'
Private Sub Dummy()
 Application.CutCopyMode = False
End Sub

'-------------------------------------------
'起動時は、
Sub Auto_Open()
  Call MenuVisible(False)
End if

'終了する場合は、
Sub Auto_Close()
  Call MenuVisible(True)
End if

'-------------------------------------------
とすれば可能です。

この回答への補足

ありがとうございます。
編集メニュー&右クリックメニューのロックができました。
そこで、補足で教えて下さい。
右クリックメニューのロックで使用している
FindControl(, 22)の引数の設定方法が調べたのですがわかりませんでした。
「22」は右クリックメニューの「編集」のことだと思いますが、数字の取得方法、もしくは一覧表のような物はあるのでしょうか。
又、第1引数は省略しない場合は何を設定するものなのでしょうか。
申し訳ありませんが、ご教示下さい。お願い致します。

補足日時:2010/01/03 08:03
    • good
    • 0
この回答へのお礼

年末のお忙しい中、早速の回答ありがとうございます。
教えていただいた方法で試してみます。

お礼日時:2009/12/31 21:45

こんにちは。



返事が遅くなりました。

>FindControl(, 22)の引数の設定方法が調べたのですがわかりませんでした。
「22」は右クリックメニューの「編集」のことだと思いますが、数字の取得方法、もしくは一覧表のような物はあるのでしょうか。

こういう質問をする人は、何年ぶりでしょうか?こういう質問は、大歓迎です。

私が、入門当事は、本の巻末に出ていましたので、それを参考にしました。しかし、私がマクロで作りましたので、ここに出しておきます。それを、ブックにコントロールリストにしても良いと思います。(ほかにも、エラーリストがマクロで出せます。Err.Number と、Err.Description で、1から10000ぐらいをループさせるだけですが。)

このマクロは、時間が掛かります。
'-------------------------------------------
'メニューコントロール一覧リスト作成
Sub ControlListsShowup()
Dim c As Variant
Dim n As Variant
Dim i As Long
 Application.ScreenUpdating = False
 On Error Resume Next
  Cells(1, 1).Resize(, 3).Value = Array("CommandBar", "Control", "ID")
  i = 2
  For Each c In CommandBars
     Cells(i, 1).Value = c.Name
   For Each n In c.Controls
     Cells(i, 2).Value = n.Caption
     Cells(i, 3).Value = n.ID
     i = i + 1
   Next n
  Next c
 On Error GoTo 0
  Application.ScreenUpdating = True
End Sub
'-------------------------------------------

今回の質問というのは、少し特殊で、抜け落ちは許さないという種類のものだと思います。その場合は、「編集」というキャプションをすべて探します。

>又、第1引数は省略しない場合は何を設定するものなのでしょうか。

第1引数は、MsoControlType とヘルプには出ていますが、msoControlButtonなどの種類で、それは、規定のコントロールの場合は指定する必要がありません。

expression.FindControl(Type, Id, Tag, Visible, Recursive)

次のTag というのは、ユーザーが設定したメニューコマンドの場合に、Add で設定するときに、ついでにTag にユニークな名前をつけておいて、後で、変更したり、メニューを解除したりするときに、そのTag で呼び出します。他は、使ったことがありません。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。
メニューコントロール一覧のリストを出力することができました。
一覧表を用いて確認することにより「抜け落ち」を防ぐことができますね。
初心者にも親切な回答をありがとうございました。

お礼日時:2010/01/04 11:46

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qエクセル VBA で行の右クリックメニューから行の挿入削除を無効にしたい

お世話になります。

右クリックメニューの行の挿入と削除を無効にしたいのですが、
セルを選択して、右クリックメニューの挿入・削除は

Private Sub Workbook_Open()
Dim mymenubar1 As CommandBar
Set mymenubar1 = Application.CommandBars("Cell")
mymenubar1.Controls("挿入(&I)").Enabled = False
End Sub

で無効にできたのですが、
行を選択→右クリックメニューの挿入削除の無効化の仕方がわかりません。
※セルに対してではなく、行に対して行いたいのです。

ご教授頂ければと幸いですのでよろしくお願いします。

Aベストアンサー

#1 の回答者です。読み落としましたので、書き加えました。
ただ、再度書きますが、Excel 2003以上には不要です。
また、これは、クラスインスタンスに設けることも多いです。
これは、右クリックメニュー(Cell)だけでなく、メニューの中も含めます。

サブルーチンを入れ替えてください。

Private Sub InsertEnabled(flg As Boolean)
With Application
 .CommandBars.FindControl(, 296).Enabled = flg
 .CommandBars.FindControl(, 293).Enabled = flg
 .CommandBars("Worksheet Menu Bar").FindControl(, 30003). _
        Controls("削除(&D)...").Enabled = flg
 .CommandBars("Row").FindControl(, 3183).Enabled = flg
 .CommandBars("Cell").FindControl(, 3181).Enabled = flg
End With
End Sub


本来は、2バイト文字を使いたくはないのですが、どうしてもできない部分があります。

#1 の回答者です。読み落としましたので、書き加えました。
ただ、再度書きますが、Excel 2003以上には不要です。
また、これは、クラスインスタンスに設けることも多いです。
これは、右クリックメニュー(Cell)だけでなく、メニューの中も含めます。

サブルーチンを入れ替えてください。

Private Sub InsertEnabled(flg As Boolean)
With Application
 .CommandBars.FindControl(, 296).Enabled = flg
 .CommandBars.FindControl(, 293).Enabled = flg
 .CommandBars("Worksheet Menu Bar").Fin...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

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

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む

Q【Excel VBA】マクロでExcel自体を終了させたい

環境:WindowsXP、Excel2003

マクロでエクセルを終了(ブックを閉じて、アプリケーション自体も終了)させたいのですが、以下のコードではアプリケーションが閉じてくれません。

ThisWorkbook.Close
ExcObj.Quit
Application.Quit

どこか悪いところはありますでしょうか?

よろしくお願いします。

Aベストアンサー

普通に考えれば質問者のコードで上手くいきそうですが
hana-hana3さんの回答にもあるようにThisWorkBook.Closeでコード終了となりますので
Application.QuitをThisWorkBook.Closeの前にもってこないといけません。
Application.Quitはそれがあるプロシージャのコードが全て終わるまで
その実行を保留するちょと特別動作をします。

'-------------------------------------
 Application.Quit
 ThisWorkbook.Close
'-------------------------------------
 
 

QVBA オブジェクトが空かどうか判定する

皆様のお知恵を拝借させてください。

エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト
が入っているかどうか検査したいのですがどうしたらいいでしょうか。

例えば---
Dim a As Workbook
If a <> nothing then ←この部分が分からない。このままだとエラー。
処理
End if
---------
環境
エクセル2003
WinXPsp1

Aベストアンサー

もし、aが空だったら
If a Is Nothing Then 

もし、aが空じゃなかったら
If Not a Is Nothing Then

QEXCEL(VBA) セルをクリックしたときの処理

何度もお世話になります。

A5:A20のどれかをクリックしたときに
クリックしたセルが値が入力済みか確認してから
ファイルを名前を付けて保存したいのですが
クリックしたという情報(イベント?)の取得方法が
わかりません。

(1)どのようにチェックすればよいのでしょうか?
(2)また、皆さんはどのようにしてこのような問題を解決してるのでしょうか?

よろしくお願いします。

Aベストアンサー

Sheet1だとして、
Sheet1のマクロで

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'
If Target.Column = 1 And Target.Row >= 5 And Target.Row <= 20 Then
If Target.Value <> "" Then MsgBox "入力済み"
End If
'
End Sub

と入れると、クリックしたセルがA5からA20のどれかで
かつセルに値が入っているときのみ”入力済み”とメッセージが表示されます。
このメッセージ表示の部分を、「名前を付けて保存」の処理に置き換えてはいかがでしょうか。

Qユーザーフォームを表示中にシートの操作をさせるには

ユーザーフォームを表示中にシートの操作をさせる事はできるのでしょうか。
セルへの入力、画面のスクロールなどは、ユーザーフォームからマクロを実行させたり、.hideでユーザーフォームを一時的に隠すなどすればいいのでしょうが、そういう手段をとらないでユーザーフォームを表示中にシートの操作をさせる事はできるのでしょうか。

Aベストアンサー

ユーザフォームの
ShowModalプロパティを
falseにすればよいかと。

QVBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。

マクロを含むエクセル(EXCEL2000)をHTMLのページからハイパーリンクで呼び出しています。そのエクセルでボタン操作に従い罫線やセルの着色を行っています。しかし、着色結果が更新されません。スクロールバー等で画面を移動すると正しく着色されています。このエクセルを通常に起動した場合は、問題なく動作するのですが、シート全体を更新する方法を教えて下さい。
各関数では、以下のスクリーンアップデータの処理を入れています。
Application.ScreenUpdating = False
    (処理)
Application.ScreenUpdating = False

Aベストアンサー

たぶん、EXCEL独特の問題だと思うのですが、HTML の場合、すでに色の部分を表面上で使用しているので、それでメモリが占有させているのではないかと私は思っています。

他にも、

 ActiveWorkbook.HTMLProject.RefreshDocument True

というのがありますね。
ホスト アプリケーション内のブックに含まれる HTML プロジェクトを更新する、というのがありますね。

Qエクセル マクロで指定フォルダを開く

エクセルにて
指定フォルダを開く、マクロがあれば教えて頂けないでしょうか。
よろしくお願いいたします。

Aベストアンサー

こんにちは。

こういうものですか?
開くフォルダを変えたいときは targ に与えるパスを変更します。

Sub OpenFolders()
Dim targ As String
targ = "C:\"
Shell "C:\Windows\Explorer.exe " & targ, vbNormalFocus
End Sub

QVBAでのコントロール操作

ボタンを押したら、そのボタンを非活性(Enabled=FALSE)にしたいです。

しかし、他に裏で処理が動いていると、すぐに非活性にならず、
少し時間がたった後、非活性になります。
私としてはすぐに非活性にしたいのですが、VBAで何か良い方法ありますか?

例えばC#では
ボタンA.Enabled = false;
ボタンA.Refresh();

これで、すぐにボタンAは非活性になります。

Aベストアンサー

> 少し時間がたった後、
タイマーではないので、その解釈では問題あるでしょう。
プログラムで実行している関数を抜けたタイミングだと思われます。
OS に制御が戻って次の処理が実行できる状態になったときに、OS が再描画
処理を命令します。

> ボタンA.Refresh();
Excel でもコントロールによってできたりできなかったり。
例えば、UserForm の Frame には Repaint があります。
(OS が再描画命令できるのだから内部処理は存在するのだろうけど、プログラム
から利用できるように公開されていない。)

総じて DoEvents が紹介されたりしますが、C# にも Application.DoEvents
があります。ヘルプで内容を確認できると思いますが、再描画の命令ではなく、
副作用があります。

これっていう良い方法は無いと思います。
上記に挙げたような内部処理を理解した人が、状況に応じてコーディングするか、
副作用込みで DoEvents するかといったところでは。


人気Q&Aランキング