技術者に師事したことはないですが、ある意味プロフェシッショナルかもしれない楽々アート会(趣味で絵を描くサークル)会員の私が、ソフト制作初心者のために蘊蓄を語ります。楽々アート会のページへ(←我々の絵画作品も掲載しています)
ExcelとはMicrosoft Officeに含まれる表計算ソフトです。表に数式を入力することで簡単に計算ができ…って今更書く必要もないくらいで解説するページもネット上に山ほど存在します。VBAも同様ではありますが、これを使うとセルに入力する関数ではどうにも出来ないことが出来るようになったりします(設定をテキストにして読みこめるしDLLやら別のアプリを使うことが出来るし…)。つまりが、Excelを使う上でやりたいことをやるための道具の1つな訳です…やりたいことが思いつかない向きもあろうかと思いますが、作ったシートを誰かに使って貰ったりすれば「こんなこと出来ない?」とか言われることもあるでしょう…それを実現するための道具…なのですが、例えば数式入力で出来ることもVBAで行うことができます。
下は税抜き金額を入力して消費税込みの金額を計算させる数式です。
解説不要ですが超初心者のために解説すれば「=B2*1.1」は、「セルB2に入力した数字に1.1掛けた数値を(この数式を記載したセルに)表示せよ」ってことです…つまりが消費税10%ですね。いや8%の商品もあるし…ってのは(これも商品が決まっているならドロップダウンさせてリストから読み込んでも良いし何らかのフラグを立てて税率を変更しても良いが…)この際無視します。
このセルをコピーして必要なだけ下に張り付ければ出来上がり。…全く同じことをVBAでやってみるのですが、前準備としてメニューに“開発”を表示します。それなりに新しいExcelなら、メニューのファイルから“オプション”を選択、“リボンのユーザー設定”で“開発”にチェックしOKとします。
さて、表示された開発メニューを選択し“Visual Basic”をクリックします。
プロジェクトの“Sheet1(Sheet1)”(現在制作中のシート)をダブルクリックすると下のようなダイアログが表示されるので、ドロップダウンから“Work sheet”を選択すると
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub
という文字列が自動で生成されます。この2列の間に書き込んだ命令は、セルの値が変更された時に実行されます。
では実験です。下記のように“MsgBox Target”と書き込んで、元のシートに戻り、値を変更してみましょう。
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target
End Sub
下記のように変更後の数値が表示されます。
MsgBox Targetは、Targetの値を(メッセージボックスで)表示せよという命令です。つまりTargetという変数には、変更されたセルの値が入っているってことです。
では再び実験です。下記のように“MsgBox Target.Address”と書き込んで、元のシートに戻り、再び値を変更してみましょう。
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target.Address
End Sub
下記のように変更されたセルのアドレスが表示されます。
つまりTarget.Addressには変更されたセルがどのセルか?という情報が入っています。
では、次に下記のように2行書き込んで、もう一度値を変更してみましょう。
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Left(Target.Address, 3)
MsgBox Right(Target.Address, Len(Target.Address) - 3)
End Sub
まずメッセージボックスで“$B$”と変更したセルの列が$に囲まれて表示され、次に“2”と変更したセルの行が表示されます。ちなみにLeft( 文字列 ,3)は左から3文字にする、Right( 文字列 ,1)は右(後)から1文字で、Len( 文字列 )は文字列全体の文字数です。$B$3の文字数は4、$B$の3文字を引いています。
「Left(Target.Address,3)って、Target.Addressの値($B$3)の左から3文字ってことなら、セルがABとか($AB$3)ならどうするの?」さて、どうするかは考えて下さい(僕はやり方自体は変更しないけども)。…例えば文字列の中にある文字が何文字か?と調べる関数に“InStr”があります。「VBA 文字列の位置」とかで検索すると幾つもヒットすると思います。列と行が区切られているのが“$”という文字だから…と MsgBox InStr(Target.Address, "$") と記述して実行すれば“1”が表示ってきます。そう、最初の$の位置が“1”だからです。
後ろから検索する“InstrRev”という関数もあるのですが、初めの$が邪魔だから削除しちゃえと思いついたら、「vba 文字列の削除」とかググると…ありゃ?「vba 文字列操作」とググるとMid( 文字列 , 開始位置 , 取得文字数 )という関数があります。MsgBox Mid(Target.Address, 2, Len(Target.Address) - 1) とすれば…
Private Sub Worksheet_Change(ByVal Target As Range)
tarads = Target.Address '変数taradsにアドレス代入
adr = Mid(tarads, 2, Len(tarads) - 1)
colstr = Mid(adr, 1, InStr(adr, "$"))
rowstr = Right(adr, Len(adr) - InStr(adr, "$"))
MsgBox adr
MsgBox colstr
MsgBox rowstr
End Sub
*2行目のクォーテーションマーク以下はコメント(説明)で実行には関係しません。
…はい、Left~、Right~の2行の分(太字のところ)に戻ります。
この MsgBox Left(Target.Address, 3) で $B$ と表示されることで変更したのがB列である、と解りました。以下のコードを実行するとB列に数字を入れると変更した行数が表示されますが、例えばA列に数字を入れても何も表示されません。
Private Sub Worksheet_Change(ByVal Target As Range)
If Left(Target.Address, 3) = "$B$" Then
MsgBox Right(Target.Address, _
Len(Target.Address) - 3)
End If
End Sub
*3行目ラストのアンダースコアはひとつの命令文を2つに分けるためのもので実際は分ける必要はありません。
元は MsgBox Right(Target.Address, Len(Target.Address) - 3) スマホ表示の為に2、3行に分けている。
シートに数式を書くのがベストな場合もあると思います。が、例えばシートに数式を書くと入れ子、入れ子で別のセルも使って…とかなる場合もVBAなら整理できます。何より行を選択して並び替えるやら、どこぞのセルをコピーするやら、計算以外の機能がごっそりとあるので、自動でそれらを行うことが出来…モノによっては処理時間がかかるのですが…自前のアプリじゃないから仕方ない…出来ます。ステータスバーに処理済パーセンテージなど表示するようにしておけば、固まってないな~とか、安心できるのではないでしょうか。
後、シートに数式を記述して、下にコピーする場合は、そそっかしい人(僕もか…)はコピー忘れなどあるのでご注意を。[VBAを使う]の最初で「=B2*1.1」としているのは「=$B2*1.1」でも構いません…が「=$B$2*1.1」と行も絶対化してしまうとコピーしてもB3、B4と自動で変わってくれません。コピーもミスすれば元も子もありませんので、ちゃんと検証することが大事です。また、他人が触ることを考えてプロテクトを掛ける(方法はググって)などの予防も必要かと思います。計算させるシートを作って非表示にするとか…よくやりましたね~