1-1-1 - gihyo.jp

11
1-1-1 メニュー 機能を選択するメニュー画面からスタートします(1)。大きく分けて 3 つの機能を持っており、 配置したボタンをクリックすることで各機能へ進みます。 Appendix では、フォームの下地やボタンに画像を使う方法も紹介しています(2)。 1-1-2 マスター編集 マスターというのは、日々積み重なっていくデータの中でも、よく使うものの情報をひとまとめ にして、あらかじめ登録しておく部分です。本書では、商品顧客社員のデータをマスターとし て扱います。 マスター選択画面、登録データの一覧画面、編集画面で構成されています(3)。 1 メニュー 1 2 画像配置した2 018 アプリケーションの解説 1 CHAPTER アプリケーション機能概要 はじめに、本書作成するアプリケーションの完成図てみましょう Excel のユーザーフォームを使って、「販売管理」 うシステムを想定ていますCHAPTER 1 11

Transcript of 1-1-1 - gihyo.jp

1-1-1 メニュー機能を選択するメニュー画面からスタートします(図1)。大きく分けて3つの機能を持っており、配置したボタンをクリックすることで各機能へ進みます。Appendixでは、フォームの下地やボタンに画像を使う方法も紹介しています(図2)。

1-1-2 マスター編集マスターというのは、日々積み重なっていくデータの中でも、よく使うものの情報をひとまとめ

にして、あらかじめ登録しておく部分です。本書では、商品・顧客・社員のデータをマスターとして扱います。マスター選択画面、登録データの一覧画面、編集画面で構成されています(図3)。

図1 メニュー 図1 メニュー 図2 画像を配置した例 図2 画像を配置した例

018

アプリケーションの解説1CHAPTER

アプリケーション機能の概要はじめに、本書で作成するアプリケーションの完成図を見てみましょう。Excelのユーザーフォームを使って、「販売管理」を行うシステムを想定しています。

CHAPTER 1

1 1

1-2-1 マスター選択と一覧最初に、どのマスターの編集を行うのか選択して「開く」をクリックすると、対象マスターの一覧画面が開きます(図8)。

図8 マスター選択と一覧

022

アプリケーションの解説1CHAPTER

マスター編集機能

「マスター編集」機能の詳しい仕様を見ていきましょう。3つの分類に分かれていますが、機能は共通です。

CHAPTER 1

1 2

1-3-1 見積一覧まずは作成されているデータの一覧が開きます。作成済みのデータに対して、見積書と受注IDが

発行されているかどうかの確認ができます(図16)。このデータは日付や見積ID、顧客IDで絞り込むことができます(図17)。

026

アプリケーションの解説1CHAPTER

販売処理機能

続いて「販売処理」の詳しい仕様を見ていきましょう。見積データを登録し、登録されたデータに対して見積書の発行や受注処理を行います。

CHAPTER 1

1 3

図16 見積一覧 図16 見積一覧 図17 検索の例 図17 検索の例

1-4-1 伝票未発行一覧受注に対して3種類すべての伝票が発行済みでない

データの一覧が表示されるので、対象データを選択して「開く」をクリックします(図31)。

「売上伝票」「納品書」「請求書」の3種類の伝票発行画面が表示されます(図32)。発行済みのものは、ボタンが使用不可になります。

033

1-4 販売処理機能

図32 伝票発行画面 図32 伝票発行画面

伝票作成機能

「伝票作成」の詳しい仕様を見ていきましょう。販売処理機能で受注が確定したデータに対して、3種類の伝票発行を行います。

CHAPTER 1

1 4

図31 データを選択して「開く」をクリック 図31 データを選択して「開く」をクリック 5CHAPTER

6CHAPTER

7CHAPTER

8CHAPTER

9CHAPTER

10CHAPTER

11CHAPTER

3CHAPTER

2CHAPTER

1CHAPTER

4CHAPTER

APPENDIX

A

1CHAPTER

すると、コードウィンドウに図29のように挿入されました。

図29 挿入されたプロシージャ

この挿入された部分はプロシージャの「枠」部分のようなもので、この中に実行したいコードを書いていきます(図30)。

図30 プロシージャの「枠」

今回は「挿入」→「プロシージャ」から自動入力しましたが、直接入力でも必要な記述がされていればプロシージャと認識されます。

Public Sub 〇〇()

End Sub

055

2-4 VBAの書き方 ~モジュールとプロシージャ

5CHAPTER

6CHAPTER

7CHAPTER

8CHAPTER

9CHAPTER

10CHAPTER

11CHAPTER

3CHAPTER

2CHAPTER

1CHAPTER

4CHAPTER

APPENDIX

A

2CHAPTER

3-1-1 コードの意味おさらいですが、2-4(P.52参照)では「M_Startup」という標準モジュールを作り、そこにコードが1行のプロシージャを書きました(コード1)。

コード1 2-4で書いたプロシージャ

Public Sub openMenu() F_Menu.ShowEnd Sub

プロシージャのはじまりの行には、それがどんな特徴を持つのかが書かれています。この場合は図1のようになっており、この記述によって使われ方が変わります。

図1 プロシージャの特徴

01

02

03

064

フォームの操作3CHAPTER

フォームの表示  ~メソッド

2-4でプロシージャの作成と実行をはじめて行いましたが、書いたコードをもう少し詳しく掘り下げてみましょう。

CHAPTER 3

3 1

15)。

図15 配列の利用

配列は、配列名 (要素数 ) as 型のように宣言することで、同じ性質の複数データをまとめて扱うことができます。同じ形の箱が1列に連なっていて、箱の番号で中身を出し入れするイメージです(図16)。

図16 配列のイメージ

176

フォーム間連携6CHAPTER

6-4-2 並び替え機能の作成と呼び出し編集フォームの登録ボタンのキャプションを、新規の場合は「登録」、既存データ編集の場合は「更新」にしたので、表示されるメッセージボックスも少し工夫してみましょう。代表して「F_Mst_Editor_Product(商品情報編集)」フォームの「btn_edit_Click」プロシージャを見てみてください。ボタンのキャプションを使って、処理前後のメッセージボックスの文章を変化させます(コード

29)。

コード29 メッセージボックスの文章を変化

Private Sub btn_edit_Click() '## 「登録」ボタンクリック時 '必須項目チェック If Me.txb_prdId.Value = "" Or _ Me.txb_prdName.Value = "" Or _ Me.txb_prdPrice.Value = "" Then MsgBox "必須項目が入力されていません", vbOKOnly + vbExclamation, "注意" 'メッセージボックスを出力 Exit Sub '終了 End If '値チェック If Not isAcceptNum(Me.txb_prdPrice) Then Exit Sub '確認メッセージ Dim msgText As String If Me.btn_edit.Caption = "登録" Then msgText = "商品ID " & Me.txb_prdId.Value & " を新規に登録します。" & vbNewLine & "よろしいですか?" Else msgText = "商品ID " & Me.txb_prdId.Value & " の内容を更新します。" & vbNewLine & "よろしいですか?" End If If MsgBox(msgText, vbOKCancel + vbQuestion, "確認") = vbCancel Then Exit Sub 'キャンセルなら終了 '値の書き込み Dim tgtRow As Long '変数宣言 tgtRow = Me.txb_tgtRow.Value '代入 With S_Mst_Product

略 End With '終了メッセージ MsgBox Me.btn_edit.Caption & "しました", vbOKOnly + vbInformation, "終了" 'フォームを閉じる

202

フォーム間連携6CHAPTER

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

す。ここで使うシートは「S_Estimates1(見積データ)」のみなので、まずは引数なし、検索での絞り込みを考えずに書いてみましょう。コード4のようになります。

コード4 見積一覧のソースとなる配列を作る関数

Public Function getOdrSrc() As Variant '## 見積一覧のリストボックスのソースを返す Dim i As Long '繰り返し用変数の宣言 'シートから配列へ格納 Dim wsData As Variant wsData = getWsData(S_Estimates1) 「見積データ」シートを元にする 'データがなかったら終了 If IsEmpty(wsData) Then getOdrSrc = Array() '空の配列を返す Exit Function End If 'データの要素数を取得 Dim maxRow As Long maxRow = UBound(wsData, 1) '元配列の最大行数 'ソースとなる配列の作成 Dim srcArray() As Variant '配列の宣言 ReDim srcArray(1 To maxRow, 1 To 5) '要素数を変数で再定義 For i = 1 To maxRow '要素の数だけ繰り返す srcArray(i, 1) = wsData(i, 1) 見積 ID srcArray(i, 2) = wsData(i, 2) 見積日 srcArray(i, 3) = wsData(i, 3) 顧客 ID srcArray(i, 4) = wsData(i, 5) 見積書発行日 srcArray(i, 5) = wsData(i, 6) 受注 ID Next i '配列を返す getOdrSrc = srcArrayEnd Function

列数は増えましたが、基本的には同じです。次に「F_Odr_List(見積一覧)」フォームの「UserForm_Initialize」にて、この配列を使ってリスト

ボックスにソースを設定しましょう。コード5のように追記します。

01

02

03

04

05

06

07

08

09

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

226

見積一覧フォーム7CHAPTER

コード32 終了メッセージ

Private Sub btn_edit_Click() '## 「登録」ボタンクリック時

'終了メッセージ用の「登録/更新」を取得 Dim btnCaption As String btnCaption = Me.btn_edit.Caption '一覧と編集フォームの更新 Call reloadForm '終了メッセージ MsgBox btnCaption & "しました", vbOKOnly + vbInformation, "終了" メッセージ出力 End Sub

動作確認してみましょう。登録後、フォームが閉じずに内容が再読み込みされるため、「新規」だった部分には登録後のIDが入っています(図29)。テキストボックスが小さいため見切れていますが、中にカーソルを入れると確認できます。

図29 動作確認

01

02

03

04

05

06

07

08

09

10

11

12

13

14

ボタンのキャプションを変数に入れておく(再読み込みで変わってしまうため)

292

見積情報編集フォーム8CHAPTER

A-6-3 分割した汎用プロシージャを作成A-6-2を参考に、実処理で使うプロシージャを「M_SrcArray」モジュールに追記します(コード

12)。データを抽出したい処理は何度もあるので、汎用的に使えるように部品化しています。取得したレコードセットをそのまま使う場合と、リストボックスのソースにするため配列に変換したい場合があるので、必要な場所で使えるように別の関数にしておきます。

コード12 「M_SrcArray」モジュールに追記

'# リストボックス用の配列を作成Option Explicit

Private m_cn As Object 'コネクション用変数 宣言セクションへ

Public Sub connectDB() 追加 '## 接続 Set m_cn = CreateObject("ADODB.connection") 'ADOコネクションオブジェクトを作成 m_cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; " & _ "Data Source=" & ThisWorkbook.FullName & "; " & _ "Extended Properties='Excel 12.0; HDR=YES; IMEX=1';" 'コネクションを開くEnd Sub

Public Sub disconnectDB() 追加 '## 接続解除 m_cn.Close Set m_cn = NothingEnd Sub Public Function getRecordSet(ByVal sql As String) As Variant 追加 '## SQLからレコードセットを返す

On Error GoTo Err_Handler 'エラーが起きたら"Err_Handler"へ 'レコードセットオープン Const adOpenKeyset = 1 'カーソルタイプの定数 Dim rs As Object 'ADOレコードセットオブジェクト Set rs = CreateObject("ADODB.RecordSet") 'ADOレコードセットオブジェクトを作成 rs.Open sql, m_cn, adOpenKeyset 'カーソルタイプを指定して実行(レコード数が取得できる形) '中身のチェック If rs Is Nothing Then 'レコードセットがなかったら Set getRecordSet = Nothing

409

A-6 SQLを使ってデータを取得する

01

02

03

04

05

06

07

08

09

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

5CHAPTER

6CHAPTER

7CHAPTER

8CHAPTER

9CHAPTER

10CHAPTER

11CHAPTER

3CHAPTER

2CHAPTER

1CHAPTER

4CHAPTER

APPENDIX

AAPPENDIX