
OS: win xp
Access Version: 2003
フォームを使って新規レコード入力できるように
Private Sub Form_Load()
Docmd.GoToRecord,, acNewRec
End Sub
として、開いています。
ここの際、問題なのですが、ホイールマウスを使っているとデータ入力中に誤ってホイールを回すことにより次の新規レコードに移ってしまいます。
これを制限したいと思います。
この類の過去で検索しましたが、解決に至っていません。
ご意見をください。
No.9ベストアンサー
- 回答日時:
No.8です。
はじめにお詫びです(汗)
「c」を「ややトリッキー」と言いましたが、かなり【控えめ】な表現でした(汗)
「b」でも充分にトリッキーで、「c」はその発展(?)になります。
> テーブルに「1件だけレコードを登録しておく」とは、どのようなことでしょうか。
「b」と「c」の違いは、「新規登録用の編集枠(=予め登録しておくレコード)」を
「作業テーブル」に用意するか、「正規テーブル」に用意するか、になります。
つまり、作業テーブルに予め登録しておくレコードは、「c」で説明したのと同様
のダミーデータです。
仮に、
・正規テーブルのフィールド構成:
ID / 氏名 / 生年月日 / 性別
(IDが主キーで、氏名に値要求あり)
・作業テーブルのフィールド構成:
氏名 / 生年月日 / 性別
(IDは正規テーブルへの登録時に設定すればいいので、ここには不要)
という形だった場合、作業テーブルには
"(入力必須)" / Null / Null
というレコードを1件登録しておきます。
これで、メインフォームを開いたときには、このレコード1件のみが表示される
ようになるので、実際の入力時には、ユーザーにはこのレコードを上書きして
もらい、『登録』ボタンを押した時(又はフォームを閉じた時)に、正規テーブル
に転記するとともに、上記レコードは元の値("(入力必須)"/Null/Null)に書き
戻す、という処理を行います。
(この「元の値に書き戻す」という処理は、フォームを開く際にも行うようにして
おくと、何らかのエラーでAccessが落ちた場合に「前回入力中だったものが
表示された」といった事態を防げます)
※正規テーブルへの転記を、フォームを閉じる時に行う場合は、明示的に
レコードの保存を行ってから、としておいた方が無難です。
なお、前回回答時は、データベースが「フロントエンド/バックエンド」の構成
(バックエンド側に正規テーブルのみを設置。フロントエンドはそのテーブルに
対するリンクテーブルと作業テーブル、フォームなどを設置)で、フロントエンド
は各ユーザーの端末、バックエンドはLAN上などで共有、との先入観(汗)から
「1レコード」としましたが、「フロントエンド/バックエンド」に分割せずに、複数
のユーザーが同時に新規登録をしうる運用をしている場合は、ユーザーの
数だけレコードを用意すると共に、それぞれの端末用であることを特定する
ためのフィールドを作業テーブルに追加する必要がありましたので、注意して
ください(汗)
※フロントエンド/バックエンドに分割済みで、作業テーブルを端末側(ローカル)
に設置している場合は、ユーザー間の競合はないので、1レコードでOk。
(1つの端末内で新規レコードを同時登録しない前提:普通はしないはず)
例えば、ユーザーが3人(鈴木/佐藤/田中)がいた場合は、作業テーブルの
フィールド構成を
氏名 / 生年月日 / 性別 / ユーザー名
とした上で、
"(入力必須)" / Null / Null / "鈴木"
"(入力必須)" / Null / Null / "佐藤"
"(入力必須)" / Null / Null / "田中"
の3レコードを保存しておき、それぞれの端末ではユーザー名の合致するもの
1件を作業用として使用する、ということになります。
(1件を抽出するクエリを作成して、メインフォームのレコードソースにはこのクエリ
を指定、と)
※端末の情報を取得するには、Environ関数が使用できます:
http://office.microsoft.com/ja-jp/access-help/HA …
http://www.moug.net/tech/exvba/0150086.html
(「Environ("UserName")」により、Windowsの『システムのプロパティ』の
『使用者』の名前が取得できます)
・・・なのですが、改めて手元のAccess2007のクエリでこの関数を使用して
みたら「未定義の関数」とのエラーが出ましたので(汗)、以下のユーザー定義
関数を用意しておき、クエリの抽出条件ではこちらを使用して下さい。
(VBA上では、Environ関数をそのまま使用できます)
Public Function ExEnviron(Parameter As Variant) As Variant
ExEnviron = Environ(Parameter)
End Function
・・・以上です。
長文、失礼致しました(汗)
No.8
- 回答日時:
横レス失礼致します。
> 1項目入力後、次の新規ページができます。
(中略)
> これを防ぎたいと考えています。
フォームの『追加の許可』(AllowAdditions)プロパティが「はい」(True)になっている
限り、新規追加を行うと、新たに新規レコードが生成されてしまうため、ご希望の
動作にはなりません。
表示レコードを1件に限定してよい(=レコード移動をしない)前提であれば、以下の
3つの代替案が提示できます:
a)メインフォームを非連結(=『レコードソース』(RecordSource)プロパティが空白の
フォーム)にした上で、クエリ(又はSQL)を使用して、テーブルにレコードを登録する
(各コントロールの『コントロールソース』プロパティも空白にする必要があります)
b)新規登録専用の作業テーブルを別途作成して1件だけレコードを登録しておき、
メインフォームのレコードソースとするとともに、フォームの『追加の許可』プロパティ
を「いいえ」に設定することで、メインフォームの表示を1レコードに限定する
(「a」案と同様に、正規のテーブルへの登録はクエリ(又はSQL)を使用)
c)現在のテーブルに「新規登録用」のレコードを予め用意しておき、メインフォーム
ではこのレコードのみを表示します(→「b」と同様に『追加の許可』プロパティを
「いいえ」にした上で、このレコードのみを抽出するクエリを新規作成し、フォーム
の『レコードソース』プロパティに使用)。
レコード確定時には、このレコードの主キーをクエリ(又はSQL)で書き換えると
ともに、改めて「新規登録用」のレコードを追加。
(メインフォームのテーブルとサブフォームのテーブルとの間のリレーションシップに
『参照整合性』が設定されている場合は、「連鎖更新」も許可する必要あり)
「a」の場合、メインフォームはレコードを表示しているわけではなくなるので、マウス
ホイールでのレコード移動は、原理的に発生しなくなります。
これは、1レコードのみの追加・編集を行う場合に一般的と思われる手法ですが、
入力規則や値要求がフィールドに設定されている場合、そのチェックを行うコードが
必要(=入力規則等の変更に合わせてメンテが必要)なのが、やや面倒です(汗)。
「b」と「c」の場合は、どちらも表示レコードが1件のみ(本当の新規レコードは表示
されない)となるので、マウスホイールを回した場合の移動先がなくなります。
この方法の利点は、「a」と違って連結フォームのため、テーブルに設定されている
現状と同様に、入力規則などはテーブルからフォームに引き継がれることです。
なお、メインフォームのテーブルとサブフォームのテーブルの間にリレーションシップを
設定していて、『参照整合性』を持たせている場合、「a」「b」ではサブフォームに
レコードを追加する前に、クエリ(SQL)による転記(保存)を実行する必要があります。
(専用のコマンドボタンを設置してもいいですし、ユーザーに意識させないという意味
ではサブフォームコントロールのフォーカス取得時イベントでやってしまう手もあります:
DoCmd.OpenQueryでやる場合、クエリ実行時の確認メッセージを非表示にする
には、「DoCmd.SetWarnings False」を実行します(クエリ実行後に「~ True」を
実行する必要あり)。なお、DoCmd.RunSQLを使用すればDoCmd.SetWarnings
は実行不要です)
・・・「c」は、ややトリッキーなので(汗)、若干追加説明しておきます。
仮に、現在のメインフォームのレコードソースにしているテーブルの主キーが「ID」で、
その最小値が「1」だったとします。
ここに、「新規追加用」としてIDが「0」のレコードを追加します。
そして、このレコードのみを抽出するクエリを新規作成して、メインフォームのレコード
ソースとします。
そして、上記の通り、フォームの『追加の許可』を「いいえ」とします。
これで、メインフォームが表示するのは「ID=0」のレコード1件となります。
ユーザーは、このレコードに、新規で追加するはずのデータを上書きします。
(サブフォームでも一時的に「ID=0」で登録するため、「a」「b」のようにメインフォーム分
だけで一旦保存する必要はなくなります)
その上で、全ての入力が終わったら、ユーザーには『保存』ボタンを押してもらいます。
このボタンには、
・「ID」を、本来の値(=例えば「現在のIDの最大値」+1)で上書きする更新クエリ
(メインフォーム/サブフォームとも)
・「ID=0」のレコードを改めて追加する追加クエリ
を実行するコードを記述しておきます。
(メイン/サブの間のリレーションシップで参照整合性を設定している場合は、「連鎖
更新」も有効にしてやれば、メイン側のIDの更新と同時に、サブ側も更新されます)
また、『取り消し』ボタンも設定しておき、
・「ID」以外のフィールドをすべてNullにする更新クエリ
を実行するコードを記述します。
(主キー以外に『値要求』が「はい」に設定されたフィールドがある場合は、「ここは
値必須」などをデフォルト値として設定するといった工夫が必要)
更に、フォームの読み込み解除時イベントでも、このレコードの保存/破棄を確認・
実行するコードを記述します。
・・・概略だけにもかかわらず長くなりましたが(汗)、以上です。
どれにするにしてもかなり手間が掛かりますので、参考までにということで・・・(汗)

ありがとうございます。現状からB案を考えています。
「new_data」という入力専用テーブルのレコードソースとしています。
フォーム終了時にクエリにて、他のテーブルへ追加登録できるような
設計です。
B案 では、フォームの『追加の許可』プロパティ
を「いいえ」にするようになっていますが、これによって、フォームは
は表示されなくなります。(コマンドボタン、ラベルのみ)
テーブルに「1件だけレコードを登録しておく」とは、どのようなことでしょうか。
よろしくおねがいします。
No.7
- 回答日時:
#4です
遅くなりましたが、解決されていたでしょうか。
> ただ、フォーム内のサブフォームにフォーカスを移動することが出来ません。
サブフォームがあったんですか・・・
サブフォームがある場合、メインのレコードを確定させてからサブに移動しようとします。
サブからメインの場合も、サブを確定させてからメインに・・・
厄介なものになりますが・・・以下、メインの「タイマ時」を使う方法となります。
マウスのホイールをいじってから更新前処理が動くのを利用します。
ホイールをいじった時、編集中であったら、
・更新前処理で Cancel = True を設定する為の変数 bCancel を True とします。
・bCancel が True の間はレコードがスクロールすることはなくなります。
・この bCancel を False にするために「タイマ時」を利用します。
以下例では、20 ms を 5回まわったら False にしています。
ホイールのイベントと、タイマ時のイベントがどのタイミングで発生するか・・・
詳細に検証したわけではないので、5回まわる途中でホイールのイベントが発生しても、その段階からさらに5回まわるようになります。
20 ms * 5 = 100 ms になりますが、100 ms を超えると思います。
(あくまでこの数値は目安です)
・時間が経過し bCancel が False になると、サブフォームに移ることが出来るようになります。
その際には、前述したようにメインのレコードは確定されます。
※ レコードをいじっていない状態でホイールをいじると、レコードはスクロールされます。
以下がメインに記述する例になります。
Dim bCancel As Boolean
Dim iCnt As Integer
Private Sub Form_Timer()
iCnt = iCnt - 1
If (iCnt <= 0) Then
Me.TimerInterval = 0
bCancel = False
End If
End Sub
Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long)
If (Me.Dirty) Then
bCancel = True
iCnt = 5
Me.TimerInterval = 20
End If
End Sub
Private Sub Form_Load()
bCancel = False
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = bCancel
End Sub
※ 上記は動きを説明する部分しか記述していません。
(Docmd.GoToRecord 等は追加してください)
※ 以下も参考になると思います。
MouseWheel イベントの使い道
http://www.f3.dion.ne.jp/~element/msaccess/AcTip …
No.5
- 回答日時:
お礼
ありがとうございます。
結果的には、ダメです。
一項目にデータを入れた瞬間、下に新規ページが作成されます。
なにかいい方法がないでしょうか。
--------------------------------------------------------------------------
テキストボックスの 全てのタブストップ(その他タグ内)が「いいえ」になっていると
[Enter]で新規レコードになります。
尚、タブストップが「はい」になっていると[Enter]でタブ移動順にカーソルが移動し、
最後の移動順のボックスで[Enter]により新規レコードになります。
No.4
- 回答日時:
以下が参考になると思います。
マウスホイールでレコード移動しないようにする
http://hatenachips.blog34.fc2.com/blog-entry-162 …
なお、フォームが新規入力専用なのであれば、
フォームのプロパティ「データ入力用」を「はい」としておけば、
Form_Load での記述はいらないと思います。
さらに、常に新規入力だけにしたい場合には、更新後処理で
Private Sub Form_AfterUpdate()
Me.Requery
End Sub
のようにすると、連続して入力した場合でも、前に戻ることはできなくなります。
更新後処理でなくても、「登録ボタン」の処理で Me.Requery すれば良いと思います。
この回答への補足
マウスホイールを無効
Private Sub Form_BeforUpdate(cancel As Integer)
cancel = True
End sub
で確かに、マウスホイールが無効になりました。
ただ、フォーム内のサブフォームにフォーカスを移動することが出来ません。
初心者ですので対応を教授ください。
お願いします
ありがとうございます。
Form_Load には、表示サイズ、位置も指定するようにしているため、
ついでに Docmd.GoToRecord,, acNewRec
も記載して運用しています。
Private Sub Form_AfterUpdate()
Me.Requery
End Sub では元に戻れませんね。
連続入力することはありませんので、一回(1件)だけの入力と
考えていただけませんでしょうか。
よろしくお願いします。
マウススクロールで移動させないモジュールは一度試してみます。
No.2
- 回答日時:
フォームではなくテーブルです。
フィールドの値要求を「はい」にするには
テーブルを右クリックしてデザインビューで開き
添付のように
[フィールドの一つ(生徒名)]→[値要求の右端]→[はい]
と進みます。

ありがとうございます。
テーブルで項目のプロパティで、値要求を「はい」または空文字列の許可を「いいえ」にしてみました。確かに有効ですが。
しかし、全て項目が必ずしも値が必要なく、場合によっては空白でいいのです。
したがって、この設定では運用上このましくありません。
他の案がありましたら宜しくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Access(アクセス) Access IF文でテーブルに存在しない場合の処理について 2 2022/10/10 18:09
- Visual Basic(VBA) Accessフォームで全レコードを指定のExcelのセルへ転送し印刷する方法について 2 2022/09/08 18:23
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Visual Basic(VBA) ExcelからAccessのテーブルに書き込む時に時間がかかる 1 2022/10/14 20:38
- Access(アクセス) アクセスの更新クエリでカレントレコードのみ更新したい 1 2022/06/02 23:32
- Access(アクセス) DoCmd.SearchForRecord が動かない時の解決方法 3 2022/07/22 15:31
- Access(アクセス) チェックボックスにチェックが入った後の挙動 1 2022/08/21 12:39
- その他(データベース) Accessフォームからパラメーターで表示したレコードを指定のExcelのセルへ転送する方法について 2 2022/08/22 18:04
- Visual Basic(VBA) access count数を変数に格納 2 2022/03/30 19:21
- Access(アクセス) Accessでセレクタをダブルクリックで別フォームで詳細表示 3 2022/12/20 10:36
このQ&Aを見た人はこんなQ&Aも見ています
-
選択したチェックボックスのみチェックを入れたいのですが
その他(データベース)
-
ACCESSのフォームで次のレコードに移動しない方法を教えてください
その他(データベース)
-
レコードを保存するコード アクセスvba
その他(Microsoft Office)
-
-
4
Access フォームのテキストボックスに半角英字のみで入力する設定は
Access(アクセス)
-
5
access テキストボックスの値取得
Access(アクセス)
-
6
Access サブフォームでの選択行の取得
その他(データベース)
-
7
ACCESSのフォームからデータの追加ができない
その他(データベース)
-
8
フォームを開くときに、コンボボックスの値を選択(アクセスVBA)
Visual Basic(VBA)
-
9
ACCESSで空白のデーターをクエリで判定/識別する方法を教えてくださ
Access(アクセス)
-
10
access2000:フォームで入力した内容を新規レコードにコピー
その他(データベース)
-
11
Accessのマクロでモジュールを実行させたい。
Access(アクセス)
-
12
VBとアクセスでSQL文に変数を使いたいのですが
Visual Basic(VBA)
-
13
アクセスでフォームビューがみれません?
Access(アクセス)
-
14
アクセスのフォームで、文字を中央揃えにしたい
Access(アクセス)
-
15
Accessで重複データを入力できないようにしたい。
PowerPoint(パワーポイント)
-
16
Accessで、フォームからフォームへ値を引き継ぐやり方
Access(アクセス)
-
17
accessで該当するレコードがない場合
その他(プログラミング・Web制作)
-
18
Access 別フォームへの再クエリ(更新)がしたい。
その他(データベース)
-
19
Access 既に開いているフォームへの値渡し
その他(Microsoft Office)
-
20
ポップアップと作業ウィンドウ固定の違いは
Access(アクセス)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
レコードを保存するコード ア...
-
アクセスでフォームビューがみ...
-
アクセス:フォーム入力で、最...
-
ACCESS起動時に所定フォームを...
-
レコード削除時に(サブ)フォー...
-
アクセスの自動保存解除はでき...
-
アクセス データの競合を非表...
-
Access データのないフォーム...
-
Access2010、値を入力したら自...
-
Accessでのデータ消滅に...
-
ACCESSのクエリで抽出したデー...
-
新規レコード行を非表示にしたい
-
アクセスのフォームとクエリの...
-
AccessVBA RecordSourceのリセ...
-
アクセス 前レコード内容を、...
-
ACCESSでフォームを使って、テ...
-
Access非連結フォームから複数...
-
Accessでフォーム上に 直前の...
-
フィルタ後のフォームの件数の...
-
アクセス帳票フォームのループ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
レコードを保存するコード ア...
-
新規レコード行を非表示にしたい
-
アクセスでフォームビューがみ...
-
レコード削除時に(サブ)フォー...
-
Accessで上の行を自動でコピー...
-
AccessVBA RecordSourceのリセ...
-
アクセスのフォームで立ち上げ...
-
ACCESSフォームのリストボック...
-
アクセスの自動保存解除はでき...
-
アクセス:フォーム入力で、最...
-
Accessで一件の新規レコードの...
-
フィルタ後のフォームの件数の...
-
アクセス データの競合を非表...
-
Access:フォームプロパティ「...
-
Access2010、値を入力したら自...
-
レコードをダブルクリックする...
-
Accessでのデータ消滅に...
-
ACCESSでフォームを使って、テ...
-
Accessでフォーム上に 直前の...
-
アクセスでの警告について教え...
おすすめ情報