Access2007で開発しています。
メインフォームにサブフォームを貼り付けており、
サブフォームに入力した「数量」「単価」から「金額」を計算して表示し、
その合計金額をメインフォームのテキストボックス(非連結)に表示しようと
しています。
サブフォームは行単位で追加、削除が可能です。
サブフォームの更新結果が正しくメインフォームに表示されずに困っています。
おわかりの方、おられましたらお教え頂きたく、よろしくお願い致します。
【サブフォーム】
・レコードソース:T_明細
・[詳細]項目:数量・・・レコードソース=T_明細・数量
単価・・・ 〃 =T_明細・単価
金額・・・数量および単価のAfterUpdateで計算して表示。
[フォームフッター]項目:金額計・・・コントロールソース=Sum([金額])
・Vbaコード:
Private Sub Form_AfterUpdate()
Forms![メインフォーム].合計計算
End Sub
Private Sub Form_Delete(Cancel As Integer)
Forms![メインフォーム].合計計算
End Sub
【メインフォーム】
・テキストボックス:「合計金額」(非連結)
Public Sub 合計計算()
Me.サブフォーム.Requery
方法1: Me!合計金額 =DSum("金額", "T_明細", (キー項目指定 記述省略))
方法2: Me!合計金額 = Me![サブフォーム].[Form].[金額計]
End Sub
ここで、
方法1の場合:数量、単価の変更入力及び行追加は正しく動作するが、
行削除の後、メインフォームの「合計金額」が再計算されず、変更前のまま。
方法2の場合:数量、単価の変更入力及び行追加すると、「合計金額」が”0”になる。
行削除しても「合計金額」は変わらず、変更前のまま。
どちらも、サブフォオームの「金額計」は正しく表示されています。
以上、よろしくお願い致します。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.7
- 回答日時:
#6です
> ご提案頂いた方法を試してみますね
とのことなので、#5での注意点を。
サブフォームは帳票フォームで、レコードセレクタを使って、
「Delete」キーでレコードを削除する操作が前提になっています。
また、レコードセレクタで行を選択する際、「新規行は含まれない」ことが前提です。
新規行を含んだ選択された場合、記述を変更する必要があります。
それ用のコードも用意してましたが、必要であれば提示できます。
※ でも、Form_Delete 以降が呼ばれないのは不思議ですね。
大変お返事が遅くなり申し訳ありません。
お教え頂いた方法、クラスを作るやりかたおよび、「キーイベント取得」を”はい”にする方法とやってみました。
どちらも、サブフォームの行削除は正常にできるのですが、親フォームの合計金額は変わりませんでした。(親フォームの合計計算モジュールは、実行されます。)
いろいろご指導いただき、本当にありがとうございました。
No.6
- 回答日時:
#5です
記述の訂正を
(時間が取れない場合は、放置してください)
> ちなみに、
> Me.サブフォーム.Requery
> を
> Me.サブフォーム.From.Requery ★
★部分 From ではなく Form でした
Me.サブフォーム.Form.Requery
わざわざロジックを考えて下さいまして、ありがとうございます!
気づくのが遅くなりました。申し訳ありません。
ご提案頂いた方法を試してみますね。ただ、今は納期が迫っており、時間がとれませんので、もう少々お待ち下さい。
重ねて、ありがとうございました。
No.5
- 回答日時:
#3です
解決された様でなによりです。
土日もがいていて、それなりに推測した結果のものになります。
お手数ですが、推測があっているかどうかだけでも教えていただけないでしょうか。
サブフォームは、帳票であることが前提となっています。
> (なお、今回の質問では単純化していますが、実際は、複雑な処理も行うため、またユーザインファーフェースのことも考慮して、VBAで作成しています。)
と言う事なので、キー操作等統一する為に「クラス」を作って、そこで共通の処理を記述していないでしょうか。
また、親の関数先頭で行っている
Me.サブフォーム.Requery
は、行を移動しないで Requery したかったのでしょうか。
ちなみに、
Me.サブフォーム.Requery
を
Me.サブフォーム.From.Requery
に変更すると、「3246の この操作は、トランザクションには実行できません」
のエラーになったと思います。(削除の処理中なので)
クラスを作って、Form_Delete 時に自力削除(以降のイベントは起きない)例を以下
クラス「clsFrm」を新規挿入し、以下を記述します。
Option Compare Database
Option Explicit
Private Const EVENT_PROCEDURE As String = "[EVENT PROCEDURE]"
Private WithEvents frm As Form
Private iCount As Long
Private bDel As Boolean
Private Sub Class_Initialize()
Set frm = CodeContextObject
frm.OnDelete = EVENT_PROCEDURE
iCount = -1
bDel = False
End Sub
Private Sub Class_Terminate()
Set frm = Nothing
End Sub
Private Sub frm_Delete(Cancel As Integer)
Dim i As Long
DoCmd.CancelEvent
If (frm.SelHeight < 1) Then Exit Sub
If (iCount < 1) Then iCount = frm.SelHeight
If (iCount = frm.SelHeight) Then
bDel = MsgBox(frm.SelHeight & "件 削除しますか?" _
, vbQuestion + vbYesNo, "確認") = vbYes
End If
iCount = iCount - 1
If (iCount = 0) Then
If (bDel) Then
With frm.Recordset
For i = 1 To frm.SelHeight
.Delete
.MoveNext
Next
End With
frm.SelHeight = 0
End If
bDel = False
End If
End Sub
サブフォームに以下を記述します。
Dim frm As clsFrm ' ★
Private Sub Form_AfterDelConfirm(Status As Integer)
MsgBox "Form_AfterDelConfirm"
End Sub
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
MsgBox "Form_BeforeDelConfirm"
End Sub
Private Sub Form_Delete(Cancel As Integer)
MsgBox "Form_Delete"
Call Me.Parent.Req
End Sub
Private Sub Form_Load()
Set frm = New clsFrm ' ★
End Sub
Private Sub Form_Close()
Set frm = Nothing ' ★
End Sub
★部分がクラスを使う宣言みたいなもの
メインフォームに以下を記述します。
Public Sub Req()
Me.FSUB.Requery
' 方法1
End Sub
※ FSUB はサブフォームコントロール名
この記述で Form_Delete しか呼ばれないものは作れました。
(細かいタイミングまではみてません。動いたっぽいレベル)
(サブフォーム Form_Delete の Cancel は意味を持たなくなります)
このようになっていると、Form_Delete のタイミングは使えないので、
クラスに制御を渡さないで、
サブフォームで「キーイベント取得」を「はい」として、例えば、
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Dim i As Long
Select Case KeyCode
Case vbKeyDelete
If (Me.SelHeight < 1) Then Exit Sub
KeyCode = 0
If (MsgBox(Me.SelHeight & "件 削除しますか?" _
, vbQuestion + vbYesNo, "確認") = vbYes) Then
With Me.Recordset
For i = 1 To Me.SelHeight
.Delete
.MoveNext
Next
End With
Me.SelHeight = 0
Call 親の関数
End If
End Select
End Sub
とすればやりたいことはできそうです。
(この場合 Form_Delete は呼ばれません)
親の関数では、方法1の方が良さそうです。
ただ、処理を統一したいクラスを使わなくなるので、良いのか悪いのか。
クラス内では、キーイベント取得はやってないような気が(私の知識不足かも)
なぜなら、Form_Delete は Private で呼ばれているので、
クラスから Private を呼び出せなかったような・・・
以上、よろしくお願いいたします。
No.4
- 回答日時:
間違ってメインフォームに記述しているとか。
。。。この回答への補足
解決しました。
Form_Deleteイベントは、
「レコードが実際に削除される前に発生するもので、この時点ではまだ削除はされていません。」
ということなので、Form_Deleteで、(サブフォームの合計金額-削除しようとしている行の金額)を計算して、メインフォームに表示する方法で解決しました。
いろいろ考えて下さってありがとうございました。
No.3
- 回答日時:
#1です
タイミング的には #2 さんの通りだと思います。
提示した参照先の画像にあるフォームに MsgBox を組み込んでみたところ、
言われているような結果にはならず、順に呼ばれました。
私はお手上げです。
簡単なメイン/サブ構成のフォームを作成し、各イベントで MsgBox のみを記述され、
確認されてはいかがでしょうか。
失礼しました。
この回答への補足
解決しました。
教えて頂いたことがヒントになりました。
おっしゃる通りForm_Deleteイベントは、
「レコードが実際に削除される前に発生するもので、この時点ではまだ削除はされていません。」
ということなので、Form_Deleteで、(サブフォームの合計金額-削除しようとしている行の金額)を計算して、メインフォームに表示する方法で解決しました。
いろいろ考えて下さってありがとうございました。
No.2
- 回答日時:
このイベントで確認したらどうでしょう。
---
Private Sub Form_AfterDelConfirm(Status As Integer)
If (Status = acDeleteOK) Then
Forms![メインフォーム].合計計算
End If
End Sub
早速回答いただき、ありがとうございます。
実は、いろいろ試行錯誤をしていまして、下記のロジックの場合、
Private Sub Form_AfterUpdate()
MsgBox "Form_AfterUpdate"
Forms![メインフォーム].合計計算
End Sub
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
MsgBox "Form_BeforeDelConfirm"
End Sub
Private Sub Form_Delete(Cancel As Integer)
MsgBox "Form_Delete"
End Sub
Private Sub Form_AfterDelConfirm(Status As Integer)
MsgBox "Form_AfterDelConfirm"
If (Status = acDeleteOK) Then
Forms![メインフォーム].合計計算
End If
End Sub
表示されるMsgboxは、"Form_Delete"のみでした。
他のイベントが発生しない理由がわからず、困っています。
他の案があれば、どうかご提案下さい。
No.1
- 回答日時:
VBA は必要無いような気がします。
過去 QA で、解決されていませんが近い構成だと思います。
access2010のフォーム上で計算したいです
http://oshiete.goo.ne.jp/qa/7079470.html
VBA でやる場合、イベントの発生タイミングを確認されたらと思います。
削除の操作を行うと、
Form_Delete / (Form_Current) / Form_BeforeDelConfirm / Form_AfterDelConfirm
のイベントが順に発生したと思います。
何もしないと、「削除しますか?」のAccessからのメッセージは、
Form_BeforeDelConfirm 後に表示されたと思います。
なので、Form_Delete 時に合計金額を求めても元のままだと思います。
早速回答いただき、ありがとうございます。
Form_BeforeDelConfirm、Form_Delete、Form_AfterDelConfirm
のそれぞれに Msgbox をつけて実行したところ、
行削除をしたタイミングで発生するイベントは
Form_Delete
のみでした。
ここで合計金額を求められないとすれば、タイミングがないですよね。
行削除を、別の方法で行うしかないのでしょうか。
他の提案があれば、ご教示いただきたく、よろしくお願いします。
(なお、今回の質問では単純化していますが、実際は、複雑な処理も行うため、またユーザインファーフェースのことも考慮して、VBAで作成しています。)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Excel(エクセル) グループの最後の行に書式、計算式なども同じ行を追加するマクロを教えてもらえませんか。 7 2022/05/18 10:13
- 相続税・贈与税 財産分与時などでの、株式などの評価額の算定法について 2 2023/01/19 18:24
- Excel(エクセル) 列を自動で追加したい 3 2022/07/11 12:58
- Access(アクセス) Accessでセレクタをダブルクリックで別フォームで詳細表示 3 2022/12/20 10:36
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 4 2023/05/26 10:43
- Excel(エクセル) 10円の誤差が分からない 11 2022/11/13 07:25
- 確定申告 個人の確定申告。「医療費のお知らせ」記載内容と医療費控除の明細書【内訳書】に記入する内容の関係 4 2023/03/04 18:41
- Visual Basic(VBA) Excel VBA ユーザーフォーム内のラベルにテキストボックスの小計を出す方法 5 2022/08/17 14:27
- 簿記検定・漢字検定・秘書検定 満期保有目的債券の償却原価法の計算について(簿記2級) 1 2022/06/18 15:40
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
Access サブフォームでの選択行の取得
その他(データベース)
-
Access サブフォームにフィルター後、計算
その他(Microsoft Office)
-
Access Dsum関数
Access(アクセス)
-
-
4
サブフォームに対してGoToRecordするには?
その他(Microsoft Office)
-
5
ACCESS──メインフォームでサブフォームのレコード件数をカウントしたい
Access(アクセス)
-
6
MS Accessでフォームの「開く時」と「読込み時」のイベントの違い
Access(アクセス)
-
7
Accessでコードを入れると名前がでるようにしたい
Access(アクセス)
-
8
サブフォームの金額合計をメインフォームに表示させたい
その他(データベース)
-
9
このオブジェクトに値を代入することはできません
その他(データベース)
-
10
Accessで、フォームからフォームへ値を引き継ぐやり方
Access(アクセス)
-
11
「RunSQL」と「Execute」の違い
Access(アクセス)
-
12
ACCESSフォーム入力後の確定
Access(アクセス)
-
13
Access VBAでタブコントロールで選択するタブをしていするには。
Access(アクセス)
-
14
YES/NO型の値
Excel(エクセル)
-
15
ACCESS クエリの抽出条件に他のテーブルの値を参照する方法
Access(アクセス)
-
16
日付型のフィールドに空白を入れる方法を教えてください
その他(データベース)
-
17
レコード削除時に(サブ)フォームに表示される#Deleted"について"
Access(アクセス)
-
18
Access2000 サブフォームのRecordSet取得法
Access(アクセス)
-
19
アクセスでテキストボックスの値が空白だったら
Access(アクセス)
-
20
ACCESSのフォームで次のレコードに移動しない方法を教えてください
その他(データベース)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
リストボックスの選択解除
-
accessで2つ以上のフォームを起...
-
VBA リストボックスをダブルク...
-
VB.net(VB)で、フォームにExcel...
-
メインフォームからサブフォー...
-
VBAにてメッセージボックスを最...
-
アクセス フォームが存在する...
-
ExcelVBAでフォーム内でブック...
-
Access 無操作の場合、自動で閉...
-
WithEvents変数について
-
フォームを1つだけ閉じる方法は?
-
データシートビューからフォー...
-
ExcelVBAでユーザーフォーム内...
-
短距離走...
-
VB.NETからエクセルを起...
-
ディスプレイ解像度より大きな...
-
ACCESS VBAサブフォーム(DATA S...
-
入力フォームをエクセルに書き出す
-
サブフォームの新規レコードに...
-
VBプログラムの終了
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAにてメッセージボックスを最...
-
VB.net(VB)で、フォームにExcel...
-
Accessでフォームから別フォー...
-
リストボックスの選択解除
-
Googleフォーム・複数人の申し...
-
ユーザーフォーム上にアイコン...
-
アクセスVBA フォームのス...
-
VBプログラムの終了
-
アクセス フォームが存在する...
-
サブフォームの新規レコードに...
-
サブフォームの行ごとにコンボ...
-
PDFフォームに本日の日付を自動...
-
accessで2つ以上のフォームを起...
-
メッセージボックスの背景色
-
PDFフォーム内で日付計算したい...
-
VBA リストボックスをダブルク...
-
Access 無操作の場合、自動で閉...
-
ディスプレイ解像度より大きな...
-
フォーム上の全てのコントロー...
-
ToolStripStatusLabelを固定し...
おすすめ情報