- ベストアンサー
VBAでサブフォームに自動的にデータを入力
- VBAを使用して、メインフォームとサブフォームを連携させ、サブフォームに自動的にデータを入力する方法を解説します。
- メインフォームには「工期自」「工期至」フィールドがあり、サブフォームには「請求予定日」フィールドが存在します。
- 工期期間中は毎月月末が請求予定日となります。ただし、「工期自」が入力されていない場合は、「工期至」の月の月末のみが請求となります。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
1・デバッグの件 >いろいろ試してみたのですが、デバッグ実行できませんでした の『いろいろ』の内容と、『デバッグ実行できませんでした』の詳細を知りたいところですが・・。 DoCmd.OpenForm "サブ", acFormDS, , "管理No='" & Me!管理No & "'", acFormEdit の行の次に、Stopと書き加えても止まります。 >フォーム自体にプログラムを書いているからでしょうか ではありません。 こちらの件は自力で頑張ってください。 2・サブフォームにデータを追加したい件。 追加したいレコードが一件なら大丈夫ですが複数の場合、 Accessから見ればサブフォームの各テキストボックスは単一のコントロールでしかないので Do ~ Loop処理しても自動的に次のレコードに追加してくれるわけでは有りません。 多分、提示されたコードが問題なく(Error が発生しなく)動いたとしても サブフォームには一件のレコードしか追加されません。 そこでレコードセットを開いて追加するか、追加クエリを行うかの選択肢になります。 テーブルやクエリの構造が不明なので今回はレコードセットを開きます。 ※~No. は全て ~No に変更しています。 最後にドット(.)が来るとAccessが誤解してオブジェクトのメンバーを探しに行ってしまう為。 テーブル・クエリ・フォーム・レポート・モジュールの全てを変更してください。 その他はコード内に変更点などをコメントで入れてます。行頭のシングルクォーテーション(') また下記コードは必要最小限の修正にありますので、望む結果が有られない場合もあります。 さらに未検証です。(文法的なエラーは無いはずです) 追伸、一般的にAccess で『サブフォーム』といえば、フォームの中に組み込まれた子フォームの ことを意味します。 Private Sub 工期至_Exit(Cancel As Integer) Dim SEIKYU As Date Dim TUKI As Integer Dim SYURYO As Integer Dim rsTo As Object '複写先レコードセット DoCmd.OpenForm "サブ", acFormDS, , "管理No='" & Me!管理No & "'", acFormEdit 'DoCmd.OpenForm "サブ", acFormDS, , "管理No=" & Me!管理No , acFormEdit '↑管理No が数値型ならこちらを Set rsTo = Forms!サブ.Form.Recordset '『サブ』フォームのレコードセット取得 If IsNull(Forms!サブ!請求書発行) Then If IsNull(Me!工期自) Then SEIKYU = Me!工期至 TUKI = Month([工期至]) Else SEIKYU = Me!工期自 TUKI = Month([工期自]) End If SYURYO = Month([工期至]) + 1 '↑ 12月に動かした場合にどこかで問題が発生しませんか?確認を Do Until TUKI = SYURYO rsTo.AddNew '新規レコード追加開始 rsTo!管理No = Me!管理No 'Forms!サブ!管理No. = "[forms]![メイン]![管理No.]" rsTo!請求書発行 = DateSerial(Year(SEIKYU), Month(SEIKYU) + 1, 0) 'Forms!サブ!請求書発行 = DateSerial(Year(SEIKYU), Month(SEIKYU) + 1, 0) rsTo.Update '新規レコード確定 SEIKYU = DateAdd("m", 1, SEIKYU) TUKI = Month(SEIKYU) Loop End If 'DoCmd.Close acForm, "サブ" '確認のため閉じない rsTo.Close: Set rsTo = Nothing End Sub
その他の回答 (1)
- nicotinism
- ベストアンサー率70% (1019/1452)
まずは、 >メインとサブは[管理No.]フィールドで繋がっています 『サブ』フォームはメインフォームの中に配置されているフォームなのですかね? 提示されたコードからは独立したフォームのように思えるのですが? 取りあえず、 ステップ実行して変数やコントロールの値を追って行ってみては? VBEの画面で適当な行でF9を押せば行が赤く変わります。 でモジュールを実行させるとその行で一旦止まりますので F8で1ステップずつ進めて行ってみてください。 カーソルをそれぞれの変数などに合わせると値が表示されます。 (メニューバーの『デバッグ』と『実行』のところのメニューもみてね) また、イミディエイトウィンドウで例えば ?Me.工期至 ででも確認できます。 此処まで確認してみては。 で問題が無かったならば。 次に、サブフォームは開いた当初、複数のレコードが表示されていて Do ~ Loop処理の中でそのレコードの更新を行いたいのですか? それともレコードを追加させたいのですか? ※Accessのバージョンは必ず記入しましょう! 当方Access2002なので期待に添えない場合も有ります。
補足
返信遅くなり申し訳ありません。 ご丁寧な回答をありがとうございます!! ●『サブ』フォームはメインフォームの中に配置されているフォームか?独立フォームか? 独立したデータシート型フォームが開くようになっています。 ●デバッグについて勉強不足でいろいろ試してみたのですが、デバッグ実行できませんでした。 クラスオブジェクトのフォーム自体にプログラムを書いているからでしょうか? その辺も最初から勉強してみます。 ●Do ~ Loop処理の中でそのレコードの更新したいのか?追加させたいのか? >>If IsNull(Forms!サブ!請求書発行) Then … ↑ここで、請求書発行が空白の場合のみ処理する(データを追加)ようにしています。 質問を投稿すると文章の行頭がそろってしまい(行頭スペースが消えた)見にくくてすいません! ●Accessのバージョン Access2003です。すいません記入漏れでした。 ●いろいろ試している中で、1回目の"工期至"フォーカス喪失時にはサブに"請求書発行"値は何も入らず、2回目実行時には思い通りに(工期4/1~9/30だと、4/30、5/31、6/30、7/31、8/31、9/30の6レコード)入った時がありました。 その後いろいろいじっていると今は2回目でも9/30しか入らなくなりました。 (変数に影響するプログラムの箇所は全く変えていないのに) このことから変数の値の取得は間違っていないのかなと思います。 サブフォームを開く時、レコードを追加する為に何らかのステップが必要なのかと悩んでいます。 何か分かりますでしょうか。どうぞ宜しくお願いします!
お礼
いろいろと試行錯誤していて返事が遅くなりました。すいません! 1・デバッグの件 デバッグしようとするとマクロのウィンドウが出てきて、そこにはプログラムの名前は一つも出てきていません。”キャンセル”しかクリックできないようになっていてそれ以降進めません。 ExcelでVBAを書いたときは標準モジュールに全てのプログラムが入り、そっちではデバッグできていたのですが…。 私はAccessでVBAを書くとき、プロパティのコードビルダからVBAを開いていたので、自動的にクラスオブジェクトのフォーム自体にコードが保存されました。それが正しいのだと思いいつもそこに記述していたのが悪いのか… 未だ不明です。 2・データ追加の件 ~No.のところは、"なんばー"と入力し変換して出るやつなので、ドットとして認識せず正しく動いています。ややこしいことしてごめんなさい。 AddNewを使って追加しなければならないことは理解しました。 教えていただいたコードを元に試行錯誤しましたが、私の力不足でうまくいかず、結局根本的に考え方を変えてデータベース自体作り変えることにしました。 (自動で請求日を追加しなくて良いように。もちろん一個ずつ手入力するわけでもありませんが。) "サブフォーム"という表現も誤って理解していて申し訳ありません。 結果的に私の力不足で解決できなかったのですが、いろいろな事を学ばせていただきました。 nicotinismさん、いろいろと考えていただいて本当にありがとうございます。 感謝しています!