Microsoft Access 掲示板

ダイアログのフォームにあるテキストボックスに値を格納したい

25 コメント
views
4 フォロー

いつもお世話になっております。
「F_依頼一覧」のテキストボックス「fld_依頼ID」をダブルクリックすると、
その値が「F_依頼入力」のテキストボックス「txt_依頼ID」に格納されるように
しています。(下記の文です)

Private Sub fld_依頼ID_DblClick(Cancel As Integer)

  DoCmd.OpenForm "F_依頼入力", acNormal
  Forms![F_依頼入力]![txt_依頼ID].Value = Me.fld_依頼ID.Value

End Sub

ところが、ダイアログ(acDialog)にすると格納されず
「実行時エラー '2450': 参照されているフォーム・・・が見つかりません。」
となって、Forms![F_依頼入力]![txt_依頼ID].Value = Me.fld_依頼ID.Value が
黄色くなってしまいます。

Private Sub fld_依頼ID_DblClick(Cancel As Integer)

  DoCmd.OpenForm "F_依頼入力",,,,, acDialog
  Forms![F_依頼入力]![txt_依頼ID].Value = Me.fld_依頼ID.Value

End Sub

ご教授頂けたら幸いです。
よろしくお願いします。

wazawaza
作成: 2023/06/15 (木) 17:43:06
通報 ...
1

acDialog(ダイアログモード)にすると、そのフォームを閉じるか非表示になるまで、次の行のコードは実行されません。
つまり、次の行の
Forms![F_依頼入力]![txt_依頼ID].Value = Me.fld_依頼ID.Value
が実行されるときには、[F_依頼入力]は既に閉じているので、「見つかりません。」というエラーになります。

対処法としてはいろいろありますが、OpenArgs引数で値を渡して、フォームの開くときイベントで代入する方法ですね。

Private Sub fld_依頼ID_DblClick(Cancel As Integer)
   DoCmd.OpenForm "F_依頼入力", , , , , acDialog, Me.fld_依頼ID.Value`
End Sub

F_依頼入力 の開くときイベント

Private Sub Form_Open(Cancel As Integer)
    Me.[txt_依頼ID].Value = OpenArgs
End Sub
2

hatenaさん、ありがとうございます!
ご提案頂いたコードを入力しましたが、
ダブルクリックしたIDは代入されませんでした。

3

「F_依頼入力」フォームをデザインビューで開いて、プロパティシートのイベントタブの「開くとき」に
[イベント プロシージャ]
と設定されてますか。
もし、設定されていない場合は、ドロップダウンリストから選択して設定してください。

次に、「開くとき」のビルドボタン[...]をクリックして、下記のコードが表示されるか確認してください。

Private Sub Form_Open(Cancel As Integer)
    Me.[txt_依頼ID].Value = OpenArgs
End Sub

下記のように表示されていたら、上記のようになるように真ん中にコードを入力してください。

Private Sub Form_Open(Cancel As Integer)

End Sub

これで、IDが代入されるはずです。

4
wazawaza 2023/06/16 (金) 00:21:10

hatenaさん、早速ご対応頂きありがとうございます。
ご指摘のところを、何度も確認しましたが、
変化がありません。

「F_依頼一覧」の「fld_依頼ID」でのダブルクリックのイベントプロシージャは

Private Sub fld_依頼ID_DblClick(Cancel As Integer)
   DoCmd.OpenForm "F_依頼入力", , , , , acDialog, Me.fld_依頼ID.Value
End Sub

に、入力ミスはありますか?
何度もスミマセン。

5
wazawaza 2023/06/16 (金) 07:38:32

hatenaさん
チョット変化しましたので報告します。
ココが原因なのかな?と薄々思っていたのですが...。

自動採番する仕組みとなっておりまして...

'##############################
'### レコード移動時のID採番 ###
'##############################

Private Sub Form_Current()

    Me.btn_最新ID取得.Enabled = True  '「btn最新ID取得」を使用可能に
    Me.btn_追加.Enabled = False       '「btn追加」を使用不可に(最新ID取得に導く仕掛け)
    
    Const prefix As String = "L"  '「Laminate」の頭文字 "L"
    
    Dim maxID As String
    maxID = DMax("fld_依頼ID", "T_依頼")  '最終IDを取り出す
    
    Dim lastNum As Long
    lastNum = Replace(maxID, prefix, "")  '最終IDから頭文字"L"を除き、数値型へ代入する
    
    Dim newID As String
    newID = prefix & Format(lastNum + 1, "000000")  '+1して桁を揃えて頭文字"L"と結合
    
    Me.txt_依頼ID.DefaultValue = "'" & newID & "'"  '既定値へ代入

End Sub

という具合になっていますが
試しに、ココに Me.[txt_依頼ID].Value = OpenArgs を入れると
採番は出来なくなる一方、fld_依頼IDをダブルクリックすると代入できる
ようになりました。

自動採番の機能を残しつつ、代入の方法はありますか?

6
hiroton 2023/06/16 (金) 08:51:44 dea3b@f966d >> 5

単純にForm_Currentを削除する(コメントアウトする)とどうなりますか?

7
wazawaza 2023/06/16 (金) 09:07:25

hilotonさん、ありがとうございます!
コメントアウトしたら、ダブルクリックで代入は
できましたが、採番が出来なくなりました。

8
hiroton 2023/06/16 (金) 09:56:30 dea3b@f966d

TextBox.Value プロパティ (Access)

TextBox.DefaultValue プロパティ (Access)

Microsfot公式でもわざわざ注釈をつけるくらいですが、valuedefaultvalueは別物です
提示されたコードを見る限りは表示が変わるようなことは考えられません
それでもForm_Currentが影響しているということであれば、

フォーム読み込み直後にレコード移動が実行され(Me!txt_依頼ID.Value=OpenArgsしたレコードは保存されて)、実際に表示されているレコードは「新規レコード」になっている

とかでしょうか

「F_依頼入力」のすべてのコードを削除してForm_Currentのコードだけにして試してみて下さい。もしくは、DoCmd.OpenFormのところからデバッグ作業で実際の動きを確認する必要があるでしょう

【超初心者向け】エクセルVBAでデバッグをする方法を解説します(経理・会計事務所向けエクセルスピードアップ講座さん)

9

このForm_Currentの自動採番のコードは、「F_依頼一覧」、「F_依頼入力」のどちらに記述されているものですか。

DoCmd.OpenForm "F_依頼入力", , , , , acDialog, Me.fld_依頼ID.Valueで開いたとき、カレントレコードはどうなってますか。既存レコードですか。新規レコードですか。

とりあえず、上記の点を明確にしてください。

10

ちなみに、フォームを開いたとき、
Form_Open → Form_Load → Form_Current の順でイベントが発生することは念頭に置いてコーディングする必要があります。

11
wazawaza 2023/06/16 (金) 11:34:52

hirotonさん、Form_Currentだけ残したところ、
ダブルクリックしても採番されたIDが代入されました。

それから、hatenaさんから提案して頂いた

Private Sub Form_Open(Cancel As Integer)
    Me.[txt_依頼ID].Value = OpenArgs
End Sub

Me.[txt_依頼ID].Value = OpenArgsにブレイクポイントを置き
「L000004」をダブルクリックすると、Me.[txt_依頼ID].Value が最新IDの「L000005」
OpenArgs が「L000004」となっていました。

12
wazawaza 2023/06/16 (金) 11:44:56

hatenaさん、
Form_Currentの自動採番のコードは「F_依頼入力」に記述してあります。
また、DoCmd.OpenForm "F_依頼入力", , , , , acDialog, Me.fld_依頼ID.Value
「F_依頼一覧」に掲載されている既存レコードです。

「F_依頼入力」を使って、新規レコードを追加することが出来つつ
既存レコードの内容も表示できるようにしたいのです。
今回は、その既存レコードのIDを代入するにあたり、苦戦しております。

またイベント順は、hatenaさんの書いている通りになっていると思います。

13
hiroton 2023/06/16 (金) 12:02:27 dea3b@f966d

とりあえず

「F_依頼入力」を使って、新規レコードを追加することが出来つつ
既存レコードの内容も表示できるようにしたいのです。

これは質問の表題からかけ離れた全く別の内容ですね。これはこれでそれ用の対応が必要でしょう(今やり取りしている対応とは全く別に対応する必要がります)


「L000004」をダブルクリックすると、Me.[txt_依頼ID].Value が最新IDの「L000005」
OpenArgs が「L000004」となっていました。

この結果、実際には「txt_依頼ID」になにが表示されていますか?「L000004」が表示されていないと思ってhirotonは回答してますが合っていますか?

14
wazawaza 2023/06/16 (金) 12:14:33

hirotonさん、

>これは質問の表題からかけ離れた全く別の内容ですね。

あら、そうなんですね😅
私は、それが目的で代入したくていたのですが、
対処方法がまったく別になってしまうとは…。
上手く伝えられず、申し訳ないです💦

「L000004」を表示したいのです!
hirotonさん、その通りです!

15

既存レコードの内容も表示できるようにしたいのです。
今回は、その既存レコードのIDを代入するにあたり、苦戦しております。

OpenFormしたときに他に何もしていなければ、先頭レコードが表示されています。
そこで、
Me.[txt_依頼ID].Value = OpenArgs
としたら、先頭レコードのIDが上書きされてしまいます。
ご希望のことはそれではないですよね。(通常主キーは上書きしないものです)

ご希望のことは、「F_依頼一覧」で選択したレコードと同じIDのレコードを表示したい、ということではないですか。
もし、そうなら、開く時にそのIDでフィルターをかければいいだけです。

Private Sub fld_依頼ID_DblClick(Cancel As Integer)
   DoCmd.OpenForm "F_依頼入力", , , "依頼ID='" & Me.fld_依頼ID.Value & "'", , acDialog
End Sub

依頼ID はレコードソースのフィールド名にしてください。

そうでないなら、もう少しやりたいことを詳細に説明してください。

16
wazawaza 2023/06/16 (金) 14:10:57

hatenaさん、まさにそれがしたのです!
レコードソースは「T_依頼」にある「fld_依頼ID」です。
ちなみに、ダブルクリックをする「F_依頼履歴」のレコードソースは
「T_依頼」の選択クエリ「Q_依頼履歴」で、「F_依頼入力」は非連結です。

で、下記を記述して実行したところ
「フォームまたはレポートがテーブルまたはクエリを基に作成されていないため、
このアクションまたはメソッドは無効です」と出現し、黄色くなりました。

DoCmd.OpenForm "F_依頼入力", , , "T_依頼.fld_依頼ID='" & Me.fld_依頼ID.Value & "'", , acDialog
17

「F_依頼一覧」のテキストボックス「fld_依頼ID」をダブルクリックすると、
その値が「F_依頼入力」のテキストボックス「txt_依頼ID」に格納されるように
しています。

ちなみに、ダブルクリックをする「F_依頼履歴」のレコードソースは
「T_依頼」の選択クエリ「Q_依頼履歴」で、「F_依頼入力」は非連結です。

「F_依頼履歴」って初めて出てきましたが、最初の「F_依頼一覧」というのはタイプミスしたということでしょうか。

あと、
「F_依頼入力」は非連結ということは、「F_依頼入力」のレコードソースは空欄ということですよね。
だとすると、話はまったく違ってきます。

「F_依頼履歴」の特定のレコードのIDをダブルクリックしたら、そのIDのレコードデータを非連結フォームの「F_依頼入力」に入力したいということですか。
非連結にしたい理由はなんでしょうか。

合理的な理由がなければ、連結フォームにするのをお勧めします。
そうすれば、

DoCmd.OpenForm "F_依頼入力", , , "fld_依頼ID='" & Me.fld_依頼ID.Value & "'", , acDialog

で解決するはずです。

18
wazawaza 2023/06/16 (金) 18:31:46

hatenaさん、

私のタイプミスです。
正しくは「F_依頼履歴一覧」です。
紛らわしくしてしまい、申し訳ありません。

「F_依頼入力」は非連結ということは、「F_依頼入力」のレコードソースは空欄ということですよね。
だとすると、話はまったく違ってきます。
「F_依頼履歴」(正:F_依頼履歴一覧)の特定のレコードのIDをダブルクリックしたら、
そのIDのレコードデータを非連結フォームの「F_依頼入力」に入力したいということですか。
非連結にしたい理由はなんでしょうか。

はい、「F_依頼履歴一覧」のレコードデータを、非連結「F_依頼入力」に入力したいと考えています。

非連結にしたい理由は、このフォームを最大15人が同時操作する可能性があり、
操作する中には、パソコンが苦手な人やAccessを初めて触る人など、多様な方が多い環境の中で、
所有する本で目にした下記の一文とサンプル例が、“まさに”その環境にマッチしていたのです。

連結フォームだと入力した時点で即反映され、入力途中のキャンセルが面倒

ちょうど1年前にも非連結で躓いて、こちらでアドバイスをいただき、結果
連結フォームにする事で解決することが出来ました。その後も、細々とではありますが
VBAやSQLなどを勉強して、今回の設計に至りました。

今回は上記の理由もあって、色々と記述には苦労しましたが、なんとかゴール目前まで辿り着けています。
あとはココだけ解決できれば、昨年躓いた計画もようやく完成するのです。
背伸びし過ぎているかもですが、完成させて自信に繋げたいと考えています!

19

非連結にしたい理由は、このフォームを最大15人が同時操作する可能性があり、

そうであるなら、非連結も一つの手段だとは思います。

確認ですが、「最大15人が同時操作」ですが、下記はありえますか。
同じテーブルに対して、複数ユーザーが同時に新規レコード入力
同じテーブルの同じレコードに対して、複数ユーザーによる閲覧、更新、削除の各操作が同時に発生する

上記が発生することがあるなら、非連結で行く場合、これらの制御はかなり難易度が高いですよ。
連結でも、危険性は高いです。
SQLサーバーとかの本格的なデータベースの導入を検討する段階かもしれません。こうなるとさらなるスキル、コストが必要にはなりますが。

===
現状の疑問点は、
非連結「F_依頼入力」で、自動採番のコードがあるということは、これは新規レコードを入力する場合の処理ですよね。
また、「F_依頼履歴一覧」フォームのダブルクリックでそのレコードデータを、「F_依頼入力」に表示させて、そこで更新作業をすることですよね。
この異なる2つの処理(新規追加処理、更新処理)の切り替えはどのようにしているのでしょうか。


とりあえず、「F_依頼履歴一覧」でダブルクリックしたレコードデータを「F_依頼入力」に表示させるコードは下記になります。

'F_依頼入力 の開くときイベント
Private Sub Form_Open(Cancel As Integer)
    Dim fld As DAO.Field
    With Forms!F_依頼履歴一覧.RecordSet
        For Each fld In .Fields
            Me(fld.Name).Value = fld.Value
        Next
   End With
End Sub

「F_依頼入力」上のテキストボックスの名前は、「F_依頼履歴一覧」のレコードソースのフィールド名と同じになっていると仮定した場合のコードです。

非連結だと、入力した後、レコード保存するコードも必要になります。「F_依頼履歴一覧」からダイアログモードで開いているなら、「F_依頼履歴一覧」のレコードセットを直接更新するのが手っ取り早いですね。

'更新ボタンのクリックイベント
Private Sub 更新_Click()
    Dim fld As DAO.Field
    With Forms!F_依頼履歴一覧.RecordSet
        .Edit
        For Each fld In .Fields
            fld.Value = Me(fld.Name).Value
        Next
        .Update
   End With
End Sub

非連結なので、入力値チェック、リンクテーブルがある場合の整合性のチェック、複数ユーザー同時入力に対する排他制御、すべて自前で処理を構築する必要があります。

20
wazawaza 2023/06/17 (土) 18:29:01

hatenaさん、ありがとうございます。

早速試してみましたが「オブジェクトが必要です」...😅

まず、ダブルクリックするのは「F_依頼履歴一覧」の「fld_依頼ID」。
その「fld_依頼ID」の値の代入先は、
「F_依頼入力」の「txt_依頼ID」です。

追加・更新・削除・読込はなんとか動いております。

非連結の「F_依頼入力」の関連していると思われる記述の全体です。


'##################################
'### btn_最新ID取得をクリックした時 ###
'##################################

Private Sub btn_最新ID取得_Click()

  Me.btn_最新ID取得.Enabled = True  '引続き最新IDを取得するため「btn最新ID取得」は使用可能に
  Me.btn_追加.Enabled = True        '最新IDを取得後を条件に「btn追加」を使用可能に
    
  Const prefix As String = "L"  '「Laminate」の頭文字 "L"
    
  Dim maxID As String
  maxID = DMax("fld_依頼ID", "T_依頼")  '最終IDを取り出す
    
  Dim lastNum As Long
  lastNum = Replace(maxID, prefix, "")  '最終IDから頭文字"L"を除き、数値型へ代入する
    
  Dim newID As String
  newID = prefix & Format(lastNum + 1, "000000")  '+1して桁を揃えて頭文字"L"と結合
    
  Me.txt_依頼ID.DefaultValue = "'" & newID & "'"  '既定値へ代入
    
End Sub

'############################
'### btn_新規をクリックした時 ###
'############################

Private Sub btn_新規_Click()

Const prefix As String = "L"  '「Laminate」の頭文字 "L"
    
    Dim maxID As String
    maxID = DMax("fld_依頼ID", "T_依頼")  '最終IDを取り出す
    
    Dim lastNum As Long
    lastNum = Replace(maxID, prefix, "")  '最終IDから頭文字"L"を除き、数値型へ代入する
    
    Dim newID As String
    newID = prefix & Format(lastNum + 1, "000000")  '+1して桁を揃えて頭文字"L"と結合
    
    Me.txt_依頼ID.DefaultValue = "'" & newID & "'"  '既定値へ代入
    
    Call initializeForm
    
End Sub

'######################
'### hatenaさんのコード ###
'######################

Private Sub Form_Open(Cancel As Integer)

  Dim fld As DAO.Field
    With Forms!F_依頼履歴一覧.Recordset
        For Each fld In .Fields
            Me.txt_依頼ID.Value = fld_依頼ID.Value
        Next
   End With
   
End Sub


'##########################
'### レコード移動時のID採番 ###
'##########################

Private Sub Form_Current()

    Me.btn_最新ID取得.Enabled = True  '「btn最新ID取得」を使用可能に
    Me.btn_追加.Enabled = False       '「btn追加」を使用不可に(最新ID取得に導く仕掛け)
    
    Const prefix As String = "L"  '「Laminate」の頭文字 "L"
    
    Dim maxID As String
    maxID = DMax("fld_依頼ID", "T_依頼")  '最終IDを取り出す
    
    Dim lastNum As Long
    lastNum = Replace(maxID, prefix, "")  '最終IDから頭文字"L"を除き、数値型へ代入する
    
    Dim newID As String
    newID = prefix & Format(lastNum + 1, "000000")  '+1して桁を揃えて頭文字"L"と結合
    
    Me.txt_依頼ID.DefaultValue = "'" & newID & "'"  '既定値へ代入
        
End Sub
21
hiroton 2023/06/17 (土) 23:16:24 49b34@2ee8f

「F_依頼入力」は非連結です。

'##########################
'### レコード移動時のID採番 ###
'##########################

Private Sub Form_Current()

非連結のフォームでなぜForm_Currentを使っているんでしょう?
「レコード移動時」とはいったいどのような状態を想定しているのでしょう?

DefaultValueの使い方についてもなぜそうしているのか疑問に思う使い方です

何となくバックグラウンドが透けて見えますが、このままだといずれ破綻しますよ(というかたぶんすでに破綻してる)
主題に絞らず「F_依頼履歴一覧」のつくりから全部見直す必要があると思います


所有する本で目にした下記の一文とサンプル例が、“まさに”その環境にマッチしていたのです。

連結フォームだと入力した時点で即反映され、入力途中のキャンセルが面倒

ホントにこんなこと書いてある本あるんですかね。hirotonならそんな本破り捨ててしまえと言いますね

22

早速試してみましたが「オブジェクトが必要です」...😅

For Eachなど、コードの意味は理解できていますか。というか理解できていないですね。
一覧フォームのダブルクリックしたレコードのデータを転記するコードのサンプルを紹介しましたが、
ちょっと先走りすぎたようです。
前回の回答のコードはスルーしてください。


追加・更新・削除・読込はなんとか動いております。

提示されているコードを見る限り、おそらくいろいろなところのコードを参考にしているのだと思われますが、コードの意味やフォームの仕様をきちんと理解できていない部分が散見されます。(hirotonさんも指摘しているForm_Currentで自動採番しているところとか)

追加 と 更新 はまったく異なる処理になりますが、それはどのように場合分けしてますか。

まず、ダブルクリックするのは「F_依頼履歴一覧」の「fld_依頼ID」。
その「fld_依頼ID」の値の代入先は、
「F_依頼入力」の「txt_依頼ID」です。

まず、この目的ですが、どのような処理を目指しいるのでしょうか。
「F_依頼入力」の「txt_依頼ID」が入力できたらそれで終わりですか。
それだけではないですよね。

それだけであるなら、最初の私の回答のコードでできるはずです。
できないということは、コードがどこか間違っているか、他の部分の影響でできないのか、、、、なのだと思います。
それの原因を探すには、デバッグ作業というのが必要になります。
もし、非連結でいくのなら、で、「最大15人が同時操作」という運用なら、それぐらいのことができるスキルは必要です。
それができないなら、いずれ破綻するでしょう。

23
wazawaza 2023/06/18 (日) 18:41:38

非連結のフォームでなぜForm_Currentを使っているんでしょう?
「レコード移動時」とはいったいどのような状態を想定しているのでしょう?DefaultValueの使い方についてもなぜそうしているのか疑問に思う使い方です

おそらくいろいろなところのコードを参考にしているのだと思われますが、コードの意味やフォームの仕様をきちんと理解できていない部分が散見されます。

お二人の推察通りです。
2冊の本を参考に、うち1冊で「F_依頼入力」を。
残る1冊で「F_依頼履歴一覧」を作りました。
ご指摘の採番に関しては、ネットから得たものを使用しました。

何となくバックグラウンドが透けて見えますが、このままだといずれ破綻しますよ(というかたぶんすでに破綻してる)

非連結でいくのなら、で、「最大15人が同時操作」という運用なら、それぐらいのことができるスキルは必要です。それができないなら、いずれ破綻するでしょう。

仕事とはいえ、身の丈にあっていないものに手を出したのだと後悔しています。
上司に掛け合って、計画の中止・見直しを考えてみます。

この度は、hirotonさん、hatenaさんには貴重の時間を割いていただき
大変申し訳無く思っております。こちらの掲示板を当てにし過ぎていました。
自戒の念を込めて、こちらの掲示板には暫く訪れないようにしたいと思います。
長々とお付き合い頂き、ありがとうございました。
失礼します。

24
hiroton 2023/06/18 (日) 23:15:10 8d8f7@2ee8f

この掲示板、大いに活用してもらっていいと思いますよ。ただ、ここは業務の請負の場ではないので、質問者には質問に見合ったレベルが求められます。レベル不足が発覚したのなら、まずはもっと低レベルの問題から解決していけばいいです
これについてはすでに「「F_依頼履歴一覧」のつくりから全部見直す」と挙げていますね。もう少し具体的にいえば「「F_依頼履歴一覧」での追加や更新を非連結フォームで行うようにするにはどうすればいいか?(○○までやったが不足はないか?)」というところからやっていけばいいと思います

少なくとも、「現状ではとてもACCESSの改修に手を付けられるレベルではない」ということが分かっただけでもこの掲示板を活用した価値はあるでしょう


仕事とはいえ、身の丈にあっていないものに手を出したのだと後悔しています。
上司に掛け合って、計画の中止・見直しを考えてみます。

個人的には「今からでもゆっくりやっていけばいいですよ」って思うんですけどね。まぁ現実はいろいろ甘くないですよね

外部委託するとどの程度の費用のものなのか、期間の猶予はどのくらいなのか、人材を育成する方向で進められるか、よく相談して蟠りなく解決できるといいですね

25
wazawaza 2023/06/19 (月) 00:37:15

hirotonさん、
暖かいお言葉、ほんとうにありがとうございます。
今回の失敗を糧に、自分を見つめ直してみます。