MS Access Tips/Sample and VBA and Blog customize etc...

データシートビューのフォームで列が削除されてしまう

Access2010 からの新機能として、フォームのデータシートビューで列を簡単に削除できるようになってます。

操作としては実に簡単です。
データシートビューでヘッダーの項目名をクリックして列を選択します。
そして、Deleteキーを押せば、簡単に!!確認メッセージもなく!!即削除出来ます。
また、列見出し上での右クリックのメニューの[削除]でも可能です。

データシートビュー列削除

ふむふむ、バージョンがあがってどんどん便利になってきますね。
って、おいっ!!こんな機能、誰得なんだよ。
ユーザーがうっかり削除してしまって、再表示できません、というクレームが開発者に殺到するではないか。

列が多すぎて見難いというなら、フィールドの非表示 という機能があるし、これなら再表示も簡単です。いったい誰がこんな機能を必要とするのだろう。

ということで、これを禁止する方法を探ってみました。

難易度:

この新機能の現象をもう少し詳しく調べてみると、データシートビューで列を削除してデザインビューにすると、該当するコントロールが削除されてしまってます。このフォームを閉じる時に、「フォームの変更を保存しますか」と確認してくれますが、ユーザーはたいてい「はい」を押してしまうでしょう。

Accessのオプションで「データシートビューでテーブルのデザインを変更できるようにする」というのがありますが、これはテーブルの場合であって、これのチェックを外しても、フォームのデータシートビューには影響しません。

Delキー削除対策

キーボードイベントで Delキーが押された時に、列選択状態を判断して、Delキーを無効にするようにしてみました。

「追加の許可」が「はい」になっていて新規行がある場合は、列選択すると、SelHeight が RecordCount+1 になるのでそれで列選択していると判断します。

フォームの「キーボードイベント取得」プロパティを「はい」にします。

キークリック時

「追加の許可」が「いいえ」あるいはソースが更新不可などで新規行がない場合は、SelHeight と RecordCount が同じなら列選択とします。

ただし、全行選択でも SelHeight=RecordCount になり列選択と区別できないので、全レコード削除ができなくなります。

右クリック-削除対策

キーボードからの削除は禁止にできましたが、まだ右クリックのショートカットメニューの[削除]クッリクで削除できてしまいます。これを防止するには、フォームの開くときのイベントプロシージャに下記のコードを設定します。

これで、列見出しの右クリックの[削除]コマンドを使用不可にできます。

データシートビュー右クリック削除使用不可

メニューバーやショートカットメニューのコマンドにはそれぞれユニークなIDが振られています。データシートビューの列の右クリックの[削除]コマンドのIDは 478 なので FindControl(ID:=478) でアクセスできます。

メニューコマンドのIDの探し方

ちなみに、この ID の探し方なんですが、下記のプロシージャを実行するとイミディエイトウィンドウにコマンドバーやメニューの名前が列挙されます。その名前から該当しそうなものを探します。

「Microsoft Office 14.0 Object Library」に参照設定

実行してみると大量に表示されて探すのが大変です。(件数を CommandBars.Count で調べてみると209でした)
そこで、データシートビューでのものなので、Datasheet を含んでいるだろうとあたりをつけて、それを含んでいるものに絞り込んで表示させるようにコードを書き換えます。

これを実行すると、表示されるのは20件ぐらいになりました。
その中から "Form Datasheet Column" がたぶん該当するものだろうと予想をつけます。
"Form Datasheet Column"のコマンドのインデックス、標題、IDを表示させる下記のプロシージャを実行します。

実行するとイミディエイトウィンドウに下記のよう出力されます。

 1 昇順で並べ替え(&S) 210 
 2 降順で並べ替え(&O) 211 
 3 コピー??(&C) 19 
 4 貼り付け??(&P) 22 
 5 再変換??(&V) 3720 
 6 ハングルと??漢字の変換(&G)... 3492 
 7 フィールド幅??(&F) 542 
 8 削除??(&D) 478 
 9 フィールドの非表示(&F) 1955 
 10 フィールドの再表示(&U) 2764 
 11 フィールドの固定(&Z) 544 
 12 すべてのフィールドの固定解除(&A) 1794 
 13 既存のフィールド??の追加(&L) 501 
 14 条件付き??書式(&D)... 3058 

実際の右クリックメニューとほぼ同じなので間違いないでしょう(一部非表示のコマンドも有るようです)。で、削除コマンドのIDは 478 とわかります。


拍手する

11 Comments

MukkuMuku says...""

MukkuMukuです。お久しぶりです。
フィールドが削除できると同じく追加もできてしまうんです。

2013.06.24 23:13 | URL | #2DdjN05. [edit]
hatena says..."既存のフィールドの追加"

MukkuMukuさん、こんばんは。

あっ、なるほど。
列見出しの右クリックメニューの「既存のフィールドの追加」ですね。

これは、[オプション]の[カレントデータベース]の[すべてのメニューを表示する]のチェックを外しておけば、表示されないですね。[削除]も使用不可になりますね。

ユーザーに配布するときはたいていそうするのでいいかな。

ただ、DELキーによる削除はできてしまいますので対策は必要ですね。

ひょっとしてフィールド追加もキー操作でできたりしますか。

2013.06.25 00:01 | URL | #5uE6dEgY [edit]
MukkuMuku says...""

DELみたいにザックリ追加されることはないのですが、
 ・ALT + F8
 ・QATに配置された [既存のフィールドの追加]
のいずれかなど。
[すべてのメニューを表示する]に関わらず追加可能になってしまいます。
削除はフィールドが選ばれた状態で、ホームタブ > レコード > 削除 でもできるんですよね。

もうね、モグラ叩きだから、accde にしてます。

2013.06.25 22:43 | URL | #2DdjN05. [edit]
hatena says..."モグラ叩き^^;"

のようですね。

ホント、誰得なんだよ(# ゚Д゚)

2013.06.26 08:57 | URL | #5uE6dEgY [edit]
ringojuice says..."サブフォームでの操作"

hatena様

サブフォームで下記のコードを設定しましたが、メインフォームで
まだ使えます...
Private Sub Form_Open(Cancel As Integer)
CommandBars.FindControl(ID:=478).Enabled = False
End Sub

メインフォームでも使えないようにするのは可能でしょうか?

2013.10.10 17:47 | URL | #mQop/nM. [edit]
hatena says..."re:サブフォームでの操作"

> サブフォームで下記のコードを設定しましたが、メインフォームで
> まだ使えます...
> Private Sub Form_Open(Cancel As Integer)
> CommandBars.FindControl(ID:=478).Enabled = False
> End Sub
>
> メインフォームでも使えないようにするのは可能でしょうか?

このコードはデータシートビューで、右クリックでの列の削除をできなくするものですが、
メインフォームもデータシートビュー表示にしているのですか。
(サブフォームはサブデータシート表示)

メインフォームの開くときにも同じコードを設定したらどうなりますか。

2013.10.10 19:30 | URL | #5uE6dEgY [edit]
ringojuice says..."re:サブフォームでの操作"

>メインフォームもデータシートビュー表示にしているのですか。
(サブフォームはサブデータシート表示)

>メインフォームの開くときにも同じコードを設定したらどうなりますか。

メインフォームはデザインビューです。
メインフォームでも同じコードを設定しましたが、だめでした。

2013.10.10 21:20 | URL | #mQop/nM. [edit]
hatena says..."re:サブフォームでの操作"

> メインフォームはデザインビューです。

デザインビュー?
デザインビューで何をしたいのですか。

> メインフォームでも同じコードを設定しましたが、だめでした。

このコードの意味を理解していますか。

メインフォームで何をしたいのか、目的を具体的に説明してもらえますか。

2013.10.10 21:43 | URL | #5uE6dEgY [edit]
ringojuice says..."re:サブフォームでの操作"


> このコードの意味を理解していますか。
>
> メインフォームで何をしたいのか、目的を具体的に説明してもらえますか。



説明不足ですみませんでした。

やりたいこと:
メインフォーム中のサブフォームの右クリックメニューの列削除機能をなくしたいです。

そのコードをメインとサブフォーム両方の「フォームを開く時イベント」で設定しましたが、
メインフォームを設定したとき、エラーが出ました。
メインフォームはデータシートビューではないです。普通のフォームビューです。
「CommandBars」このプロパティがないらしいです。

Private Sub Form_Open(Cancel As Integer)
Me.Sub.Form.CommandBars.FindControl(ID:=478).Enabled = False
End Sub

恐れ入りますが、ご指南のほどよろしくお願いします。

2013.10.10 22:39 | URL | #mQop/nM. [edit]
hatena says..."re:サブフォームでの操作"

> やりたいこと:
> メインフォーム中のサブフォームの右クリックメニューの列削除機能をなくしたいです。
>
> そのコードをメインとサブフォーム両方の「フォームを開く時イベント」で設定しましたが、
> メインフォームを設定したとき、エラーが出ました。
> メインフォームはデータシートビューではないです。普通のフォームビューです。
> 「CommandBars」このプロパティがないらしいです。

CommandBars はフォームのプロパティではないです。
Aplication のプロパティです。

サンプルを作成してテストしてみたら、なぜか、サブフォームでは無効にできませんでした。

対策として、このコメント欄の [839] と [840] を参照してください。

ユーザーにデザイン変更をさせないというのが目的なら Accde にするというのが一番確実かと思います。

2013.10.11 09:24 | URL | #5uE6dEgY [edit]
ringojuice says..."re:re:サブフォームでの操作"

> CommandBars はフォームのプロパティではないです。
> Aplication のプロパティです。
>
> サンプルを作成してテストしてみたら、なぜか、サブフォームでは無効にできませんでした。
>
> 対策として、このコメント欄の [839] と [840] を参照してください。
>
> ユーザーにデザイン変更をさせないというのが目的なら Accde にするというのが一番確実かと思います。

hatena様

ご説明ありがとうございます。
Accdeにする方法を参考にさせていただきます。

> CommandBars はフォームのプロパティではないです。
> Aplication のプロパティです。

なるほど...
このコードがだめな原因が分かりました。
Me.Sub.Form.CommandBars.FindControl(ID:=478).Enabled = False
ご教授ありがとうございます。
勉強になりました!

2013.10.11 10:03 | URL | #mQop/nM. [edit]

Leave a reply






Trackbacks

trackback URL
http://hatenachips.blog34.fc2.com/tb.php/370-1c9c5cdd
該当の記事は見つかりませんでした。