必要に迫られて簡易的な在庫管理システムを作りました。
在庫管理システムを作るにあたり、それはもう膨大な数のWebサイトを参考にしました。そのまま使えるAccessの在庫管理システムがあればいいのに、そのまま使えるものは一つもありませんでした。そこで在庫管理だけ必要な人向けの簡易なAccessデータベースを作りましたので、それを公開します。ごく簡単なデータベースです。
各々の環境に合わせて作り変えていただければ、と思います。特にデザインには自信がありません。各自のデザインセンスに合わせて作り変えてください。
Accessを単なるテーブルだけのデータベースとして使ったことはあっても、クエリやVBAを使ってシステムを組むのはこれが初めての経験でした。在庫管理システムは前職で使用していたSAPを念頭にして作りました。しかしAccessだけではSAPのようにはいきませんね。(注:SAPは在庫管理だけでなく、受注から組み立て・売上処理まで含んだシステムです)
この在庫管理システムはマクロを一切使用しておりません。VBAを基本としております。
最後にサンプルのデータベースをダウンロードできるようにしておきました。ここに記載のものをハナから入力するよりかは、ダウンロードしたAccessデータベースファイルを加工して使っていただいた方が便利かと思います。
-
-
VBAでのデバッグ
VBA(VB for Application)でのデバッグ方法がわからなくて苦労されている方はいらっしゃいますか?下記の方法をご存じない方はやってみてください。デバッグの効率が上がります。
続きを見る
一部記事の内容表示がうまくできなくなっています。いつから発生しているのかわかりません。復旧までお時間をください。
8月6日追記:サーバーを移転したことで、画像表示がなくなった箇所があります。近日中に修正します。
データベースの改訂履歴
テーブルやクエリを改造(項目を追加)した際の修正について
クエリから改造しようとして、一旦テーブルを削除・・・などとすると、後々とても面倒なことになります(経験上)。
各所に記述されているSQL文を修正した方が早いですので、その場合についてまとめました。必要に応じて参照ください。
-
-
クエリが参照するテーブルを変更した場合(Access)
Accessで在庫管理システムを作成中です⇩ 皆さん、それぞれの会社の仕組みに合わせてカスタマイズしたいと思います。テーブルの名前を変更したり、フィールドを追加しても、クエリに反映されませんよね。そこ ...
続きを見る
フォームのプロパティ(共通)
プロパティ | 変更後の設定 |
ポップアップ | はい |
レコードセレクタ | いいえ |
移動ボタン | いいえ |
境界線スタイル | なし(一部はサイズ調整可) |
試行錯誤のうえで到達しているため、書き漏らしたことがまだまだあるかと思います。
テーブルの作成
テーブルの数が多いために、一覧をタブにしましたが、タブでも見づらいでしょうか?ご勘弁ください。
ID | オートナンバー型 |
品目コード | 数値型 |
品目型式 | テキスト型 |
メーカー | テキスト型 |
安全在庫 | 数値型 |
最小ロット | 数値型 |
標準ロット | 数値型 |
標準納期 | 数値型 |
仕入先コード | 数値型 |
保管場所コード | 数値型 |
Webサイト | ハイパーリンク型 |
削除 | Yes/No型 |
ID | オートナンバー型 |
保管場所コード | 数値型 |
保管場所 | テキスト型 |
ID | オートナンバー型 |
社員コード | 数値型 |
社員 | テキスト型 |
所属 | テキスト型 |
権限 | テキスト型 |
パスワード | テキスト型 |
平文 | テキスト型 |
削除 | Yes/No型 |
平文はパスワードそのものです(パスワードの項目にはSHA256で計算されたハッシュ値が入ります)。
動作確認用ですので、実際に運用の際には削除ください。
ID | オートナンバー型 |
入出庫コード | 数値型 |
入出庫 | テキスト型 |
ID | オートナンバー型 |
仕入先コード | 数値型 |
仕入先会社名 | テキスト型 |
郵便番号 | 数値型 |
住所 | テキスト型 |
電話番号 | 数値型 |
FAX番号 | 数値型 |
営業担当者 | テキスト型 |
携帯電話番号 | 数値型 |
Eメールアドレス | テキスト型 |
削除 | Yes/No型 |
ID | オートナンバー型 |
入出庫コード | 数値型 |
入出庫 | テキスト型 |
ID | オートナンバー型 |
日付 | 日付/時刻型 |
社員コード | 数値型 |
品目コード | 数値型 |
入出庫コード | 数値型 |
数量 | 数値型 |
単位コード | 数値型 |
削除 | Yes/No型 |
削除日付 | 日付/時刻型 |
ID | オートナンバー型 |
検索履歴 | テキスト型 |
ID | オートナンバー型 |
社員コード | 数値型 |
日時 | 日付/時刻型 |
成功or失敗 | Yes/No型 |
IPアドレス | テキスト型 |
ID | オートナンバー型 |
成功or失敗 | Yes/No型 |
ログイン | テキスト型 |
ID | オートナンバー型 |
指図番号 | テキスト型 |
予算 | 数値型 |
工数 | 数値型 |
「指図番号」の名称は自由に書き換えてください。前職では下記の「サイド番号」とセットでした。
ID | オートナンバー型 |
サイド番号 | 数値型 |
名前 | テキスト型 |
前職では000…工数、420…通信費、460…出張費など指図番号以下に使用目的のサイド番号がありました。必要に応じて使うなり削除するなりしてください。
ID | オートナンバー型 |
バージョン | 数値型 |
更新内容 | テキスト型 |
ログイン画面
ログイン画面については別途記事を作成しております。
-
-
アクセス履歴付き ログイン画面を作る(Access)(サンプル付き)
在庫管理システムを作っていて、ログインが必要かなと思いました。ハッシュ値(SHA256)の求め方が載っているサイトを見つけましたので、ログイン画面だけのサンプルを作ってみました。アクセス履歴のログ作成機能付きです。Accessユーザーの参考になれば幸いです。
続きを見る
在庫管理システムの方にエクスポートした後、以下のVBAコードを修正します。
ログイン画面のVBA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
Option Compare Database Private Sub cmd_ログイン_Click() Dim rs1 As DAO.Recordset Dim rs2 As DAO.Recordset Dim sql As String If IsNull(Me.cmb_社員コード) Then MsgBox "社員コードを入力してください" Exit Sub End If If IsNull(Me.txt_パスワード) Then MsgBox "パスワードを入力してください" Exit Sub End If sql = "SELECT * FROM T_社員 WHERE 社員コード=" & Me.cmb_社員コード Set rs1 = CurrentDb.OpenRecordset(sql) Set rs2 = CurrentDb.OpenRecordset("T_ログイン履歴", dbOpenTable) With rs2 If rs1.EOF Then MsgBox "レコードがみつかりません" ElseIf rs1.Fields("パスワード") <> SHA256(Me.txt_パスワード) Then MsgBox "パスワードが違います" .AddNew .Fields("社員コード") = Me.cmb_社員コード .Fields("日時") = Now .Fields("成功or失敗") = False .Fields("IPアドレス") = GetIPAddress .Update lngLoginID = 0 Else 'MsgBox "ログインしました" .AddNew .Fields("社員コード") = Me.cmb_社員コード .Fields("日時") = Now .Fields("成功or失敗") = True .Fields("IPアドレス") = GetIPAddress .Update lngLoginID = Me.cmb_社員コード DoCmd.Close End If End With rs1.Close Set rs1 = Nothing rs2.Close Set rs2 = Nothing If lngLoginID <> 0 Then DoCmd.OpenForm ("F_メイン") End Sub Private Sub cmd_PW変更_Click() DoCmd.OpenForm "F_PW変更" If IsNull(txt_社員コード) Then Forms![F_PW変更]![txt_社員コード].SetFocus Else Forms![F_PW変更]![txt_社員コード].Value = Me!cmb_社員コード Forms![F_PW変更]![txt_社員コード].SetFocus End If End Sub Private Sub txt_パスワード_Enter() Dim rs As DAO.Recordset Dim sql As String sql = "SELECT * FROM T_社員 WHERE 社員コード=" & Me!cmb_社員コード Set rs = CurrentDb.OpenRecordset(sql) If rs.Fields("初期パスワード") = True Then MsgBox "初期パスワードを変更してください" cmd_PW変更_Click End If End Sub |
ログイン履歴のVBA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Option Compare Database Private Sub Form_Resize() Me.Q_ログイン履歴のサブフォーム.Width = Me.InsideWidth Me.Q_ログイン履歴のサブフォーム.Height = Me.InsideHeight End Sub Private Sub cmd_Clear_Click() On Error Resume Next DoCmd.RunSQL "DELETE FROM T_ログイン履歴" DoCmd.Requery End Sub Private Sub cmd_close_Click() DoCmd.Close End Sub Private Sub cmd_エクスポート_Click() DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "Q_ログイン履歴", "在庫管理.xls", True, "ログイン履歴" MsgBox ("マイドキュメントにエクスポートしました") End Sub |
メインフォーム
F_メイン
【作成】からフォームの中の【空白のフォーム】を選んで、コマンドボタンを貼っていきます。1つコマンドボタンを作ったらコピペで増やしていくと、同じサイズのボタンになります。ヘッダーとフッターも使用しました。

メインメニューの下半分、管理者メニューとし、管理者でログインした以外はグレーアウトするようにしてあります。

コマンドボタンを配置します。
ここでは「cmd_入出庫処理」「cmd_入出庫履歴」
「cmd_在庫転送」「cmd_単位変換」
「cmd_在庫検索」「cmd_安全在庫」
「cmd_品目マスタ」「cmd_社員マスタ」「cmd_社員マスタ」
「cmd_ログイン履歴」「cmd_閉じる」
としております。
メインフォームのVBA
フォームのデザインを開き、【デザイン】タブの【コードの表示】から、VBAの画面に遷移します。

メインフォームのVBAは下記の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
Option Compare Database Private Sub cmd_入出庫処理_Click() DoCmd.OpenForm "F_入出庫処理" End Sub Private Sub cmd_入出庫履歴_Click() DoCmd.OpenForm "F_入出庫履歴" End Sub Private Sub cmd_在庫検索_Click() DoCmd.OpenForm "F_在庫検索" End Sub Private Sub cmd_在庫転送_Click() DoCmd.OpenForm "F_在庫転送" End Sub Private Sub cmd_安全在庫_Click() DoCmd.OpenForm "F_安全在庫" End Sub Private Sub cmd_単位変換_Click() DoCmd.OpenForm "F_単位変換" End Sub Private Sub cmd_品目マスタ_Click() DoCmd.OpenForm "F_品目マスタ" End Sub Private Sub cmd_社員マスタ_Click() DoCmd.OpenForm "F_社員マスタ" End Sub Private Sub cmd_仕入先マスタ_Click() DoCmd.OpenForm "F_仕入先マスタ" End Sub Private Sub cmd_ログイン履歴_Click() DoCmd.OpenForm "F_ログイン履歴" End Sub Private Sub cmd_閉じる_Click() DoCmd.Close End Sub Private Sub Form_Open(Cancel As Integer) If lngLoginID <> lngAdmin Then cmd_品目マスタ.Enabled = False cmd_社員マスタ.Enabled = False cmd_仕入先マスタ.Enabled = False cmd_ログイン履歴.Enabled = False End If End Sub |
コマンドボタンのプロパティのイベントが空のままです。イベントを割り当てなければなりませんので、【プロパティシート】の【イベント】タブの【…】をクリックします。

【コードビルダー】を選んで【OK】をクリックします。上述のVBAのコードに飛びます。コマンドボタン1つ1つにこの作業が必要です。

入出庫処理
F_入出庫処理
Access素人には苦労したフォームです。空白のフォームから下記のようにコントロールを配置していきます。

日付:テキストボックス(名前:txt_日付、プロパティで書式を「日付 (S)」に変更する)
品目:コンボボックス(名前:cmb_品目)、直下にラベル配置(名前:lbl_品目)
数量:テキストボックス(名前:txt_数量)
入出庫:コンボボックス(名前:cmb_入出庫)、右横にラベル配置(名前:lbl_入出庫)
単位:コンボボックス(名前:cmb_単位)、右横にラベル配置(名前:lbl_単位)
保管場所:コンボボックス(名前:cmb_保管場所)、右横にラベル(lbl_保管場所)社員:コンボボックス(名前:cmb_社員)、右横にラベル配置(名前:lbl_社員)
品目検索ボタン:コマンドボタン(名前:cmd_品目検索)
OKボタン:コマンドボタン(名前:cmd_OK)
Cancelボタン:コマンドボタン(名前:cmd_Cancel)
終了ボタン:コマンドボタン(名前:cmd_終了)
コンボボックスについてはもう少し記載しておきます。【プロパティシート】の【データ】タブの中の【値集合ソース】を下記のようにします。
cmb_品目:SELECT T_品目.品目コード,T_品目.品目型式 FROM T_品目 ORDER BY T_品目.品目型式;
cmb_入出庫:SELECT T_入出庫.入出庫コード,T_入出庫.入出庫 FROM T_入出庫;
cmb_単位:SELECT T_単位.単位コード , T_単位.単位 FROM T_単位;
cmb_保管場所:SELECT T_保管場所.保管場所コード,T_保管場所.保管場所 FROM T_保管場所;cmb_社員:SELECT 社員.社員コード,社員.社員 FROM 社員;
コンボボックスは【プロパティシート】にて【列数】を「2」にします。そうすることによって、コンボボックスのプルダウンにて「コード」と「名前」が同時に表示できるようになります。選択される時は「コード」の方にしてあります。各列の幅が長かったり、短かったりすると思います。サンプルでは「列幅」に「1.5cm;5cm」を入力してあります。この数値を調整してください。コンボボックスの直下にラベルを配置したのは、コードだけでは不十分ですので、コードに対応する名前をラベルに表示させて、間違いを防止するようにします。

入出庫処理フォームのVBA
フォームのデザインを開き、【デザイン】タブの【コードの表示】から、VBAの画面に遷移します。

フォーム「F_入出庫処理」のVBAは下記の通りです。項目に空欄があると警告を出すようにしています。
「cmd_Cancel」ボタンを押すと、全てのコントロールを初期化してデータベースは更新しません。
データベースを更新したときにはAccessは何もアクションがないため、コントロールを初期化してメッセージボックスでデータベースを更新したことを報せます。
入出庫データは「T_入出庫処理」テーブルに格納されていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
Option Compare Database Private Sub Form_Load() ClearControls End Sub Private Sub cmd_OK_Click() Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_入出庫処理", dbOpenTable) If Me.txt_日付.Value = "" Or Me.cmb_品目.Value = "" Or Me.cmb_入出庫.Value = "" Or Me.txt_数量.Value = "" Or Me.cmb_単位.Value = "" Or Me.cmb_保管場所.Value = "" Then MsgBox ("空欄があります") Exit Sub End If With rst .AddNew .Fields("日付") = Me.txt_日付 .Fields("品目コード") = Me.cmb_品目 .Fields("入出庫コード") = Me.cmb_入出庫 .Fields("数量") = Me.txt_数量 .Fields("単位コード") = Me.cmb_単位 .Fields("保管場所コード") = Me.cmb_保管場所 .Fields("社員コード") = lngLoginID .Fields("指図番号") = Me.cmb_指図番号 & "-" & Me.cmb_サイド番号 .Update End With rst.Close Set rst = Nothing MsgBox ("記入しました") Call ClearControls End Sub Private Sub cmd_品目検索_Click() DoCmd.OpenForm "F_品目検索" strFormName = "F_入出庫処理" End Sub Private Sub cmd_Cancel_Click() Call ClearControls End Sub Private Sub cmd_終了_Click() DoCmd.Close acForm, "F_入出庫処理", acSaveNo End Sub Sub ClearControls() With Me .txt_日付 = Date .cmb_品目.Value = "" .lbl_品目.Caption = "" .txt_数量.Value = "" .cmb_単位.Value = 529 .lbl_単位.Caption = "個" .cmb_入出庫.Value = "" .lbl_入出庫.Caption = "" .cmb_保管場所.Value = "" .lbl_保管場所.Caption = "" .cmb_指図番号.Value = "" .cmb_サイド番号.Value = "" End With End Sub Private Sub cmb_品目_AfterUpdate() On Error Resume Next Me.lbl_品目.Caption = cmb_品目.Column(1) End Sub Private Sub cmb_入出庫_BeforeUpdate(Cancel As Integer) If (Me.cmb_入出庫.Value = 610 Or Me.cmb_入出庫.Value = 601) And Me.txt_数量.Value > 0 Then Me.txt_数量.Value = Me.txt_数量.Value * (-1) End If If (Me.cmb_入出庫.Value = 611 Or Me.cmb_入出庫.Value = 600) And Me.txt_数量.Value < 0 Then Me.txt_数量.Value = Me.txt_数量.Value * (-1) End If End Sub Private Sub cmb_単位_AfterUpdate() On Error Resume Next Me.lbl_単位.Caption = cmb_単位.Column(1) End Sub Private Sub cmb_入出庫_AfterUpdate() On Error Resume Next Me.lbl_入出庫.Caption = cmb_入出庫.Column(1) End Sub Private Sub cmb_保管場所_AfterUpdate() On Error Resume Next Me.lbl_保管場所.Caption = cmb_保管場所.Column(1) End Sub |
入庫及び出庫取り消しのときにはプラスに、出庫及び入庫取り消しのときにはマイナスになるようにします。しかし、いかんせん、入出庫処理をせずに品目や商品を持っていったり入れたりする人がいるものです。棚卸しして差異が生じたときには「棚卸調整」にて増えたらプラスに減っていたらマイナスの数量を入力するようにします。
上記コードにて「600」が入庫、「601」は入庫取り消し。「610」は出庫、「611」は出庫取り消しとしております。これはサンプルデータベースの数値ですので、変更時には上記コードも修正ください。
F_品目検索
会社では在庫品目の種類が思いの外多く、また類似の品目名が多々存在するために、品目検索のフォームを作りました。
当初はフォーム「F_入出庫処理」からのみ呼び出していましたが、「F_在庫転送」や「F_単位変換」からも呼び出せるようにしました。
Q_品目
検索のためにテーブル「T_品目」だけを置いたクエリ「Q_品目」を作ります。

抽出条件はVBAで記載しますので、ここでは書きません。
SQLビュー
1 2 3 |
SELECT T_品目.品目コード, T_品目.品目型式 FROM T_品目 ORDER BY T_品目.品目型式; |
上記SQLをクエリにコピーするには【作成】タブから【クエリデザイン】を選びます。【テーブルの選択】は閉じて、現れたウィンドウのタブの部分で右クリックし、【SQLビュー】を選びます。【SQLビュー】の状態でコードをペーストし、タブから【デザインビュー】を選べば元に戻ります。

F_品目検索のフォーム
空白のフォームから下記のようにコントロールを配置していきます。

品目型式:コンボボックス(名前:cmb_品目型式)
クエリ「Q_品目」を呼び出します。クエリの条件にテキストボックスの品目名の一部を使いますので、テキストボックスの下にそのような表記をラベルで作っておくと親切だと思われます。【プロパティシート】の【値集合ソース】は
1 |
select distinct T_検索履歴.検索履歴 from T_検索履歴 |
検索:コマンドボタン(名前:cmd_検索)
終了:コマンドボタン(名前:cmd_終了)
サブフォームコントロールは名前を「Q_品目のサブフォーム」としておきます。
F_品目検索のVBA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Option Compare Database Private Sub cmd_検索_Click() With Me.Q_品目のサブフォーム.Form .Filter = "品目型式 Like '*' & [Forms]![F_品目検索]![cmb_品目型式] & '*'" .FilterOn = True End With Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_検索履歴", dbOpenTable) With rst .AddNew .Fields("検索履歴") = Me.cmb_品目型式 .Update .Close End With Set rst = Nothing End Sub Private Sub Form_Resize() Me.Q_品目のサブフォーム.Width = Me.InsideWidth Me.Q_品目のサブフォーム.Height = Me.InsideHeight End Sub |
Q_品目のサブフォームのVBA
「品目コード」の部分でも「品目型式」の部分でもダブルクリックするとフォーム「F_入出庫処理」に値が入るようにしていますので、同じ記述が並んでおります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
Option Compare Database Private Sub 品目コード_DblClick(Cancel As Integer) Select Case strFormName Case "F_入出庫処理" DoCmd.OpenForm "F_入出庫処理" Forms![F_入出庫処理]![cmb_品目].value = Me!品目コード Forms![F_入出庫処理]![lbl_品目].Caption = Me!品目型式 Forms![F_入出庫処理]![txt_数量].SetFocus Case "F_在庫転送" DoCmd.OpenForm "F_在庫転送" Forms![F_在庫転送]![cmb_品目].value = Me!品目コード Forms![F_在庫転送]![lbl_品目].Caption = Me!品目型式 Forms![F_在庫転送]![txt_数量].SetFocus Case "F_単位変換" DoCmd.OpenForm "F_単位変換" Forms![F_単位変換]![cmb_品目].value = Me!品目コード Forms![F_単位変換]![lbl_品目].Caption = Me!品目型式 Forms![F_単位変換]![txt_変換前数量].SetFocus End Select DoCmd.Close acForm, "F_品目検索", acSaveNo End Sub Private Sub 品目型式_DblClick(Cancel As Integer) Select Case strFormName Case "F_入出庫処理" DoCmd.OpenForm "F_入出庫処理" Forms![F_入出庫処理]![cmb_品目].value = Me!品目コード Forms![F_入出庫処理]![lbl_品目].Caption = Me!品目型式 Forms![F_入出庫処理]![txt_数量].SetFocus Case "F_在庫転送" DoCmd.OpenForm "F_在庫転送" Forms![F_在庫転送]![cmb_品目].value = Me!品目コード Forms![F_在庫転送]![lbl_品目].Caption = Me!品目型式 Forms![F_在庫転送]![txt_数量].SetFocus Case "F_単位変換" DoCmd.OpenForm "F_単位変換" Forms![F_単位変換]![cmb_品目].value = Me!品目コード Forms![F_単位変換]![lbl_品目].Caption = Me!品目型式 Forms![F_単位変換]![txt_変換前数量].SetFocus End Select DoCmd.Close acForm, "F_品目検索", acSaveNo End Sub |
モジュール
このフォームを使いまわしをするために、標準モジュールに下記の1行を入れます。どのフォームから呼び出したかを記憶し、SELECT CASE文で帰るフォームの処理を振り分けします。
1 |
Public strFormName As String |
検索履歴機能
インターネットブラウザの検索テキストボックスのようにAccessのテキストボックスでも検索履歴を表示させたいと思い、検索履歴機能を追加してみました。
エッセンスは別記事にまとめてあります。
-
-
検索履歴つきテキストボックスをコンボボックスで実現(Access)
インターネットブラウザの検索テキストボックスのようにAccessのテキストボックスでも検索履歴を表示させたいと思い、この方法をやってみました。
続きを見る
入出庫履歴
Q_メイン
【作成】-【クエリデザイン】から「メイン」「品目」「入出庫」「社員」「単位」を選びます。

「メイン」と他の共通するコードを連結します。例えば「品目コード」を結びます。この時、結合線をダブルクリックしてプロパティを開き、

2の「’メイン’の全レコードと’品目’の同じ結合フィールドのレコードだけを含める」とします。他の結合線も同様です。
それから下記のようにします。

※必要に応じて表示させる項目を追加・削除してください。
このクエリから「Q_入出庫履歴」と「Q_集計」に転用します。「Q_入出庫履歴」と「Q_集計」はQ_メインを使わずに独自に作っても全然構いません。
SQLビュー
下記の記述を【SQLビュー】からコピペすると早いです。
1 2 |
SELECT T_入出庫処理.日付, T_入出庫処理.品目コード, T_品目.品目型式, T_品目.[メーカー], T_入出庫処理.数量, T_単位.単位, T_入出庫.入出庫, T_保管場所.保管場所, T_社員.社員, T_品目.安全在庫, T_入出庫処理.削除, T_入出庫処理.ID, T_入出庫処理.削除日付, T_指図番号.指図番号 FROM (((((T_入出庫処理 LEFT JOIN T_社員 ON T_入出庫処理.社員コード = T_社員.社員コード) LEFT JOIN T_単位 ON T_入出庫処理.単位コード = T_単位.単位コード) LEFT JOIN T_入出庫 ON T_入出庫処理.入出庫コード = T_入出庫.入出庫コード) LEFT JOIN T_品目 ON T_入出庫処理.品目コード = T_品目.品目コード) LEFT JOIN T_保管場所 ON T_入出庫処理.保管場所コード = T_保管場所.保管場所コード) LEFT JOIN T_指図番号 ON T_入出庫処理.指図番号 = T_指図番号.指図番号; |
Q_入出庫履歴
Q_入出庫履歴には「Q_メイン」を利用します。

VBAを使わずにクエリにて抽出条件を記載する場合です。画像ですと抽出条件が見づらいため、表にします。
フィールド | 日付 | 品目型式 | [Forms]![F_入出庫履歴]![txt_開始日付] | [Forms]![F_入出庫履歴]![txt_終了日付] |
テーブル | Q_メイン | Q_メイン | ||
並べ替え | ||||
表示 | ||||
抽出条件 | >[Forms]![F_入出庫履歴]![txt_開始日付] And <[Forms]![F_入出庫履歴]![txt_終了日付] | Like "*" & [Forms]![F_入出庫履歴]![cmb_品目型式] & "*" | ||
または | <[Forms]![F_入出庫履歴]![txt_終了日付] | Like "*" & [Forms]![F_入出庫履歴]![cmb_品目型式] & "*" | Is Null | |
>[Forms]![F_入出庫履歴]![txt_開始日付] | Like "*" & [Forms]![F_入出庫履歴]![cmb_品目型式] & "*" | Is Null | ||
Like "*" & [Forms]![F_入出庫履歴]![cmb_品目型式] & "*" | Is Null | Is Null |
SQLビュー
1 2 3 |
SELECT Q_メイン.日付, Q_メイン.品目コード, Q_メイン.品目型式, Q_メイン.数量, Q_メイン.単位, Q_メイン.[メーカー], Q_メイン.保管場所, Q_メイン.入出庫, Q_メイン.社員, Q_メイン.削除, Q_メイン.ID, Q_メイン.削除日付 FROM Q_メイン ORDER BY Q_メイン.日付 DESC; |
F_入出庫履歴
入出庫履歴を表示するフォームです。全て見えると規模によっては邪魔になりますので、「品目型式」、「履歴の開始日付」、「履歴の終了日付」で検索できるようにしています。

品目型式:コンボボックス(名前:cmb_品目型式)
開始日付:テキストボックス(名前:txt_開始日付)
終了日付:テキストボックス(名前:txt_終了日付)
サブフォームの配置は下記を参照ください。
サブフォームの配置の仕方
【デザイン】タブのコントロールのサブフォームをクリックします。このとき、【コントロールウィザードの使用】をONしておきます。

下の図のまま【次へ】をクリックします。

【テーブル/クエリ】から「Q_入出庫履歴」を選び、全ての項目を【選択したフィールド】へ移します。

【完了】でも良いですが、【次へ】をクリックすればサブフォームの名前を付ける画面になります。

サブフォームサイズや、フィールドの幅は各自適宜変えてください。
名前は「Q_入出庫履歴のサブフォーム」のままとしました。気に入らない方は変えてください。
入出庫処理取り消し
当初、取り消し処理のコードを用意していましたが、「削除」フィールドを利用することにしました。
フォーム「入出庫履歴」のフィールド「入出庫」の項目をダブルクリックしますと、入出庫処理取り消しの確認のメッセージボックスが表示されます。そこで「はい(Yes)」を選択すると、該当する入出庫処理のフィールド「削除」にチェックが入ります。このチェックが入った処理は「在庫検索」処理にも反映されません。
入出庫履歴フォームのVBA
「検索ボタン」のプロパティからイベントプロシージャを選択して、下記のようにVBAコードを記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
Option Compare Database Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeyReturn KeyCode = 0 Call cmd_検索_Click Case vbKeyEscape KeyCode = 0 Call CMD_終了 End Select End Sub Private Sub cmd_検索_Click() On Error Resume Next Dim strFilter As String strFilter = "" If (Not IsNull(Me.cmb_品目型式)) Then strFilter = "(Q_メイン.品目型式 Like '*' & [Forms]![F_入出庫履歴]![cmb_品目型式] & '*')" If (Not IsNull(Me.txt_開始日付)) Or (Not IsNull(Me.txt_終了日付)) Then strFilter = strFilter & " and " End If End If If (Not IsNull(Me.txt_開始日付)) Then strFilter = strFilter & "Q_メイン.日付 >= [Forms]![F_入出庫履歴]![txt_開始日付]" If (Not IsNull(Me.txt_終了日付)) Then strFilter = strFilter & " and " End If End If If (Not IsNull(Me.txt_終了日付)) Then strFilter = strFilter & "Q_メイン.日付 <= [Forms]![F_入出庫履歴]![txt_終了日付]" End If Debug.Print strFilter If (Not IsNull(strFilter)) Then With Me.Q_入出庫履歴のサブフォーム.Form .Requery .Filter = strFilter .FilterOn = True End With End If Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_検索履歴", dbOpenTable) With rst .AddNew .Fields("検索履歴") = Me.cmb_品目型式 .Update .Close End With Set rst = Nothing End Sub Private Sub cmd_終了_Click() DoCmd.Close acForm, "F_入出庫履歴", acSaveNo End Sub Private Sub cmd_エクスポート_Click() DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "Q_入出庫履歴", "在庫管理.xls", True, "入出庫履歴" MsgBox ("マイドキュメントにエクスポートしました") End Sub Private Sub Form_Resize() Me.Q_入出庫履歴のサブフォーム.Width = Me.InsideWidth Me.Q_入出庫履歴のサブフォーム.Height = Me.InsideHeight End Sub |
入出庫履歴サブフォームのVBA
フィールド「品目型式」をダブルクリックした時に、「在庫検索」フォームを開き、テキストボックスにダブルクリックした箇所の「品目型式」を渡す記述です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
Option Compare Database Private Sub 入出庫_DblClick(Cancel As Integer) Dim YesNo As Boolean Dim rs As DAO.Recordset If Me!削除.value = True Then Exit Sub YesNo = MsgBox("処理を取り消しますか?", vbYesNo, "処理取消") If YesNo = False Then Exit Sub Else Set rs = CurrentDb.OpenRecordset("T_入出庫処理", dbOpenDynaset) With rs .FindFirst "ID=" & Me!ID .Edit .Fields("削除") = True .Fields("削除日付") = Date .Update End With Set rs = Nothing MsgBox ("処理を取り消しました") End If End Sub Private Sub 品目型式_DblClick(Cancel As Integer) DoCmd.OpenForm "F_在庫検索" Forms![F_在庫検索]![cmb_品目型式].value = Me!品目型式 Forms!F_在庫検索!.Q_集計のサブフォーム.Requery End Sub |
在庫検索
Q_集計
「Q_メイン」クエリを利用して下記のように作ります。

計算がありますので、【デザイン】タブを開いて「Σ集計」をクリックしておきます。

Σ集計をクリックすると、今度は「集計」という行が現れます。下記のように「数量」を計算(合計)できるようにします。

「数量の合計:数量」となっているフィールドはプロパティを開いて【表題】を「在庫数」にしておくと、フォームが表示された時に「在庫数」と表示されます。
「品目型式」の抽出条件はVBAで記載します。
※必要に応じて表示させる項目を追加・削除してください。
SQLビュー
1 2 3 4 5 |
SELECT DISTINCTROW Q_メイン.保管場所, Q_メイン.品目コード, Q_メイン.品目型式, Q_メイン.[メーカー], Sum(Q_メイン.数量) AS [数量 の 合計], Q_メイン.単位, Q_メイン.安全在庫, Q_メイン.削除, Q_メイン.指図番号 FROM Q_メイン LEFT JOIN (T_品目 LEFT JOIN T_仕入先 ON T_品目.仕入先コード = T_仕入先.仕入先コード) ON Q_メイン.品目コード = T_品目.品目コード GROUP BY Q_メイン.保管場所, Q_メイン.品目コード, Q_メイン.品目型式, Q_メイン.[メーカー], Q_メイン.単位, Q_メイン.安全在庫, Q_メイン.削除, Q_メイン.指図番号 HAVING (((Q_メイン.削除)=False)) ORDER BY Q_メイン.保管場所; |
空白のフォームから下記のようにコントロールを配置していきます。

品目型式:コンボボックス(名前:cmb_品目型式)
検索:コマンドボタン(名前:cmd_検索)
終了:コマンドボタン(名前:cmd_終了)
サブフォームコントロールは名前を「Q_集計のサブフォーム」としておきます。
在庫検索フォームのVBA
「検索ボタン」のプロパティからイベントプロシージャを選択して、下記のようにVBAコードを記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
Option Compare Database Private Sub cmd_検索_Click() 'Me!Q_集計のサブフォーム.Requery With Me.Q_集計のサブフォーム.Form .Filter = "品目型式 Like '*' & [Forms]![F_在庫検索]![cmb_品目型式] & '*'" .FilterOn = True End With Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_検索履歴", dbOpenTable) With rst .AddNew .Fields("検索履歴") = Me.cmb_品目型式 .Update .Close End With Set rst = Nothing End Sub Private Sub cmd_エクスポート_Click() DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "Q_集計", "在庫管理.xls", True, "在庫数" MsgBox ("マイドキュメントにエクスポートしました") End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeyReturn KeyCode = 0 Call cmd_検索_Click Case vbKeyEscape KeyCode = 0 Call CMD_終了 End Select End Sub Private Sub cmd_終了_Click() DoCmd.Close acForm, "F_在庫検索", acSaveNo End Sub Private Sub Form_Resize() Me.Q_集計のサブフォーム.Width = Me.InsideWidth Me.Q_集計のサブフォーム.Height = Me.InsideHeight End Sub |
安全在庫
Q_安全在庫

「Q_集計」と似ていますが、数量の合計の抽出条件を下記のようにします。
1 |
<[T_品目].[安全在庫] |
品目型式の抽出条件はVBAにて記載します。「数量の合計:数量」をVBAに記載する方法がわかりませんでした。このクエリに残っております。
※必要に応じて表示させる項目を追加・削除してください。
SQLビュー
1 2 3 4 |
SELECT DISTINCTROW T_品目.品目コード, T_品目.品目型式, Sum(T_入出庫処理.数量) AS 数量の合計, T_品目.安全在庫, T_入出庫処理.削除 FROM T_入出庫処理 LEFT JOIN T_品目 ON T_入出庫処理.品目コード = T_品目.品目コード GROUP BY T_品目.品目コード, T_品目.品目型式, T_品目.安全在庫, T_入出庫処理.削除 HAVING (((Sum(T_入出庫処理.数量))<[T_品目].[安全在庫]) AND ((T_入出庫処理.削除)=False)); |
F_安全在庫
空白のフォームから下記のようにコントロールを配置していきます。

品目型式:コンボボックス(名前:cmb_品目型式)
検索:コマンドボタン(名前:cmd_検索)
終了:コマンドボタン(名前:cmd_終了)
サブフォームは「クエリQ_安全在庫」を選び「Q_安全在庫のサブフォーム」としました。
安全在庫フォームのVBA
安全在庫フォームのVBAです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
Option Compare Database Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeyReturn KeyCode = 0 Call cmd_検索_Click Case vbKeyEscape KeyCode = 0 Call CMD_終了 End Select End Sub Private Sub cmd_終了_Click() DoCmd.Close acForm, "F_安全在庫", acSaveNo End Sub Private Sub cmd_検索_Click() With Me.Q_安全在庫のサブフォーム.Form .Filter = "品目型式 Like '*' & [Forms]![F_安全在庫]![cmb_品目型式] & '*'" '.Filter = " and DSum(数量, Q_安全在庫, <[T_品目].[安全在庫])" .FilterOn = True End With Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_検索履歴", dbOpenTable) With rst .AddNew .Fields("検索履歴") = Me.cmb_品目型式 .Update .Close End With Set rst = Nothing End Sub Private Sub Form_Resize() Me.Q_安全在庫のサブフォーム.Width = Me.InsideWidth Me.Q_安全在庫のサブフォーム.Height = Me.InsideHeight End Sub |
安全在庫設定に引っかかる品目が生じたら、発注担当者などにEメールを飛ばせるようにしたいと考えていました。AccessではEメールは飛ばせないであろうという先入観から調べてもいませんでしたが、実際にはやろうと思えばできるようです。AccessデータベースによるEメール送信のサンプルを作ってみました。そのうちにこの在庫管理システムにも実装したいと思います。サンプルは下記を参照ください。
-
-
AccessデータベースからEメールを送る(サンプル付き)
在庫管理システムを作っていて「【安全在庫】に引っかかる品目が現れたら管理者にEメールを飛ばしたい」と思っていました。サンプルファイルを作って実行してみましたら、すんなり成功しました。サンプル付きです。
続きを見る
在庫転送
F_在庫転送
空白のフォームから下記のようにコントロールを配置していきます。

コントロールは「F_入出庫処理」とほぼ同様です。
日付:テキストボックス(名前:txt_日付、プロパティで書式を「日付 (S)」に変更する)
品目:コンボボックス(名前:cmb_品目)、直下にラベル配置(名前:lbl_品目)
数量:テキストボックス(名前:txt_数量)
単位:コンボボックス(名前:cmb_単位)、直下にラベル配置(名前:lbl_単位)
転送元:コンボボックス(名前:cmb_転送元)、直下にラベル配置(名前:lbl_転送元)
転送先:コンボボックス(名前:cmb_転送先)、直下にラベル配置(名前:lbl_転送先)社員:コンボボックス(名前:cmb_社員)、直下にラベル配置(名前:lbl_社員)
品目検索ボタン:コマンドボタン(名前:cmd_品目検索)
OKボタン:コマンドボタン(名前:cmd_OK)
Cancelボタン:コマンドボタン(名前:cmd_Cancel)
終了ボタン:コマンドボタン(名前:cmd_終了)
コンボボックスのプロパティシートのデータタブの中の値集合ソースを下記のようにします。
cmb_品目:SELECT T_品目.品目コード,T_品目.品目型式 FROM T_品目 ORDER BY T_品目.品目型式;
cmb_単位:SELECT T_単位.単位コード , T_単位.単位 FROM T_単位;
cmb_転送元:SELECT T_保管場所.保管場所コード,T_保管場所.保管場所 FROM T_保管場所;
cmb_転送先:SELECT T_保管場所.保管場所コード,T_保管場所.保管場所 FROM T_保管場所;cmb_社員:SELECT 社員.社員コード,社員.社員 FROM 社員;
在庫転送フォームのVBA
在庫転送フォームのVBAです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
Option Compare Database Private Sub Form_Load() ClearControls End Sub Private Sub cmd_OK_Click() Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_入出庫処理", dbOpenTable) If Me.txt_日付.value = "" Or Me.cmb_品目.value = "" Or Me.cmb_単位.value = "" Or Me.cmb_転送元.value = "" Or Me.cmb_転送先.value = "" Or Me.txt_数量.value = "" Then MsgBox ("空欄があります") Exit Sub End If If Me.cmb_転送元.value = Me.cmb_転送先.value Then MsgBox ("転送元と転送先が同じです") Exit Sub End If With rst .AddNew .Fields("日付") = Me.txt_日付 .Fields("品目コード") = Me.cmb_品目 .Fields("入出庫コード") = 650 .Fields("数量") = Me.txt_数量 * (-1) .Fields("保管場所コード") = Me.cmb_転送元 .Fields("単位コード") = Me.cmb_単位 .Fields("社員コード") = lngLoginID .Update .AddNew .Fields("日付") = Me.txt_日付 .Fields("品目コード") = Me.cmb_品目 .Fields("入出庫コード") = 640 .Fields("数量") = Me.txt_数量 .Fields("保管場所コード") = Me.cmb_転送先 .Fields("単位コード") = Me.cmb_単位 .Fields("社員コード") = lngLoginID .Update End With rst.Close Set rst = Nothing MsgBox ("記入しました") Call ClearControls End Sub Private Sub cmd_品目検索_Click() DoCmd.OpenForm "F_品目検索" strFormName = "F_在庫転送" End Sub Private Sub cmd_Cancel_Click() Call ClearControls End Sub Private Sub cmd_終了_Click() DoCmd.Close acForm, "F_在庫転送", acSaveNo End Sub Private Sub cmb_品目_AfterUpdate() On Error Resume Next Me.lbl_品目.Caption = cmb_品目.Column(1) End Sub Private Sub cmb_転送元_AfterUpdate() On Error Resume Next Me.lbl_転送元.Caption = cmb_転送元.Column(1) End Sub Private Sub cmb_転送先_AfterUpdate() On Error Resume Next Me.lbl_転送先.Caption = cmb_転送先.Column(1) End Sub Private Sub txt_数量_BeforeUpdate(Cancel As Integer) If txt_数量.value < 0 Then txt_数量.value = txt_数量.value * (-1) End Sub Private Sub cmb_単位_AfterUpdate() On Error Resume Next Me.lbl_単位.Caption = cmb_単位.Column(1) End Sub Sub ClearControls() With Me .txt_日付 = Date .cmb_品目.value = "" .lbl_品目.Caption = "" .cmb_転送元.value = "" .lbl_転送元.Caption = "" .cmb_転送先.value = "" .lbl_転送先.Caption = "" .txt_数量.value = "" .cmb_単位.value = 529 .lbl_単位.Caption = "個" End With End Sub |
単位変換
F_単位変換
空白のフォームから下記のようにコントロールを配置していきます。

日付:テキストボックス(名前:txt_日付、プロパティで書式を「日付 (S)」に変更する)
品目:コンボボックス(名前:cmb_品目)、直下にラベル配置(名前:lbl_品目)
変換前数量:テキストボックス(名前:txt_変換前数量)
変換後数量:テキストボックス(名前:txt_変換後数量)
変換前単位:コンボボックス(名前:cmb_変換前単位)、直下にラベル配置(名前:lbl_変換前単位)
変換後単位:コンボボックス(名前:cmb_変換後単位)、直下にラベル配置(名前:lbl_変換後単位)
保管場所:コンボボックス(名前:cmb_保管場所)、直下にラベル(lbl_保管場所)社員:コンボボックス(名前:cmb_社員)、直下にラベル配置(名前:lbl_社員)
品目検索ボタン:コマンドボタン(名前:cmd_品目検索)
OKボタン:コマンドボタン(名前:cmd_OK)
Cancelボタン:コマンドボタン(名前:cmd_Cancel)
終了ボタン:コマンドボタン(名前:cmd_終了)
コンボボックスのプロパティシートのデータタブの中の値集合ソースを下記のようにします。
cmb_品目:SELECT T_品目.品目コード,T_品目.品目型式 FROM T_品目 ORDER BY T_品目.品目型式;
cmb_入出庫:SELECT T_入出庫.入出庫コード,T_入出庫.入出庫 FROM T_入出庫;
cmb_変換前単位:SELECT T_単位.単位コード , T_単位.単位 FROM T_単位;
cmb_変換後単位:SELECT T_単位.単位コード , T_単位.単位 FROM T_単位;
cmb_保管場所:SELECT T_保管場所.保管場所コード,T_保管場所.保管場所 FROM T_保管場所;cmb_社員:SELECT 社員.社員コード,社員.社員 FROM 社員;
単位変換フォームのVBA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
Option Compare Database Private Sub Form_Load() ClearControls End Sub Private Sub cmd_OK_Click() Dim rst As DAO.Recordset Set rst = CurrentDb.OpenRecordset("T_入出庫処理", dbOpenTable) If Me.txt_日付.value = "" Or Me.cmb_品目.value = "" Or Me.cmb_変換前単位.value = "" Or Me.cmb_変換後単位.value = "" Or Me.txt_変換前数量.value = "" Or Me.txt_変換後数量.value = "" Or Me.cmb_保管場所.value = "" Then MsgBox ("空欄があります") Exit Sub End If If Me.cmb_変換前単位.value = Me.cmb_変換後単位.value Then MsgBox ("変換前と変換後の単位が同じです") Exit Sub End If With rst .AddNew .Fields("日付") = Me.txt_日付 .Fields("品目コード") = Me.cmb_品目 .Fields("入出庫コード") = 660 .Fields("数量") = Me.txt_変換前数量 .Fields("保管場所コード") = Me.cmb_保管場所 .Fields("単位コード") = Me.cmb_変換前単位 .Fields("社員コード") = lngLoginID .Update .AddNew .Fields("日付") = Me.txt_日付 .Fields("品目コード") = Me.cmb_品目 .Fields("入出庫コード") = 670 .Fields("数量") = Me.txt_変換後数量 .Fields("保管場所コード") = Me.cmb_保管場所 .Fields("単位コード") = Me.cmb_変換後単位 .Fields("社員コード") = lngLoginID .Update End With rst.Close Set rst = Nothing MsgBox ("記入しました") Call ClearControls End Sub Private Sub cmd_品目検索_Click() DoCmd.OpenForm "F_品目検索" strFormName = "F_単位変換" End Sub Private Sub cmd_Cancel_Click() Call ClearControls End Sub Private Sub cmd_終了_Click() DoCmd.Close acForm, "F_単位変換", acSaveNo End Sub Sub ClearControls() With Me .txt_日付 = Date .cmb_品目.value = "" .lbl_品目.Caption = "" .cmb_変換前単位.value = "" .lbl_変換前単位.Caption = "" .cmb_変換後単位.value = "" .lbl_変換後単位.Caption = "" .txt_変換前数量.value = "" .txt_変換後数量.value = "" .cmb_保管場所.value = "" .lbl_保管場所.Caption = "" End With End Sub Private Sub cmb_品目_AfterUpdate() On Error Resume Next Me.lbl_品目.Caption = cmb_品目.Column(1) End Sub Private Sub txt_変換前数量_AfterUpdate() On Error Resume Next If txt_変換前数量.value > 0 Then txt_変換前数量.value = txt_変換前数量.value * (-1) End Sub Private Sub txt_変換後数量_AfterUpdate() On Error Resume Next If txt_変換後数量.value < 0 Then txt_変換後数量.value = txt_変換後数量.value * (-1) End Sub Private Sub cmb_変換前単位_AfterUpdate() On Error Resume Next Me.lbl_変換前単位.Caption = cmb_変換前単位.Column(1) End Sub Private Sub cmb_変換後単位_AfterUpdate() On Error Resume Next Me.lbl_変換後.Caption = cmb_変換後.Column(1) End Sub Private Sub cmb_保管場所_AfterUpdate() On Error Resume Next Me.lbl_保管場所.Caption = cmb_保管場所.Column(1) End Sub |
マスタ
品目マスタ
品目の基本情報(マスタ)を編集したいときがきます。そのためのフォームを作ります。
上半分にテキストボックスを、下半分にサブフォーム(テーブル品目を選択)を配置していきます。
フォームの【レコードソース】にテーブルを割り当てるのではなく、テキストボックスをサブフォームのテキストボックスに合わせていきます。

サブフォームの項目の分だけ上半分にテキストボックスとチェックボックスを配置します。
テキストボックスとサブフォームのテキストボックスの関連付け
上半分のテキストボックスの【プロパティ】の【データ】にて、【コントロールソース】の右端の【…】をクリックします。

下記のように、サブフォーム-フィールド-<値>とし、<値>のところでダブルクリックします。
テキストボックスには
1 |
=[品目のサブフォーム].[Form]![品目コード] |
という具合に値が入り、サブフォームのテキストボックスと連動します。

最後にフォームに「終了ボタン:コマンドボタン(名前:cmd_終了)」を追加しておきます。
品目マスタのVBA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Option Compare Database Private Sub cmd_インポート_Click() Dim rs As DAO.Recordset Set rs = CurrentDb.OpenRecordset("T_品目", dbOpenTable) DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "品目", strFileName, True, "品目!A1:K65536" Me.品目のサブフォーム.Requery MsgBox "インポートしました" Set rs = Nothing End Sub Private Sub cmd_終了_Click() DoCmd.Close End Sub Private Sub Form_Resize() Me.品目のサブフォーム.Width = Me.InsideWidth Me.品目のサブフォーム.Height = Me.InsideHeight End Sub |
社員マスタ
社員マスタのVBA
サブフォームで「T_社員」を選択する以外は「品目マスタ」同様です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Option Compare Database Private Sub cmd_終了_Click() DoCmd.Close End Sub Private Sub cmd_インポート_Click() Dim rs As DAO.Recordset Set rs = CurrentDb.OpenRecordset("T_社員", dbOpenTable) DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "社員", strFileName, True, "社員!A1:G65536" Me.社員のサブフォーム.Requery MsgBox "インポートしました" Set rs = Nothing End Sub Private Sub Form_Resize() Me.社員のサブフォーム.Width = Me.InsideWidth Me.社員のサブフォーム.Height = Me.InsideHeight End Sub |
仕入先マスタ
仕入先マスタのVBA
サブフォームで「T_仕入先」を選択する以外は「品目マスタ」同様です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Option Compare Database Private Sub cmd_終了_Click() DoCmd.Close End Sub Private Sub cmd_インポート_Click() Dim rs As DAO.Recordset Set rs = CurrentDb.OpenRecordset("T_仕入先", dbOpenTable) DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "仕入先", strFileName, True, "仕入先!A1:K65536" Me.仕入先のサブフォーム.Requery MsgBox "インポートしました" Set rs = Nothing End Sub Private Sub Form_Resize() Me.仕入先のサブフォーム.Width = Me.InsideWidth Me.仕入先のサブフォーム.Height = Me.InsideHeight End Sub |
その他
バーコード
各種コードをバーコードで表示させる方法を簡単に記しておきました。(Excelによる帳票サンプル付き)
-
-
バーコード印刷(サンプル付き)
管理している品目にバーコードを付けてバーコードリーダで読み取らせたい場合もあるかと思います。バーコードのフォントをインストールしますと、簡単に実現できます。今回はCode39というバーコードを例にして説明します。
続きを見る
完成したら
完成すると、フォームの表示だけにしたくなります。その際のAccessの設定は下記リンクに記載がありますので参照ください。ここでダウンロードするデータベースは編集できるように下記リンクのような処理は施しておりません。
・フォームオープン時のVBA記述
・Accessのオプション設定
https://www.feedsoft.net/access/guide-form/guidef81.html
バックアップ
私は経験したことがありませんが、データベースはたまに破損するようです。
こまめにバックアップを取って万が一に備えましょう。
データベースの分割
ここの記事を参考にされている方は小規模な組織での運用で品目点数や入出庫回数も少ないかもしれません。
しかし、時間を追うごとに蓄積されるデータが多くなり、重くなるかもしれません。そんな時はデータベースをテーブルとフォームなどに分割するといいかもしれません。方法は【データベースツール】タブから【Accessデータベース】を選びます。これでファイルが2つに分割されます。テーブルのファイルをファイルサーバ上に置いておき、フォーム等のファイルを利用者のローカルPCにコピーして使います。

デザインについて
旧式のAccessの形式(*.mdb)にて作成しております。従ってコマンドボタンがフラットになっています。
【ファイル】タブから【名前を付けて保存】にて*.accdb形式にて保存すれば、3Dのコマンドボタンをデザインすることができます。他にもデザイン的にかっこよくできるかと思います。
ダウンロード
拡張子.mdb形式にしましたので、Access2002~Access2019で開けると思います。データベースを開くとログイン画面がポップアップ表示されます。そのウィンドウで右クリックし、「閉じる」をクリックしてください。また「コンテンツの有効化」をクリックします。これで編集して使えるようになります。

Ver.1.61(2020年6月12日版)
ダウンロードはこちら
Ver.1.5(2020年5月31日版)
一部データが入っていますが、テスト用のデータは概ね削除してあります。データインポート用のExcelファイル同梱です。
ダウンロードはこちら
Ver.1.3(2020年5月8日版)
データなし版のAccessデータベース
ファイルはこちら(在庫管理システム(データなし).zip)
仮データのうち、テーブル「メイン」「品目」「保管場所」「社員」「検索履歴」を空にしたものです。(「仕入先」は元々空です)
テーブル「単位」「入出庫」「バージョン履歴」も削除したい(作り変えたい)方はご自身で行ってください。
参考⇩
-
-
テーブルのオートナンバーをクリアする(Access)
注意 実行の前にデータベースのバックアップをお忘れなく テーブルの内容をまとめて削除するだけなら、Visual BASICエディタのイミディエイトウィンドウにて [crayon-603877a74b2 ...
続きを見る
仮データを含む版のAccessデータベース
ファイルはこちら(在庫管理システム(仮データ付).zip)
コードの付け方
会社では社員番号が「0」から始まる8桁の数値なので、それをそのまま用います。サンプルのデータベースでは「1」から始まる5桁の数値にしました。所属の項目がありますが、ない方が良い場合もあるでしょう。人事異動の度に書き換えていたら大変です。
品目コード(あるいは商品コード)は「20」~「29」で始まるコードで割り振ります。これはインストアマーキングと呼ばれるスーパーマーケットなどでの野菜などのパッケージ化されていない商品にコードを割り振るルールだそうです。組織や管理する品目の規模にも依りますが6桁前後あればこと足りるのではないでしょうか。
単位コードはサンプルのデータベースには「5」で始まる3桁の番号にしました。サンプルのデータベースではインボイスの単位を参照しました(リンク切れ)。
入出庫コードはサンプルのデータベースには「6」で始まる3桁の番号にしました。
保管場所コードはサンプルのデータベースには「7」で始まる3桁の番号にしました。
最後に
在庫管理システムのパッケージを購入するほどの規模ではない会社・組織にて、しかし在庫管理はしなくてはならない方向けです。市販のパッケージと比較して不足する機能は多々あります。
処理の削除機能と削除されたデータが在庫に計上されないような処理を入れました。どうでしょうか?入出庫コードの取消を使うようにした方がいいでしょうか?
改善・追加したい機能
可能な限りの改善改良は行ってみますので、お気軽にコメントに要望等をご記入ください。また、もっと容易な方法があるよ、というアドバイスもいただければ幸いです。Ver.2.0として下記のいくつかを取り入れます。
- 指図番号とサイド番号のマスタを忘れていました
- ローカルPCの画面解像度が異なるとフォームの見え方が変わります。それをなんとかしたい
- 新規ユーザーの場合は管理者が仮パスワードを登録して本人に通知し、最初のログイン時に本パスワードに変更する方法に変えようかと思います
- 棚卸し用データのエクスポートと集計結果をインポート
- 閲覧・編集権限をより細かく設定したい
- ログ(履歴)関連を増やしたい
- 購買発注や営業・管理部門の経験がないため、そのあたりを勉強して追加できれば(しないかも)いいですね
ログイン画面のみのサンプルを作成しました。⇩
-
-
アクセス履歴付き ログイン画面を作る(Access)(サンプル付き)
在庫管理システムを作っていて、ログインが必要かなと思いました。ハッシュ値(SHA256)の求め方が載っているサイトを見つけましたので、ログイン画面だけのサンプルを作ってみました。アクセス履歴のログ作成機能付きです。Accessユーザーの参考になれば幸いです。
続きを見る