- ベストアンサー
VBAを使用してアクセスのデータベースに1枚ごとに伝票番号を連番で振りたい
- アクセスのデータベースで伝票を1枚ごとに入力しています。各伝票には一意の伝票番号が振られています。伝票の上段には請求先や日付や金額の総合計があり、その下には細かい項目分類ごとの品目や数量、単価、小計が入力されています。各項目分類ごとに連番を振りたいです。
- VBAを使用してアクセスのデータベースに連番の伝票番号を振りたいです。伝票は1枚ごとに入力され、上段には請求先や日付や金額の総合計があり、下には品目や数量、単価、小計が入力されています。各項目分類ごとに連番を振りたいです。
- アクセスのデータベースで伝票を1枚ごとに入力し、各伝票には一意の伝票番号が振られています。伝票の上段には請求先や日付や金額の総合計があり、下には品目や数量、単価、小計が入力されています。各項目分類ごとに1から連番を振りたいです。
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
Private Sub Form_BeforeInsert(Cancel As Integer) こんばんは。 DCount や DMax には、3番目のパラメータがあります。 テーブルやクエリから特定の希望するレコードだけを取り出す条件式です。(SQLのWhere句のWhereを除いた式になります。) 具体的には以下のようにしたらよいでしょう。 「Q_分析用クエリ」に、伝票No.用のフィールド「伝票No.」があるとして、フォーム上にある「伝票No.」というテキストボックスに関連付けられているとします。、 If DCount("*", "Q_分析用 クエリ","[伝票No.]=" & [伝票No.]) = 0 Then 項目番号 = 1 Else 項目番号 = DMax("項目番号", "Q_分析用 クエリ","[伝票No.]=" & [伝票No.]) + 1 End If
その他の回答 (9)
- CHRONOS_0
- ベストアンサー率54% (457/838)
>データベースの初心者であるとどうして言えるのか、 たくさんの初心者の質問を読んできた経験からです 質問の中身もそうですし、用語の使い方、 テーブルにはほとんど触れずインタフェースであるフォームの説明がやけに詳しい など初心者の質問の特徴ですね >主キーであるなどとはどこにも書いていない 確かに書かれていませんが、それは話がそこにいっていないだけで 親子関係の子テーブルで親の主キーと親の主キーに対してユニークな 例えば行ナンバーといったものは 親の主キー+行ナンバーで子テーブルの主キーとすべきものです
お礼
今年の1月ごろより、本などを読みながら、勉強を始めたばかりで、質問のしかたや内容など、稚拙で、ご迷惑をおかけしました。 また、たくさんの参考意見をありがとうございました。 また、データベースなど、きちんと学習しなければと思います。
- hakkiriitte
- ベストアンサー率41% (20/48)
そもそも、他人のスレッドで言い争いをしてはいけないのですが、naka66さんが、データベースの初心者であるとどうして言えるのか、不思議です。VBスクリプトが不得手なだけで、データベースについては十分に理解してらっしゃると思います。 さらに、「正規化」を軽視する発言をしたつもりもありません。 ここで「正規化」を語るのは、そぐわないのでは、と言っているだけです。 「正規化」はデータベースを構築してきた先人の知恵です。 プログラムにもスクリプトの記述にもそれぞれセオリーがあるのは、そういった先人の知恵なのであって、それらの知恵を学ばずに立ち向かっても、過去の多くの人が躓いた失敗を繰り返すだけです。 そして、リナンバーについては、伝票につける行番号であって主キーであるなどとはどこにも書いていないことを申し添えておきます。 そもそも、私が書いた手順では、主キーの変更はできません。
お礼
どうもありがとうございました。 正規化等、基本情報の勉強をしたとき、少し用語の意味を知っただけで、よく勉強していませんでした。 連番にした行番号は、主キーではありません。 ただ、1枚の伝票に、いくつの項目があるのか、その行数をカウントするために、手で1、2、と順番に入力すればいいのを、その手間を省くために、今回の質問になりました。 解決しまして、ありがとうございました。
- CHRONOS_0
- ベストアンサー率54% (457/838)
>市場に出回っているパッケージ商品には、その「正規化規則」とやらを >無視したデータ構造を持っているものがあります。 初心者の人に対してこのようなことを言って [正規化]をあたかも無視していいようなものであるかのような印象を植え付ける発言は無責任なのでは 確かに大きなシステムではどこかで正規化を外した部分を持つものが多いですが これは正規化を無視や軽視しているわけではなく 正規化について十分に熟知している設計者が正規化を外すデメリットと 外したことにより得られるメリットを比較して意図的に正規化を外しているのです さらに外すことによるデメリットに対する対策も組み込まれています 初心の方はまず正規化について理解し それに則ったテーブル設計をするようにしましょう データベースの基本はテーブルです ここをおろそかにして先に進めても要らぬ大回りをするだけです >「削除時のリナンバー」 こんなことは絶対にやってはいけません この番号は伝票Noと組み合わせて詳細テーブルの主キーになるものです 主キーの振りなおしなんてのはデータベースの改造時にしかするべきものではありません
- hakkiriitte
- ベストアンサー率41% (20/48)
ANo1.、ANo.3 です。 ちょっと理解に苦しみますが、質問者の方の意図するところと外れた回答が多い気がします。 データベースについての解説ならば、相応の書籍やサイトがあるので、そちらを紹介すればよいのであって、ここで説明するのは、話がふくらみすぎる気がします。 私の全くの個人的な意見なので、無視してくださって結構ですが、「正規化規則」というと、絶対守らなければならないような気がしますが、市場に出回っているパッケージ商品には、その「正規化規則」とやらを無視したデータ構造を持っているものがあります。 特に移行時やメンテナンスの際などに効率よく運用するために、推進されている規格ぐらいにとらえればよいと思います。 ああ、そうそう。データ構造ですが、DMaxなどを使う以上、1本のテーブルの、同じフィールドに集計する数値が収まっていると考えるのがふつうです。違いますか? また、「主フォームに総計を表示」、「削除時のリナンバー」というのは、ANo.4さんがおっしゃるほど難しい作業ではないと思います。 比較的よくつかうテクニックといえます。 「主フォームに総計を表示」は、 1作業中のレコードを保存。 2元のテーブルから、合計値を計算。 3所定のテキストボックスに表示。 「削除時のリナンバー」 1リナンバーしたいレコードだけを抽出してナンバー順に並べるクエリを作製。 2念のため、旧ナンバーを格納するフィールドを追加。 3旧ナンバーを2のフィールドに格納。 4先頭から読み取って、番号を振りなおす。 5旧ナンバーフィールドは邪魔だったら、作業後、消去。 そもそも、ANo.6さんもおっしゃっているように、削除時のリナンバー自体それほど必要とも思えません。 どうしても直したいのならば、手作業で直したほうが早いかもしれません。 以上、自分で「関係ない議論」といいながら、蛇足的で申し訳ありません。
お礼
再度やり直して、 下に書きました、 Private Sub Form_Click() の部分 は、不要でした。 hakkiriitteさんのアドバイスどおりで、お世話になりました。
- CHRONOS_0
- ベストアンサー率54% (457/838)
>ANo.1です。 >私には、テーブルの構造がすでにANo.2さんの回答のようになっているように思えるのですが >細かい項目分類ごとの、品目や数量、単価、小計などを入力するようにしています。 これでそう読めますか? 伝票Noごとに番号を振るというのならいいのですけどね 小計を取るというのは同じ項目番号で複数の品目があるということなのでは >行1、行2、行3と入力していって行2を削除することも考慮するべきでしょう。 これはデータベース的には何の問題もありません 伝票Noと行番号の組み合わせがユニークであればいいので 連続性が失われても何の問題もありません
補足: No1さんの回答は質問の正答だと思います。 ただ、中途削除にはどのように・・・と思っただけです。
お礼
連番になった項目を削除すると、そこは飛び番になりました。 ただ、他の方が記入した伝票を見ながら、私が入力して、その後ファイリングしていますので、削除するようなことは、ほぼ起きないような感じです。 いろいろ考えてくださり、ご回答いただき、どうもありがとうございました。
私は、主表と従表との関係で主表に総合計を設けるのが是が非かの論議には中立的です。 が、少なくとも主フォームにそれを表示するのは至難ですよ。 ベリファイのため、後段の処理の手抜きのために設ける位の考えがお勧めです。 さて、肝心の質問の回答ですが、これはチト考えられておられるやり方には疑義ありです。 まず、行1、行2、行3と入力していって行2を削除することも考慮するべきでしょう。 その場合は、行3を行2に変更しなきゃならんです。 つまり、DempyoRenumber(テーブル名,ID)なる関数を作成することがテーマになるかと思います。 この場合、SQL文を発行するということも考えられます。 この場合、レコードセットを呼び出し更新するということも考えられます。 DMAX関数という発想では、ユーザのオペレーション頼りになるかと思います。
お礼
どうもありがとうございます。 主テーブルには、総合計は、手で金額を入力しただけのものが入れてあり、サブで、項目ごとに小計を出して、最後にその小計の合計を計算して主テーブルに表示するようにしているので、手で入力した総合計と、計算で出た総合計の数字があっていれば、まちがいないと確認できるようにしています。 途中で行を削除するところまで、考えていませんでした。
- hakkiriitte
- ベストアンサー率41% (20/48)
ANo.1です。 私には、テーブルの構造がすでにANo.2さんの回答のようになっているように思えるのですが。 naka66さんのご質問にデータ構造の説明が一切されていないので、想像で言っているだけですが。 DMaxやDCountにCriteriaを指定するのも、テーブル構造がそのようになっているという前提です。 naka66さんのご要望が、伝票No.ごとの連番をつけたいということであると判断して回答しました。単純に全ての連番にするのだったら、フィールドのデータ型をオートナンバーにしてやればいいだけですから。
お礼
>naka66さんのご要望が、伝票No.ごとの連番をつけたいということであると判断して回答しました。 その通りです。 説明不足で申し訳ありません。 仕事の手順として、まず、依頼先に対して、総合計の金額の請求を先に済ませて、その後、こちら側の分析資料として(どういう内訳の依頼であったか、とか)サブフォームに、項目を入力していきます。 ですので、上段の主テーブルの分は、先に入力した分が既に表示されています。 それで、下段のサブフォームに項目を入力していくのですが、(各1枚の伝票ごとに、)項目の連番を自動的に振れるようにしたいのです。
- CHRONOS_0
- ベストアンサー率54% (457/838)
作る(考える)順序が変ですよ データベースではまずテーブルを設計し それからユーザーインタフェースを考えます このケースでは伝票テーブルをどのように作るかをまず考えてから 入力インタフェース(フォーム)を考えます それともう一点 1レコード内に複数の品目、数量、単価、小計を入れる などというのは正規化規則にもろ違反した構造です 例としては [伝票見出し](伝票No、請求先、日付、・・・) [伝票詳細](伝票No、伝票行No、項目番号、品目、数量、単価) [項目マスタ](項目番号、項目名、・・・) こんなところでしょうか ここを変更せずに先に進めても早晩行き詰ります 考え直してから再質問されたほうがいいですね
お礼
説明の足りない質問で、大変お騒がせしてしまい、本当に申し訳ありませんでした。そして、お答えいただき、どうもありがとうございました。 今日、仕事に行き、上の回答を参考にして、修正し、希望通りにすることができました。 If DCount("*", "Q_分析用 クエリ","[伝票No.]='" & Forms!F_依頼書[伝票No.]&"'") = 0 Then 項目番号 = 1 Else 項目番号 = DMax("項目番号", "Q_分析用 クエリ","[伝票No.]='" & Forms!F_依頼書[伝票No.]&"'") + 1 End If End Sub と、して、 Private Sub Form_Click() の後にも、同じように書いてみました。 伝票ごとに、自動的に、1、2と行番号が連番として振れるようになりました。 インプレス社の、「できるアクセス2000」ビジネス活用編の、 「連番の見積もり番号を自動的に入力するには」の項で、最初の、書き方を真似てやったのですが、3つ目の、条件を設定する部分が、よくわかっていませんでした。 どうも、ご迷惑をかけ、またお世話になり、ありがとうございました。
補足
さっそくにどうもありがとうございます。 質問の内容だけを持ち帰り、実際のファイルは職場に置いてきてしまってたため、明日、それでやってみようと思います。 手順がおかしくなってしまい、申し訳ありません。 伝票ごとに依頼ナンバーを振っていて、主テーブル、サブのテーブルにも同じナンバーで関連づけてますので、それでいけるように思います。