2024/04/26
【ExcelVBA】VBAを使ってシートの初期設定を自動化

【ExcelVBA】VBAを使ってシートの初期設定を自動化

Excel関連の何かしらの作業を自動化する際に、便利な機能としてマクロというものがあります。
このマクロを開発することができるプログラミング言語がVBAになります。
こちらでは、以下の作業を自動化するマクロを、VBAを用いて開発する方法について解説していきます。
※開発したファイルは記事に最後にて配布しています。

【作業内容】

1.以下のテンプレートシート「YYYYMMDD」のコピーを作成し、シート名を作業日の日付(YYYYMMDD形式)にする

2.コピーしたシートのセルB2に作業日の日付を入力する

では早速、自動化するマクロを開発していきます。
※開発したマクロに関しては、「Ctrl+Shift+A」というショートカットで実行できるようにも設定していきます。

まずは、[開発]タブを選択し、その中の[マクロ]を選択します。

次に、以下の画面にて、好みの名前を入力し、[作成]を選択します。
こちらでは「シート作成」と入力しています。

表示されました以下の画面にて、プログラムを記述していきます。
※「Option Explicit」は設定内容によっては表示されません。


記述する内容は、以下になります。

こちらのプログラムに関して、1行ずつ解説していきます。

まずは、以下の内容について解説します。

Worksheets("YYYYMMDD").Copy After:=Worksheets(1)

こちらでは、「YYYYMMDD」のシートをコピーし、2枚目の位置に貼り付けています。
「Worksheets(1)」が先頭から1番目のシートを指しているため、「Copy」というコピーする機能の設定(引数)の「After」に「Worksheets(1)」を指定することで1番目のシートの後ろと指定しています。

次は、以下の内容について解説します。

With ActiveSheet
    .Name = Format(Date, "yyyymmdd")
    .Range("B2").Value = Date
End With

まずは、「With」について解説します。
「With」を用いることにより、「With」から「End With」の間に関して、「With」の後ろに指定した要素「ActiveSheet」を省略して記述することができるようになります。
省略して記述する場合は、「.」から記述します。

つまり、以下のプログラムと同じ意味になります。

ActiveSheet.Name = Format(Date, "yyyymmdd")
ActiveSheet.Range("B2").Value = Date

同じ要素(こちらでは「ActiveSheet」)に対して操作する場合は、「With」で囲むことによって、処理の塊が分かりやすくなります。

では次に、以下のプログラムについて解説します。

ActiveSheet.Name = Format(Date, "yyyymmdd")

「ActiveSheet」とは現在選択されているシートを指します。
シートをコピーして複製すると、その複製されたシートが自動で選択されるため、「ActiveSheet」は新たに追加したシートのことを指しています。
そのシートの名前「.Name」を「Format(Date, “yyyymmdd”)」で、マクロを実行した日付にしています。
「Date」で、マクロを実行した日付の情報を取得することができるのですが、シート名にはYYYYMMDD形式で設定したいため、Format関数を活用して、形式を変換しています。

では最後に、以下のプログラムについて解説します。

ActiveSheet.Range("B2").Value = Date

こちらでも先ほど同様に「ActiveSheet」を指定しています。
そのシートのセルB2「Range(“B2”)」の値「.Value」に、マクロを実行した日付「Date」を入力しています。

Excel本紹介

このようにして開発することができました。
開発したプログラムは、対象のプログラム名を指定し、実行ボタンを押すことで実行することができます。

実行することにより、以下のようにシートが作成され、セルB2に日付が入力されます。

注意点として、Excel上には同じシート名のシートを作成することができないため、同日に複数回実行すると、以下のようなエラーが表示され、処理が中断されます。

再度実行する際は、作成したシートを削除してから行う必要があります。 必要に応じて、シート名が重複した場合には「YYYYMMDD_2」のような番号を加えるようにプログラミングするのも良いかと思います。
その方法については、こちらでは省略します。

ExcelVBAレベル確認

最後に、ショートカットの設定方法です。
毎回、VBAの編集画面(VBE)を開いて実行するのは手間になるため、ショートカット活用するのがオススメになります。
まずは、[開発]タブの中の[マクロ]を選択し、以下の画面を表示します。

こちらの画面より、開発したプログラム名を選択し、[オプション]を選択します。

以下の画面の[ショートカットキー]のテキストボックスを選択し、Shiftキーを押しながらAキーを押すことで、「Ctrl+Shift+A」というショートカットを設定することができます。

設定後は、[OK]を選択して確定し、設定画面を全て閉じることで、CtrlキーとShiftキーを押しながらAキーを押すして、開発したマクロを実行することができるようになります。

こちらで開発したファイルは、以下から取得できます。


今回の内容は、VBAを用いて繰り返し作業を自動化する一例になります。
ぜひ、日々の繰り返し作業の自動化に、VBAを活用してみてください。
※理解していないプログラムの実行は、情報漏洩データの紛失などの大きな問題につながる可能性があるため、理解した上で実行してください。

2024/03/29
【ExcelVBA】更新履歴を自動で入力

【ExcelVBA】更新履歴を自動で入力

以下のような更新履歴表に関して、「更新」ボタンを押して更新内容を入力するだけで、表の最終行に「更新日、更新者(パソコンにログオン(ログイン)したユーザー名)、更新内容(インプットボックスに入力した値)」が自動で入力される仕組みを開発していきます。

VBAを活用することで、簡単にパソコンに記録されている情報(パソコンにログオンしたユーザー名など)を取得することができます。
今回は、更新者としてパソコンにログオンしたユーザー名を取得していますが、他の値を取得する方法についても、確認用のマクロを配布して解説しています。

機能を開発するために、まずは更新履歴表を用意します。
今回こちらでは、以下のような表を用意しています。

5行目以降に関しては、罫線のみで値を入力していない状態にしておきます。
※用意した表のレイアウト(項目の位置など)によっては、開発するプログラムの内容が異なります。

Excel本紹介

次に、[開発]タブの中の[マクロ]を選択します。

※[開発]タブが表示されていない場合は、以下の手順をご確認ください。

>マクロを開発する準備

以下の画面が表示されましたら、開発する機能の名前(こちらでは「更新」)を入力し、[作成]を選択します。

以下の画面が表示されましたら、「Sub 更新()~End Sub」の間にプログラムを入力していきます。
※環境によっては、「Option Explicit」が表示されていないことがありますが、今回はなくても問題ございません。

では次に、以下のようにプログラムを入力します。
※こちらを実装したExcelファイルは、記事の最後にて配布しています。

Sub内はTabキーにてインデント(字下げ)しています。
インデントの有無では処理に影響はないのですが、処理の見やすさの観点からインデントする癖をつけておいた方が良いです。


プログラムの内容について簡単に確認していきます。

まずは、以下の内容です。

「Dim」と書かれているのは、一時的に値を格納する部屋(変数)を用意する宣言(変数宣言)になります。
「As」の後に部屋の種類を記述しています。(「String」は文字専用の型)

次に、用意した「detail」という変数にインプットボックス「InputBox」に入力した値を格納します。

「InputBox」の括弧の中の文字は、インプットボックスに表示される文字になります。
イメージは以下になります。

次に以下の内容です。

「Dim」は先ほど同様に変数宣言になります。(「Long」は数値専用の型)

「Rows.Count」はシートに存在している最大の行番号になるため、「Cells(Rows.Count,”B”)」でシート上のB列の一番下のセルを指定しています。

このセルから、Ctrlキーを押しながら上に移動「.End(xlUp)」し、止まった位置の行番号「.Row」に1を加えた数を取得しています。
→ B列の下から上に向かっていく中で、次に文字が入力されているセルの一つ下の行番号(5)を取得

次に以下の内容です。

先ほど取得した行番号のB列のセルに実行した時の日付「Date」を入力し、C列のセルにパソコンにログオンしたユーザー名を入力、D列のセルにインプットボックスに入力した値を入力しています。 ユーザー名はEnviron関数を用いて取得しています。
※Environ関数で取得できる値については、最後に確認用マクロを配布して解説しています。

最後に以下の内容にて、Excelファイルを保存しています。


これで機能としては完成しているため、後はボタンを作成し、そのボタンに開発した機能を割り当てれば完成です。

ボタンは、[開発]タブの中の[挿入]から作成すると良いです。

上記のボタンを選択後、図形の作成時と同様にボタンを作成すると、[マクロの登録]画面が表示されます。
そこでは、開発したマクロの名前を選択することで、マクロを割り当てたボタンを用意することができます。
ボタンの表示名などは必要に応じて変更してください。
※作成したボタンを編集する場合は、Ctrlキーを押しながら選択します。

このようにして、ボタンを押してインプットボックスに更新内容を入力するだけで、表の最終行に値が入力されます。


・Environ関数について

最後に、Environ関数で取得できる値について、確認用のファイルを配布して解説していきます。

Environ関数で取得できる値は以下になります。

Environ関数の引数に上記の左側にある環境変数名を設定することで、その値を取得することができます。
先ほどのプログラムで使用した値は「USERNAME」になります。

どのような値が取得できるのかは、実際に試された方がイメージしやすいかと思いますので、各々で確認できるファイルを配布します。
配布ファイルのマクロの実行を許可し、「出力」ボタンを押すだけで、値を確認することができます。

今回開発した「更新履歴を自動で入力する機能のExcelファイル」と「Environ関数の出力確認用のExcelファイル」は以下になります。

ぜひ試してみてください。

2024/02/16
【ExcelVBA】表の先頭にデータを追加する機能(ノーコード)

【ExcelVBA】表の先頭にデータを追加する機能(ノーコード)

以下のような表があります。
表の上の登録フォームに値を入力して「登録」ボタンを押すことで、表の先頭行(6行目)に挿入される仕組みをノーコードで実現していきます。

ノーコードで作成するために、こちらでは「マクロの記録」を活用します。
マクロの記録は、[開発]タブの中の[マクロの記録]から行えます。

「マクロの記録」とは、記録を開始してからの操作内容が自動で記録され、自動でVBA(マクロを開発するためのプログラム)を作成する機能になります。
無駄な操作を行うと、その内容まで記録されてしまうため、結果的に処理が重くなったり予期せぬエラーに繋がり兼ねます。
そのため、マクロの記録を開始する際は、予め記録する手順を確認してから行うと良いです。

また、記録された内容を放置すると機能がブラックボックス化(仕組みが分からない状態)します。
そうなると、正しく処理されるという保証がなくなります。
たまたま上手く実行出来ているけど、ある日を境に正しく実行できなくなるということが起こりやすいです。

これは、最近話題のChatGPTにVBAを書かせることに関しても同様です。
内容を理解せずに運用するということは、急に業務が回らなくなるリスクがあるということになります。

そのため、今回の内容に関しては、実質ノーコードで作成しますが、作成されたプログラムの内容についても振り返りたいと思います。

Excel本紹介

・記録する手順を確認する

まずは、記録する手順を確認します。
登録フォームに値が入力されている前提で、どのようにしたら、先頭行にデータが挿入されるかと考えます。

今回は、次のような手順を行います。

①登録フォーム全体を選択し、コピー(Ctrl+C)する

②表の1行目を選択し、右クリックのメニューから[コピーしたセルの挿入]を選択する

③次の画面で[下方向にシフト]を選択し、[OK]で確定する

④再度、登録フォーム全体を選択し、値を削除(Delete)する

⑤登録フォームの日付の項目を選択する

この手順ならば、登録フォームの入力値に関わらず、常に対応ができるかと思います。
最後に、登録フォームの日付の項目を選択した理由は、次のデータの入力へと誘導するためです。


・マクロの記録を行う

[開発]タブの中の[マクロの記録]を選択します。

以下の画面にて、開発するマクロの名前(こちらでは「登録」)を入力し、[OK]で確定します。

次に、先ほどの①~⑤の手順を無駄な操作なく行います。
※無駄な操作を行うと、処理が正しく記録されなくなります。

手順が完了しましたら、[開発]タブの中の[記録終了]を選択します。

以上で、マクロが自動で作成されます。

Excel本紹介

・記録したマクロを確認する

記録したマクロは、[開発]タブの中の[マクロ]を選択することで、確認できます。
以下の画面から記録したマクロ名(こちらでは「登録」)を選択して[実行]を選択すると、記録した処理を実行することができます。
また、[編集]を選択すると、記録されたVBA(プログラム言語)の内容を確認することができます。
→VBAの内容についての解説と改善方法については、最後に解説します。

[実行]を選択し、記録した内容が正しく実行できることを確認します。

また、[編集]を選択して確認できるプログラムは以下になります。
※「Option Explicit」は設定によっては表示されません。

ただ、このプログラムには無駄な処理があります。
この無駄な処理によって、実行時に画面がパカパカするかと思います。
後から無駄な処理については解説するため、一度のこのままで実行ボタンを作成していきます。


・記録したマクロをボタンに割り当てる

記録したマクロは、好みの図形や画像、ボタンに割り当てることができます。
割り当てることで、その図形や画像、ボタンを選択するだけで、処理を実行することができるようになります。

ボタンを作成するには、[開発]タブの中の[挿入]にある[ボタン]を選択します。
※フォームコントロール内のボタンを選択してください。

選択後は、通常の図形と同じようにボタンを作成することができます。
作成後に、[マクロの登録]という画面が表示されるため、記録したマクロ名(こちらでは「登録」)を選択します。

ボタンの名前に関しては、好みの名前を設定します。
※ボタンを作成後に選択すると、処理が実行されてしまいます。そのため、作成後のボタンを編集する場合は、Ctrlキーを押しながら選択します。

これで機能を開発することができました。


・記録したマクロを改善する

記録したマクロの内容を細かく確認し、画面のパカパカに関しても改善していきます。

こちらのプログラムでは、「Sub」から始まり、次に登場する「End Sub」までの処理が、上から順番に行われます。

この中の「○○.Select」というのは、該当する要素を選択するという処理になります。
「Range(“B3:D3”).Select」の場合は、セルB3からD3を選択するという処理です。

また、この中に「Selection」というものがあります。
これは、その時点で選択しているものに対して処理を行うというものです。
「Selection.Copy」の場合は、その前の行でセルB3からD3が選択されているため、セルB3からD3をコピーするという処理です。
「Selection.Insert Shift:=xlDown」の場合は、その前の行でセルB6が選択されているため、セルB6を基準に下方向にコピーしたセルを挿入するという処理になります。
最後の「Selection.ClearContents」は、その前の前の行でセルB3からD3が選択されているため、セルB3からD3の値を削除するという処理になります。

「Application.CutCopyMode = False」は、コピーモードを解除するという処理になります。

この中の無駄な処理は、以下の2つになります。

・毎回セルを選択する必要がない → 画面がパカパカする原因に繋がる
・コピーモードの解除に関しては、セルの値を削除すると同時に勝手に解除されるため、記述する必要がない

この2点を改善したコードが以下になります。

最後の登録フォームの先頭を選択する処理に関しては「Select」を残していますが、それ以外に関しては全て修正しました。
実際は、これだけで同じ処理を実現することができます。

また、この処理の中には、毎回セルを選択する処理がないため、画面がパカパカしません。

こちらで使用したファイルは、以下にて配布します。

というような感じで、「マクロの記録」は便利な機能ではありますが、無駄が多いということも分かったかと思います。
AIも発達してきたため、より誰もがプログラムを開発しやすい時代にはなってきましたが、最低限の知識は今後も必要になることが考えられます。

「マクロの記録」の活用を機に、プログラムを学習してみるのも、良いかと思います。

2024/02/09
【ExcelVBA】選択した行を自動で色付け

【ExcelVBA】選択した行を自動で色付け

以下のように指定した範囲(セルB2~F13)に関して、選択している行全体を色付けする方法について解説していきます。
こちらで作成したファイルは、記事の最後にて配布しています。

このような仕組みを実現するには、条件付き書式を活用します。
条件付き書式とは、指定した条件を満たしている時に、指定したセルの書式を変更するという機能になります。
色を設定する条件を考えると以下のようになります。

・現在選択している行番号と、対象の行番号が一致する場合

少しイメージが難しいかもですが、例えば、セルB2に以下のような式が設定されているとします。

=現在選択している行番号=ROW(B2)
// 「現在選択している行番号」は、実際には別の数式が入ります。

ROW関数では、引数に指定したセルの行番号を取得することができます。
そのため、2行目のセルのいずれかが選択されている時に、この条件を満たすことになります。

この条件を満たしている時に、対象のセルの背景色を変える必要があるため、この条件の数式を条件付き書式に設定する必要があります。


「現在選択している行番号」を取得するには、CELL関数を活用します。
CELL関数の引数に以下のように指定することで、現在選択しているセルの行番号を取得することができます。

=CELL("row")

複数のセルが選択されている場合は、アクティブになっているセルの行番号が取得されます。

先ほどの条件を表す数式にCELL関数を用いると、以下のようになります。

=CELL("row")=ROW(B2)

この数式を、条件付き書式にて設定していきます。

対象の範囲を選択し、[ホーム]タブの中の[条件付き書式]の[新しいルール]を選択します。

条件付き書式の設定画面にて、[数式を使用して、…]を選択し、先ほどの数式を入力し、書式を設定します。

=CELL("row")=ROW(B2)
// 「B2」はアクティブセルのアドレスにする

このように設定することで、対象の範囲内に関して、選択している行全体を色付けすることができます。

ただ、条件付き書式の設定のみですと、色付けを反映するには、セルを編集するか数式を更新する必要があります。
その理由は、CELL関数で取得される値は、数式が更新されたタイミングに、値が更新されるためです。

そのため、対象の範囲が選択された場合は、自動で数式を更新する仕組みを実現する必要があります。


セルの選択と同時に数式を更新する仕組みを実現するには、シートモジュールを活用します。
[開発]タブの中の[Visual Basic]を選択し、表示された画面(VBE)から対象のシートモジュールを開きます。
※VBEに[プロジェクト]が表示されていない場合は、VBEの[表示]タブより表示することができます。
 「Option Explicit」は設定によっては表示されませんが、表示がなくても問題ありません。

次に、[General]と表示されているリストから、[Worksheet]を選択します。
[Worksheet]を選択することで、Worksheet_SelectionChangeというプロシージャが表示されます。
万が一、別のプロシージャが表示された場合は、右隣りのリストから[SelectionChange]を選択します。

このプロシージャは、該当するシートのセルが選択されたタイミングに自動で実行されます。
そのため、以下のように「数式を更新する」という内容を記述するだけで、セルの選択と同時に数式を更新させることができます。

ただ、この状態ですと、常に数式が更新されることになるため、Excelファイル自体の処理が重くなる原因に繋がります。
そのため、該当する範囲を選択した場合に関してのみ、数式が更新されるように記述する必要があります。

そのためには、以下のように記述します。

プロシージャの引数の「Target」に、選択されたセルの情報が格納されます。
そのため、IF文を用いて、「その対象の行番号が2以上かつ13以下、列番号が2以上かつ6以下である場合」という条件を満たしたときのみに、数式が更新されるように記述しています。
※IF文の中の「_」は、プログラムを改行するために記述しています。

このようにすることで、対象の範囲を選択した場合に関してのみ、その範囲の行全体を色付けすることができます。

▼サンプルファイル▼

2024/02/02
【ExcelVBA】記入時刻を自動入力

【ExcelVBA】記入時刻を自動入力

以下のような表があります。
この表の[内容]という項目に何かしら入力すると同時に、[記入時刻]という項目に、入力時の時刻が自動で入力される仕組みの実現方法について解説していきます。

特定のシートの特定のセルに値を入力した後に、何かしらの処理を実行するには、「シートモジュール」を活用します。

まず、[開発]タブの中の[Visual Basic]を選択し、表示された画面(VBE)から、該当するシートモジュールを開きます。
※設定によっては「Option Explicit」が表示されないことがありますが、そのままでも問題ございません。

プロジェクトの画面が表示されていない場合は、[表示]タブのメニューから表示することができます。
プロジェクトの中に「Sheet1」と書かれている箇所があります。
その隣の括弧の中の文字(議事録)はシート名になります。

次に、シートモジュールの上の[General]と表示されたリストから[Worksheet]を選択します。

次に、右隣りのリストから[Change]を選択します。

この時に表示される[Worksheet_Change]というプロシージャにて開発していきます。
[Worksheet_SelectionChange]のプロシージャに関しては、削除しても問題ございません。

ExcelVBAレベル確認

[Worksheet_Change]というプロシージャは、該当するシートのセルが編集された時に実行される特殊なプロシージャ(イベントプロシージャ)になります。
実行時に、引数の[Target]に操作されたセルの情報が格納されて実行されます。

このプロシージャに以下のように記述します。

If文の中の「Target.CountLarge = 1」で編集された対象のセルが1つであることを確認しています。
その上で、「.Row >= 5」と「.Column = 2」で、対象が5行目以上であることと2列目(B列)であることを確認しています。

この条件を満たした時に以下の処理が行われます。

こちらでは、対象のセルと同じ行のA列の値が空の場合に、そのセルに現在の時刻(Time)を入力するようになっています。

このような設定をすることで、以下のように[内容]の項目に何かしら入力すると同時に、A列の[記入時刻]の項目に入力時の時刻が入力されます。

今回開発したファイルは、以下からダウンロードできます。

このような機能を活用することで、会議の際の議事録として活用することができるかと思います。
また、会議を録音する際に、セルB1に録音の開始時刻を入力することで、後からの確認が容易になります。
開始時刻と記入時刻の差を表示する項目を用意すると、より便利になるかと思います。

2024/01/26
【ExcelVBA】半角文字を自動で全角文字に変換

【ExcelVBA】半角文字を自動で全角文字に変換

住所を入力する項目などに、以下のように全角文字と半角文字が混ざって入力されていることがあります。

このように、全角文字と半角文字が混ざっている状態は、以下のような問題点があります。

・一貫性がない:データを確認する際の誤解が生じる可能性がある
・データ処理が行いづらい:検索や並べ替え時に想定通りに出来なかったり、重複した内容を認識するのが大変になることがある
・外部システムとの互換性:システムによっては、全角文字のみしか入力を許可していないケースがあるため、そのままの貼り付けで入力ができなくなる

他にも、色んな理由が考えられますが、データを管理する場合は、ルールを統一して管理した方が良いです。
ただ、表を扱う全員が同じ認識でないと、ルールが守られない可能性があります。

ということで、こちらでは、入力した文字を強制的に全角文字に変換する方法について解説していきます。
※こちらで使用したファイルは、記事の最後にて配布しています。

こちらでは、VBAを活用して実現していきます。
特定のシートのセルに入力したタイミングに、自動で処理を行う場合は、シートモジュールを活用します。

まず初めに、[開発]タブの中の[Visual Basic]を選択します。

以下の画面が表示されましたら、該当するシートをダブルクリックし、表示された画面の上のリストから[Worksheet]を選択します。

次に、右側のリストから[Change]を選択します。
※「Option Explicit」が表示されていなくても問題ございません。

選択後に表示される[Worksheets_Change]というプロシージャを活用して実現していきます。

このプロシージャは、該当するシート上のセルを編集した後に実行される特殊なプロシージャ(イベントプロシージャ)になります。
引数の[Target]に、編集されたセルの情報が格納され、実行されます。


まず以下のように入力します。

こちらの内容は、「編集したセルの値を全角文字に置換して、自身のセルに上書きする」という処理になっています。
「StrConv」という関数が、指定した文字を指定した形式に置換した値を返すというものになります。
「Target」に編集したセルの情報が格納されるため、「Target.Value」というのは、そのセルの中に入力されている値を指します。
「vbWide」というのが、「全角文字に変換する」という設定になります。

プログラムの世界の「=」は、一般的に、「右辺の値を左辺に代入する」という意味になります。
そのため、こちらの内容は、全角文字に置換された値を自身のセルに上書きしていることを意味します。

これだけで、セルに入力した値を自動で全角文字に置換することができます。

ただ、この内容ですと問題点があります。
それは、住所の項目以外でも適用されてしまう点と、複数のセルをコピペした場合など、複数のセルに同時に値を入力した場合にエラーになってしまう点です。

そのため、その問題点を解決する必要があります。
解決するには、以下のように修正します。

すこし難しくなりました。
「Target」には複数のセルの情報が入ってくる可能性があります。
そのため、「Target」が持っているセルの情報を1つ1つに分解して処理を実行する必要があります。
「Dim r As Range」で「r」というセルの情報を格納する用の変数を用意しています。
※ここで言う「変数」とは、一時的に値を格納する用の入れ物のことを指します。

「For Each」にて、「Target」の内容を1つずつ順番に「r」に渡して実行しています。
「For Each」から「Next」までを、繰り返し実行します。

その1つのセルの情報「r」に対して、「If」にて、住所の項目の範囲内かどうかを確認しています。
住所の範囲は、B列の3行目以降になります。
そのため、「r.Row >= 3 And r.Column = 2」と、「r」のセルが3行目以上かつ2列目(B列)であることを確認しています。

「If」から「End If」の中のプログラムは、「r.Row >= 3 And r.Column = 2」という条件を満たしている時のみに実行されます。
その時に、全角文字に置換した内容を上書きする処理を実行します。

以上のように修正することによって、対象の範囲の指定と複数のセルにも対応させることができます。
そのため、住所が入力されている範囲をコピーし、同じ範囲に貼り付けることによって、一瞬で全角文字に変換することができます。

Excel本紹介

ここまでで、一応完成していますが、他にも懸念点が残っています。
それは、「膨大な範囲を一括で入力した際に、処理が完了するまで時間がかかってしまう」という点です。

入力したセルの数が多ければ多いほど、「For Each」での繰り返し回数が増えてしまうため、処理が完了するまでに時間がかかってしまうようになります。
私、個人的な感覚では、10,000セルよりも多い範囲を同時に入力した場合は、流石に処理の完了を待つのが辛くなるという印象です。

「そんなに同時に入力することがない」と考えていたとしても、「無意識に列ごとコピーして貼り付け」などを行うと、処理が完了するまでに膨大な時間がかかってしまうことになります。
そのため、なるべく対策はしておいた方が良いかと思います。

その対策を組み込んだプログラムは、以下になります。

「If」は「Then」の後に、1行で処理を記入した場合は、「End If」を省略することができます。
こちらでは、「Target.CountLarge」にて対象のセルの数を取得し、その数が10,000より多い場合という条件が設定されています。
この条件を満たしている場合は、「End」が実行されます。
「End」は処理を終了させるものになるため、対象のセルの数が10,000より多い場合は、下の処理が実行されることなく、処理が中断されます。

機能の開発は以上になります。
開発したファイルは以下よりダウンロードしていただけます。

システムを開発する場合は、利用するユーザーの行動を予想して開発していく必要があります。
システムには、エラーが付き物になります。
そんな中でも、なるべく快適に扱うために、予想できる想定外の操作を考慮して、開発していくのが良いかと思います。
※「予想できる想定外の操作」と若干矛盾している言い方ですが、「想定外によるエラーをなるべく無くす」という意味で表現しています。

2024/01/12
【ExcelVBA】ダブルクリックで値を切り替える方法

【ExcelVBA】ダブルクリックで値を切り替える方法

以下の表のステータスは、「着手中、完了」のリストになっています。
「着手中」を選択すると背景色を黄色に、「完了」を選択すると行全体をグレーになるように条件付き書式を設定しています。

このステータスの項目に関して、ダブルクリックするだけで、「着手中→完了→空白→…」と切り替えられるようにする方法について解説していきます。

特定のシート内のセルをダブルクリックすることで、何かしらの処理を実行するには、シートモジュールを活用します。

[開発]タブの中の[Visual Basic]を選択します。

次の画面にて、該当するシートをダブルクリックします。

プロジェクトの画面が表示されていない場合は、「Ctrl+R」もしくは、[表示]タブから表示することができます。

開かれたエディタの上の[General]と書かれているリストから[Worksheet]を選択し、その後、隣のリストから[BeforeDoubleClick]を選択します。
※この時、「Option Explicit」が表示されていなくても問題ございません。

リストから選択することで表示された「Private Sub Worksheet_BeforeDoubleClick(…」内に、以下のようにコードを入力します。

▼サンプルファイル▼

このプロシージャは、該当するシートのセルがダブルクリックされた時に、自動で実行される特殊なプロシージャ(イベントプロシージャ)になります。

実行される時に、引数の「Target」にダブルクリックされたセルの情報が渡されます。
そのため、以下のコードにて、3行目以上かつ4列目の場合という条件を指定し、ステータスの範囲に関してのみ、処理が実行されるように分岐させています。

「Cancel = True」は、セルをダブルクリックした後の入力モードを取り消すためのものになります。
このコードを入れることによって、ダブルクリックした後に、セルが編集されることなく、値のみを切り替えることができます。

最後に、以下のIF文で、ダブルクリックしたセルの値に応じて、そのセルの値を切り替えるようにしています。

・「着手中」→「完了」
・「完了」→空白
・「着手中、完了」以外→「着手中」

以上の設定を行うことで完成です。

2024/01/05
【ExcelVBA】結合されているセルを色付け

【ExcelVBA】結合されているセルを色付け

表の中にセル結合されている箇所が存在すると、正しく集計ができないことがあります。
セル結合は便利な機能ですが、表の中のセルを結合してしまうと、絞り込みや並べ替えといった操作が正しくできなくなります。

例えば、以下のような表に対して絞り込みをしてみます。
絞り込みをすると、以下の画像のように、正しく絞り込むことが出来ていないことが分かります。

セルの結合がされている場合、そのセルに入力されている値は、結合範囲の先頭のセルの値として管理されます。
そのため、上図のように先頭のみが絞り込みされたということになります。

では、並べ替えについても確認していきます。
先ほどと同じ表で並べ替えを行うと、以下のように警告が表示されます。

以上のように、結合されているセルは集計には向かないことが確認できます。

そのため、結合されているセルが表の中に存在する場合は、その結合を取り除く必要があります。
そこで今回は、結合されているセルを自動で色付けする機能の開発方法について解説していきます。

開発する具体的な内容としては以下のようになります。

「選択されている範囲内で、セルが結合されている場合に、その対象のセルを色付けする」

では、開発していきます。


まず、[開発]タブの中の[マクロ]を選択します。

表示された以下の画面にて、好みの名前を入力し、[作成]を選択します。
こちらでは、”セル結合色付け”と入力しています。

表示された画面にて、以下のように入力します。

先頭のIf文で、選択範囲のセルの数が10000より多い場合は、メッセージボックスを表示させ、Endで処理を強制終了させています。
この処理はメインの処理ではありませんが、選択範囲が多いと、セル結合のチェックに処理時間がかなりかかってしまう可能性もあるため、選択範囲のセルの数に制限を設けています。

「For Each ~ Next r」の処理で、選択範囲(Selection)のセルを1つ1つ順番に変数rに格納して繰り返します。
For文の中のIf文で、変数rに格納されたセルが結合されているかどうかを確認しています。
結合されている場合は、「r.Interior.Color」にてセルの背景色を黄色(RGB(255, 255, 0))にしています。

こちらの処理を、以下のシートの範囲に対して実行してみます。
実行は、[開発]タブの中の[マクロ]から作成したマクロを選択して、[実行]を選択する、もしくは、開発画面(VBE)の再生ボタン(右向きの三角マーク)を選択することで行えます。

このように、自動で色を設定することができました。
今回は、色を設定するという機能でしたが、必要に応じて、「結合を解除して、先頭のセルの値を全てのセルに格納する」というような処理にしても良いかと思います。

2023/12/18
【ExcelVBA】予定表の各日付に1行を追加する

【ExcelVBA】予定表の各日付に1行を追加する

※こちらの記事では、開発したExcelファイルを配布しています。

以下のように、すでに予定が入力されている予定表(スケジュール表/カレンダー)があります。

1日2行単位の予定表になっているのですが、1行を加えて3行単位に変更する場合、手作業で行うのは大変になります。
このような時に、VBAが使えると便利になります。

こちらでは、VBAを使って既存の予定表に1行追加する方法について解説していきます。

・手順確認

まずは、開発する手順を考えます。
行を挿入したい行が、4行目、6行目、10行目、…の場合、4行目から順番に挿入していけば良いように感じますが、実はそれでは上手くいきません。

その理由は、4行目を挿入した時点で、その次に挿入する予定だった行(6→7行目)が1行下へ移動してしまうためです。

そのため、行を一定間隔で挿入するプログラムを開発する際は、表の先頭からではなく、表の最終行から行うと良いです。

次に、表の中の行を挿入する最終行の確認をします。
こちらの表の場合は、186行目になります。

そのため、実行する手順は以下のようになります。

・186行目から4行目まで、2行ずつ上に移動しながら行を挿入

ちなみに、今回の手順の場合、予定表の真ん中に行を挿入することになります。

下に挿入するようにする場合は、罫線が崩れてしまう可能性があるため、挿入時に罫線を設定するプログラムも実装する必要があります。
※こちらでは、予定表の真ん中に挿入する方法のみを解説していきます。


・開発

では、以下の内容をVBAで実現していきます。

・186行目から4行目まで、2行ずつ上に移動しながら行を挿入

まず、[開発]タブの中の[マクロ]を選択します。

次の画面にて、好みの名前を入力し、[作成]を選択します。
こちらでは、「行挿入」という名前を入力しています。

標準モジュールが作成されましたら、以下のように記述します。

Sub 行挿入()
    
    Dim i As Integer
    For i = 186 To 4 Step -2
        Rows(i).Insert
    Next i
    
End Sub

・Dimでは数値を格納する用の入れ物「i」を用意しています。(変数の用意)
・For ~ Next間で「i」の値を変えながら繰り返し実行しています。
・For ~ Next間の「i」は、186から4まで、-2ずつ変化させています。
・Rows(i).Insert で「i」行目に行を挿入しています。

記述できましたら、実行ボタンを押すことで、瞬時に予定表の各日程に1行挿入されます。

Excel本紹介

VBAは理屈が分かってくると、そこまで難しいものではないので、まだVBAを触ったことがない方は、挑戦してみることをオススメします。

▼サンプルファイル▼

2023/11/15
【ExcelVBA】「マクロの記録」でクラス分け

【ExcelVBA】「マクロの記録」でクラス分け

以下のような名簿があります。
こちらの名簿には、A~Cの複数のクラスが含まれます。

この表をクラス分けして、以下の別々のシート(A~C)に表示させる機能の開発方法について解説していきます。

今回、こちらでは「マクロの記録」という機能を活用して開発していきます。
解説する流れは以下になります。

・手順の確認
・「マクロの記録」の実行
・記録内容の確認と修正(修正後のファイルも配布)

実際に、「マクロの記録」にて開発したファイルは以下になります。
※こちらのファイルは、記録後の未修正ファイルです。

では、順番に解説していきます。


・手順の確認

「マクロの記録」を上手く活用するには、無駄な手順を無くし、尚且つ、繰り返し実行できる手順を考える必要があります。
今回は、以下の手順で記録することで実現していきます。

① 表にフィルターを設定(ショートカット:Ctrl+Shift+L)

② Aクラスで絞る

③ A~B列をコピー(ショートカット:Ctrl+C)

④ シート「A」のセルA1を選択して貼り付け(ショートカット:Ctrl+V)

⑤ シート「A」のセルA1を選択

⑥ ②~⑤の手順を、Bクラス、Cクラスでも実行する

⑦ 表のフィルターを解除(ショートカット:Ctrl+Shift+L)

この手順のポイントは、③でコピーする際に列全体をコピーしているというところです。
列全体を選択することで、今後、データ数が増えてきた場合にも対応することができます。


・「マクロの記録」の実行

では、先ほどの手順を記録していきます。
[開発]タブの中の[マクロの記録]を選択し、好みの名前で作成します。

[作成]を選択した後は、以下のように[記録終了]という文字に切り替わり、記録が開始します。

記録が開始すると、その後の操作は、すべて記録されてしまうため、無駄な操作なく、先ほどの手順を行います。
※記録される操作は、「マクロの記録」に対応している操作のみになるため、Windowsの操作などは記録されません。

先ほどの①~⑦の操作が完了したら、上記の[記録終了]を選択することで完成です。
実行は、[マクロ]の中の作成した名前を選択することで行えます。


・記録内容の確認と修正

記録された内容を確認します。
記録されたコードは、[VisualBasic]を選択することで確認することができます。

記録されたコードは以下になります。

こちらには、無駄なコードが多く存在します。
[マクロの記録]を活用するデメリットはここにあります。
[マクロの記録]を活用した後は、中身を確認し、無駄な処理を修正した方が、保守的になります。

では、無駄な処理を確認していきます。

まずは以下の内容です。

Selection.AutoFilter
ActiveSheet.Range("$A$1:$C$51").AutoFilter Field:=3, Criteria1:="A"

この処理は、「選択したセルを基準にフィルターを設定し、その後にセルA1~C51が含まれるフィルターの3列目が「A」のもので絞り込む」という内容になっています。
ここの無駄なポイントは、以下になります。

・フィルターの設定と絞り込みを分ける必要がない
・フィルターの範囲を指定するには、設定が含まれるセルであればよいので、A1~C51などの指定が不要
・ActiveSheet(現在選択されているシート)というのが抽象的で、別のシートを選択して実行すると不具合を起こす

こちらを改善すると、以下のようになります。

Sheets("学年").Range("A1").AutoFilter Field:=3, Criteria1:="A"

この処理は、「シート「学年」のセルA1を基準にフィルターを設定し、設定したフィルターの3列目が「A」のもので絞り込む」という内容になっています。
このように、無駄な処理を修正し、より不具合が起こりにくい処理にすることができました。

次に、以下の処理です。

Columns("A:B").Select
Range("B1").Activate
Selection.Copy
Sheets("A").Select
ActiveSheet.Paste
Range("A1").Select

この処理は、「現在選択されているシートのA列とB列を選択し、セルB1をアクティブにしてコピーし、シート「A」を選択し、貼り付けて、セルA1を選択する」という内容です。
ここの無駄なポイントは、以下になります。

・コピー対象は選択されている範囲であり、現在、どのセルが選択されているのかは関係ない
・シート情報が省略されているため、別のシートを選択して実行すると不具合を起こす

こちらを改善すると、以下のようになります。

Sheets("学年").Columns("A:B").Copy
Sheets("A").Range("A1").PasteSpecial
Sheets("A").Select
Range("A1").Select

この処理は、「シート[学年」のA~B列をコピーし、シート「A」のセルA1を基準に貼り付け、シート「A」のセルA1を選択する」という内容です。
Pasteメソッドはシートに対してしか使えないため、セルに対して直接貼り付けできるPasteSpecialメソッドを使用しています。

この流れで他も修正すると、以下のようになります。

これだけでも、かなり見やすくなったかと思います。
こちらのファイルは以下になります。


「マクロの記録」は、とても便利な機能ですが、無駄な処理も多く記録されてしまいます。
また、中身の確認が出来ない場合は、機能の仕組みはブラックボックスとなり、どのタイミングで不具合を起こすのかが予測できません。

その状態での業務での運用は、かなり危険になります。
初めは大変ですが、「マクロの記録」を活用した場合は、コードの内容を確認することを推奨します。

2023/10/16
【ExcelVBA】瞬時にフィルターで絞り込み

【ExcelVBA】瞬時にフィルターで絞り込み

以下のような表に関して、対象のデータを探す際に、フィルターボタンから絞り込みをするとします。

この絞り込み作業が毎回発生する場合、フィルターのメニューから絞り込み条件を毎回設定するのは大変に感じることがあります。

こちらでは、データを絞り混む際に、フィルターのメニューを操作せずに、瞬時に絞り込む機能の開発方法について解説していきます。
具体的には、対象の項目の上の空白セルに、検索したい文字を入力することで、その文字が含まれるデータのみを瞬時に絞り混むという機能になります。
以下の画像がイメージになります。

こちらでは、項目[ふりがな]を絞り込むための機能を開発する方法について解説していきます。

※全項目に対応した機能を開発する場合は、以下のコンテンツをご確認ください。

>【業務】瞬時に表のデータを絞り込む機能


こちらで開発するファイルは、記事の最後にて配布しております。

まず初めに、[開発]タブの中の[Visual Basic]を選択します。

次に[プロジェクト]から対象のシートモジュールを開きます。

※[プロジェクト]が表示されていない場合は、[表示]タブから表示することができます。

開いたシートモジュールのエディターの上に[General]と書かれたリストがあります。
こちらから[Worksheet]を選択します。

選択すると、隣のリストの[Declarations]が[SelectionChange]に切り替わり、[Private Sub Worksheet_SeletionChange]というプロシージャが表示されます。
今回は、こちらを使用せず[Worksheet_Change]というプロシージャを使用するため、隣のリストから[Change]を選択します。

選択することで、[Worksheet_Change]というプロシージャが表示されます。
[Worksheet_SelectionChange]のプロシージャに関しては、今回は使用しないため、削除しても問題ないです。

次に[Worksheet_Change]のプロシージャ内に以下のように記述します。

このコードの意味を説明します。

[Worksheet_Change]というプロシージャは、対象シートのセルの値を編集した際に自動で実行される、イベントプロシージャと呼ばれる特殊なプロシージャになります。
引数の[Target]には、編集したセルの情報がRange型で格納されます。

その[Target]の情報を活用して、対象のセルが編集されたかどうかを確認します。

If Target.CountLarge = 1 And Target.Address = "$D$1" Then ~ End If
// 上記の画像内の「_」はコードを改行する際に使用します。

上記のコードにて、編集されたセル[Target]が1つのセルなのかどうかと、アドレスがセルD1なのかを確認しています。
[.CountLarge]で対象のセルの数を取得することができ、[.Address]で対象のアドレスを絶対参照で取得することができます。

この条件を満たした時に以下のコードが実行されます。

Range("B2").AutoFilter 3, "*" & Range("D1").Value & "*"

上記のコードにて、セルB2が属している表にフィルターを設定し、[3]で列番号を指定、[“*” & Range(“D1”).Value & “*”]で絞り込み条件を指定しています。

[3]は表の先頭からの列番号になります。
[ふりがな]の項目は先頭から3番目の要素になるため、[3]と指定しています。

[“*” & Range(“D1”).Value & “*”]は、条件として、「セルD1の値を含む」という意味になります。
[Range(“D1”).Value]でセルD1の値を取得し、[“*” &]と[& “*”]で、セルD1の値に「*」という文字を結合しています。
「*」は0文字以上の文字という特殊な意味があり、「*」で囲むことによって、「その値を含む」という条件にすることができます。


以上の設定にて完成です。
セルD1に好みの値を入力することで、その文字を含む値のみに絞り込むことができます。

数値の項目に適用する場合は、「○○を含む」という条件では実現できないため、「*」の結合を無くすなどと条件を変更する必要があります。

▼サンプルファイル▼

2023/09/28
【ExcelVBA】チェックボックスを一括リセットするボタン作成

【ExcelVBA】チェックボックスを一括リセットするボタン作成

作成したチェックボックスを一括でリセットする方法について解説していきます。

まずはチェックボックスの作成方法から解説していきます。

・チェックボックスの作成方法

チェックボックスを作成するには[開発]タブを表示する必要があります。
[開発]タブの表示方法についてはこちらをご確認ください。

[開発]タブを表示できましたら、[開発]タブ内の[挿入]から作成することができます。
[挿入]内のフォームコントロールの[チェックボックス]を選択することで作成することができます。

作成する際は、セル内に収めることを意識して作成すると、その後に複製しやすくなります。
まずは、適当なサイズで作成し、テキストが不要な場合は、テキストを削除した上で、セル内にサイズを調整します。

作成した後に選択すると、チェックのON・OFFが切り替わってしまいます。
修正したい場合は、Ctrlキーを押しながら選択することで、サイズ調整などを行うことができます。

1つ作成できましたら、そのセルをコピーすることで簡単に複製することができます。

Excel本紹介

作成することができましたら、チェックの有無をセルに表示させます。
チェックボックスの上で右クリックし、[コントロールの書式設定]を開き、リンクするセルを設定します。
それぞれ、チェックボックスを含むセルのアドレスを設定します。

それぞれに設定をすると、チェックボックスのON・OFFを切り替えた場合に、対象のセルにTRUEもしくはFALSEの値が表示されるようになります。
※以下の画像の場合は、セルの幅が狭いため”###”と表示されていますが、数式バーにて実際の値を確認することができます。

セルの値がTRUEの場合にチェックされ、FALSEもしくは空白の場合にチェックが外されます。
見た目では、チェックの有無に関しては瞬時に判断できるため、TRUE・FALSEの値は不要かと思います。
そのため、TRUE・FALSEの値を非表示にしていきます。

Excel本紹介

実際の値を残した状態で、見た目のみを非表示にするには表示形式が活用できます。

設定内容は、表示形式の[その他の表示形式]より、[ユーザー定義]にて「;;;」とセミコロンを3つ並べて確定します。

この設定によって、以下のように非表示にすることができます。

余談にはなりますが、このTRUE・FALSEの値を用いて、チェックの数を集計することが可能です。
具体的には、以下のような数式で求めることができます。

=COUNTIF(B2:B4,TRUE)

では次に、チェックボックスのチェックを一括でリセットするボタンを開発していきます。

Excel本紹介

・チェックを一括でリセットするボタンの開発方法

[開発]タブの中の[マクロ]を選択し、「チェック取消」という名前を入力して[作成]を選択します。

表示された「Sub チェック取消」の中身に、以下のコードを記述します。
※こちらのファイルは配布しています。

Sub チェック取消()
    
    Range("B2:B4").ClearContents
    
End Sub

連続しているセルを指定する場合は、「”B2:B4″」もしくは「”B2″,”B4″」のようにRangeの中に記述します。
離れているセルを指定する場合は、「”B2,B5,C3″」のように「”」内にカンマ区切りでアドレスを指定します。

このコードの意味は、指定したセルの値を削除する(ClearContents)というものになります。

入力できましたら、[開発]タブの中の[挿入]より、フォームコントロールの[ボタン]を選択し、適当な位置に作成します。
作成時に、「マクロの登録」という画面が表示されるため、先ほど作成した「チェック取消」を選択します。

必要に応じて、ボタンのテキストを変更することで完成です。

こちらのボタンを選択することで、チェックを一括で取り消すことができます。

▼サンプルファイル▼