テキストデータを扱う

テキストデータを扱う際の操作の流れの解説と記事一覧

VBAでテキストデータを扱うには、まずテキストデータを開く必要があります
この開くという動作は、ブックを開くというアプリを起動してデータを開く方法ではなくメモリ上にデータを開きます

以降、このメモリ上でテキストデータは操作します
追記や編集、取得を行う操作を行った後、最後にテキストデータを閉じる操作を行います

テキストデータとは、文字列のみで表現されたデータのことになります
主な使用場面は、通常のテキストデータやCSVデータ、設定用にiniファイルを操作することもできます

テキストデータを扱う際の流れは以下の通りになります

  1. テキストデータを開く-Openステートメントを使用してデータを開く
  2. テキストデータの各種操作を実行する-編集・取得を行う
  3. テキストデータを閉じる

以上の操作を行い、テキストデータの形式や使用用途によって操作を分けて実行します

テキストデータを扱う際、特にcsvデータはデータサイズが特大になりがちです
このデータを操作する際には、メモリ上に展開して操作することから処理時間が異様にかかってしまうことがあります
特にループ処理時に発生しやすいので、ループ処理に組み込む際は実装前に想定以上のビッグデータでテストしてみたほうが良いです

また、テキストデータ操作はFileSystemObjectでも行うことができます
こちらは、単一のテキストファイルだけでなくフォルダ内にあるすべてのファイルを操作する時などでは合わせて実装できるので、便利ですし
コードも分かり易くて使いやすいです

ただ、本記事の操作方法は標準コードなので前準備が必要ないのが利点です

単体のテキストデータでは、本記事操作を行う
複数のテキストデータでは、FileSystemObjectを使用する

この様に使い分けると良いと思います

文字コードから文字入力する

Chr関数はコードから特別な文字入力を行えます、よく使う入力コードを掲載

'「 」半角スペースを入力
Debug.Print Chr(32)
'「"」ダブルクォーテーションを入力
Debug.Print Chr(34)
'「'」シングルクォーテーションを入力
Debug.Print Chr(39)
'タブ(半角スペース4つ)を入力
Debug.Print Chr(9)
'改行文字(vblf)を入力
Debug.Print Chr(10)
'改行文字(vbcr)を入力
Debug.Print Chr(13)

文字コードから文字を入力するには「Chr」関数を使用します

引数に指定されたコードの文字を返します

例コードでは、VBAのコード中で特別な意味を持つため文字として入力する際によく使用されるものを上げています

「”」は文字列として入力したい場合に使用します、いちおう連続入力で代用はできます
このあたりの解説は以下の記事で行っています

また改行文字はVBAでよく使われるのが「vbcrlf」ですが、コードを見て分かるようにこの「vbcr」と「vblf」が結合されているものであることが分かります
Asc関数で「vbcrlf」のコードを取得すると、先にある「vbcr」の「13」が取得されます

文字コードに関しては以下のリンクから確認することが出来ます
MicrosoftDocs-文字セット(0~127)

この関数に指定するコードはAsc関数で調べることもできます
Asc関数に関しては以下の記事で解説しています

上記のAsc関数の解説記事内でもありますが、このChr関数もBとWを付与することで同じように文字コードから入力できます

ただ、VBAでは1バイト文字というのが存在しません
半角であっても2バイトで表現されるためです、なのでVBAコード上で表現できないためワークシートに入力して使用しますが、非常に使いどころが少なく良い例が見つかりませんので割愛しておきます
良い例が見つかれば改めて記事にしたいとは思います

また、ChrW関数に関しては環境依存文字を使用する場合に使用することが多いので、ここでは解説せず別の記事にて解説を行います
以下の記事で環境依存文字とからめた関数の解説を行っています

文字コードを取得する

文字コードの取得にはAsc・AscB・AscW関数を使用します。それぞれの使用方法について

'文字コードを取得
Debug.Print Asc("a")
'1バイト目の文字コードを取得
Debug.Print AscB("a")
'Unicode文字コードを取得
Debug.Print AscW("a")

文字コードを取得するには「Asc」関数を使用します
また、AscにBを付けると最初の1バイト文字を取得します
Wを付けるとUnicode文字コードを取得します

この関数の引数に指定した文字のコードを整数値で返します

なお、複数の文字を指定しても最初の1文字のコードのみが返されるので、文章に対してコードを取得する場合は1文字ずつ処理を行う必要があります
あまりそんな状況は無いとは思いますが・・・

関数の解説

Debug.Print Asc("aあ")
→→→ 97

Asc関数を使用して文字コードを取得しています
1文字目のみが対象となるため、「a」の文字コード「97」が取得されます

Debug.Print Asc("あbc")
→→→ -32096

Asc関数を使用してひらがなの文字コードを取得しています
1文字目の「あ」が対象となり、文字コード「-32096」が取得されます

Debug.Print AscB("aあ")
→→→ 97

AscB関数を使用して文字コードを取得しています
AscB関数は1バイト目の文字コードを取得します
半角文字の「a」は、上記と同じく「97」が取得されます

Debug.Print AscB("あbc")
→→→ 66

AscB関数を使用してひらがなの文字コードを取得しています
ひらがなは2バイト文字になるので、うまく取得はできません
実際このコードを使用しても、「あ」を入力することはできません

Debug.Print AscW("aあ")
→→→ 97

AscW関数を使用して文字コードを取得しています
Unicodeであっても半角文字のコードは同じなので「97」が取得されます

Debug.Print AscW("あbc")
→→→ 12354

AscW関数を使用してひらがなの文字コードを取得しています
こちらでは同じ文字であってもコードは違うため「12354」が取得されます

基本的には、ひらがなであればAsc関数の文字コード内にあるものはそれで取得すればいいです

このコード以外のものを取得する際にはAscW関数を使用します
特に環境依存文字を使用する場合には必要になります
その方法の解説は以下の記事で行っています

ダブルクリックで入力を切り替える

シートイベントのダブルクリックでセルの入力値を切り替える処理の解説

作成したい入力例
作成したい入力例

まず、この画像のような表があるとします
毎日なんらかの確認作業を行い、確認完了後にチェックを付ける表です

単純に○を入力するだけのなんてことない表ですが、これが項目数が大量にあった場合は結構大変になります
画像は結果表示なので一気に入力されてますが、実際は1つずつ入力する必要があります

そこで、セルをダブルクリックするだけでチェックを入力して、間違った時のことも考えて、ダブルクリックで○と空白を切り替えるようにします
こうすると、結構入力が楽になります

まずは、処理上選択されているセル範囲のみで実行する必要があります
見出しや日付のセルに○が入力されると困ります

名前定義セルの作成

名前定義を作成するボタン
名前の管理ボタンの場所

処理したいセル範囲を選択して、数式タブにある名前の管理ボタンからセル範囲に名前定義を作成します

名前定義の新規作成方法

名前の管理画面から新規作成ボタンを選択します

表示された新しい名前画面から、新規作成内容を設定します
名前はなんでも構いませんが、範囲はシート範囲にするようにしてください

シートを複製しても処理が問題なく動作できるように、名前定義の範囲を限定しておきます

また、画面作成をおこなわずにコードで行いたい場合は以下の記事から行ってください

シートイベントの作成

シートイベントの作成画像
イベントの作成

シートのイベントプロシージャで処理を作成していきます

今回の処理では、ユーザーの意思による操作で誤操作の可能性の低いダブルクリックを選択します
ダブルクリックは、ワークシート上では編集モードに入る操作なので無意識にしてしまうことは少ないのでこういった処理に向いています

ダブルクリックをしたときに発生するイベントが「BeforeDoubleClick」イベントになりますのでシートモジュールでプロシージャボックスから選択して作成してください

作成したコード画像
作成したコード

今回作成したコードがこのような形になっています

コード解説

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    If Not Intersect(Range("チェック範囲"), Target) Is Nothing Then
        Cancel = True
        If Target = "○" Then
            Target.ClearContents
        Else
            Target = "○"
        End If
    Else: End If
End Sub

このコードでは、ダブルクリックされたセルが指定範囲であれば入力処理を実行します
入力処理では、空白セルには○を入力し、○が入力されていれば消去する処理です

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

シートイベントです。
シートのセルをダブルクリックした後に発生するイベントで、引数Targetにダブルクリックしたセルが代入されます

Targetにはセル範囲が代入されますので、単一セルとは限りません
ですが、ダブルクリックはExcelの仕様上必ず1セルに限定されます
この仕様からもダブルクリックイベントは使いやすいです

    If Not Intersect(Range("チェック範囲"), Target) Is Nothing Then

~~ 中略 ~~

    Else: End If

ここでTargetセル範囲と名前定義したセル範囲で処理実行するセル範囲かを判定しています
このセル範囲判定に関しては以下の記事で詳しく解説しています

        Cancel = True

このコードを実行すると、既定の動作をキャンセルします
イベントによって規定の動作は変わります

ここではセルの編集モードに入るのをキャンセルします
最後に解説しますが、入力モードに入られると非常にわずらわしいです

        If Target = "○" Then
            Target.ClearContents
        Else
            Target = "○"
        End If

最後に入力処理になります

If分岐でセルに○が入力されているかで分岐します
○が入力されていれば、ClearContentsメソッドにより入力内容を消去します
○以外であれば、○を入力します

○以外の別の文字列でも○を入力します
これはCOUNTIF関数を使用したことがある人は分かるかもしれませんが、○をカウントするのに別の文字を入力されていてうまく個数が取得できないことがあります
そういったことを回避する意味でも指定文字以外なら指定文字にしてしまいます

動きの解説

入力時のコードの動き
○が入力される動き

まずは空白セルに○を入力する動きです
セル範囲が処理実行可能範囲なので、処理が実行されます
またCancelにTrueを代入することで、ダブルクリックしたセルが編集モードに入りません

空白セルで○以外セルなので、○が入力されてい処理が完了です

入力解除時のコードの動き
セルが空白になる動き

今度は○が入力されているセルをダブルクリックしたときの動きです

今回は○が入力されているため、そのセルは空白になります

指定セル範囲以外では処理が動いてない動き
処理範囲外の動き

最後に処理が許可されていない範囲をダブルクリックしたときの動きです

日付セルは名前定義したセルとは重複していないため、最初のIf分岐で何も処理を実行しない形になっています

このとき、Cancelも変更されていないため、通常の操作通りセルの編集モードに入っていることが確認できます

この処理は、入力処理ですが非常に応用範囲が広い内容です

例えばセルへのデータ入力ではなく書式設定の変更を行えばダブルクリックでセルの背景色を切り替えたりできます
ユーザーフォームの表示処理を行うことも可能です、この場合表示ボタンが必要なくなります

まずは入力処理から行って、動きが確認できたら色々な設定変更を行ってみてください

任意のセル範囲が指定セル範囲に含まれているか調べる

Intersectメソッドを使用して処理セル範囲かを判定する方法

'アクティブセルがB列か判定
If Not Intersect(Range("B:B"), ActiveCell) Is Nothing Then
Debug.Print "範囲内"
Else: End If

任意のセル範囲が指定セル範囲に含まれているかを調べるにはIntersectメソッドを使用します

コード解説

任意のセル範囲とは、ユーザーが選択しているセル範囲であったりする
動的に変化する指定セル範囲のことになります
このコードでは、ActiveCellの部分になります

指定セル範囲とは処理の実行を前提とした固定の指定セル範囲のことになります
ActiveCellがこのセル範囲内にあれば処理を実行するような判定の親要素のセル範囲になります
コードでは、Range(“B:B”)になります

このコードを実行した時点のアクティブセルの位置によって処理が分岐します
引数のセル範囲は順番は関係ありませんので、入れ替えても使用可能です

If Not Intersect(Range("B:B"), ActiveCell) Is Nothing Then

ここで条件分岐を行っています

Intersectメソッドは重複する範囲が存在しない場合は「Nothing」を返します
Nothingは文字列ではないので、比較には「Is」演算子を使用します

これで、重複する範囲が無い時はTrueとなります
ただそれでは処理上少しわかりにくいので、逆説を取って判定します

その為に「Not」演算子を合わせて使用します
これで、範囲内に存在する場合にTrueになります

主な使用場面

ユーザーにセル範囲を指定させて処理を実行するような場合には、必ず使用します

データを入力したり、背景色を変更したりするような処理であった場合に、見出しのセル範囲であったり、関数の入力されたセルを指定されては困ります
そういった場合に、処理の実行前にこのコードで実行可否を判定します

また、Range(“B:B”)の部分を名前定義セルにすれば複雑なセル範囲も簡単に指定できますのでおすすめです

このコードをより実用的に使用するには、以下の記事にある方法を使用します

埋め込みコントロールのイベントをまとめる

Witheventsとクラス定義を使用して、複数のコントロールのイベントを集約する方法

埋め込みコントロールはワークシートにコントロールを作成したものです
このコントロールはワークシートの広さから、往々にしてコントロールの数が多くなります

しかも、ほとんど同じ動きをさせることも多い場合があります

そんな状態で、1つ1つのコントロールにイベント処理を何個も作成していくのは、大変だし、メンテナンス性も劣化します

そんな時に使用するのが、コントロールをクラスでまとめて制御する方法です
これにはイベント最強説があるWitheventsを使用します
以下にその説の実の部分が書いてあります

クラスモジュールを作成する

まずはクラスモジュールの作成を行います
モジュールの作成自体は、標準モジュールと全く同じで挿入メニューから行えます
挿入方法に関しては以下の記事のユーザーフォームモジュールの挿入方法を参考にしてください

クラスモジュールが作成出来たら、そのモジュール内にコードを作成します

Classのコード内容
クラスモジュールのコード内容

画像の様なコードを作成しました
プロジェクトウィンドウの青くなっている「Class1」モジュール内です

Dim WithEvents 作成 As MSForms.OptionButton

Sub 紐付け(作成コントロール As MSForms.OptionButton)
    Set 作成 = 作成コントロール
End Sub

Private Sub 作成_Change()
    If 作成.Value = True Then
        Selection.Interior.Color = 作成.BackColor
    Else: End If
End Sub

こちらは、クラスモジュール内に作成するコードなので、OptionButtonの取得であればコピペしてそのまま使用できます

Dim WithEvents 作成 As MSForms.OptionButton

この1行が集約するコントロールを代入させる変数の宣言です
WithEventsを使用することにより、イベントの作成が可能になります

MSForms.OptionButtonはオプションボタンのコントロールです
変数の型指定です、Object型は指定できません

Sub 紐付け(作成コントロール As MSForms.OptionButton)
    Set 作成 = 作成コントロール
End Sub

ここで紐付け処理を作成しています

後述で出てくる紐付け作業の時に、実行されるプロシージャです
中身は引数のコントロールを上記の変数に代入させているだけです
ただ、これだけで以降は後述のイベント処理が実行されます

Private Sub 作成_Change()
    If 作成.Value = True Then
        Selection.Interior.Color = 作成.BackColor
    Else: End If
End Sub

イベント処理です
内容は、OptionButtonがON(True)ならコントロールの背景色を選択範囲に適用するだけです
ここに作成したイベントが紐付けされたコントロール全てで実行されます

もし、イベント処理に変更があった場合はここの処理を変更すればいいだけです
コントロールの数が10個あろうが100個あろうが、ここで全てが集約されています

考えるだけで便利な話です

ここまでで、クラスモジュールの作成は完了です

シートモジュールの処理作成

クラスが作成出来たら、それを使用してシートモジュールに処理を作成します

シートモジュールのコード内容

画像の様なコードを作成しています
モジュールは青色になっている、「Sheet1」モジュールになります

Dim 動的作成() As New Class1

Private Sub Worksheet_Activate()
    Dim 取得用 As Shape, インデックス As Long
    For Each 取得用 In ActiveSheet.Shapes
        If 取得用.Name Like "*OptionButton*" Then
            ReDim Preserve 動的作成(インデックス)
            動的作成(インデックス).紐付け OLEObjects(取得用.Name).Object
            インデックス = インデックス + 1
        Else: End If
    Next 取得用
End Sub

Private Sub Worksheet_Deactivate()
    Erase 動的作成
End Sub

Private Sub CommandButton1_Click()
    Selection.Interior.ColorIndex = 0
    Erase 動的作成
End Sub

こちらは、コントロールの名前が違っていると使用できませんのでコピペする場合は修正をしてください

Dim 動的作成() As New Class1

クラスを使用する場合には、クラスの作成が必要になります
この1行が、クラスの作成とその変数の宣言になります

コントロールの個数分この変数が必要になるため、変数は動的配列で作成します
またNewキーワードによりクラスがここで作成されています

Private Sub Worksheet_Activate()
    Dim 取得用 As Shape, インデックス As Long

シートのActivateイベントを使用します、シートがアクティブ状態になったときに発生するイベントです

まずは使用する変数の宣言です
「取得用」はシートに配置されたコントロールをループ処理で代入させるための変数です。配置されたコントロールは全てShapesオブジェクトとなるため、型指定はShape型を使用します。ここには図形なんかも入ってきます

「インデックス」は動的配列のインデックス番号用の数値で使用します。整数なのでLong型を使用します

    For Each 取得用 In ActiveSheet.Shapes

~~ 中略 ~~

    Next 取得用

次にシートに配置されたコントロールの取得処理に入ります
ここではシート上のShapesオブジェクトをForEachループで1つずつ検証しながら取得を行っていきます

変数の取得用に各オブジェクトが代入されます

        If 取得用.Name Like "*OptionButton*" Then

~~ 中略 ~~

        Else: End If

オブジェクトの取得ができたら、そのオブジェクト名で取得可否の条件分岐を行います

If分岐で文字列比較を行います
今回はオプションボタンを取得するので、名前に「OptionButton」が含まれていたら処理を中略の処理が実行されます

含まれていなければ何も行いません

            ReDim Preserve 動的作成(インデックス)

取得可能なコントロールが見つかったら、まずは動的配列を追加します
もちろんそれまでに取得したコントロールを削除されていは困りますのでPreserveキーワードを使用してください

変数インデックスはあとで加算しています

            動的作成(インデックス).紐付け OLEObjects(取得用.Name).Object
            インデックス = インデックス + 1

ついにクラス定義の出番です
ここまで長かったです、書いてる自分もお尻が痛いです

まず、クラス宣言した変数名ではクラスモジュールで作成したメソッドやプロパティが使用できます

今回は、紐付けという処理を作成しました
それはメソッドという形でここで使用することが出来ます
変数に対するメソッドなので、「.」を付けることでインテリセンス入力できます

これはCallによる処理の呼び出しでは無いので、引数に「()」は必要ありません
半角スペースを入れてから、引数を指定します

今回は「OLEObjects(取得用.Name).Object」となっています
まずもって、そのままでは取得できません
変数「取得用」がShape型だからです

なので、コントロールとしてのオブジェクトで指定する必要があります
OLEObjectsはシートにあるコントロールのコレクションです
その中から取得用.Nameで指定することで取得しているコントロールを指定することができます
指定したコントロールのObjectプロパティを指定することで最終的にコントロールが指定される状態になります

この時点でクラスの紐付けプロシージャが実行されて、クラスで宣言した変数「作成」に代入されます

ここ以降にクラスで作成したイベントがこのコントロールで実行されるようになります

紐付けが出来たら、変数「インデックス」に1を加算します

ここまでで、処理の作成が完了です、おっつかれした~

処理の動きと紐付けの解除

シート切替により紐付けされている動き
シートイベント発生時

まずは、シートのアクティブイベントを実行する必要があります

Sheet2からSheet1への切り替えを行っています
この時点でOptionButtonのクラスの紐付けが完了しています

実際の処理の動き
イベントが実行されている動き

実際にOptionButtonを切り替えてみると、選択範囲の背景色がOptionButtonのONのものと同じに切り替わっています

OptionButtonが増えたとしても、問題は無いしコントロールの背景色を変更すれば変更後の色指定も合わせて行えます

Private Sub Worksheet_Deactivate()
    Erase 動的作成
End Sub

また、このDeactivateイベントにより動的配列変数を解放しています
このイベントはシートがアクティブ状態でなくなったときに発生するイベントなので、別のシートに移動したら紐付けを解除する動きになります

状況によっては必要ないかもしれません

Private Sub CommandButton1_Click()
    Selection.Interior.ColorIndex = 0
    Erase 動的作成
End Sub

解放自体をユーザーにゆだねることも出来ます
その為にコマンドボタンを1つ作成しています

コマンドボタンをクリックすると、背景色を塗りつぶし無しに設定します
その後、動的配列変数を解放しています

紐付けを解除したときの動き
紐付けが解除された状態

画像の動きを確認してください

ボタンをクリックすることで、背景色が無くなり、Redのオプションボタンに切り替えても背景色は塗られることはありません
イベントが発生していないことが確認できます

動的配列でメモリ上に乗っかったままなので、基本的には必要ない時は解放してあげるほうが良いです

複数のコントロール

単一のコントロールだけであれば、全く問題にならないので普通にシートモジュールに作成すればいいです

また、コードによるコントロールの作成後の処理でも同様です
単一の作成後処理は以下の記事にあります

この記事でもありますが、複数のコントロールになるとこのクラスを使用する方法しかありません

クラス自体は、使用頻度が非常に低く無くても処理作成を行えることが多いため
初心者では踏み込みづらい内容かもしれません

なので、たくさんのコントロールのイベント処理を一括して管理するにはクラス使わなあかん、とだけ認識しておいてください

埋め込みコントロール(ActiveX)の作成

ワークシートに直接コントロールを作成する方法の解説

ActiveXコントロールとは、ユーザーフォームで扱うコントロールの事です

ここでは、そのコントロールをフォーム上ではなくワークシート上に作成する方法の解説を行います

ワークシートにコントロールを埋め込む

ワークシートにコントロールを作成する利点は、ワークシート自体を有効利用できる点にあります

例えば、フォームをブックを開くと同時に表示するような処理であった場合、シートに作成しておけばそもそもそんな処理を作成する必要はありません
さらに、特定のシートのみで動作させたいフォーム処理であっても、シートの判定がまったく必要なくなります

さらに、リストコントロールを使用しなくてもそこにワークシートがあるのでデータの展開も楽になります
あと地味に大きいのがマウスホイールで画面を移動できる点です

ユーザーフォームを必要としないように作成を行うことも可能になります

コントロールの作成方法

埋め込みコントロールの挿入ボタンの位置
コントロールの挿入ボタン

まずは、開発タブにある挿入ボタンを選択します

ここからコントロールを選択して追加していきます

表示された挿入できるコントロール一覧
挿入できるコントロール一覧

赤枠内に表示されたアイコン一覧が挿入できるコントロールになります
ユーザーフォームでの作業同様に、一覧にないコントロールは追加可能ですがPC環境に左右されるので、基本のコントロールのみで作成していきます

フォームコントロールについては後述します

今回はコマンドボタンを作成してみます

コントロールの作成方法
作成方法

作成するコントロールを選んだら、ワークシートに挿入します

この時の操作は図形作成要領と同じなので、難しくは無いはずです
大きさや位置は後で調整できるので適当にクリックするだけでもいいです

編集モードの終了方法
編集モードの解除

コントロールの追加モードになると、自動的にデザインモードという編集モードに切り替わります

この状態では、コマンドボタンをクリックしても選択されるだけです
挿入ボタンの隣にあるデザインモードボタンをクリックすることで編集モードを切り替えることが出来ます

デザインモードを解除すれば、コントロールを操作可能な状態になります
コマンドボタンをクリックすると、動作するようになっているはずです

ただ、このままでは何も起きませんので処理を作成します

コードやプロパティの表示方法
コード作成方法

コントロールを編集する場合は、デザインモードをクリックして有効にします

その状態で、コントロールの右クリックメニューを開きます
その中にある赤枠内のコードの表示を選択してください

作成されたイベントとプロパティの表示状態
作成された状態

すると、VBEの画面に切り替わりコントロールの既定イベントが作成されます

また、その際にプロパティウィンドウに表示されているのが、作成したコントロールのプロパティです
ここを変更すれば、作成したコントロールの細かい設定変更が可能です
プロパティ設定はユーザーフォームのものとほぼ同じなので、そちらを参考にしてください

また、このイベントプロシージャはユーザーフォームではユーザーフォームモジュール内に作成していました
これはシートのコントロールのイベントになりますので、シートモジュール内に作成されることになります

それ以外はユーザーフォームでの作成方法と同じです
オブジェクトボックスから選んで、プロシージャボックスからイベントを選択する流れになります

ワークシート上にコントロールを作成した時点で、オブジェクトボックスで選択可能になりますので、上記のような右クリックメニューから実行しなくてもVBEの画面から作成することも可能です

フォームコントロールとActiveXコントロールについて

ちなみに、ActiveXコントロールの上に「フォームコントロール」というコントロールがあり挿入できる種類も同じものがあります

こちらは、簡易版と思ってもらっていいです
簡易版なので、作成してセルとの連携を簡単に設定できます
スクロールバーの数値設定なども書式設定から行えるので手軽に作成できます

ただ、簡易版ですので設定が簡単な分出来ることは少なくなっています
色の変更なども行えませんし、なによりイベントの利用が出来ません
コントロールの最大利点のイベントが利用できず、マクロ登録による単一マクロしか対応できませんのであえて使う理由がほぼありません
比較的すぐに限界を感じると思います

それに、ActiveXコントロールはユーザーフォームと同じように作成できるので、慣れやすいのも優位性があると思います

動的作成コントロールにイベントを作成する

Witheventsを使用してコードで作成されたコントロールにイベント処理を作成する方法

ユーザーフォームでデザインウィンドウではなく、コードにより動的に作成したコントロールに処理を作成するには「Withevents」を使用します
Withevents最強説に関しては以下の記事を確認してください

作成して、紐付けする

作成したコード
作成例

画像の様なコードを作成しています

Dim WithEvents 動的作成 As MSForms.TextBox

最初にWitheventsを使用した変数宣言があります
これに代入するテキストボックスに処理を作成できるようになります

Private Sub 動的作成_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
動的作成.BackColor = RGB(0, 200, 0)
End Sub

ここで、動的に作成するコントロールのイベント内容を作成しています
内容としては、マウスカーソルがコントロール上で移動すると背景色を緑色に変更するだけの処理です

Private Sub CommandButton1_Click()
Set 動的作成 = Me.Controls.Add("Forms.TextBox.1", "")
End Sub

ここで、コマンドボタンのクリックによりテキストボックスを作成しています
プロパティ設定は何も行っていないので、作成しているだけです

それと同時に、動的作成に代入を行っています
この代入により、Witheventsで作成した変数と紐付けされるので、以降で作成したイベントが発生するようになります

処理の実際の動き
イベントが発生している動き

画像を確認してください、コマンドボタンをクリックするとテキストボックスが作成されます

そのテキストボックスにマウスを移動させると、背景色が緑色に変化します
イベントが実行されていることがわかります

動的に作成したコントロールには、こうして処理を作成しておき
実際に作成された後に紐付け処理を行うことで、使用することができるようになります

紐付けの解除

Set 動的作成 = Nothing

紐付けには変数に代入することで行いました

なので、紐付けの解除は変数を解放してあげればいいだけです
このコードを解除したいタイミングで実行すれば可能です

解除用コードを追加
解除用のコード挿入

赤枠内に解除用コードを挿入しました
上記のコードに、紐付け直後に解除する動きになっています

イベントが発生していない様子
イベントが発生していない状態

画像のように、テキストボックス作成後にマウスをコントロール上に移動させても背景色が変化しません
イベントが発生していないことがわかります

この仕様をうまく使えば、ユーザーフォームでは使用できないApplication.EnableEventsプロパティの代用ができます

単体でのみ有効な処理

この処理は変数が1つしかありませんので、単体のコントロールでのみ有効な処理です

変数を増やせばいいだけと考えてしまうかもしれませんが、その分イベント処理の作成も同時に増加していきます
こうなると、もはやなんのための処理か分からなくなります

イベント処理は1つで集約して、代入する変数を増やすには、クラスが必要になります
クラスを使用することで、例でいう「動的作成」という変数を配列で指定することが出来るようになります

そのあたりの内容に関しては以下の記事で解説を行っています

Excelのイベントであったり、作成するコントロールが単体であればクラスまで使わなくてもこの記事の内容で対応可能です
可読性もこちらのほうが良いので、場面で使い分けるようにすればいいです

GotFocus・LostFocusイベント

埋め込みコントロールのフォーカスの取得・喪失で発生するイベントです

埋め込みコントロールでの特別なイベントに「GotFocus」「LostFocus」イベントがあります
埋め込みコントロールについては以下の記事を確認してください

このイベントは名前の通り、フォーカスを取得した時(GotFocus)と失った時(LostFocus)に発生するイベントです

コード作成例

Private Sub TextBox1_GotFocus()

Range("A1") = "あなたの名前を入力してください"

End Sub

GotFocusイベントは、コントロールがフォーカスを取得したときに発生するイベントです
このイベントに、A1セルにテキストボックスの使用説明を表示します

Private Sub TextBox1_LostFocus()

Range("A1") = "テキストボックスを選択してください"

End Sub

LostFocusイベントは、コントロールがフォーカスを失った時に発生するイベントです
このイベントに、A1セルに操作手順の説明文を表示します

イベント作成時の動き
実際の動き

コードを作成して、実際の動きを確認してみます

セル選択されている間は、A1には「テキストボックスを選択してください」と表示されます
指示に従い、テキストボックスを選択すると「あなたの名前を入力してください」に表示が切り替わります

このようにコントロールを選択した時点で処理を行うことでユーザーの操作性が向上します

ただ、このLostFocusイベントで注意点があります
このイベントは「デザインモードに入ったときには発生しない」という点です

コントロールにフォーカスがある状態で、コントロールの追加や編集などでデザインモードに切り替わると、フォーカスは失っていますがイベントは発生しません

通常の操作では起こりえない話なので問題は無いと思いますが、そういった瞬間も存在していることは理解しておいたほうが良いと思います

文字列に半角が含まれているか調べる

LenB関数を使用することで、文字列に半角が含まれているかを調べることが出来ます

’半角の存在確認
Dim 対象文字列 As String
対象文字列 = "ナンバー32"

If LenB(対象文字列) > LenB(StrConv(対象文字列, vbFromUnicode)) Then
Debug.Print "含まれています"
Else
Debug.Print "含まれていません"
End If

文字列に半角が含まれているかを調べるには、文字列のバイト数で比較を行う必要があります
この文字列のバイト数に関する注意点が以下の記事にありますので確認しておいてください

コード解説

Dim 対象文字列 As String
対象文字列 = "ナンバー32"

ここでは、引数の文字列が後で複数回でてくるので変数に代入しています

If LenB(対象文字列) > LenB(StrConv(対象文字列, vbFromUnicode)) Then

ここで判定処理を行っています、If分岐を使用しています

LenB(対象文字列)

左辺では、LenB関数によりバイト数を取得しています
VBAでは文字は2バイトを返します

LenB(StrConv(対象文字列, vbFromUnicode))

右辺では、文字形式を変換して半角を1バイトに表現してバイト数を取得しています

この2つの比較により、LenB関数単体より少なければ含まれていることが分かります

If LenB(対象文字列) > LenB(StrConv(対象文字列, vbFromUnicode)) Then
Debug.Print "含まれています"
Else
Debug.Print "含まれていません"
End If
→→→ 含まれています

例にある「ナンバー32」という文字列に対して、コードを実行すると「含まれています」が返されます
「32」が半角のため、バイト数が一致しないからです

これは1バイトと2バイト文字という表現に対して有効な処理です
3バイト以上の文字があった場合は別の対応が必要になります
ただ、この対応はかなり稀でありどこまでのバイトを対応するかも難点です