[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『エクセルで入荷管理。日付の早い順に出荷管理したい』(Hate)
食品倉庫業をしている者です。現在手書きで在庫管理をしています。
かなり手間なので、エクセルで管理するよう指示されたのですが、調べるとVBAを使用しないといけないと判明。現在本とにらめっこしながらやってます。
sheet1には倉庫内の実在庫数
B C D E F G H
2 商品名 商品名2 品番 在庫数 賞味期限 在庫数 賞味期限
3 ジュース 360ml a-1 200 20130901 500 20131001
4 牛乳 150ml b-1 100 20130801 200 20130805
5 お茶 360ml c-1 300 20130701 500 20130901
・
・
各列で1商品を管理。G、Hには同商品の新しい賞味期限分。書いてはないですが、I、Jにも更に新しい日付の在庫数、賞味期限が加わります。
sheet2(入荷データー)
B C D E F 1 商品名 商品名2 品番 入荷数 賞味期限 2 ジュース 360ml a-1 50 20130901 3 ジュース 360ml a-1 500 20131231 4 牛乳 150ml b-1 100 20130805 5 お茶 150ml c-1 100 20131001
これを入力したら、sheet1の在庫が増える。同じ賞味期限が該当しない場合
自動的にI、Jに自動で貼付される。
例
ジュース--賞味期限が20130901が50個入荷すると、E列の在庫が増え250になる。
賞味期限が新しい20131231はどこにも該当データーがないので、
空白のセルIに500、Jに20131231が添付される。
sheet3 (出荷データ)
B C D E 1 商品名 商品名2 品番 出荷数 2 ジュース 360ml a-1 500 3 牛乳 150ml b-1 70 4 お茶 150ml c-1 100
これを入力したら、賞味期限の早い順に在庫が減るようにしたいです!
欠品が出た場合は何個足りないか在庫数欄にマイナス表示される。
例
ジュース--賞味期限20130901の商品が倉庫在庫200。賞味期限20131001の商品が500。
出荷指示が500の場合
賞味期限20130901から順に減っていき、足りなくなったら20131001の在庫分から減る。
https://www.excel.studio-kazu.jp/kw/20090528093123.html
過去見てみたんですがうまくいきません。
どなたか、お力お貸しください。
回答ではないんだけど、この管理を本格的にしようと思うと結構、骨がおれるような気がするねぇ。 奥が深いので、有償のWMSが販売されているわけで。
まぁ、過去にも、この板でWMS関連のVBA処理でお手伝いはしているので、できないことはないねど。
それはそうと、VBAで管理するならVBAで管理しやすいレイアウトにしたほうがいいねぇ。 特に Sheet1 。I,Jのみならず、賞味期限が異なれば、どんどん列が増えていくんだよね。 古いものから順に出荷していって、なくなれば、データそのものをなくして前づめにするような ことも必要だろうけど、まず、この各行の中の並びを賞味期限の降順にしておくと、なにかと便利かも。 VBAでSheet1にデータ反映させる際に、VBA内で、並び替えたほうがいいね。
それと、一般に、出荷時、賞味期限がすぎていれば出荷停止とか、実際には、そういった 条件が、もっともっとあるように思えるけどね。
(ぶらっと)
早速の連絡ありがとうございます。
過去の質問にもぶらっとさんの回答あって、お名前だけ知っていたので
有名人と話している気分ですw
VBAで管理するならVBAで管理しやすいレイアウト
具体的にどこをどうレイアウトするように
したらよいでしょうか?
勉強不足すぎてお恥ずかしい...
確かに出荷停止いりますね。抜けておりました。
過去にも、この板でWMS関連のVBA処理でお手伝いはしているので、できないことはないねど。
→すごいですね!
ぜひ私がしたい事のお力になっていただければと...
ちょっとやってみます。 レイアウトは、現時点のものでそんなに問題はないと思うけど、Sheet1に総在庫数があれば何かと便利かな?(E列あたりに) あとは、レイアウトではなく、コメントしたように、横方向の並び順として賞味期限の古いものから順にセットしてあれば これも、VBA処理上、かなり楽になるような予感。Sheet1に書き込んだ後にコード内で並び替えをすればいいと思う。
それと、日付なんだけど、これは日付型じゃなく yyyymmdd という 【数字】で入っているのかな?
(ぶらっと)
わがまま聞いていただき誠にありがとうございます。
どうぞ宜しくお願い申し上げます。
総在庫数があれば何かと便利かな?(E列あたりに)
→なるほど!さすがですね!
日付ですが、ご指摘の通りでございます。
yyyymmdd 半角数
こちらでまちがいございません。
色々ありがとうございます。
宜しくお願い致します。
Hate
了解。シコシコやってみるね。 ところで、Win7 限定でいいかな?(XP環境では動かさない?) XPもありうるなら、それなりに(ちょっと面倒だけど)対応するけど。
追記)↑は無視して。 賞味期限の並び順は、それがどうなっていてもいいような処理にする予定。
(ぶらっと)
それではお言葉に甘えさせて頂きます。
シコシコお願いします。
実はWin7限定ではないんです...
XPもあるのです...
色々すいません。
非常に助かります。
宜しくお願い申し上げます。
Hate
とりあえず簡単な入庫を。 なお、E列は総合計、F列から在庫、賞味期限
Sub 入庫() Dim c As Range Dim x As Variant Dim z As Long Dim j As Long Dim k As Long Dim shZ As Worksheet Dim updFlag As Boolean
Set shZ = Sheets("Sheet1") '在庫シート
With Sheets("Sheet2") '入庫シート For Each c In .Range("D2", .Range("D" & .Rows.Count).End(xlUp)) x = Application.Match(c.Value, shZ.Columns("D"), 0) If IsNumeric(x) Then '存在 z = shZ.Cells(x, .Columns.Count).End(xlToLeft).Column updFlag = False For j = 6 To z Step 2 If shZ.Cells(x, j + 1).Value = c.Offset(, 2).Value Then shZ.Cells(x, j).Value = shZ.Cells(x, j).Value + c.Offset(, 1).Value updFlag = True Exit For End If Next If Not updFlag Then '新規賞味期限 shZ.Cells(x, z + 1).Resize(, 2).Value = c.Offset(, 1).Resize(, 2).Value shZ.Cells(2, z + 1).Resize(, 2).Value = Array("在庫数", "賞味期限") End If shZ.Cells(x, "E").Value = calTotal(shZ, CLng(x)) Else '新規商品 With shZ x = .Range("D" & .Rows.Count).End(xlUp).Row + 1 .Range("B" & z).Resize(, 3).Value = c.EntireRow.Range("B1:D1").Value .Range("F" & z).Resize(, 2).Value = c.tntirerow.Range("E1:F1").Value .Range("E" & z).Value = calTotal(shZ, z) End With
End If Next End With
End Sub
Private Function calTotal(sh As Worksheet, i As Long) As Long Dim x As Long For x = 6 To sh.Cells(i, sh.Columns.Count).End(xlToLeft).Column Step 2 calTotal = calTotal + sh.Cells(i, x).Value Next End Function
(ぶらっと)
↑ とりあえずアップしたけど、今後、出庫を書いていった場合に、そこで使うコードを入庫でも使うために 入庫も書き直してアップする予定。
ところで、(現在まで、それがわからないから特に困っていると言うことではないんだけど) 各シートのA列は「完全空白列」と考えていいのかな? それと、Sheet1の1行目も、「完全空白行」と考えていい?
以降は単なるメモ。
・このあとの出庫も含めて、これだけの要件に限定すれば、できあがりのコードはコンパクトなものですむ。 ・ただ、この形で運用していったとき、たぶん、Sheet1の在庫と現物在庫があわないということが わりあいすぐに発生してくると思う。 それが誤出荷によるものなのか、Sheet2やSheet3への記入ミスによるものなのか、 あるいはマクロのチョンボによるものか、特定するのに骨がおれそう。 当面は、Sheet2やSheet3は履歴で、どこかのブックに追加して保存していったほうがいいかも。 ・要件としては、きっと、訂正とか取消もほしいなと、で、その先、取り置きも含めた 出荷引当も欲しいな、出荷保留もほしい、出荷保留解除も欲しい・・・ といったことがでてくるのかもしれない。 そうなると、かなり煩雑な仕組みになってくる。 ・そうなっていったとき、在庫シートの持ち方は、現在のSheet1の形ではなく、オリジナルのそちらのレイアウトで言えば B〜F列だけがずらっと下に並んでいる。かつ、賞味期限と在庫数の列をいれかえ。 こうしておくことで、並び替えなんかも容易になる。 ・Sheet1のような形のシートが必要なら、この在庫シートから作り出す。
こういったことを、ツラツラ感じたりしている。 まぁ、このあたりは、将来のテーマとして、そちらでも考えておいた方がいいかもね。
(ぶらっと)
結局、入庫は、あまりさわらなかった。少しロジックを整理して分岐処理を少なくしたくらい。 で、出庫と合わせてフルセット。 (繰り返すけど、E列は総在庫。F列以降が在庫と賞味期限なので、最初はE列に値をいれておいてね。 以降は、マクロ内で総合計をセットするので)
夕方から月曜日まで、エクセルのないところに逃避行するので、もし何かあれば、火曜日以降の対応になる。
Sub 入庫() Dim c As Range Dim x As Variant Dim z As Long Dim j As Long Dim k As Long Dim shZ As Worksheet
Application.ScreenUpdating = False
Set shZ = Sheets("Sheet1") '在庫シート
With Sheets("Sheet2") '入庫シート For Each c In .Range("D2", .Range("D" & .Rows.Count).End(xlUp)) x = Application.Match(c.Value, shZ.Columns("D"), 0) If IsNumeric(x) Then '存在 z = shZ.Cells(x, shZ.Columns.Count).End(xlToLeft).Column For j = 6 To z + 2 Step 2 If shZ.Cells(x, j + 1).Value = c.Offset(, 2).Value Or _ Len(shZ.Cells(x, j + 1).Value) = 0 Then '在庫数量の足しこみ shZ.Cells(x, j).Value = shZ.Cells(x, j).Value + c.Offset(, 1).Value '賞味期限 shZ.Cells(x, j + 1).Value = c.Offset(, 2).Value shZ.Cells(2, j).Resize(, 2).Value = Array("在庫数", "賞味期限") Exit For End If Next shZ.Cells(x, "E").Value = calTotal(shZ, CLng(x)) Else '新規商品 With shZ x = .Range("D" & .Rows.Count).End(xlUp).Row + 1 .Range("B" & z).Resize(, 3).Value = c.EntireRow.Range("B1:D1").Value .Range("F" & z).Resize(, 2).Value = c.tntirerow.Range("E1:F1").Value .Range("E" & z).Value = calTotal(shZ, z) End With
End If Next End With
shZ.Select Application.ScreenUpdating = True MsgBox "入庫処理がおわりました"
End Sub
Sub 出庫() Dim c As Range Dim x As Variant Dim z As Long Dim i As Long Dim j As Long Dim k As Long Dim n As Long Dim dt As Long Dim shZ As Worksheet Dim dtV() As Long Dim qtV() As Long Dim outQ As Long Dim invQ As Long Dim newV() As Variant
Application.ScreenUpdating = False
Set shZ = Sheets("Sheet1") '在庫シート
With Sheets("Sheet3") '出庫シート For Each c In .Range("D2", .Range("D" & .Rows.Count).End(xlUp)) outQ = c.Offset(, 1).Value If outQ = 0 Then MsgBox c.Value & " の出庫数量がゼロ。スキップします" Else '在庫シートの存在チェック x = Application.Match(c.Value, shZ.Columns("D"), 0) If Not IsNumeric(x) Then MsgBox c.Value & " が在庫シートにありません。スキップします" Else '存在 invQ = shZ.Cells(x, "E").Value ''在庫総量 If invQ <= 0 Then MsgBox c.Value & "の在庫がないので出庫できません" Else If outQ > invQ Then MsgBox c.Value & " 在庫:" & invQ & " VS 出庫:" & outQ & vbLf & _ "全量出庫できませんので在庫数量の範囲で出庫します" outQ = invQ End If
z = shZ.Cells(x, shZ.Columns.Count).End(xlToLeft).Column n = (z - 5) / 2 '賞味期限数 ReDim dtV(1 To n) ReDim qtV(1 To n) k = 0 For j = 6 To z Step 2 k = k + 1 qtV(k) = shZ.Cells(x, j).Value dtV(k) = shZ.Cells(x, j + 1).Value Next '有効期限の古いものから処理 For i = 1 To n dt = WorksheetFunction.Large(dtV, i) k = WorksheetFunction.Match(dt, dtV, 0) If outQ <= qtV(k) Then qtV(k) = qtV(k) - outQ outQ = 0 Exit For Else outQ = outQ - qtV(k) qtV(k) = 0 End If Next '引き落とし後、在庫のあるものを抽出 ReDim newV(1 To n * 2) k = 0 For i = 1 To n If qtV(i) <> 0 Then k = k + 1 newV(k) = qtV(i) '在庫数 k = k + 1 newV(k) = dtV(i) '賞味期限 End If Next '更新結果の書き込み shZ.Cells(x, "F").Resize(, n * 2).Value = newV shZ.Cells(x, "E").Value = calTotal(shZ, CLng(x)) End If End If End If Next End With 'なくなった商品行を削除、不要になったタイトルをクリア With shZ z = .Range("E2").End(xlToRight).Column 'タイトル行の一番右の列 n = 0 For i = .Range("D" & .Rows.Count).End(xlUp).Row To 3 Step -1 If .Cells(i, "E").Value = 0 Then '在庫のない行を削除 .Rows(i).Delete Else '残ったデータの一番右の列 n = WorksheetFunction.Max(n, .Cells(i, .Columns.Count).End(xlToLeft).Column) End If Next If n < z Then '余分なタイトルをクリア .Cells(2, n + 1).Resize(, z - n).ClearContents End If End With
shZ.Select Application.ScreenUpdating = True MsgBox "出庫処理がおわりました"
End Sub
Private Function calTotal(sh As Worksheet, i As Long) As Long Dim x As Long For x = 6 To sh.Cells(i, sh.Columns.Count).End(xlToLeft).Column Step 2 calTotal = calTotal + sh.Cells(i, x).Value Next End Function
(ぶらっと)
仕事でバタバタして返信遅くなり申し訳ないです。
お忙しいのに対応していただきありがとうございます!!!!!!!!!
今、ちょっと別の作業がたて込んでいて
まだ触っていないですが、時間見つけてやってみます!!!
火曜以降のご連絡とかもご丁寧にありがとうございます!
各シートのA列は「完全空白列」と考えていいのかな?
→その通りです。ご連絡せず、申し訳ございません。
あと、ぶらっとさん、逃避行とか
飾らない文面、面白い方ですね!
ありがとうございます!
Hate
ちょっと時間見つけてやってみました。
本当にありがとうございます。
ちょっと質問していいですか?
まず、私VBAに関しては素人すぎて全く理解できていないので
初歩すぎる質問かもしれませんが
まず、そもそも各Sheetのレイアウトが違うと話にならないかもなので
Sheet1
B C D E F G H I J K 1 商品名 商品名2 品番 総在庫 在庫 賞味期限 在庫 賞味期限 在庫 賞味期限 2 ジュース 360ml a-1 250 50 20130601 100 20130701 100 20130801 3 牛乳 150ml b-1 150 50 20130609 100 20130801 4 お茶 150ml c-1 100 100 20130610
Sheet2(入荷)
B C D E G 1 商品名 商品名2 品番 入荷数 賞味期限
Sheet3(出荷)
B C D E 1 商品名 商品名2 品番 出荷数
まずは上記で間違いないでしょうか??
質問
入荷について
Sheet2(入荷)
B C D E G 1 商品名 商品名2 品番 入荷数 賞味期限 2 ジュース 360ml a-1 100 20130801 これを入力しても 「インデックスが有効範囲にありません」 この表示のみになります! 自分で調べたもののよくわからずでした...
出荷について
\x{fffd}@賞味期限の新しい分から数値が減っていきます。
sheet3に
B C D E 1 商品名 商品名2 品番 出荷数 2 ジュース 360ml a-1 10
と入力しても
Sheet1の
B C D E F G H I J K 1 商品名 商品名2 品番 総在庫 在庫 賞味期限 在庫 賞味期限 在庫 賞味期限 2 ジュース 360ml a-1 250 50 20130601 100 20130701 90 20130801
20130801の分から減っていってしまいます。
\x{fffd}A出荷可能在庫がなくなった時に、在庫 賞味期限が まるまる消えるのですが
賞味期限だけを残す事は可能でしょうか??
仮に出荷数110として
sheet3に
B C D E 1 商品名 商品名2 品番 出荷数 2 ジュース 360ml a-1 110 と入力したら
Sheet1
B C D E F G H I J K 1 商品名 商品名2 品番 総在庫 在庫 賞味期限 在庫 賞味期限 在庫 賞味期限 2 ジュース 360ml a-1 140 50 20130601 90 20130701
J、Kの数値が消えるのを
賞味期限は残す
(賞味期限を残す事で、出荷時の検品の際、古いアイテムがちゃんと出ているのを確かめるためなのです..)
わかりにくい説明で申し訳ないです。
\x{fffd}B出荷可能数を越えたら、不足分をマイナス表示は可能でしょうか??
仮に出荷数110として
sheet3に
B C D E 1 商品名 商品名2 品番 出荷数 2 お茶 150ml c-1 110 と入力したら
Sheet1
B C D E F G H I J K 1 商品名 商品名2 品番 総在庫 在庫 賞味期限 在庫 賞味期限 在庫 賞味期限 4 お茶 150ml c-1 100 -10 20130610
こういうのは可能でしょうか?
(不足数を知るためなのです)
長々と、質問すいません。
素人すぎるので申し訳ないです。
ご確認宜しくお願い致します
Hate
今、まだ逃避行中でエクセルのない場所で閲覧しているだけなので本格的な回答は明日まで待ってね。 とりあえず回答できる範囲で。
・レイアウトは1つをのぞき同じ理解。入荷シートの賞味期限はF列じゃなかったの? E列に総量を追加するのは在庫シートのみと考えていた。
・「インデックスが有効範囲にありません」 出庫ではでずに、入庫でのみでたということは With Sheets("Sheet2") '入庫シート ここでエラーになっているのかな? 考えられる理由は1つだけ。"Sheet2"という名前のシートが存在しないということだけど? 後ろにスペースがついているとか?
・\x{fffd}@賞味期限の新しい分から数値が減っていきます。
ごめん!おはずかしい。日付の大きなもの、つまり、新しいものから引き落としていた。 dt = WorksheetFunction.Large(dtV, i) これを Small にかえればいいんだけど、明日、訂正版としてアップするね。
・\x{fffd}A出荷可能在庫がなくなった時に、在庫 賞味期限が まるまる消えるのですが 賞味期限だけを残す事は可能でしょうか??
うん。できるよ。いまは、わざわざ、けしているので、それをやめればいい。 ということは、在庫総量がゼロになっても残すという事だね。
でも・・・そのうちに行がいっぱいになってしまうよねぇ、いつの日か。
(ぶらっと)
入庫エラーについては↑でコメントしたとおりなので確認お願い。 出庫については、以下。出荷数量が在庫を上回っても、最新の賞味期限のもにを出荷しマイナス表示。
Sub 出庫() Dim c As Range Dim x As Variant Dim z As Long Dim i As Long Dim j As Long Dim k As Long Dim n As Long Dim dt As Long Dim shZ As Worksheet Dim dtV() As Long Dim qtV() As Long Dim outQ As Long Dim newV() As Variant
Application.ScreenUpdating = False
Set shZ = Sheets("Sheet1") '在庫シート
With Sheets("Sheet3") '出庫シート For Each c In .Range("D2", .Range("D" & .Rows.Count).End(xlUp)) outQ = c.Offset(, 1).Value If outQ = 0 Then MsgBox c.Value & " の出庫数量がゼロ。スキップします" Else '在庫シートの存在チェック x = Application.Match(c.Value, shZ.Columns("D"), 0) If Not IsNumeric(x) Then MsgBox c.Value & " が在庫シートにありません。スキップします" Else '存在 z = shZ.Cells(x, shZ.Columns.Count).End(xlToLeft).Column n = (z - 5) / 2 '賞味期限数 ReDim dtV(1 To n) ReDim qtV(1 To n) k = 0 For j = 6 To z Step 2 k = k + 1 qtV(k) = shZ.Cells(x, j).Value dtV(k) = shZ.Cells(x, j + 1).Value Next '有効期限の古いものから処理 For i = 1 To n dt = WorksheetFunction.Small(dtV, i) '★訂正 k = WorksheetFunction.Match(dt, dtV, 0) If i = n Or outQ <= qtV(k) Then qtV(k) = qtV(k) - outQ outQ = 0 Exit For Else outQ = outQ - qtV(k) qtV(k) = 0 End If Next '更新結果を行イメージに変換 ReDim newV(1 To n * 2) k = 0 For i = 1 To n k = k + 1 If qtV(i) <> 0 Then newV(k) = qtV(i) '在庫数 k = k + 1 newV(k) = dtV(i) '賞味期限 Next '更新結果の書き込み shZ.Cells(x, "F").Resize(, n * 2).Value = newV shZ.Cells(x, "E").Value = calTotal(shZ, CLng(x)) End If End If Next End With
shZ.Select Application.ScreenUpdating = True MsgBox "出庫処理がおわりました"
End Sub
(ぶらっと)
早速やりました!素晴らしすぎです!!!
入荷も私のミスでした!
・レイアウトは1つをのぞき同じ理解。入荷シートの賞味期限はF列じゃなかったの?
→こちらは私の勘違いでした。Fで間違いありません。すいません。
入荷での質問させてください!
入荷処理がうまくいきません。
まずSheet1の在庫が仮に
Sheet1
B C D E F G H I J K 1 商品名 商品名2 品番 総在庫 在庫 賞味期限 在庫 賞味期限 在庫 賞味期限 2 ジュース 360ml a-1 250 50 20130601 100 20130701 100 20130801 3 牛乳 150ml b-1 150 50 20130609 100 20130801 4 お茶 150ml c-1 100 100 20130610
だとしまして
Sheet2の入荷に以下を
B C D E G 1 商品名 商品名2 品番 入荷数 賞味期限 2 ジュース 150ml a-1 10 20130601
すると、型が一致しません と表示され
以下のように、F,G 列の 1行目が 在庫数 賞味期限 と 入力されます。
L、Mの2行目にも 在庫数 賞味期限 と 入力されます。
Sheet1
B C D E F G H I J K 1 商品名 商品名2 品番 総在庫 在庫 賞味期限 在庫 賞味期限 在庫 賞味期限 2 ジュース 360ml a-1 250 在庫数 賞味期限 100 20130701 100 20130801 3 牛乳 150ml b-1 150 50 20130609 100 20130801 4 お茶 150ml c-1 100 100 20130610
しかし
Sheet2の入荷に 牛乳にすると
B C D E G 1 商品名 商品名2 品番 入荷数 賞味期限 2 牛乳 150ml b-1 10 20130601
うまく入荷作業いきます。
でもでも
Sheet2の 入荷の3行目に お茶にすると
B C D E G 1 商品名 商品名2 品番 入荷数 賞味期限 2 3 お茶 150ml c-1 10 20130601
Range メソッドは失敗しました worksheet オブジェクト
と表示されます。
自力無理です...
因みに、出荷完璧すぎです!!!!!
興奮してます!!嬉しすぎて目が覚めました
Hate
入荷の件、こちらで、今回アップされたテストデータで実行したけど、問題なく処理される。 入荷シート(出荷シートも同様だけど)1行目がタイトル行、データは2行目からだけど そこは大丈夫?
ちょっと気になるのは "在庫数"とセットされるというところ。 最初にアップしたコードでは、タイトル行に"在庫数"というコンスタント値をコードの中で埋め込んでいるけど 2回目に出荷とともにフルセットアップした入荷のコードでは、それをやめたので、"在庫数" とセットされると言うことは ありえないんだけど?
2回目にアップしなおしたコードを使ってくれているかな?
引き続き、こちらでも調査してみるけど、確認お願いね。
追記
>型が一致しません
や
>Range メソッドは失敗しました worksheet オブジェクト
具体的に、どのコードが黄色く光っていたか教えてね。
(ぶらっと)
またまた、私の勘違いでした!
2回目にアップしなおしたコードを使ってくれているかな?
1回目の分でした...!
今度こそ入荷、出荷ともに完璧!!です!!!
私が求めていた、、、、本当にに求めていた事を実現してくれるなんて...
言葉じゃ言い表せないくらい感謝してます!!!!
Hate
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.