ユーザー定義関数のススメ

ワークシート関数とユーザー定義/カスタム関数の比較

いいとこどりすればいいが、とりあえずセルの中にIF関数や()、セル番地がいっぱいあるんだったら標準モジュールに書いたほうが読みやすい。ここからVBAに慣れるのも1つ方法です。

ユーザー定義関数は、カスタム関数とも言う。自作関数が分かりやすい。私は、自作関数だすぐにわかるように関数名を「my機能内容」にする。

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

配列数式があってよかった

配列数式と配列を返すユーザー定義関数の組合わせは最強だと思う。令和2年1月13日時点で私が見る限り以下の2つは動画としては見ていない。(この意味は、必要ないか知らないのどっちか。このページの需要も無いことに。読んで下さる方、ありがとうございます。関数っぽいマクロです。使えます。)

  1. 配列を返すユーザー定義と配列数式
  2. マクロの記録をライブで見ながら説明する。削除や書き込みもする。

INDEX、MATCH 関数を組み合わせてと VLOOKUP 関数の話しはよくあるが、IF関数の入れ子より難しいから解説がある。解説が多いのはいいことではない。IF関数の入れ子が多いならユーザー定義関数を作る方法もある。また、次の動画のユーザー定義関数ならFor EachとRange、二次元配列がわかればINDEX関数などより流れは読みやすい?。配列の話しはまたします。

Youtubeで。

動的に変化するリストのようなものを作る場合は、イベントも使えるが、こんな方法もある。この方法がスマートかな。簡単なのはイベントかな?。

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

並び替えは漢字のふりがな順

「ふりがなが」バックにあるのね。

並べ替えは、漢字でもあいうえお順に並ぶね。

並べ替えは、漢字でもあいうえお順に並ぶね。昔はアスキーコード順といって文字コード順だった。Excelは見えないがバックでふりがな使ってる。

名簿の名前の入力の場合、空白文字が前後にあったり、名字の後に空白文字が2つや、ひらがなをカタカナ入力、半角のカタカナなど。また、渡辺、 渡部 、渡邉など同じふりがなだが入力間違い。この対処は、ふりがなで並べ替えて住所などの他の列で判断するしかない。

  1. 空白文字を取り除く。ワークシート関数のTRIM(トリム)
  2. ふりがなを確認する:ワークシート関数のPHONETIC( フォネティック )
  3. ふりがなの情報がない場合の登録:マクロ記録で調べる

ActiveCell.SetPhoneticでふりがな登録できます。SetがあったらGetがあるでしょう。GetPhoneticはApplicationにあるということは、 SetPhonetic での読みに関してはアプリ/Excelが持っている辞書で「よみがな」が入るということです。以下は、イミディエイトウィンドウで入力。?から始まる行は入力。その下は出力。

?application.GetPhonetic("英語")
エイゴ

会社のデータベースからデータを取って来る場合は、拡張子がCSVやTXTでしょう。CSVはそのままExcelで読んでもきっちりセルに割り当てますが、TXTの方は 文字列の区切りを指定するウィザードが起動するかもしれません。

動画のデータ作成用マクロ。

Sub 表作成()

       Range("A1").Select
    ActiveCell.FormulaR1C1 = "番号"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "バンゴウ"
    Range("B1").Select
    ActiveCell.FormulaR1C1 = "名前"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "ナマエ"
    Range("c1").Select
    ActiveCell.FormulaR1C1 = "説明"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "セツメイ"
    
    Range("A2").Select
    ActiveCell.FormulaR1C1 = "1"
    Range("A2").Select
    Selection.AutoFill Destination:=Range("A2:A14"), Type:=xlFillSeries
    Range("A2:A14").Select

    Range("B2").Select

    ActiveCell.FormulaR1C1 = "前田  あきこ"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("B3").Select
    ActiveCell.FormulaR1C1 = "前田 あきこ "
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("B4").Select
    ActiveCell.FormulaR1C1 = "前田アキコ"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("C4").Select
    ActiveCell.FormulaR1C1 = "←空白文字なしでカタカナ"
    ActiveCell.Characters(2, 4).PhoneticCharacters = "クウハクモジ"
    Range("C2").Select
    ActiveCell.FormulaR1C1 = "←全角空白文字2つ"
    Range("C3").Select
    ActiveCell.FormulaR1C1 = "←半角角空白文字"
    Range("B5").Select
    ActiveCell.FormulaR1C1 = "前田あきこ"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("C5").Select
    ActiveCell.FormulaR1C1 = "←空白文字なし"
    ActiveCell.Characters(2, 4).PhoneticCharacters = "クウ"
    Range("B6").Select
    ActiveCell.FormulaR1C1 = "前田 あきこ "
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("B7").Select
    ActiveCell.FormulaR1C1 = "前田アキコ"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("B8").Select
    ActiveCell.FormulaR1C1 = "前田 あきこ "
    ActiveCell.Characters(1, 2).PhoneticCharacters = "マエダ"
    Range("C5").Select
    ActiveCell.FormulaR1C1 = "←空白文字なし"
    ActiveCell.Characters(2, 4).PhoneticCharacters = "クウ"
    Range("C6").Select
    ActiveCell.FormulaR1C1 = "←先頭最後に空白"
    Range("C7").Select
    ActiveCell.FormulaR1C1 = "←名前が半角カタカナ"
    ActiveCell.Characters(2, 2).PhoneticCharacters = "ナマエ"
    ActiveCell.Characters(5, 2).PhoneticCharacters = "ハンカク"
    Range("C8").Select
    ActiveCell.FormulaR1C1 = "←全角空白文字、最後にも空白文字"
    ActiveCell.Characters(2, 2).PhoneticCharacters = "ゼンカク"
    ActiveCell.Characters(4, 2).PhoneticCharacters = "クウハク"
    ActiveCell.Characters(6, 2).PhoneticCharacters = "モジ"
    Range("B9").Select
    ActiveCell.FormulaR1C1 = "吉田裕子"
    ActiveCell.Characters(1, 4).PhoneticCharacters = "ヨシダユウコ"
    Range("B10").Select
    ActiveCell.FormulaR1C1 = "吉田 裕子"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "ヨシダ"
    ActiveCell.Characters(4, 2).PhoneticCharacters = "ユウコ"
    Range("B11").Select
    ActiveCell.FormulaR1C1 = " 吉田 裕子"
    ActiveCell.Characters(2, 2).PhoneticCharacters = "ヨシダ"
    ActiveCell.Characters(5, 2).PhoneticCharacters = "ユウコ"
    Range("C11").Select
    ActiveCell.FormulaR1C1 = "←先頭に空白文字"
    ActiveCell.Characters(2, 2).PhoneticCharacters = "セントウ"
    ActiveCell.Characters(5, 4).PhoneticCharacters = "クウハクモジ"
    Range("B12").Select
    ActiveCell.FormulaR1C1 = "渡部 真一"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "ワタナベ"
    ActiveCell.Characters(4, 2).PhoneticCharacters = "シンイチ"
    Range("B13").Select
    ActiveCell.FormulaR1C1 = "渡辺真一"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "ワタナベ"
    ActiveCell.Characters(3, 2).PhoneticCharacters = "シンイチ"
    Range("B14").Select
    ActiveCell.FormulaR1C1 = "綿鍋真一"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "ワタナベ"
    ActiveCell.Characters(3, 2).PhoneticCharacters = "シンイチ"
    Range("C11").Select
    ActiveCell.FormulaR1C1 = "←先頭に空白文字"
    ActiveCell.Characters(2, 2).PhoneticCharacters = "セントウ"
    ActiveCell.Characters(5, 4).PhoneticCharacters = "クウハクモジ"
    Range("C13").Select
    ActiveCell.FormulaR1C1 = "←上と名前は同じ?"
    ActiveCell.Characters(2, 1).PhoneticCharacters = "ウエ"
    ActiveCell.Characters(4, 2).PhoneticCharacters = "ナマエ"
    ActiveCell.Characters(7, 1).PhoneticCharacters = "オナ"
    Range("C14").Select
    ActiveCell.FormulaR1C1 = "←漢字変換間違い"
    ActiveCell.Characters(2, 4).PhoneticCharacters = "カンジヘンカン"
    ActiveCell.Characters(6, 2).PhoneticCharacters = "マチガ"
    Range("A2").Select
    Application.CutCopyMode = False
    ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A$1:$c$14"), , xlYes).Name = _
        "テーブル"
 
    Columns("B:B").EntireColumn.AutoFit
    Columns("A:A").EntireColumn.AutoFit
    Columns("c:c").EntireColumn.AutoFit
End Sub
カテゴリー: 4 マクロ記録でオブジェクトを調査する | コメントする

イベントプロシージャーは中身だけ書く

プロシージャの中で、イベントプロシージャだけは中身だけ書く。イベントはオブジェクトがすでに持っている機能なので自分で「 Private Subから()など」を書かない。「 Private SubからEnd Sub」まではモジュールの上にあるイベント/プロシージャのリストから選択して入れる。

オブジェクトボックスとプロシージャー/イベントボックス、宣言領域

Workbook_Openイベントは、ワークブック、Excelのファイルを開いたタイミングで自動的にイベントが発生する。オブジェクトごとにイベントは決まっており、Sheet1などのワークシートにはファイル関係のイベントは無い。

練習:Worksheet_SelectionChangeプロシージャに
Debug.Print "Worksheet_SelectionChange",Targetと入れてどのタイミングで動作するか引数のデータは何か確認する

オブジェクトボックスから「Worksheet」を選択するとWorksheet_SelectionChangeプロシージャーがすぐに現れるのでプロシージャ内にコードを追加する。プロシージャを書いたワークシートのセルを変更するタイミングでイベントを発生する。他のワークシートでは発生しない。

練習:どんなデータを入れても1が入るようにする。

2行の赤い行だけを入力する。Private SubからEnd SubまではWorksheetオブジェクトをオブジェクトボックスから選択し、Worksheet_Changeはイベントボックスから選択する。

Private Sub Worksheet_Change(ByVal Target As Range)
    Debug.Print Now
    Target = 1
End Sub

Nowによって多くの時間を表示する。「Target = 1」をコメントアウトすると1度しかイベントは発生しない。イベントの中で自分のデータを変更するために何度もイベントが発生する。

カテゴリー: 14 イベントの使い方 <VBA> | コメントする

アプリとWindowsの関係とイベント

イベントプロシージャのコードを見ると普通のプロシージャとよく似ているが、プログラムから呼び出すのではなく、ユーザーの操作やイベントを誘発させるプログラムによってイベントプロシージャは実行される(呼び出される)。
イベントプロシージャが呼び出されるタイミングは、ユーザーが意識している場合と無意識に処理する場合がある。

  1. 意識できるイベントの例:コマンドボタンを押したときのイベントプ ロシージャ
  2. 無意識なイベントの例:ファイルの呼び込み、データ入力時のイベント プロシージャ

後者のイベントを使うとユーザーにプログラムを意識させない処理ができる。イベントを使う注意は、どのタイミングに何度、発生するのか確認しないと意図しない結果になる。

話しは変わって、イベントをメモり空間で説明します。

プログラムでのデータの処理は、大雑把(抽象的)にコンピュータのメモリをイメージする必要がある。

次図のアプリとは、ExcelやWordなどのことで、これらのアプリをWindows(OS、オペレーティングシステム)が管理する。OSは常に固定でメモリに存在するがアプリは時間ごとに切り替わって複数のアプリが連続いているように見せている。

アプリがファイル保存する場合は、アプリがWindowsにファイルの保存を要求する。ファイルを保存するのはアプリではなくWindowsがする。

Windowsがマウスやキーボード、ディスプレイ、HDD(ハードディスクドライブ)などを複数のアプリから統一管理する。ディスプレイやHDDなどの機器は1つ、アプリが複数動くような仕組みを作るためにWindowsがある。マウスなどの周辺装置からのイベントはWindowsが管理し、Windowsが必要なイベントを各アプリに知らせる(Windowsメッセージ)。

メモリイメージ (外部との入出力はWindowsが担当する)

Excelのイベントプロシージャを呼び出すキッカケはExcel自身が起動した時などのイベントの他にWindowsからの知らせるイベントもある。Windowsからイベントを受け取って処理するかどうかの仕組みはアプリの作り方で決める。

メモリとファイルの違いは以下。

  1. メモリはアプリごとに独立
  2. ファイルはWindowsを通して複数のアプリで供給できる

カテゴリー: 14 イベントの使い方 <VBA> | コメントする