ユーザー定義関数(自作の関数)のすすめ。利点と欠点

「学問のすすめ」みないな。

Excelの標準モジュールに作った関数は、セルの中で使える。

ユーザー定義関数(自分で作る関数)を作るためには以下の知識が必要です。

  1. プロシージャが書ける
  2. 引数が使え、型を知っている
  3. セルの処理、Range,Cells、Offsetが使える
  4. WorksheetFunction関数、VBA関数がある程度使える
  5. 条件分岐、繰り返し処理ができる。
  6. 条件式が書ける

SUMIFやVLOOKUPなどのワークシート関数(Excel/エクセルに組み込まれている関数)は、何かやりたいことがあって使うのだが、自分が作ったわけではないので処理内容を確認しながら進める。以下の手順でワークシート関数を使う。

  1. 使えそうなワークシート関数を探す
  2. 使い方をチェック、期待する処理ができるか確認する。調査能力がアップするだけでプログラム力では無い。

一方、自分で関数を作ることができれば以下の手順で関数を作る。

  1. 入力と出力を決める。入力は引数でセルか値を渡す。出力はFunctionプロシージャの戻り値。
  2. 処理手順を標準モジュールに書いてFunctionプロシージャを作る

「???ができるワークシート関数はどれかな?」って探すのではなく、自分で作るので自作関数とかカスタム関数、ユーザー定義関数とか言う。

(プログラムする)利点

  1. セルの中に長い式を書かなくていい。最重要!
  2. 処理内容がコードにとして見える
  3. VBA学習のスタート課題として使える。これで力を付ける。
  4. VLOOKUP関数など複雑なワークシート関数の使い方を覚えなくていいし、ユーザー定義関数/自作関数の作成はスキルアップになる。作れば作るほど技能がアップする。

(プログラムする)欠点としては、プログラムやVBA関数を知らない人には読めない、修正、引き継ぎが出来ない点。「他の人が修正できないが!」というクレーム。

再計算の対象にするためユーザー定義関数内にApplication.Volatileを挿入する必要がある。一般的に動作が遅くなると言われるが更新されないクレーム回避策になる。

一般的なExcel使いの人の意見でスキルを止めてはいけない。使いやすい関数を提供してあげえればいい。

一般的に、INDEXやVLOOKUPなどを組み合わせるような式は読みにくい。メンテナンスする点からも、「引き継ぎ」に関して大抵は引き継げるほど簡素では無いはずだ。Excelのセルの中のコードを読むのって難しい。じゃない?

比較的簡単でセルの中を見れば処理内容が分かる程度ならExcelのワークシート関数を使う。どちらを使うかの判断は、「どちらが読みやすいか」だが、練習の場合は単純でもユーザー定義関数を作ればいい。

カテゴリー: 9 セルの中で使うユーザー定義関数の作成 <VBA> | 2件のコメント

mySUM関数 複数のセルを引数とする関数

SUMというワークシート関数があるが、あえて自作のmySUM関数を作る。

セルの範囲を引数で受け取る場合のユーザー定義関数の基本的な書き方は以下のようになる。

Function 関数名(引数名 As Range)
    Dim v
    For Each v In 引数名   '引数に複数のセルが入っていることを前提にしている。
         処理コード
    Next
End Function

ワークシート関数にSum関数がある。これと同じような関数をユーザー定義関数で書く。

Function mySUM(範囲 As Range)
    Dim v As Variant      ’As Variantは省略しても同じ意味
    For Each v In 範囲
        mySUM = mySUM + v
    Next
End Function

範囲のセルの値を変えたらmySUMの値も変わることを確認する。次のコードは合計数と最大値を文字列にして返す。

Function mySUM2(範囲 As Range)
    Dim s As String, i As Integer
    ReDim ar(範囲.Count) As Double 'ワークシート関数のMaxを使うための配列
    For i = 1 To 範囲.Count
        mySUM2 = mySUM2 + 範囲(i)
        ar(i - 1) = 範囲(i) '配列にも入れる
    Next
    s = "合計は" & mySUM2 & "です。最大値は" & WorksheetFunction.Max(ar) & "です。"
    mySUM2 = s
End Function
練習:myKake関数を作る。掛け算をする関数。ただし、セルの中の””は計算しないが0が入っている場合は計算する。

まず、下記のようなコードを思い付くと思う。myKakeの初期値がEmptyというバリアント型特有の値でたいていは0として扱われ永遠に0の結果を返す関数になる。

Function myKake(r As Range)
    Dim v
    For Each v In r
        myKake = myKake * v
    Next
End Function

対応が必要なのはセルが空白文字や文字列、myKakeがEmptyの時。ElseIfまで必要になる。

Function myKake(r As Range)
    Dim v
    For Each v In r
        If "" = v Then  '""の空白は何もしない
        ElseIf VBA.IsNumeric(v) Then '数値の場合
            If VBA.IsEmpty(myKake) Then 'まだmyKakeがEmptyの場合は1で掛ける
                myKake = 1 * v
            Else
                myKake = myKake * v '通常の掛け算
            End If
        End If
    Next
End Function

条件分岐が複数になると試行錯誤、条件が5,6個程度ならコードを先に書いて確認する方が早い。

令和6年9月22日追記です。

CharGPTで作ってみた。

カテゴリー: 9 セルの中で使うユーザー定義関数の作成 <VBA> | 2件のコメント

テキストファイルの処理 メモ帳、CSV形式も

Excelは、メモ帳などが扱うテキストファイルも使える。

Workbooks.Openメソッドでテキストファイルを呼び込む。このメソッドはテキストファイルを呼び込めばマクロ記録でコードを得ることができる。上書き保存はSaveメソッドがある。ファイル名を指定する場合は、SaveAsメソッドがある。

ドキュメントフォルダにa.txtをメモ帳で作成してからExcelでこれを読み込む。メモ帳の中身はTABキーを入れるとExcelのシートでは、別の列に入る。改行で次の行に入る。

イミディエイトウィンドウ

?vba.CurDir     'カレントフォルダを調べる
C:\Users\take\Documents  'VBAのカレントフォルダの初期値はドキュメントフォルダ takeはユーザー名
excel.Workbooks.Open "a.txt"      'a.txtファイルのデータがA列に入る
excel.Workbooks(1).Save   ‘上書き。1かどうかは「?excel.Workbooks(1).Name」で要確認
excel.Workbooks(1).SaveAs "b.txt"  '別の名前で保存する
‘フルパスで呼び込む場合
?vba.CurDir & "\a.txt"           'a.txtファイルをC:\からの文字列になるか確認
C:\Users\take\Documents\a.txt
excel.Workbooks.Open curdir & "\a.txt"      '\を付ける
練習:CSV形式で表を保存してからExcelで表示する

CSV形式とは、以下の特徴がある。
1,テキストファイルなのでメモ帳でも読み込み、保存できる。
2,コンマ区切りで列を、改行コードを1行とする表形式のデータ
ExcelでもCSV形式を呼び込み、保存できる。

以下はイミディエイトウィンドウ

excel.Workbooks.Open "a.csv"

3行目のB、C列は2,000のつもりでも””で囲まないと別のセルになる。

Excel側のC3に「2,000」と入れる。

?excel.Application.Workbooks(1).Name  'ファイル名を確認
a.csv
excel.Application.Workbooks(1).save  '上書き保存

メモ帳でa.csvを開く(ショートカットメニューの編集かメモ帳を開いておいてa.csvファイルをドラッグ)とには”2,000”になる。

練習:Excelの表をCSV形式で保存する。

Sheet1の表形式のデータをcsv形式で保存する。SaveASメソッドを使う。マクロ記録では以下のようになっている。以下はイミディエイトウィンドウ。「:=」は名前付き引数で順番に引数を入れてもいいが、引数名があると読みやすい。

    ActiveWorkbook.SaveAs Filename:="C:\Users\take\Documents\名簿.csv", FileFormat _
        :=Excel.xlCSV, CreateBackup:=False

名前付き引数にせず第一引数のファイル名はCurDirを使って保存するファイル名を指定した。丁寧にSaveAsで名前を指定して保存する。

Sheet1.SaveAs vba.CurDir & "\名簿.csv"

メモ帳で表示する。イミディエイトウィンドウでメモ帳を起動する。

shell "notepad 名簿.csv",vbNormalFocus

以下は、体験のために使うデータ。

a.txtのデータ
1234	333
abcde	ddd	

a.csvのデータ
12,3,4
aa,kk,ff
"1,000",2,000

カテゴリー: 13 ファイル処理、メモ帳とのデータ処理 | コメントする

ExcelからWordを操作する

まず、WordのVBEからWordを操作してから、ExcelのVBEからWordを操作する。同じことだけとすごいことしてます。

Wordのオブジェクのモデル

Word上でマクロ記録し、そのコードをExcelで実行するとWordをExcelで操作することになる。

マクロ記録でメソッドやプロパティがわかってもオブジェクト全体のモデルを知っていないとコードを修正、追加できない。

Wordのオブジェクトモデル

Paragraphs:パラグラフ、段落。改行コードが区切り文字。
Sentences:センテンス、文。「。」が区切り文字。
Words:ワード、単語
Characters:キャラクタ、文字。1文字。

Wordオブジェクトモデルを参考に操作する

次図のような短い文書を作って確認する。イミディエイトウィンドウで、Countプロパティで個数を確認してから、Characters以外の各オブジェクトの中身を出力した。

Wordのイミディエイトウィンドウでオブジェクトの中身を確認

以下に上の図で使う材料を置きます。

Wordに入れる文書。

1つ目の段落です。
2つ目の段落です。改行が段落の区切り文字になります。

Excel側のVBEのイミディエイトウィンドウで実行するコード

?word.Application.Documents.Count 
?word.Application.Documents(1).Name
?word.Application.Documents(1).Paragraphs.Count
?word.Application.Documents(1).Paragraphs(1).Range
?word.Application.Documents(1).Paragraphs(2).Range
?word.Application.Documents(1).Paragraphs(3).Range
?word.Application.Documents(1).Paragraphs(2).Range.Sentences.Count
?word.Application.Documents(1).Paragraphs(2).Range.Sentences(1)
?word.Application.Documents(1).Sentences(1) 
?word.Application.Documents(1).Sentences(2)
?word.Application.Documents(1).Sentences(3)  

ExcelからWordを操作する

アプリ間のやり取りは、共有できるファイルやネットワークを使う方法が考えられる。しかし、ExcelやWord、SolidWorks(CADソフト)などVBEの「メニュー/ツール/参照設定」で見えるよにWindowsの仕様として組み込まれた仕組みによって他のアプリを起動し、起動したアプリを操作できるインターフェースが公開されている。そのため、比較的簡単に他のアプリの機能を利用することができる。カット&ペースとかOLEとかできるようにアプリ間のデータの受け渡しは以前からできるが、これをプログラムでやったようなもの。

やることは、ExcelのVBEでWordのライブラリを参照設定すれば、WordでVBEの操作と同様にできる。

スマホの方は、ここをクリックするYouTubeで見れます。

カテゴリー: 8 ExcelとVBEの関係、Wordとのデータ処理 Excelオブジェクト | コメントする

マクロ記録の状態をリアルタイムで見る

マクロの記録を見ながらExcelのオブジェクトを操作する。記録中に削除もできるで!。コメントも追加できる。

マクロ記録を見ながらできることを紹介

これができるとExcelオブジェクトのメソッドやプロパティを調べやすくなる。と思うのだが。

でもマクロ記録のコードの特徴があるからこれに慣れんとね。これはまたいずれ。

カテゴリー: 4 マクロ記録でオブジェクトを調査する | コメントする