データ登録フォーム 伝票形式 その5 削除処理 [Form登録伝票版]
伝票形式での、削除処理の詳細です。
削除ボタンも登録ボタンと同様に、明細用と伝票用の2つがあります。
画面中央右側の削除ボタンが、明細の削除用です。
処理的には、「データ登録フォーム 1画面版 その5 データの削除」と、同じ要領ですので、ここでは省略します。
次に、画面下部分にある「伝票削除」ボタン。こちらが伝票削除用です。
このボタンをクリックすると、明細を含め、伝票全体のデータが削除されます。
以下、削除処理の説明です。
データ登録フォーム 伝票形式 その4 登録処理 [Form登録伝票版]
伝票形式での、登録処理の詳細です。
まず、画面中央右側にある「登録」ボタン。
この登録ボタンは、明細登録を行うための物です。
処理的には、「データ登録フォーム 1画面版 その4 データをテーブルに書き込む」と同じ要領なので、ここでの説明は省略します。
次に、画面下部分にある「伝票登録」ボタン。(前回からちょっと画面修正しました。)
このボタンで、伝票全体を登録します。
伝票登録を行うまでは、明細の内容はワークテーブルに登録されており、本来のデータテーブルにはまだ登録されていません。
伝票登録処理で、ワークから本来のデータテーブルへの反映と、伝票部分(ラベルが緑色の項目)の登録処理を行います。
以下、伝票登録ボタンの処理を説明します。
Private Sub cmdDENENT_Click() '売上伝票データ 登録処理 Dim Cn As New ADODB.Connection Dim recW As New ADODB.Recordset Dim recD As New ADODB.Recordset Dim lngDNO As Long Dim lngCM As Long Dim datNow As Date datNow = Now '1)入力項目チェック '顧客CDチェック If IsNumeric(Me.txt顧客CD) = False Then MsgBox "顧客CDを入力して下さい。", vbInformation Me.txt顧客CD.SetFocus Exit Sub End If '注文日チェック If IsDate(Me.txt注文日) = False Then MsgBox "注文日を入力して下さい。", vbInformation Me.txt注文日.SetFocus Exit Sub End If '納品日チェック If IsDate(Me.txt納品日) = False Then MsgBox "納品日を入力して下さい。", vbInformation Me.txt納品日.SetFocus Exit Sub End If '担当者CDチェック If IsNumeric(Me.txt担当者CD) = False Then MsgBox "担当者CDを入力して下さい。", vbInformation Me.txt担当者CD.SetFocus Exit Sub End If '明細行が入力されているかチェック If DCount("*", "TW売上明細") = 0 Then MsgBox "明細行が入力されていません", vbExclamation Exit Sub End If '2)コネクション準備・トランザクション開始 Set Cn = CurrentProject.Connection Cn.BeginTrans If Me.txtDENmode = "新規" Then '3)伝票 新規登録 '伝票番号作成 recD.Open " SELECT MAX(伝票番号) AS DENNO FROM TD売上伝票 ", Cn, adOpenForwardOnly, adLockReadOnly If recD.EOF = True Then lngDNO = 1 Else lngDNO = Nz(recD!DENNO, 0) + 1 End If recD.Close 'レコードセットオープン recD.Open "SELECT * FROM TD売上伝票 WHERE 伝票番号 = " & lngDNO, Cn, adOpenForwardOnly, adLockOptimistic If recD.EOF = False Then MsgBox "新規伝票番号の採番に失敗しました。", vbCritical recD.Close Cn.RollbackTrans Exit Sub End If '新規レコード作成、項目セット recD.AddNew recD!伝票番号 = lngDNO recD!登録日 = Now Else '4)伝票 更新登録 'レコードセットオープン lngDNO = Me.txt伝票番号 recD.Open "SELECT * FROM TD売上伝票 WHERE 伝票番号 = " & lngDNO, Cn, adOpenForwardOnly, adLockOptimistic If recD.EOF Then MsgBox "変更する売上伝票データが見つかりません。", vbCritical recD.Close Cn.RollbackTrans Exit Sub End If End If '5)項目セット recD!顧客CD = Me.txt顧客CD recD!注文日 = Me.txt注文日 recD!納品日 = Me.txt納品日 recD!担当者CD = Me.txt担当者CD recD!メモ = Me.txtメモ recD!備考欄 = Me.txt備考欄 recD!税抜合計 = Me.txt税抜合計 recD!消費税額 = Me.txt消費税額 recD!総額合計 = Me.txt総額合計 recD!変更日 = Now recD.Update recD.Close '6)明細処理 '明細を削除 Cn.Execute "DELETE FROM TD売上明細 WHERE 伝票番号 = " & lngDNO 'ワークテーブルOPEN recW.Open " SELECT * FROM TW売上明細 ORDER BY 明細番号 ", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly 'TD売上明細 Open recD.Open " SELECT * FROM TD売上明細 WHERE 伝票番号 = " & lngDNO, Cn, adOpenForwardOnly, adLockOptimistic lngCM = 0 '7)ワークからTD売上明細へ While recW.EOF = False lngCM = lngCM + 1 recD.AddNew recD!伝票番号 = lngDNO recD!明細番号 = lngCM recD!商品CD = recW!商品CD recD!数量 = recW!数量 recD!単価 = recW!単価 recD!金額 = recW!金額 recD!消費税額 = recW!消費税額 recD!総額 = recW!総額 recD!備考欄 = recW!備考欄 recD!変更日 = datNow recD.Update recW.MoveNext Wend recD.Close recW.Close 'コミット Cn.CommitTrans '8)後処理 '変更の時は終了する If Me.txtDENmode <> "新規" Then DoCmd.Close acForm, Me.NAME Forms.F売上伝票一覧.subList.Requery Exit Sub End If '新規の時は初期化する 'ワークテーブル削除 Cn.Execute "DELETE FROM TW売上明細 " Call subMeiInit Call subDenInit Me.subMEI.Requery End Sub
以下、ブロックごとに説明です。
1)入力項目チェック
実際にデータを登録する前に、入力項目への入力が正しく行われているかチェックします。
このプログラムのチェックは、とりあえずのざっくりチェックですのでご了承下さい。
また、明細が1件も登録されていない場合、伝票の登録はできないようにしています。
2)コネクション準備・トランザクション開始
ADOで処理を行うための準備で、ここでは単純に、CurrentProjectのConnectionを利用しています。
ここから先、データの更新を行うので、トランザクションを開始しています。
今回の処理では、TD売上伝票テーブル・TD売上明細テーブルと、複数のテーブルに対して更新を行うのに加えて、TD売上明細テーブルへは、複数件のレコードを処理します。
途中、何らかの原因で処理が中断してしまった場合や、処理中の判断で処理を中止した場合などに、テーブルの更新内容が中途半端な状態になってしまう可能性があります。
トランザクションを行っておけば、更新内容を取り消したい場合は、ロールバックを行えば、トランザクションを開始した状態に簡単に戻すことができます。
プログラムが途中で停止した場合も、コミットがされていない限り、元の状態に戻ります。
バッチ処理など、複数の処理が一連で行われる場合も、トランザクションを利用すると便利です。
3)伝票 新規登録
伝票データの処理で、新規登録の場合です。
まず、キーとなる伝票番号を採番します。
ここでは単純にテーブル中の最大の番号から、1を加えた値を伝票番号とするようにしています。
採番した伝票番号を条件にして、TD売上伝票をオープンしています。
この時、新規作成なので、この伝票番号でレコードは抽出されないはずです。
念のため、レコードが抽出されてしまったときの処理を書いていますが、ここに来ることはまず無いと思われます。
AddNewで新規レコードを作成して、新規登録の時のみ設定する項目、伝票番号を設定します。
他の項目は、変更登録と共通の処理で設定します。
4)伝票 更新登録
伝票データの変更登録の場合です。
画面上に表示されている伝票番号を条件に、TD売上伝票をオープンしています。
普通であればレコードが抽出されるはずですが、念のためチェックを行っています。
5)項目セット
レコードの各盲目に、入力内容を設定しています。
Updateして、Closeして、伝票の処理はここで終了です。
6)明細処理
ここから明細の処理です。
ワークからTD売上明細にレコードを作成するので、あらかじめTD売上明細側のレコードを削除しておきます。
新規の場合は不要なんですが、念のため。
ワークテーブルのレコードセットと、TD売上明細のレコードセットをオープンします。
7)ワークからTD売上明細へ
ループでワークからTD売上明細へ、レコードを作成していきます。
この処理では、明細番号をきれいに振り直すようにしています。
明細レコードを作成し終えたら、更新処理は完了ですので、コミットを行っています。
8)後処理
更新処理の後、画面をどうするかの処理です。
新規の場合は、画面を初期化して、次の入力が行えるようにします。
変更の場合は、入力画面を終了して、一覧画面に戻ります。
戻る前に、一覧画面の一覧をRequeryして、最新の内容が表示された状態にしています。
伝票形式タイプは、複数のレコードを処理するので、少々手間がかかります。
処理が複数段階になっていますが、個々の処理は複雑ではないので、ADOによる基本的な処理ができれば、さほど難しくないと思います。
次回は、削除処理で完了です。
その5へつづく。
データ登録フォーム 伝票形式 その3 一覧画面から入力画面へ [Form登録伝票版]
まず最初に一覧画面が表示されます。
この画面は現在登録されているデータを確認する目的と、データを選んで編集画面へ展開する機能と、新規入力作業へ進む機能があります。
一覧画面の作り方は、「データ一覧フォーム その1」あたりを参考にしてください。
ここでは省略します。
まずは新規入力ボタン。
これがクリックされた時は、入力画面を新規入力として開きます。
フォームを開くのには、DoCmd.OpenFormを使います。
DoCmd.OpenFormは、最後のパラメタ(第7パラメタ)を使って、値を渡すことが出来ます。
ここに値がセットされていない場合は、開かれるフォーム側で新規で開かれたと判断するようにします。
新規入力ボタンの「クリック時」イベントに、以下のコードを記述します。
Private Sub cmdNEW_Click() '新規入力ボタン クリック DoCmd.OpenForm "F売上伝票入力", acNormal End Sub
次に「編集」ボタン。
既に登録されているデータを再度編集する場合は、一覧から該当データの編集ボタンをクリックします。
入力画面が選択されたデータの編集として開かれます。
入力画面を開くとき、先程のDoCmd.OpenFormの第7パラメタを使って、変更するデータのキーを渡すようにします。
入力画面側では、これによってどのデータの編集であるか判断します。
編集ボタンの「クリック時」イベントに、以下のコードを記述します。
Private Sub cmdEdit_Click() '編集ボタン クリック時 DoCmd.OpenForm "F売上伝票入力", acNormal, , , , , Me.txt伝票番号 End Sub
今回のテーブルでは、伝票番号がキーになっているので、この項目の値があればどのデータなのか識別できます。
キー項目が複数ある場合は、それなりに工夫が必要です。(カンマで区切るとか、ゼロ埋め固定長にして並べるとか)
後は入力画面のプログラムに引き継がれます。
新規入力で開いた場合の入力画面。
何も入力されていない状態で画面が開きます。
「注文日」に日付が表示されているのは、当日が初期値ということで。
編集ボタンから開いた場合の入力画面。
登録されている内容がコントロールにセットされた状態で開きます。
画面が開かれたときの処理は、フォームのイベント「開く時」(Form_Open)で行っています。
Private Sub Form_Open(Cancel As Integer) 'フォームオープン 初期設定処理 Dim Cn As New ADODB.Connection Dim recD As New ADODB.Recordset Dim recW As New ADODB.Recordset Dim strSQL As String '1)ワークテーブル削除 Set Cn = CurrentProject.Connection Cn.Execute "DELETE FROM TW売上明細 " Me.subMEI.Requery '2)入力コントロール初期化 Call subMeiInit Call subDenInit '3)変更モードならデータ呼び出し If Me.OpenArgs = "" Or IsNull(Me.OpenArgs) Then Exit Sub End If '4)伝票データ読込 recD.Open "SELECT * FROM TD売上伝票 WHERE 伝票番号 = " & Me.OpenArgs, Cn, adOpenForwardOnly, adLockReadOnly If recD.EOF Then MsgBox "変更伝票データが見つかりません。", vbExclamation DoCmd.Close acForm, Me.Name Exit Sub End If Me.txt伝票番号 = recD!伝票番号 Me.txt顧客CD = recD!顧客CD Me.txt注文日 = recD!注文日 Me.txt納品日 = recD!納品日 Me.txt担当者CD = recD!担当者CD Me.txt税抜合計 = recD!税抜合計 Me.txt消費税額 = recD!消費税額 Me.txt総額合計 = recD!総額合計 Me.txt備考欄 = recD!備考欄 Me.txtメモ = recD!メモ recD.Close '5)明細データをワークテーブルへ recW.Open "SELECT * FROM TW売上明細 ", Cn, adOpenForwardOnly, adLockOptimistic strSQL = " SELECT MEI.* , SYO.商品名 " & _ " FROM TD売上明細 AS MEI" & _ " LEFT JOIN TM商品 AS SYO ON MEI.商品CD = SYO.商品CD " & _ " WHERE MEI.伝票番号 = " & Me.OpenArgs & " ORDER BY MEI.明細番号 " recD.Open strSQL, Cn, adOpenForwardOnly, adLockReadOnly Do While recD.EOF = False recW.AddNew recW!伝票番号 = recD!伝票番号 recW!明細番号 = recD!明細番号 recW!商品CD = recD!商品CD recW!商品名 = recD!商品名 recW!数量 = recD!数量 recW!単価 = recD!単価 recW!金額 = recD!金額 recW!消費税額 = recD!消費税額 recW!総額 = recD!総額 recW!備考欄 = recD!備考欄 recW.Update recD.MoveNext Loop recW.Close recD.Close Me.subMEI.Requery '6)モード表示 Me.txtDENmode = "変更" End Sub
今回の説明に関係のない処理は省いてます。
コメントの番号順に説明していきます。
1)ワークテーブル削除
最初に、ワークテーブルを全件削除しておきます。
このワークテーブルの内容が、画面の明細部分に表示されます。
データが残っていた場合を考えて、まず削除を行っておきます。
2)入力コントロール初期化
画面のコントロールの内容をクリアします。
画面を開いたとき、通常であればコントロールの内容は空なわけですが、念のため空にする処理を通します。
クリアの関数を準備しておき、それを呼び出します。
初期値のある項目は、コントロールを空にする代わりに、クリア関数で初期値を設定するようにしておくと、コードで確認できてわかりやすいので、私はこのパターンを使ってます。
Private Sub subDenInit() '伝票項目クリア Me.txt伝票番号 = Null Me.txt顧客CD = Null Me.txt注文日 = Date Me.txt納品日 = Null Me.txt担当者CD = Null Me.txt税抜合計 = Null Me.txt消費税額 = Null Me.txt総額合計 = Null Me.txtメモ = Null Me.txt備考欄 = Null Me.txtDENmode = "新規" Me.txt顧客CD.SetFocus End Sub Private Sub subMeiInit() '明細項目クリア Me.txt明細番号 = Null Me.txt商品CD = Null Me.txt数量 = Null Me.txt単価 = Null Me.txt金額 = Null Me.txt明細消費税額 = Null Me.txt総額 = Null Me.txt明細備考欄 = Null Me.txtMEImode = "新規" Me.txt商品CD.SetFocus End Sub
こんなふうに、各項目を空にする処理を行います。
「注文日」のみ、今日の日付が初期値として表示されるようにしています。
フォーカスの位置もここで設定しています。
3)変更モードならデータ呼び出し
DoCmd.OpenFormの第7パラメタで設定した値は、Me.OpenArgsを参照することで確認できます。
Me.OpenArgsに値が設定されていなければ、新規で呼び出された事になります。
新規入力画面の準備はここまでで完了しているので、新規の場合はここで終了です。
Me.OpenArgsに値が設定されている場合は、その値をキーにして、データを読み込む処理を行います。
4)伝票データ読込
Me.OpenArgsに伝票番号がセットされているので、それを条件にして、伝票情報(TD売上伝票)を読み込んでいます。
5)明細データをワークテーブルへ
伝票データと同様に、Me.OpenArgsの伝票番号を条件にして、明細情報(TD売上明細)を読み込んで、それをワークテーブル(TW売上明細)に移し替えています。
この時、TD売上明細に商品名項目を持たせていないので、クエリで取得してワークテーブルにセットしています。
フォームのデータソースのクエリで商品マスタと結合して持ってきても良いのですが、今回は上記のようにしました。
INSERT文で追加しても良いと思いますが、ここでは追加用と読込用の2つのレコードセットを使って行っています。
ワークテーブルにデータができたら、サブフォームをRequeryして明細部分の表示を更新します。
6)モード表示
伝票の方のモード表示を「変更」にしています。
以上で画面表示の処理は完了です。
データの読込を、伝票と明細の2つについて行わなければならない点と、明細が複数件あってワークに一旦移す点がちょっと面倒です。
次回はデータ登録処理についてです。
その4へつづく。
データ登録フォーム 伝票形式 その2 テーブルについて [Form登録伝票版]
まず、この伝票タイプのデータを扱うためのテーブルについて説明しておきます。
その1でも説明しましたが、この画面では、伝票情報部分と、明細部分の2種類のデータを扱います。
画面の緑ラベルの部分が伝票情報で、青ラベルの部分が明細情報です。
明細情報は、複数件登録できる前提です。
これらの情報をテーブルに格納するわけですが、それぞれ、伝票情報部分をTD売上伝票、明細情報部分をTD売上明細、というテーブルに分けて登録します。
伝票情報1件につき、明細情報は複数件(1件以上)登録します。
また、画面で入力作業中の明細表示用に、TD売上明細テーブルとは別に、TW売上明細と言うワークテーブルを設けます。
入力作業中の一時的な状態を、このワークテーブルに保存します。
上の図の明細部分は、このワークテーブルから表示させています。
最終的な登録段階まで、TD売上明細テーブルは更新せず、伝票の登録ボタンクリックでワークの内容をTD売上明細テーブルに反映させます。
次からプログラムです。
その3へつづく。
データ登録フォーム 伝票形式 その1 概要 [Form登録伝票版]
まず、「伝票」とは。
「会社・商店などで、金銭の出入や取引内容などを記入する一定の様式を備えた紙片。」
大辞泉より引用(Yahoo)
例えば、商品の販売を行う際に、売る商品の一覧や金額などが記入された紙のことを伝票と呼んでいます。
会社が独自で作成した物や、業界で共通化された形式の物があります。
また、文房具店に行くと、様々な形式・サイズの物が売られています。
標準化された物では、チェーンストア伝票とか有名なんじゃないかと思います。
ネットで拾ったイメージ。
チェーンストア伝票ターンアラウンド用1型と言います。チェーンストア伝票という名前でも、いくつか種類があります。その中のひとつです。
私は作る人なので、実際に使ったことは無いのですが、商品の発注や納品の際に使われている物なんだと思います。