GEN MUTO'S HOMEPAGE  エクセル大事典  エクセルVBA超入門

エクセルExcel大事典 エクセル大事典TOPページへ
 ■ エクセルVBA超入門−9ステップで"Hello World!"からオブジェクト指向まで!
  構造体(ユーザー定義型)をつかってみよう
 
■ データの構造化
 
前回、構造化プログラミングの初歩で機能を構造化する方法について話しました。
今回は、データを構造化する方法、構造体(ユーザー定義型)について説明したいと思います。

プログラムを大きく2つに分けると制御部(ルーチン)とデータ部(変数)に分かれます。
構造化プログラミングでは単に制御部を構造化するだけでなく、データを構造化することでさらに保守性のよいプログラムを作ることが可能です。
今回はデータの構造化、「構造体(ユーザー定義型)」について学んでみましょう。

前回までのtestプロシージャではSyainMSTから単なるVariant型の二次元配列にデータを吸い上げて使用していました。
しかしこれでは、二次元配列のどこになんのデータが入っているのかわかりにくいです。さらにVariantのため、データにどんな値(たとえば数値型の項目に文字列など)が入っていたとしてもエラーになりません。

これではデータが構造化されているとは言い難いものがあります。Variant型の二次元配列を構造体の一次元配列に格納してみましょう。
データの型チェックもその時行います。

' モジュール宣言部に記述ここから −−−−−−−−−−−−−−−−−−−−−−−−−−
Public Type SyainData
  Id As Long
  Name As String
  Kinzoku As Long
  Syozoku As String
  Yakusyoku As String
End Type
' モジュール宣言部に記述ここまで −−−−−−−−−−−−−−−−−−−−−−−−−−

Public Sub test()
Dim i As Long
Dim WrkSyainData() As SyainData
  If GetSyainData(WrkSyainData()) Then
    For i = 1 To UBound(WrkSyainData)
      If WrkSyainData(i).Id = Range("syain_id") Then
        Call SetSyainData(WrkSyainData(i))
        Exit For
      End If
      Range("hyoji_all").ClearContents
    Next i
  Else
    MsgBox "SyainMSTに不正なデータがあるため処理を中断しました", vbCritical
  End If
End Sub

Public Function GetSyainData(ByRef pWrkSyainData() As SyainData) As Boolean
Dim i As Long
Dim WrkRange As Variant
  On Error GoTo ErrGyo
  WrkRange = Sheets("SyainMST").UsedRange
  ReDim pWrkSyainData(UBound(WrkRange))
  For i = 2 To UBound(WrkRange)
    pWrkSyainData(i).Id = WrkRange(i, 1)
    pWrkSyainData(i).Name = WrkRange(i, 2)
    pWrkSyainData(i).Kinzoku = WrkRange(i, 3)
    pWrkSyainData(i).Syozoku = WrkRange(i, 4)
    pWrkSyainData(i).Yakusyoku = WrkRange(i, 5)
  Next i
  GetSyainData = True
Exit Function
ErrGyo:
  GetSyainData = False
End Function

Public Function SetSyainData(ByRef pWrkSyainData As SyainData)
  Range("syain_id").Offset(1, 0) = pWrkSyainData.Name
  Range("syain_id").Offset(2, 0) = pWrkSyainData.Kinzoku
  Range("syain_id").Offset(3, 0) = pWrkSyainData.Syozoku
  Range("syain_id").Offset(4, 0) = pWrkSyainData.Yakusyoku
End Function

またしても、ずいぶんゴチャゴチャとしてしまいました。でもやっぱりこちらのほうがいいコードです。
(※ コードを見やすくするため前回のChkNumber関数の部分は割愛してあります)
なぜそうなるのかを説明していきましょう。
まず、Type〜End Typeの部分が構造体の宣言部分です。この部分はプロシージャ内にかけませんので、モジュールの一番上(宣言部)に記述する必要があります。



このとき宣言したIdやName等の部分を構造体のメンバと呼びます。型宣言してあるので、このメンバに型の異なるデータを代入しようとすると当然エラーになります。
この構造体、ここで宣言しただけでは使えません。プロシージャ内で構造体変数として実体化してやる必要があります。

testプロシージャ内のWrkSyainData()で配列をもつユーザー定義型として宣言しました。社員データは複数のデータを持つので構造体変数も配列として宣言する必要があります。
4行目のGetSyainDataが構造体配列に実データを入れる関数を呼び出しています。WrkSyainData()もこのときはじめて実体化されます。

GetSyainData関数内では、おなじみVariantの二次元配列にシートデータを代入、構造体配列に一つずつデータを代入しています。
このとき、データの型が違うとエラー処理でOn Error GoTo ErrGyoで宣言した行ラベルErrGyo:にとび、GetSyainDataはFalseを返します。
For i = 2 ループカウンタが2から始っているのは1行目の項目名を構造体に取り込ませないようにするためです。
一度もエラーが出なかった場合だけGetSyainDataはTrueを返し、構造体に正しい型のデータが代入されたことを保証します。
(データ範囲や文字数の制限など、チェックしたい処理をさらに追加することもできます)
※エラー処理についての詳細な解説はこちらを参照してください。
  エラー処理の重要性1 エラー処理の重要性2

さてtestプロシージャに制御が戻り、Range("syain_id")に入力された社員IDを見つけ出すと、SetSyainData関数に見つけ出した社員データの構造体を送ります。
SetSyainData関数は渡された引数の構造体データ(このときのデータは社員1レコード分です)をワークシートに記述する処理を行います。
 
ところで2つの関数の引数の頭にByRefというキーワードが付いていることに注目してください。
前回の引数の頭にはByValが付いていましたね。前回説明しなかったのですがこのByValとByRef、引数をどういう形で渡すかを指定しています。
ByValのことを値渡しといい、引数のデータを直接値で渡しています。ByRefは参照渡しといい引数のメモリ上のポインタを渡しています。
値渡しはデータをコピーして渡しているので渡し先の関数内でいくらデータを書き換えても元のデータには何ら影響を及ぼしません。
参照渡しはデータのメモリ上の場所を教えているだけなので渡し先でデータを書き換えれば当然、元のデータの値も変化します。

構造体そのものを引数にする場合は値渡しができません。必ず参照渡しとなります。
どうしても値渡ししたい場合はメンバを直接引数にしてやる必要があります。

GetSyainData関数では参照渡しした構造体を渡し先関数内で書き換えています。ですので元のプロシージャ(test)のほうでも書き換えた構造体のデータを参照することができたのです。
※引数、返り値の詳しい解説はこちらを参照してください
  引数の参照方法(値渡し・参照渡し)を明示しよう
※構造体のデータを一気に複写したいときはこちらを参照してください
  配列・構造体の中身を一気に複写

 
 
このコードがなぜ前回のコードより優れているのかというと、構造体にデータを取得する部分GetSyainDataと構造体のデータを出力する部分SetSyainDataが独立しているからです。関数を呼び出す元のコードはこの関数が何を処理しているのか知る必要はありません。

ただGetSyainDataを使えば構造体にデータが取得でき、SetSyainDataを使えばそれが出力できることさえ知っていればよいのです。
もし将来的にSyainMSTの構造が変わりプログラムを修正する必要ができたとき、メインのプログラムを何ら修正することなく、GetSyainData、SetSyainData、の関数を修正するだけで対応できるからです。
もしこの関数が他のたくさんのプロシージャから呼び出されていた場合を想像してください、修正する範囲が少なくて済む有用性がお分かりいただけると思います。

構造化プログラミングを突き詰めていくと、こうした個々のプロシージャの独立性を高めそれぞれがお互いの役割を果たし、できるだけ他の処理に影響を与えない透明性の高いコーディングをすることが可能となります。
この部分を理解していないとこの先のオブジェクト指向プログラミングの有用性も十分に理解できません。

オブジェクト指向プログラミングは決して構造化プログラミングと対をなすものはありません。
構造化プログラミングを追及したその先にあるものなのです。

 

>> 次の話にすすむ


サイト内検索ができます

Microsoft Most Valuable Professional

Microsoft MVP Excel
武藤 玄 プロフィール
 

■■■ 執筆した書籍 ■■■
 

EXCEL VBA 業務自動化
 

Excel VBA を5日でマスターする本
 

仕事を速くする Excel VBA 入門
 

Excel VBAと業務改善のポイントがわかる本
 

Access VBA ベーシック スタンダード
 

Excel VBA アクションゲーム作成入門
 

■■■ 連載中の記事 ■■■
 

Excel VBAで業務改善!
 

実務で使うExcel VBA
 


TOPページ


■ エクセルVBA超入門

 ・9ステップで"Hello World!"
  からオブジェクト指向まで!
  1."Hello World!"を表示しよう
  2.基本はデータの入出力
  3.繰り返し処理
  4.シートで簡易データベース
  5.名前をつけよう
  6.構造化プログラムに挑戦
  7.構造体を使ってみよう
  8.フォームを使ってみよう
  9.オブジェクト指向に挑戦

■ エクセルVBA中級編

 ・VBAでいろんなテクニック
  変数・関数のスコープ
  引数の参照方法を明示
  配列の中身を一気に複写
  識別子がよいコードを作る
  データ定義型をもっと知ろう
  定数と列挙型を活用しよう
  エラー処理の重要性1
  エラー処理の重要性2
  いろいろな条件分岐
  いろいろな繰り返し処理
  演算子について知ろう
  文字列操作 連結 変換 置換
  文字列操作 検索 比較 書式
  日付操作関数を知ろう
  数値操作・評価・その他関数
  並び替えソートをマスター
  いろいろな検索をマスター
  VBEditorを使いこなそう
  マクロの記録を活用しよう1
  マクロの記録を活用しよう2
  VBAからVBEを操作しよう1
  VBAからVBEを操作しよう2
  VBAからVBEを操作しよう3
 ・ワークシートを使いこなす
  セルの参照をマスターしよう
  セルの選択をマスターしよう
  セルの操作をマスターしよう
  セルの書式設定をマスターしよう
  行・列の操作をマスターしよう
  シートの参照をマスターしよう
  シートの操作をマスターしよう
  ブックの操作をマスターしよう
  ウィンドウの操作をマスターしよう
  イベントプロシージャを活用しよう
  ワークシートを印刷しよう1
  ワークシートを印刷しよう2
  音声(読み上げ)機能を操作しよう
  グラフを操作しよう
 ・ユーザーフォームを使いこなす
  ユーザーフォームを使おう
  UserFormsオブジェクト
  Labelコントロール
  TextBoxコントロール
  ComboBoxコントロール
  ListBoxコントロール
  CheckBoxコントロール
  OptionButtonコントロール
  ToggleButtonコントロール
  CommandButtonコントロール
  ScrollBarコントロール
  SpinButtonコントロール
 ・VBA関数の一覧
  Aから始まる関数の一覧
  Cから始まる関数の一覧
  Dから始まる関数の一覧
  Eから始まる関数の一覧
  Fから始まる関数の一覧
  Gから始まる関数の一覧
 
■ エクセルVBAを極める
 VBAスーパーテクニック
 
 ・データベースへ接続してみよう!
  CSVファイルへの接続
  ワークシートへの接続
  mdbファイルへの接続
  SQL Serverへの接続
  ADOレコードセットの操作1
  ADOレコードセットの操作2
 ・ファイルを操作してみよう!
  FileSystemObjectの操作
  Drive File Folderの操作
  TextStream ダイアログ
  ステートメントでファイル操作1
  ステートメントでファイル操作2
 ・他アプリと連携してみよう!
  ActiveXオートメーションの操作
 ・ゲーム技でマクロを超える
  エクセルで音を鳴らす1
  エクセルで音を鳴らす2  
  スクリーン座標を取得
  様々なイベント取得
  リボンUIを制御しよう1
  リボンUIを制御しよう2
  シート上でアニメを動かそう
 
■ 一歩上行くエクセル
 基本操作の完全マスター!

 
 ・あなたはいったい
  エクセルで何をしたいのか?
  エクセルで業務効率化
  エクセル関数を使いこなす
  エクセルの便利技
  エクセルは最高の帳票ツール
 ・エクセル基本操作上級編!
  セル選択、コメント、シリアル値
  オート機能を使いこなそう!
  参照、条件付書式、入力規則
  関数をもっと理解しよう!
  配列数式を有効利用しよう!
  データの正規化をしよう!
  ショートカットキーを利用しよう1
  ショートカットキーを利用しよう2
  Office用アプリを作成しよう!
  PowerPivotとExcelで簡単BI!
 ・世間の誤ったエクセルの
  べからず集
  エクセルで文章を書くべからず
  エクセルで図形を描くべからず
  エクセルでシステムをつくるな
 
■ エクセル関連その他

 ・エクセルコミニュティにあなたも
  参加しませんか?
  Excel関連リンク・コミニュティ
 ・VBの理解がVBAをマスターする
  最短距離!
  VB関連の老舗・大家サイト
 ・エクセルExcel大事典掲示板
 ・プライバシーポリシー

2000アイテムを超えるラベルを販売
送料無料、即納対応の優良ショップ
今買っているラベルより確実に安い!
OAラベルの販売専科グラフトラベル




エクセルExcel大事典ははリンクフリーです エクセル大事典Excel大事典
お問い合わせはこちら gengengen@yahoo.co.jp

Copyright© Gen Muto 武藤 玄 All Rights Reserved,