- ベストアンサー
ACCESSで在庫管理を行うための計算式について
- ACCESSで在庫バラ数をケース数、ボール数、バラ数へ換算する際、ボール数の計算式にMOD演算子を使用すると小数点部分が丸められてしまい正しい在庫ボール数に換算できない問題が発生しています。
- さらに、バラ数に至っては求める計算式が分からず困っています。
- このような計算はVBAなどのプログラミング言語の力を借りなければ実現できないのでしょうか?助けてください。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
標準モジュールに、以下のコードを張り付けます。 関数名はバラ、ボールなど日本語だろう、なので いいかげんですが。 'ケース数 Function funcCase(myZAIKO As Long, conCASE As Long, conBOUL As Long) As Long Dim i As Long Dim j As Long i = myZAIKO Mod (conCASE * conBOUL) If i >= 0 Then '取り出せるケース数 funcCase = Int(myZAIKO / (conCASE * conBOUL)) Else funcCase = 0 End If End Function 'ボール数 Function funcBOUL(myZAIKO As Long, conCASE As Long, conBOUL As Long) As Long Dim i As Long Dim j As Long Dim k As Long 'ケース取り出し後の残り = 在庫数 - 取り出せるケース数xケース入り数xボール入り数 i = myZAIKO - (Int(myZAIKO / (conCASE * conBOUL))) * conCASE * conBOUL '残りの在庫から取り出せるボール数 j = (Int(i / conBOUL)) If j >= 0 Then funcBOUL = j Else funcBOUL = 0 End If End Function 'バラ数 Function funcBARA(myZAIKO As Long, conCASE As Long, conBOUL As Long) As Long Dim i As Long Dim j As Long Dim k As Long 'ケース取り出し後の残り = 在庫数 - 取り出せるケース数xケース入り数xボール入り数 i = myZAIKO - (Int(myZAIKO / (conCASE * conBOUL))) * conCASE * conBOUL '取り出せるボール数 j = Int(i / conBOUL) '残りのバラ数 k = i - j * conBOUL If k > 0 Then funcBARA = k Else funcBARA = 0 End If End Function クエリを以下のようにします。商品CDのCDは英文で表記しています。 SELECT 在庫テーブル.商品CD, 商品マスターテーブル.商品名, 商品マスターテーブル.入り数ケース, 商品マスターテーブル.入り数ボール, 在庫テーブル.在庫数, funcCASE([在庫数],[入り数ケース],[入り数ボール]) AS ケース数, funcBOUL([在庫数],[入り数ケース],[入り数ボール]) AS ボール数, funcBARA([在庫数],[入り数ケース],[入り数ボール]) AS バラ数 FROM 商品マスターテーブル INNER JOIN 在庫テーブル ON 商品マスターテーブル.商品CD = 在庫テーブル.商品CD; クエリを開いて結果を確認します。 関数の中では該当しない場合は0としています。 クエリでは同様に0が表示されます。 以上です。関数に間違いがなければ動くはずですが。
その他の回答 (7)
- bonaron
- ベストアンサー率64% (482/745)
No.4 No.5 です。 To layy さん > クエリ見栄え以前に > 求めたい式、逆からの計算式を確実に理解するのが先です。 これって、No.5 の > こちらの方が美しいですね。 に対して仰っていますか? 「美しい」というのは、もちろん、「論理的に」であって、「見栄え」の問題ではありませんよ。 長年、プログラマなどをやっていると、 式 や プログラムのコードを「美しい」というと暗黙に「論理が」ということになります。 周りも同じような理系の人が多いので 「クエリ見栄え」と解釈する人がいようとは思ってもみませんでした。 いやぁ~、勉強になりました。 なぜ、No.4 より No.5 の方が論理的に美しい(と私が感じる)か 両者の > 計算式を確実に理解 していただければお分かりになるかと思います。 解説しようかと思ったけど面倒になったから止め。
- layy
- ベストアンサー率23% (292/1222)
クエリ見栄え以前に 求めたい式、逆からの計算式を確実に理解するのが先です。 発展してケース単位でしか発注しないという計算もあった、となると途中端数切り上げもありえます。 また VBAについて、やろうと思えば出来るレベルか教えて下さい。
お礼
VBAについては、初歩の初歩と言う段階です。 まだまだ勉強することが沢山あって皆様の回答はとても参考になりました。 >求めたい式、逆からの計算式を確実に理解するのが先です。 求めたい式や逆からの計算式を完全に理解できないまま計算式だけを 必死にいじって「できない、できない」と言っていたので耳が痛いですが このお言葉を肝に銘じて成長できたらと思います。 ありがとうございました。
- piroin654
- ベストアンサー率75% (692/917)
クエリの中で、入数ケース、入数ボールを 入り数ケース、入り数ボールとしています。 テーブルのフィールド名を合わせると、 SELECT 在庫テーブル.商品CD, 商品マスターテーブル.商品名, 商品マスターテーブル.入数ケース, 商品マスターテーブル.入数ボール, 在庫テーブル.在庫数, funcCASE([在庫数],[入数ケース],[入数ボール]) AS ケース数, funcBOUL([在庫数],[入数ケース],[入数ボール]) AS ボール数, funcBARA([在庫数],[入数ケース],[入数ボール]) AS バラ数 FROM 商品マスターテーブル INNER JOIN 在庫テーブル ON 商品マスターテーブル.商品CD = 在庫テーブル.商品CD; です。
- bonaron
- ベストアンサー率64% (482/745)
No.4です。 もっと簡単になります。 こちらの方が美しいですね。 ケース数: [在庫数]\([入数ケース]*[入数ボール]) ボール数: ([在庫数] Mod ([入数ケース]*[入数ボール]))\[入数ボール] バラ数: [在庫数] Mod [入数ボール]
お礼
回答ありがとうございます。 コードを張ってもらえたので今回はpiroin654様の回答を使わせてもらいましたが それぞれの換算の計算式、すごく参考になりました。
- bonaron
- ベストアンサー率64% (482/745)
クエリだけでできますよ。 割り算の部分を、「/」 ではなく整数除算「\」 (円マークです。意味はご自分で調べてください) にすると、簡単になります。 ※ケース、ボールの概念は、No.1さんに従っています。 ケース数: [在庫数]\([入数ケース]*[入数ボール]) ボール数: ([在庫数]-[ケース数]*([入数ケース]*[入数ボール]))\[入数ボール] バラ数: [在庫数]-([入数ボール]*(([入数ケース]*[ケース数])+[ボール数]))
お礼
回答ありがとうございます。 クエリでもできたのですね、一人で完全にこんがらがっていたので大変参考になりました。
- piroin654
- ベストアンサー率75% (692/917)
関数のボール数の計算で、 Dim k As Long としていますが、kは使っていないので Dim k As Long をコメントアウトか削除してください。
- layy
- ベストアンサー率23% (292/1222)
これからの夏場では、 缶ビールだと6本単位×4束=24本で良く売られています。 これを例にとれば 82本のとき、 82/(6×4)=3.41・・・=int(3.41)=3・・・・(1) 82-【(6×4)×(求めた3)】=10・・・・・・・・・・・・(2) 10/6=1.66・・・=int(1.66)=1・・・・・・・・(3) 10-【6×(求めた1)】=4・・・・・・・・・・・・・・・・・(4) となり 在庫数=82の入数6×4のときは 3ケース、1ボール、4バラとなると思います。 逆算すると 4バラ+1ボール×6+3ケース×(6×4)=82 入り数換算は クエリ上の算出だけでなくフォーム、レポートなどでも使えるように VBAで関数化(情報渡して結果をもらうFUNCTION化)するのが良いと思います。 ※ケース、ボール概念が逆になっていたらすみません。
お礼
さっそくのお答えありがとうございます。 ケース、ボール概念全くその通りです。 こんがらがっていた頭がlayy様の答えでかなり整理できました。 VBA使えるように頑張りたいと思います。
お礼
回答ありがとうございます。 標準モジュールにコードを張り付けクエリを確認しましたところボール数とバラ数が正しく 換算できなかったので j = (Int(i / conBOUL)) → j = (Int(i / conCASE)) k = i - j * conBOUL → k = i - j * conCASE と変更したら求めていた結果がでました。 これからVBAを頑張って勉強しようと思います。 本当にありがとうございました。