関数に汎用性を持たせる、共通に使える関数作り

[VBA系メニューへ] [質問掲示板] [バックナンバー目次]




どうも、三流プログラマーのKen3です。

前回は、プログラムは水の流れのように、、、なんて説明してました。
今回は、関数を分割して汎用性を持たせる案を説明します。
*たいしたことじゃないのですが、、、

今回作成したテストプログラム
http://www.ken3.org/p/lzh/off004.lzh
に
Book-004.xlsが保存されてます。
ダウンロードして、動きをチェックして見てください。

/* * 1.汎用性? */

プログラムが組めるようになってくると、修正のしやすさや(労力をかけたくない)、 流用の効くプログラムの書き方、、、などで差がでてきます。 私もあまり将来流用可能なプログラムを組んでないので、 偉そうなこと言えないんだけど(笑) 前回、フォルダー名を貰い、そのファイル名をセルにセットする。 なんて処理を作りましたよね。 '引数(パラメータ)でフォルダー名をもらい、 'データをA列にセットする
Sub setFILELIST(strFolder As String)

    Workbooks.Add   '新しいブックを追加

    Dim strFileName As String  'ファイル名
    Dim nYLine      As Integer '行カウンタ

    '最初のファイル名を取る
    strFileName = Dir(strFolder & "\*.*", vbNormal)
    
    'ファイルが見つからなくなるまでループしてデータをセットする
    nYLine = 1
    Do While strFileName <> ""   ' ループを開始します。
        Cells(nYLine, 1) = strFileName 'セルにファイル名をセットする
        Cells(nYLine, 2) = strFolder & "\" & strFileName
        nYLine = nYLine + 1      ' カウントアップする
        strFileName = Dir        ' 次のファイル名を返します。
    Loop

End Sub
ざっと見ると、できてるんだけど、変更が来た時、流用が効きにくいです。 えっ、どこが? まぁまぁ、これから書くので、あせらないで。

/* * 2.1つの考え方、固定処理をパラメーターにする */

フォルダーからファイル名を取得して、データをセットしてました。 *.jpg や *.xls とファイルの指定をして取出したくなったら? 1つの考え方は、 '最初のファイル名を取る strFileName = Dir(strFolder & "\*.*", vbNormal) この部分を、"\*.*""\*.xls"と指定ファイルに変える方法があります が、 そんなことやってたら、*.bmpがほしい、*.htmlが、、、 と 種類別に関数が増えてしまいます。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ そんな時は、フォルダーと一緒にファイルパターンもパラメーターで 貰うようにします。 Call setFILELIST(strFolder, "*.*") 'データのセット ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ とファイル名とパターンで関数を呼ぶようにします。 ※関係ない話だけど、\*.*←が顔文字に見えたアナタ、重症だよ って書くってことは、Ken3がそんな風に感じたんだよね  ギクっ、、バレたか・・・ '引数(パラメータ)でフォルダー名とファイルの種類をもらい、 'データをA列にセットする
Sub setFILELIST(strFolder As String, strPattern As String)

    Workbooks.Add   '新しいブックを追加

    Dim strFileName As String  'ファイル名
    Dim nYLine      As Integer '行カウンタ

    '最初のファイル名を取る
    strFileName = Dir(strFolder & "\" & strPattern, vbNormal)
    
    'ファイルが見つからなくなるまでループしてデータをセットする
    nYLine = 1
    Do While strFileName <> ""   ' ループを開始します。
        Cells(nYLine, 1) = strFileName 'セルにファイル名をセットする
        Cells(nYLine, 2) = strFolder & "\" & strFileName
        nYLine = nYLine + 1      ' カウントアップする
        strFileName = Dir        ' 次のファイル名を返します。
    Loop

End Sub
たんに、 setFILELIST(strFolder As String, strPattern As String) と関数の受け取りのパラメータが増えて、 strFileName = Dir(strFolder & "\" & strPattern, vbNormal) で、指定してるだけなんですね。

/* * 3.関数の機能を少なくしてシンプルにする */

もう一つのアプローチ方法として、 関数の機能を少なくしてシンプルにして 汎用性を持たせる方法があります。 ^^^^^^ なんか回りくどく説明してますが、 余計な機能がついていないほうが、 組み合わせで使える幅が増えます。 '引数(パラメータ)でフォルダー名とファイルの種類をもらい、 'データをA列にセットする setFILELIST(strFolder As String, strPattern As String) この関数、 ・フォルダー内をパターンで検索して、 ・ファイル名を新規のブックに保存します。 と、検索とデータセット、2つの機能が入ったお得な関数です。 どこが得なんだよ、、 オレは、ファイル名だけほしいのに、、、なんて時ありますよね。 ※セットじゃなくて、単品がほしいんだよ、単品が。 新規ブックに保存する処理がジャマなんですねとても。 その通り、携帯は通話だけできれば十分、えっ写メールは必要だって? まぁ、1つで何でもできるのもいいけど、 プログラムの場合、組み合わせの時邪魔になるときがあります。 あまり分割し過ぎも、バラバラで組み合わせや管理が大変なのですが、 よく使う共通関数は、1関数、1機能、なんてシンプルに作ってみると、 利用し易いです。※最低限を作成して、足りないところに外側から肉付けする。 試しに 配列にファイル名をセットする関数を作ってみます。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '引数(パラメータ)でフォルダー名とファイルの種類をもらい、 'データを受け取った配列にセットする
Sub setFILELIST(strFNBOX() As String, _
                strFolder As String, strPattern As String)

    Dim strFileName As String  'ファイル名
    Dim n As Integer           '配列の要素数

    n = 1              '初期化
    ReDim strFNBOX(n)  '配列の数を動的に変える

    '最初のファイル名を取る
    strFNBOX(n) = Dir(strFolder & "\" & strPattern, vbNormal)

    'ファイルが見つからなくなるまでループしてデータをセットする
    Do While strFNBOX(n) <> "" ' ループを開始します。
        n = n + 1              ' カウントアップする
        ReDim Preserve strFNBOX(n) ' 配列の数を動的に変える
        strFNBOX(n) = Dir      ' 次のファイル名を返します。
    Loop

End Sub
見なれない書き方ですが、まず配列を受け取ってます。 Sub setFILELIST(strFNBOX() As String, _ strFolder As String, strPattern As String) strFNBOX()と数を指定しない受け取り方です *ファイル名がいくつになるか不明なので。 次のポイントが ReDim strFNBOX(n) ReDim Preserve strFNBOX(n) ' 配列の数を動的に変える です、これは、普通はDim A(10)など配列の数を指定するのですが、 動的に好きな数に配列のサイズを取ります。 Preserveのキーワードは、前のデータを残してサイズを拡張する、 ^^^^^^^^ 今回のような処理の時に使います。 ※サイズを増やしながらデータを追加していくイメージなので、  サイズ変更前のデータを残しながら処理してます。 Do While strFNBOX(n) <> "" ' ループを開始します。 n = n + 1 ' カウントアップする ReDim Preserve strFNBOX(n) ' 配列の数を動的に変える strFNBOX(n) = Dir ' 次のファイル名を返します。 Loop と、配列を拡張しながらファイル名をセットします。 分割した表示部は、 'フォルダー名とファイル名配列を受け取り、シートを新規作成
Sub make_data(strFolder As String, strFN() As String)

    Dim nYLine      As Integer '行カウンタ
    
    Workbooks.Add   '新しいブックを追加

    For nYLine = 1 To UBound(strFN)  'ファイル名をセットする
        Cells(nYLine, 1) = strFolder & "\" & strFN(nYLine)
    Next nYLine

End Sub
と、フォルダー名、ファイル名の配列を受けとって、 新規ブックにファイル名を書き込んでます。 ここで、おっ?と思うのは、 For nYLine = 1 To UBound(strFN) 'ファイル名をセットする Cells(nYLine, 1) = strFolder & "\" & strFN(nYLine) Next nYLine の部分の、UBound(strFN)です。 UBoundに配列を渡すと、インデックス番号の最大値を返してくれるので、 これを利用してループを作ってます。 よく、文字列分割の関数 Split関数と組み合わせてUBound関数を使ったりしてます http://www.ken3.org/cgi-bin/test/test024-2.asp ポイントは、実行時に配列の要素数が変化しているので、 その最大値をもらって、処理してます。 メインルーチンは、
Sub Main()

    Dim strFolder As String '選択されたフォルダーを格納
    Dim strBOX()  As String 'ファイル名格納用変数

    'フォルダーを選択させる
    strFolder = getFOLDER()  'フォルダーの選択関数を呼ぶ

    'キャンセルだったら処理を抜ける
    If strFolder = "キャンセル" Then
       Exit Sub
    End If

    '選択されたフォルダーを表示関数に渡し表示する
    Call setFILELIST(strBOX(), strFolder, "*.*") 'データのセット
    
    '新規のシートにデータをセットする
    Call make_data(strFolder, strBOX())

End Sub
と修正しました。 ポイントは、 Dim strBOX() As String 'ファイル名格納用変数 配列のサイズを指定しない定義方法、 と Call setFILELIST(strBOX(), strFolder, "*.*") 'データのセット Call make_data(strFolder, strBOX()) の関数の呼び方です。 配列変数に一度ファイル名を全て保存します で、その配列からシートにデータをセットしてます。 一回配列に保管するのがムダな場合もあるが、 機能が分かれていると、 Call setFILELIST(strBOX(), strFolder, "*.CSV") 'データのセット でCSVのファイル名を取得、 For n = 1 To UBound(strFN) 'ファイルをインポート strIN = strFolder & "\" & strFN(nYLine) strINを使用してインポート Next nYLine なんて少し変更した処理も比較的簡単に作成することができます。 シンプルな汎用性のある共通関数作りにもチャレンジしてみてください。

/* * 4.終わりの挨拶 */

機能を分割すると、汎用性のあるプログラムが書けることが、 なんとなくわかったと思います。 Dim FN() As String Call setFILELIST(FN(), strFolder, "*.jpg") 'データのセット で、ファイルリストが取りたい時などに使える関数になりました。 (*標準関数に少し肉付しただけなんですが(笑)) 今回作成したテストプログラム http://www.ken3.org/p/lzh/off004.lzh に Book-004.xlsが保存されてます。 ダウンロードして、動きをチェックして見てください。 何かの参考となれば幸いです。 プログラム作りは簡単で面白いなぁと感じるような 解説/メールマガジンを書きたいと思ってます。 よろしくお願いします。 AB型の変わり者、三流プログラマーのKen3でした。

質問・感想を送る

作者に感想・質問/要望を送る(気軽に質問・感想書いてください)
あなたのお名前(ニックネーム) さん

作者からの返信は、 不用 E-mail で受信したい

三流君のHP主な飛び先

VBA系のメルマガで書いた解説を項目ごとにまとめてます

[VBAでAccessを操作(一般)]
[VBAでAccessのレポートを操作]
[VBAでAccessのUserForm/サブフォームを操作]
[VBA Access から Excel 連携]

[VBA でExcel オブジェクト/プロパティ/メソッド/一般]
[VBA でExcel UserForm(ユーザーフォーム)を操作する]
[VBA ExcelからAccessを操作する]

[VBA Outlookの操作]
[VBA IEの操作]
[VBA テキストファイル(*.txt,*.html,*.csv)の操作]
[VBA標準関数関係とその他解説]

ASP系の解説を項目ごとにまとめてみました

[ASP Form等を使用したデータのやり取り]
[ASP その他処理サンプル]
[ASP テキストファイル処理]
[ASP VBScript関数関係の説明]
[ASP ADOでMdbファイルを使う]
[ASP ADOでExcelと接続してみた]

分類別

[アクセスランキング] [サイトマップ] [リンク先・相互リンク先など]
VBAで楽しくプログラミング 掲示板 バックナンバー メルマガ登録と解除
コンビニのオモテとウラ話 掲示板 バックナンバー メルマガ登録と解除
ASPで遊ぶ、失敗する 掲示板 バックナンバー メルマガ登録と解除
三流プログラマー 業務の愚痴 掲示板 バックナンバー メルマガ登録と解除
初心者にやさしいプログラム 掲示板 バックナンバー メルマガ登録と解除
ネットで稼ぐ本音と失敗談 掲示板 バックナンバー
www.ken3.org(サイト内)から Google を利用して、

Ken3の日記(weblog) -- [広告・副収入系] [プログラマー業務の愚痴] [VBA系の話題] [ASP系の話題] [コンビニ系ネタ] [その他]

その他、宣伝ページです

・[ アンケート/ポイント]などで月500円を必死に稼いでます(笑)
・[ SOHO/在宅プログラマー/派遣]の話題、Webエントリー後の反応など
・[ ネットで小金を稼げるか?]実験中だが成果は無し
※あとは、[パソコン関係の書籍]や[ゲームソフト]、 [パソコンパーツ] をバナーから売ろうとするけど、
 なかなかうまくはいかないよね(笑)

楽天の商品売れ筋ランキング紹介ページ

ドリンク

[コーヒー・ココア] [ソフトドリンク] [ハーブティー] [ビール・地ビール] [ワイン] [中国茶] [中国酒] [日本茶] [日本酒] [水・ミネラルウォーター] [洋酒] [焼酎] [紅茶] [その他(ドリンク)]

グルメ・フード

[キムチ・漬け物] [チーズ・乳製品] [パン] [フルーツ・野菜] [] [惣菜・食材] [中華料理・惣菜] [和風料理・惣菜] [洋風料理・惣菜] [水産物・水産加工品] [] [肉・肉加工品] [菓子] [調味料] [麺類] [その他(フード)]

ファッション

[インナーウェア・ナイトウェア] -- [ショーツ] [ブラジャー] [ストッキング] [キャミソール] [スリップ] [ガードル] [補正下着] [マタニティ用下着] [ナイトウェア]
[カジュアル] -- [Tシャツ] [シャツ] [カットソー] [セーター] [カーディガン] [ジーンズ] [パンツ] [ジャンバー・ブルゾン] [スカート]
[レディース・婦人服] -- [スーツ] [ワンピース] [スカート] [パンツ] [ブラウス] [フォーマル]
[ジュエリー・アクセサリー] -- [指輪] [ネックレス] [ペンダント] [イヤリング] [ピアス] [ブレスレット] [ジュエリーボックス・ケア用品]
[香水] -- [シャネル] [クリスチャン・ディオール] [ジバンシー] [グッチ] [ブルガリ]
[メンズ・紳士服] [メンズ-スーツ] [メンズ-シャツ] [メンズ-トランクス] [メンズ-ブリーフ] [メンズ-ボクサーパンツ] [メンズ-Tシャツ] [トレーナー・パーカー] [メンズ-ポロシャツ] [メンズ-カットソー] [メンズ-セーター] [メンズ-カーディガン] [メンズ-ジーンズ] [メンズ-ジャンバー・ブルゾン]
[バッグ] [] [ベビー・キッズ・マタニティ] [和服] [眼鏡・サングラス] [コンタクト・コンタクト用品] [腕時計] [雑貨・小物] [スイムウェア]

パソコン・家電・AV

[オフィス・サプライ] [コンパクトカメラ] [デジタルカメラ] [ビデオカメラ] [一眼レフカメラ] [ソフトウェア] [パソコン・コンピュータ] [デスクトップパソコン] [ノートパソコン] [モバイル・携帯電話] [周辺機器パーツ] [スキャナ] [プリンタ] [家電・AV] [エアコン・空気清浄機] [オーディオ] [冷蔵庫・冷凍庫] [掃除機] [映像機器]

生活・インテリア

[家具・インテリア] [手芸・クラフト] [文具] [日曜大工・作業用品] [日用品・生活雑貨] [食器・調理用具]

ヘルス・ビューティ

[ダイエット] [健康用品] [サプリメント] [医薬品] [福祉・介護] [美容・化粧品] [スキンケア] [メイクアップ]

スポーツ・アウトドア

[アウトドア] [ウィンタースポーツ] [サッカー] [ストリート系スポーツ] [テニス] [トレーニング] [フィッシング] [マリンスポーツ] [自転車] [野球] [スポーツグッズ] [格闘技グッズ] [その他スポーツ・用品]

フラワー・ガーデン

[エクステリア] [ガーデニング] [フラワー・花] [植木] [観葉植物] [造花]

ホビー・ペット・コレクション

[アート・美術品] [おもちゃ] [ペット・ペットグッズ] [占い・開運] [囲碁・将棋] [楽器] [趣味・コレクターグッズ]

CD・DVD・ゲーム

[CD・カセット] [DVD・LDソフト] [アニメ(DVD・LD)] [ミュージック(DVD・LD)] [洋画] [邦画] [テレビゲーム] [ビデオ] [音楽CD] [R&B] [アニメソング] [ジャズ] [ダンス&ソウル] [ヒップホップ] [ロック・ポップス(洋)] [ロック・ポップス(邦)]

車・バイク

[カー用品] [カーナビ] [カーオーディオ] [タイヤ・ホイール] [洗車用品] [バイク]

ゴルフ

[ゴルフ・クラブ] [ゴルフ・シューズ] [ゴルフ・ウェア] [ゴルフ・バッグ] [ゴルフ・ボール] [ゴルフ・小物] [ゴルフ・トレーニング用具]