2016年7月10日日曜日

【VBAリファレンス】いっちょまえに変数を語ってみよう。

さて、このブログ開設時、最初に記事にしたのが変数でしたが
今回は変数についてもう少し掘り下げて書いてみたいと思います。

以前の記事:【VBAリファレンス】変数は宣言してください。お願いします。

先日仕事中にハッと気づいた経験談を兼ねて
書いてみます。

変数には、整数型(Long)や文字列(String)をはじめとして
たくさんの型が存在します。

しかし、使い方を間違えると、
結果としてとんでもない結果を引き起こすことがあるわけです。

中でも、数字の取り扱いには細心の注意を払っていただきたいと思います。


一番わかりやすい例をコードで記述してみます。

サンプルその1
--------------------------------
Sub test()

Dim a As Long

a = 123
MsgBox a + a

End Sub
--------------------------------

サンプルその2
--------------------------------
Sub test()

Dim a As String

a = 123
MsgBox a + a

End Sub
--------------------------------

サンプル1の結果











サンプル2の結果












サンプル1は整数型、つまり数字として扱われています。
その為、数字(123)+数字(123)でその結果246という値になります。

変わって、サンプル2に代入されているのは文字列型、
つまり、テキストとして扱われます。
その為、テキスト(123)&テキスト(123)でその結果123123と扱われます。


では、以下のサンプルの場合どうなるでしょう。
--------------------------------
Sub test()

Dim a As String
Dim b As Long

a = 123
b = a
MsgBox b + b

End Sub
--------------------------------
最初にString(文字列)型のaとLong(整数)型のbを宣言した後
aに123を代入しています。
その後、bの箱にaを代入します。
ここで、bに代入された123の型はどうなっているか…

答えはこうです。

変数とは名の通り、値が変わるものですが
代入された値は、その変数の型にならうようにされています。

数字の場合、文字としても、整数としても使用するものなので
代入されたとの変数の型に変更されます。
※つまり、最初のaの変数に"こんにちは"と代入すると、
 bの変数で型が一致せず、コンパイルエラーが発生します。

その為、数字の取り扱いには十分に注意していただきたいと思います。
データサイエンティスト系のお仕事をしていると、
特に注意が必要です。

For文を2重3重にくるくる回しまくって、
実際セルの結果として入力すべき数値とが入り組んでくると
変数の宣言も混乱してしまいがちです。
コメントなどを使って上手く変数の管理をしてみてください。


あと、変数の宣言方法について
訂正というか、この頃発見したことがあるので
合わせて記載させてください。

変数の宣言時
--------------------------------
Dim i As Long
Dim j As String
--------------------------------
こういった記述方法は基本ですが、
宣言する変数が多くなったとき1列で記述する方法についてです。

正解の宣言例
--------------------------------
Dim i As Long, j As Long
Dim x As String, y As String
--------------------------------

間違った宣言例
--------------------------------
Dim i, j As Long
Dim x, y As String
--------------------------------

宣言をつなげる場合は
変数名とAsと型とカンマで1セットとし、そのあと引き続き記述します。

間違った宣言例はどうなるかというと、
実際にLong型で宣言されているのはjのみ
String型で宣言されているのはyのみとなっており、
iとxはVariant型で宣言されたことになります。

Variant型なので、不都合が生じることはあまりないでしょうが(いや、実際にはあるかも)
きっちりと型を宣言して処理を進める癖を身に付けるためにも
横着はしないようにしましょう。


でも、変数が増えるとほんと面倒になるんですよね~。
いや、プロシージャを分けて、Callで読み込めばいいんだけど…
でも、プロシージャを分けるキリが悪いところだったりして
ついつい、長ったらしく記述したり…


みなさんはこんな悪い大人にならないように気を付けてください!

2016年7月5日火曜日

【VBAリファレンス】ステップイン機能とブレークポイントを上手に使ってデバック作業を制する。

コーディング作業にも慣れてくると
恐れることなく、バンバン長いコードを書いていけるようになります。

そうすると、いつの間にかこんなに長いコードを書いていたのかと
自分で自分を褒めたくなる半面、ちょっと怖くなります。

特に、集中して一気に記述して
いざ実行!ってボタンを押して
即エラー表示がされたりします。
私の場合よくやるのは、変数の宣言し忘れとか
If文のEndIfの記述忘れという、クソツマンネーエラーが多いので
そんな時は、周りの誰にもばれない表情で
シレっと修正してコードを実行します。

しかし、中にはエラーの原因、理由などが
よくわからなく、何度も同じ箇所でデバック対応を余儀なくされることがあります。

短いコードならまだしも、先述したとても長いコードを書いてしまったときは
恐怖を超えて狂気すら感じます。

私の場合、1回の実行で完了まで10~30分時間を要するコードを書いたり
しかも、エラーは出てないが期待している
処理結果が得られないことなどもあり、そういった場合
どこが間違っているか分からない事象が発生した場合
文字通り頭を抱えてしまいます。

毎回、スタートから完了までを通すわけには行かないので
そういったときは、まずある程度の箇所に目処を付けたうえで
ステップインで進めます。

ステップインとは、そのプロシージャの1行目から
1行ずつコードを実行していく方法です。

まず、サンプルコードです。
------------------------------------
Sub test()

Dim i As Long, j As Long

'掛け算の結果を出すFor文
For i = 1 To 9
    For j = 1 To 9
 
    Cells(j, i) = i * j
 
    Next j
Next i

End Sub
------------------------------------
実行結果は以下の通りとなります。





























これをステップインで実行する場合
コードの記述まで行った後
画面の開発のタブマクロ作成したプロシージャ名を選択ステップ インをクリックします。




























そうすると、VBE画面が表示され、
現在の進行箇所が黄色く表示されます。
そして、次の行に移動するにはファンクションの8番(F8キー)を押します。

実行最初の画面


F8キーを1回押した状態


F8キーを2回押した状態


F8キーを押しっぱなしにすると、
ものすごいスピードでブルブルン!って実行状態を見ることが出来ます。

一つ一つの実行結果を確認するには
もってこいの機能です。
もちろん、Excelの画面を開きながらやれば
もちろん画面反映を確認しながら進めることも出来ます。

また、Forの動きなどは、
このステップインを見ていると、どういった動きをしているのか
目で確認できるので、非常に良いと思います。


ただし、先述したとてつもなく長いコードを記述した際
しかも、確認したい箇所は最後の方
その上、それまでの箇所にFor文を連掛けしているなど
不都合の女神に微笑まれた場合は
任意の場所までは一気に実行するという方法もあるのです。

それはブレークポイントの設定です。

下図赤枠内ジャンプさせたい列辺り


クリックすると、赤黒い●マークがつきます。


ステップイン実行後、このブレークポイントを実行すると
その箇所までは、通常のコードを実行したスピードで
コードが実行されます。

その後、F8を押せば、1行ずつステップイン作業が実行されます。
その後、すべてのコードを実行する場合は
F5(実行ボタン)か四角のリセットボタンを押せば
作業の継続かストップを選択できます。

是非、この機能を活用して無駄のないデバック作業を行ってください。

私の場合、デバック作業のいらない完璧なコードばかりではなく
たくさんのエラーを経験した方が
よりよりコードが書けるようになると信じてます。



2016年6月26日日曜日

【VBAコラム】VBAコードを記述した方がいい時としない方がいい時

プログラミングの世界では
ある物を作るとき、全く無の状態から作成されていきます。
そんな時に、何をどう作っていくのか、細かく書かれている説明書のようなものを
仕様書といいます。

大きなソフト開発プロジェクトでは、必ずそういった仕様書がありますが
個人的にExcelのデータ操作を行う場合に記述するVBAでは
そこまで大げさなものもありません。


そもそもどうしてVBAのプログラムまで覚えて、コーディングして、マクロを実行するのでしょう。

と、同時に現在VBAの勉強に行き詰っている人がいたとすると、
行き着く答えの出口は意外と同じなんてこともあります。

つまり、目的です。

どういう動作をエクセルにさせたいか。

VBAのプログラミングを行うときに
一番重要な箇所、それが仕様です。


表題の件に関してですが
VBAのコードを記述した方がいい時と、記述しない方がいい時
こればかりは、ギブアンドテイクの天秤で測るしかないのですが
A1からA10までに数値が入っていて、その合計をA11に表示させるのであれば
VBAでコードを記述するよりA11のセルに=SUM(A1:A10)と関数を入れてしまった方が
早いわけなんです。

では、こんな内容はどうでしょう。

A1からA10までのセルに1~100まででランダムの数値が入っていたとします。
A11には合計を入力し、B1~B10の間でそのランダムの数値が
1~50までは黒い文字、51~100までであれば赤い文字にする。
なお、ブック内に同様のシートが5000シート分あります。
そうなれば、手作業で行うより、VBAを記述した方が早いでしょう。

手で動かして動作させても、VBAコードを記述して
処理を自動化させても、結果は同じことですが
どのように進めていくかが仕様になります。


なにもVBAは作業の効率化だけではありません。
確かに、膨大なデータをボタン1クリックで
あっという間に処理を行ってくれるという機能は
誰しもご存知かと思います。

しかし、その裏で作業を行うのはコンピューターであり
仕様さえ間違いがなければ
決定的なエラーが1つなくなります。
それがヒューマンエラーです。

どんなに頑張っても、
ミスの少ない人はいても、ミスを絶対にしない完璧な人はいません。
ヒューマンエラーは人間が引き起こす
仕様書の欠落です。

単純作業ほど回数を重ねれば
人間は精度を落とし、いつかエラーを起こします。
しかし、コンピューターはそういったことは絶対にしません。

私が、仕事中で悩む最初の分岐は
自分で処理を行うか、コンピューターに処理を行うかの
選択になります。

簡単にIf文で例えてみます。

-------------------------
If me =>-5 Then
    VBAコード入力を開始
Else
  自分で処理を行う
-------------------------
という文になります。

これは勝手な印象値になりますが
僅かに処理結果にマイナスが発生したとしても
大幅なマイナスにならないようであれば、
VBAでコーディングして処理を実行させるようにします。

もう少し、具体的にいうと
手作業の場合は3時間かかる、
VBA入力の場合はコーディングから実行まで4時間かかるとしたとき
私はVBAのコーディングを選択するようにしてます。

理由は2つあります。
■先述した通り、コンピューターは指示通りの作業をこなすので
記述したコードが間違いなければ処理ミスはありえない。
■手作業で行った処理で処理ミスが発生した場合
最悪もう一度最初からやり直す必要があり、結果倍の6時間を要する。

メリットは他にもあります。
VBAに対する知識や発想力は、たくさんのテーマをクリアすればするほど豊富になり、
さらに次への対応の幅が広くなります。
もちろんデメリットもあります。
VBAの仕様コーディングに誤りがあり
予想していた以上にコーディングに時間がかかってしまうこともあります。

ただし、ここでのデメリットはメリットの経験を重ねれば重ねるほど
どんどん小さくなってきます。

やはり、やるに越したことはないわけです。
少々のロスは承知の上で、果敢にVBAコーディングに挑んだ方が
返ってくるメリットは大きいといえるでしょう。



2016年6月19日日曜日

【VBAリファレンス】ワークシートの作成、任意の名前のワークシートの作成、任意の名前のワークシートを作成し移動させる。の3本立てです。

たくさんのデータを取り扱っていると
ワークシートを追加した上で
新たな処理を行う必要性が出てきます。

ワークシートを追加する場合の
基本コードは以下の通りです。

-------------------------------------------
Sub ワークシートを追加()

Worksheets.Add

End Sub
-------------------------------------------
この1行を記述するだけで
ワークシートを追加できます。
Excelのバージョンによりますが
2013以降はデフォルトのワークシート数がSheet1のみとなっており
以前はSheet1~3までとなっています。

上記のコードを実行すると
以降のシート番号が自動で割り振られ
シートが生成されます。

※処理結果


















ただし、VBAコードで処理を実行するとき
シートを指定したうえで、作業を行うことがあり
時に、Sheet番号を指定してするにはちょいと面倒だったりします。
そんなのいちいち覚えてられませんし。
余談ですが、Exceブックlを開いたままシートを生成すると
生成した数だけシート番号が上がっていきます。
しかし、ブックを開きなおすと、またそのシート番号は最初のSheet1から生成され始めます。
といっても、ブック内にSheet1があると飛ばされSheet2から生成されます。
(ここは覚えなくていです)


さらに横道にそれますが
シートを指定して処理を行う場合、
以下のように記述してワークシートを指定します。
-------------------------------------------
Sub ワークシート処理()

Sheets("指定したいシート名").Select

End Sub
-------------------------------------------
赤文字の箇所を指定したいシート名に変えて実行すると
そのシートを指定することが出来ます。

さて、ではシートを作成した時に任意のシート名を記述しておけば
希望通りの処理を行うことが出来ますね。

一連の処理を記述します。
・【新しいシート】という名称のワークシートを作る
・そのシートを指定する
・そのシートに算数の九九の結果をFor文を使って記述する

上記3つの処理を1つのプロシージャで作成してみます。
なお、シート名をつけたい時は
Worksheets.Addの次の行に
ActiveSheet.Name = "指定したいシート名"と記述するだけでOKです。


まずは、実行前のブックの画像です。


なんてことはない普通のシートです。

記述するコード画像です。


記述している内容は以下の通りです。
-------------------------------------------
Sub test()

Dim i, j, x As Long

'新しいシートを生成し、シート名を新しいシートに変更する
Worksheets.Add
ActiveSheet.Name = "新しいシート"

'新しいシートを選択する
Sheets("新しいシート").Select

'新しいシートに九九の表示を行う
For i = 1 To 9
    For j = 1 To 9
    x = j * i
    Cells(j, i) = x
    Next j
Next i

End Sub
-------------------------------------------

実行後の画像


新しいシートが作成され、九九の結果が記述されています。



では、もう少し詳しく説明させてください。

作成時シートを任意の場所にあらかじめ移動しておきたい場合は
以下のように記述します。
-------------------------------------------
Sub ワークシートを追加()

Worksheets.Add after:=Worksheets(Worksheets.Count)

End Sub
-------------------------------------------
これは作成したシートを
まず、ブック内にあるシートの枚数をしらべます※赤文字の部分です。
で、そのシートの後(Afterの部分)に移動をさせるという記述です。

カッコ内のWorksheets.Countの部分はシート名で指定することが出来ます。
例):新しいシートというシートの後に移動させたい場合は
Worksheets.Add after:=Worksheets("新しいシート")となります。
シート名を指定する場合は、ダブルクォーテーションで囲ってあげてください。


また、指定しているシートの前に生成したい場合は
afterbeforeに変えてあげれば、指定したシートの左隣に移動されます。
右隣がafterで左隣がbeforeと覚えておきましょう。

※シートの作成時に特に指定をしない場合は、
一番左側に新しいシートが生成されますので合わせて覚えておいてください。


2016年6月16日木曜日

【VBAリファレンス】InputBoxは他の誰かのために使いましょう。

今日はInputBoxについて記事を書いていきたいと思います。

さて、世の中にたくさんあるツールの中で
何かの処理を行う場合、
とある入力を求められることがあります。

こういうやつです。


インプットボックスっていって
使用するユーザーに任意の情報を入力するための
テキストボックスになります。

記述自体はとても簡単です。
-------------------------------------------------
Sub test()

'ダブルクォーテーションの間のメッセージを変えるだけで
'表示するメッセージを変えられます
Application.InputBox ("名前を入力してください")

End Sub
-------------------------------------------------
上記、ウィンドウを表示させるにはこのコードを記述するだけで
出現させることが出来ます。

しかし、これだけではウィンドウが出るだけで
文字を入力してもなーんの意味もありません。

InputBoxって、文字を入力して
その入力した文字を何かしらの処理の材料として使いたいわけですよね。

なので、右辺を左辺に代入するということで
変数を使用します。

Application.InputBoxの前に、宣言済みの変数をイコールで
つなげてあげましょう。
-------------------------------------------------
Sub test()

Dim ipt_b As String

ipt_b = Application.InputBox("名前を入力してください")

End Sub
-------------------------------------------------
変数名ipt_bとします。
で、今回は入力する値が名前なのでテキスト型(String)を宣言します。
※当然ですが値が数値の場合は、Long型を宣言してあげてください。

これを実行すると、InputBoxで入力した文字列が
変数ipt_bに代入されます。

さて、これだけでも意味がありません。

あとは、変数に代入した値をどう使うかは皆様次第です。


例えば、列の処理をする場合は
String型として、直接列の値を入力して見るのもいいかもしれません。


任意の列を削除したい時
以下のような使い方が出来ます。
-------------------------------------------------
Sub test()

Dim ipt_b As String

ipt_b = Application.InputBox("削除したい列を入力してください")
Columns(ipt_b).Delete

End Sub
-------------------------------------------------

サンプル画像(C列を削除したいと思います)


先ほどのコードを実行します。
InputBoxにCと入力しOKを押すとコードが実行されます。










ここでは文字列の【C】が
変数ipt_bに代入されます。
そして、Columns(ipt_b).Deleteに充てられるので
Columns(C).Deleteと同じ意味になりますね。

処理結果




C列にあった【この列は消す】という列が消えています。


InputBoxはおもに、他の誰かから情報を取得する場合、
あるいは、都度変わる任意の情報を直接入力する場合
に大変役立つ機能です。


この使用例はほんの一部ですので、色々と試してみてください。

2016年6月14日火曜日

【VBA実践】特定の列を一括挿入する。

別の記事で
特定の列を削除する内容をご案内しました。
【VBA実践】特定の列を一括削除する。
今回は作業を行うため、空の列を挿入するコードを記述します。
基本は列を削除する内容とあまり変わりません。
For文を駆使して行っていきます。

サンプル画像
 1から10(AからJ列)までデータが入っており
その各列に空の列を挿入します。

コードは以下の通り。

削除するコードと基本は同じ逆打ちです。
-------------------------------------------------
Sub 特定の列を挿入するコード()

Dim col As Long

For col = 10 To 2 Step -1
    Columns(col).Insert
Next col

End Sub
-------------------------------------------------
1列目までは挿入する必要はないので
カウンタは10 To 2 になります。
また、Stepは-1になります。
処理分は挿入のInsertです。

実行後画面

上手く実行できたことが確認できました。



逆打ちではなく、通常カウントで実行できなくもないのですが
やはりそのやり方はおすすめできません。

試しにサンプル実行してみます。
※Excelのスタート画面は同じレイアウトとします。

コードは以下の通り。

カウント値を逆にしStepは 2とします。

結果は以下の通りです。

上手くいっているように見えますが
よく見てみると、様子が変です。

右方向にスクロールしてみます。

6以降が挿入されていません。

勘のいい方はすぐにお分かりいただけたかと思いますが
カウンタが10となっていることとStep 2となっているところがポイントです。

2列目から挿入されステップで2飛ばしとなって
最後は10で終了しているカウントということは
J列が最後の列になります。
この場合の対応方法は通常の倍のカウント数にしなければいけないということです。

なので、直感的に処理を行うのであれば
やはり前者にご覧いただいた
カウント逆打ちが一番いいですね。

また、データが入っている最終列の値を出すコードを
合わせて組み込み、Forの逆打ちの最初のカウントに代入しておくだけで
後はVBAが勝手に処理してくれます。

コードはただ書くだけではなく
無駄なく処理が実行されることも重要です。

ぜひ活用してみてください。

【VBA実践】特定の列を一括削除する。

今回は不要となった特定の列を削除するコードをご紹介します。
列を挿入するコードは別の記事にてご案内していますので
是非参考にしてみて下さい。
【VBA実践】特定の列を一括挿入する。

大量のデータを処理をしていると
A列に大元のデータがありB列にA列のデータを処理した結果を入れたりします。
また、それが、C列以降、同様の列が続いたりします。

例えば、データ処理が終わった場合
不要となった列を削除したりすることがあります。

間が飛び飛びになっている場合は、
一つ一つの列を手作業で削除していくのは大変骨が折れる作業です。
また、誤って消すつもりのない列を消してしまったりする
大変なことになります。


そんな作業も、ちょっとコードを入力するだけで
正確かつ一瞬で終了します。

サンプル画像

























まずは偶数(赤文字)が記載されている列を一括で削除するコードです。
































上記コードを実行すると以下の結果がでます。


-------------------------------------------------
Sub 特定の列を削除するコード()

Dim col As Long

For col = 100 To 1 Step -2
    Columns(col).Delete
Next col

End Sub
-------------------------------------------------
まず変数は、列を意味するcolumnの最初の3文字を取って
変数名colにします。
colはFor文のカウンタの役割を行うので
値を代入しておく必要はありません。

次にFor文では逆打ちカウンタでStepは-2となります。

まず、なぜ逆打ちにするかということですが
通常の2..4..6..8..10とカウントしていった場合
削除する列がおかしくなってしまうんです。
例えば、最初に2があるB列を消すと、隣のC列にあったデータがB列になります。
ということは、次のカウント4列目つまりD列には
E列に入っていたデータを消してしまうことになります。

サンプル画像1
































上記コードを実行すると以下の結果となります。























手前から消すと先のデータは前にずれてくるので
全ての結果がずれてきます。

その為、データの最後から実行していくことで
ターゲットの列データがずれることはなくなります。
こういった逆打ちでデータを操作する方法は、VBAの処理ではよく使用されるので
頭の片隅に置いとていただけると幸いです。




ちなみに、Columns(col).Deleteは削除です。
ClearContentsやClearにすると、列の削除はされず、値や値と書式のみが削除されます。

サンプルコードの画像
































実行後の画像

という結果となります。

A、B、Cを1ブロックとして、そのB、C列を削除したいという
2列消しをする場合も要領は同じとなります。
サンプル画像

赤くなっている文字の列を削除する場合のサンプルコードは以下の通りです。


削除する列は2列に増えるので
Columns(col).Delete(指定している列)と
Columns(col -1).Delete(指定した左隣の列)を合わせて記述し削除します。
(col -1)というのは、変数colに代入されている値をマイナス1にするという記述です。
※結構こういった使い方することがあるのでぜひ覚えておいてください。
なお、2列消して、3列戻るので、Step -3としてください。

実行後の画面


上手く実行できたことが確認できました。


さて、別の記事でも今後記載予定ですが
先日、データが入っている最終行を取得するというコードを案内しましたが
最終列を取得するコードも当然あります。


column = Cells(1, Columns.Count).End(xlToLeft).Column

変数名columnとして、そこにデータが入っている最終列の値を代入するようにします。
Cells(1,~~の1は1行目を指定する箇所であり、
データが入っている行をここで入力します。
なので、1列目にデータが入っていないときは、データが最終列まで入っている行を
ここで入力してあげてください。
そして、その変数columnをカウンタに設定してあげます。

-------------------------------------------------
Sub 特定の列を削除するコード()

Dim col As Long
Dim column As Long

column = Cells(1, Columns.Count).End(xlToLeft).Column
For col = column To 1 Step -2
    Columns(col).Delete
Next col

End Sub
-------------------------------------------------
最終列が100行まで入っている場合、
変数columnには100が代入されるので
For col = 100 To 1 Step -2と同じ意味になります。
変数の宣言も忘れず行ってください。


ちょっと長い記事になってしまいましたが、
状況に応じてぜひ活用してみてください。



2016年6月12日日曜日

【VBAリファレンス】プロシージャってなんでしょう。Callステートメントで呼び出すやつです。

VBAコードを記述を行う時はVBE(Visual Basic Editor)に行います。
VBEを表示させるには
Excelの画面のリボンの【開発】からVisual Basicをクリックし
挿入よりモジュールをクリックするとエディターが起動します。

そこにぱちぱち入力していくのです。
























もし、【開発】のタブがない場合は、
スタートメニュー、オプション、リボンのユーザー設定で開くと
リボンの設定画面が開くので
開発のところにチェックを入れて下さい。


さて、表題の件ですが
マクロの記述をしたあと、そのコードを確認しに行くと
コードが書かれています。
マクロの記述を行った場合、自動的に
【プロシージャ】というものが作成され、そこにコードが記載されます。

その時、何も設定しない場合Macro1という名前で登録されるのですが、
その名称をプロシージャ名といいます。
つまり、1括りの記述の集まりをプロシージャといいます。

基本形ですが、1つのプロシージャは
SubからEnd Subまでの間に処理内容を記述します。

そして、モジュールの中には
複数のプロシージャを記述することが可能です。
























複雑な処理を行う場合、
どうしても記述するコードが長くなります。
もちろん、全体把握がしっかり出来ている頭のいい方であれば
1つのプロシージャに全ての処理内容を記述してもかまいません。


でも、私のようなポンコツおじさんは限界があります。

そんな時は、全体処理を部分化させて全体把握をしやすくします。
つまり、プロシージャごとに処理内容を分けて記述します。

しかし、そんなことをすると、
全処理を実行するにはプロシージャ1つ1つを実行しなければなりません。


それはそれで面倒です。


そんな時は、Callステートメントを使います。

Callステートメントは
あるプロシージャ内で、別のプロシージャ(つまり別の処理)を
呼び出すことができます。

記述の仕方は
Call プロシージャ名
だけです。

サンプル画像





































サンプル画像のVBE内、一番上のプロシージャがメインプロシージャで
以降は具体的な処理を記述したプロシージャです。

一番最初の全処理工程を記述のプロシージャを実行すると
2番目から4番目までのプロシージャが順番に実行されます。

さらにサンプル画像2





































このCallステートメントを使用することで
全体を把握しやすくなったり、
各パーツごとでデータを実行したりと、
後々編集もしやすくなりますし、エラーが発生した場合でも
メンテナンスがしやすくなります。

VBAの記述量が少ないうちは
あまり使用することはないですが、
多くの処理内容があるコードを記述する場合は
こまめにプロシージャを分けることをおすすめします。


2016年6月11日土曜日

【VBAコラム】VBAの技術を身に付けたいのであれば、是非読んでみてください。

さて、このブログも2016年5月31日に開設し、
早10日が経過しようとしてます。


今日はここで少し重要なお話をしようと思っています。



こんな私でも、今まで素人に羽毛が生えた程度の柔らかさで
よくも偉そうにしゃあしゃあと記事を書いてきたものです。

■変数の宣言
【VBAリファレンス】変数は宣言してください。お願いします。
■Rangeや行列の選択
【VBAリファレンス】セルの値を指定する方法は主に2種類あるのです。
【VBAリファレンス】行や列を指定する
■Forステートメント
【VBAリファレンス】For文を理解してフォアフォアしてみよう。
■Ifステートメント
【VBAリファレンス】もし、If文を使うなら…True、使わないならFalse
などなど





しかし、ForやIfなんか覚えただけでは
何の役にも立ちません!!







ズコーーっ!!!






はい、皆さんも一緒に



ズコーーーっ!!!!!



ただ、一部の方の中には
そうだね~と共感していただける方もいるはずです。


誤解を与えるような書き方をしてしまい申し訳ありません。
ここまで、記事でご案内したForやIf、変数の宣言から
Range、Cellsプロパティを思い出してください。

・変数の宣言をして、値を変数に代入したからどうするのん?
・セルを選択したあとどうするのん?
・Forを使ってカウンタが上がっていくからなんなん?
・Ifで分岐させた後、どうなるん?

勉強を始めようとしたとき、
こういった疑問持つ人の方が圧倒的に多いと思います。

それが自然なんです。
私もそうでした。

何故なら、使いたい使い方を知らないからなんです。

家の台所に真っ白い金属製の白い箱があったとします。
その箱は、煮る、焼く、茹でる、揚げる、炒めるをすべて1台でこなす
超ハイパー家電だったとします。

でも、説明書はありませんでした。

ハイそこー!

しかも、料理経験が全くありません。

さらにそこー!

先ほど疑問を抱いた方は、
説明書がない状態、もしくは料理経験がない状態なだけです。
説明書や、経験がなければ何もできないのは当然です。


For文もIf文も組み合わせて、
さらに複数の変数を宣言したうえで、
注釈のコメント書きながらやるからこそ、
手作業で10時間かかる作業がボタン1クリックするとものの数分で処理が完了する
コードが本当に役に立つコードです。


書籍やWebサイトを見ても、自分がやりたい処理の
具体的なコードが見つからなくて、嘆いた経験はありませんか?
私は、ありました。
特にVBAの勉強を本気で使用と思ってすぐの時でした。

しかし、今同じ条件でWebで検索すると
答えはごろごろ転がっています。
ど~れ~に~し~よぅ~か~な~って感じです。


その差は何かというと、
最初はWebなどで記述されてるコードの意味が分からないだけなのです。
だから、使い方はおろか、正解か不正解かの前に
見つからないと結論付けるのです。


でもそれは慣れなんですね。
毎日何かしらコードを記述したりすることで
自然と身に付く、自転車運転方法でしかありません。

基本が乗っている書籍なんて本屋さんや
AMAZONでいくらでも売っているので、本来ここに書くべきものでもないのですが
私自身、ずいぶん遠回りしながらも、どうにか身に付けてきた知識を
皆様は遠回りしないようショートカットで身に付けていただければと考えました。

書籍には使用方法は書かれていますが
例や目的は書かれていないことがとても多いです。


どのリファレンス(教材)本にも共通することですが
評価が高い本は、実用的な使用方法がたくさん書かれていることが多いです。
あるいは、本当に使用方法だけがギッチリぱんぱんに詰め込まれているかのどちらかです。

しかし、実用的な使用方法が書かれている本は
やはり少ないのです。

おこがましい話ですが
私も1から始めたことで、たくさんの壁や挫折を経験してきたからこそ
まだ、初心者の目線は忘れてはいません。
だからこそお伝えできる例え方や、文章が書けるだろうと調子に乗ってます。
適度なリファレンスと、オーソドックスで変態的な使用例を
うまく合わせて、お伝えできればと考えます。

まだまだ、お伝えしたいことがたくさんあります。
なので、じっくりお付き合いください。

少しでも、誰かのお役に立てれば幸いです。



P.S 最終回ではありません


2016年6月10日金曜日

【VBAリファレンス】記載するコードは長くても短くてもコメントはたっぷりお願いします。

VBAのコード入力も波に乗ってくると
調子にものって、ガツガツたくさんのコードを1つのプロシージャに
書いてしまいがちです。

VBAのコードというのは皆様もご存知の通り
英字と数字と記号を主に記述します。
日本語が入る時は、大体If文の条件分岐とかで
特定のワードに対して使ったり
ワークシートに対する処理を行うときなどに日本語が入り混じります。

さて、ひとまず以下のコードをご覧ください(ちょっと長いです)
---------------------------------------------------------------------------------
Sub Maxif()

Dim datavalue, cntvalue, d_one, d_two, Boobyvalue, Lastvalue, Maxvalue As Long

Maxvalue = WorksheetFunction.Max(Range("B1:B40"))

For cntvalue = 1 To Maxvalue
Lastvalue = 0

    For datavalue = 1 To 40
    Boobyvalue = Lastvalue

            If Cells(datavalue, 2) = cntvalue Then
            d_one = Cells(datavalue, 3)
            Else
            d_one = 0
            End If
       
            If Cells(datavalue + 1, 2) = cntvalue Then
            d_two = Cells(datavalue + 1, 3)
            Else
            d_two = 0
            End If
       
        If d_one > d_two Then
        Lastvalue = d_one
        ElseIf d_one < d_two Then
        Lastvalue = d_two
        Else
        End If
   
        If Lastvalue > Boobyvalue Then
        Lastvalue = Lastvalue
        ElseIf Lastvalue < Boobyvalue Then
        Lastvalue = Boobyvalue
        Else
   
        End If
         Cells(cntvalue, 7).Value = Lastvalue

    Next datavalue

Next cntvalue
End Sub
---------------------------------------------------------------------------------

これは実際に数日前に私が記述した
Maxifの代用で試しに起こしてみたコードです。

これをみて、若干イヤんなちゃった人は少なくないはずです。
これでも、そこまで長くはない記述ですが
こんなコードがたくさんあって、プロシージャがさらに連なってってなると
もう、見るだけで嫌になります。

当然のことです。


VBAではコードを記述する際
どういった処理のコードか、メモ書きのようにしておける機能があります。
人はそれをコメントといいます。

シングルクォーテーションを最初に入れて
そのあとに入れたい文字を入れます。

-----------------------------------
Sub test()

'セルのA1にこんにちはと入れる
Range("A1").Value = "こんにちは"

End Sub
-----------------------------------
VBAに記述する際もシングルクォーテーションを入れた後
文字は緑色になり
その行の最後までは処理に関係のないものとされます。
つまり、メモを入れるということになります。
改行をする場合は新たにシングルクォーテーションをつける必要があります。

記述したコードは
何も自分ばかりが見るものではなく、他の方が見たり
手入れしたりする可能性もあります。
その際、どの部分でどういった処理が起こるか
その簡易説明があるかないか
確認作業や修正作業
さらには、人に説明をしなければいけない場合など、
作業が円滑に進むものです。

おそらく、こういった作業は個人差(性格)が出るものですが
出来る限り分かりやすく、簡潔に書いておくことに越したことはありません。

今日お仕事で、私はそのコメントの記述を怠ったばかりに
どういった処理が行われているか、すぐに説明できませんでした。
戒めの意味で、自分のメガネをヤスリでサッ!ってやっておきます。


意外と軽視されがちですが
やはりコメントというのは重要です。
それは、たくさんのコードを書けば書くほど身に染みるものです。

だからといってやたらめったら書いていいものではないです。
先ほども申し上げましたが
出来る限り分かりやすく、簡潔に書くというのが前提です。

さて、先ほどのコード。
コードが付いているものを改めて乗せてみたいと思います。
---------------------------------------------------------------------------------
Sub Maxif()

Dim datavalue, cntvalue, d_one, d_two, Boobyvalue, Lastvalue, Maxvalue As Long

'B1~40までの最大値をMaxvalueに代入
Maxvalue = WorksheetFunction.Max(Range("B1:B40"))

For cntvalue = 1 To Maxvalue  'Maxvalueの数だけループ
Lastvalue = 0  'Lastvalueを初期化

    For datavalue = 1 To 40   '元データの末端行の値
    Boobyvalue = Lastvalue  'LastvalueデータをBoobyvalueデータに移行

     'd_oneに1個目のデータを代入 なければ0で初期化
            If Cells(datavalue, 2) = cntvalue Then
            d_one = Cells(datavalue, 3)
            Else
            d_one = 0
            End If
          
     'd_twoに2個目のデータを代入 なければ初期化
            If Cells(datavalue + 1, 2) = cntvalue Then
            d_two = Cells(datavalue + 1, 3)
            Else
            d_two = 0
            End If
       
        'd_oneとd_twoを比較し、大きい方をLastvalueに代入
        If d_one > d_two Then
        Lastvalue = d_one
        ElseIf d_one < d_two Then
        Lastvalue = d_two
        Else
        End If
   
        'この前にLastvalueからBoobyvalueに代入していた値と最新のLastvalueを比較し、
        '大きい方をLastvalueに代入
        If Lastvalue > Boobyvalue Then
        Lastvalue = Lastvalue
        ElseIf Lastvalue < Boobyvalue Then
        Lastvalue = Boobyvalue
        Else
   
        End If
         Cells(cntvalue, 7).Value = Lastvalue

    Next datavalue

Next cntvalue
End Sub
---------------------------------------------------------------------------------
このようにコメントの記載があるかないかで
読みにいく気持ちも変わってきます。

他人のためでもあり、自分のためのコメントなので
長い、短いにかかわらず、コメントはたっぷりしっかり記述するようにしましょう。


2016年6月8日水曜日

【VBAリファレンス】もし、If文を使うなら…True、使わないならFalse

さて、前回のForステートメントに続き
今回はIfステートメントをご紹介します。

Forステートメントの記事はこちら。
【VBAリファレンス】For文を理解してフォアフォアしてみよう。


一般的な事務や、データ解析、操作系の仕事をされているのであれば
For文と、If文をマスターしていれば
大体のことは出来るのではないでしょうか。

ちょっと大げさかもしれませんが
そこから派生した疑問などは
大体Webを見ると解決したりするものです。


つまり、基本をしっかり!マスターしていれば
あとはGoogle先生が教えてくれるものです。

実際に私も、Ifは理屈的に理解していましたが
For文の理解度を高めた事で、二段飛ばしくらいあれをあれしたものです。


それではIf文の基本的な説明ですが
原理はこうです。
もし○○が□□だったら、▲する
そうじゃなければ△△する。

または
もし○○が□□だったら、▲する
それか、◇だったら、☆☆する。※1
そうじゃなければ△△する。
※1 それか、◇◇じゃなければ、☆☆するは何回も重ねられます。


If文はFor文と違って上から下に流れて終わります。

その際にとある条件に一致しているかしていないか、のどちらかで
処理内容が変わる、条件分岐、分かれ道方式になります。
またその条件は柔軟に変動が可能です。


その時の答えとして
そうだ!って時はTrue、違う!って時は、Falseに置き換えたうえで
処理が進められます。

それでは、さっそく基本文を書いてみます。
-------------------------------
Sub test()

If Range("A1") = "1" Then
    Range("B1").Value = "男"
End If

End Sub
-------------------------------
これは、セルのA1に1が入力されていた場合
その隣のB1のセルに男と入れるIf文です。

1以外の文字列、もしくは何も入ってなかったら
何も起きません。
If Range("A1") = "1" Then → もしセルのA1に1が入っていたら
Range("B1").Value = "男" → B1に男と入れてね。
ですね。

つまり、1以外の時は End Ifに飛んで、このコードは終わります。



次に、1以外のデータが入っていたときは
B1に女と入れるコードを書きたい時、
Else(エルス)を使用します。
-------------------------------
Sub test()

If Range("A1") = "1" Then
    Range("B1").Value = "男"
    Else
    Range("B1").Value = "女"
End If

End Sub
-------------------------------
セルのA1に1以外のデータ(空欄含む)が入っている場合は
セルのB1に女が入力されます。


つまり、1以外どんな状態でも女と入るわけです。
これではちょっと雑だな~って時は
さらにElse If(エルスイフ)を使用します。

-------------------------------
Sub test()

If Range("A1") = "1" Then
    Range("B1").Value = "男"
    ElseIf Range("A1") = "2" Then
    Range("B1").Value = "女"
    Else
    Range("B1").Value = "エラーです"
End If

End Sub
-------------------------------
これは、セルのA1に1と入っていた場合はB1に男と入力され
2と入力されていた場合はB1に女と入力され
それ以外のデータだった場合は、B1にエラーですと返すコードです。
この時点で、条件分岐は3つに分かれるわけです。

このElseIfはいくつも連結が可能ですが
最後は必ずElseをつけて終わりに導いてください。
Elseで特に指定したい条件がない場合は
Else以降何も書かなくてよいです。

そして、条件は必ずしもイコール(一致)だけというわけではありません。
○○より大きい
○○以上
○○より小さい
○○以下
○○と等しい(今まで使っていたイコールです)
○○と等しくない
の主に6種類あり、
それを比較演算子といいます。
意味さえ知っていれば、特に言葉を覚えなくてもいいです。

比較演算子の記号は以下の通りです。
○○< →○○より大きい
○○≦ →○○以上
○○> →○○より小さい
○○≧ →○○以下
○○= →○○と等しい(今まで使っていたイコールです)
○○<> →○○と等しくない
となります。

やはり使う頻度が多いのは、<、>、=、<>の4つが多いでしょうか。
<や>は使い方を誤ると、えらい方向にはまりがちなので
ぜひぜひご注意ください。

先ほど【条件は柔軟に変動が可能です】と記載をしましたが
私が普段使用しているIfの条件サンプルを記述してみたいと思いますので
ご参考頂ければ幸いです。

その1
-------------------------------
Sub test1()

If Range("A1") = "" Then
Range("A1").Value = "○"
ElseIf Range("A1") = "○" Then
Range("A1").ClearContents
Else
End If

End Sub
-------------------------------
その1は完全な2択です。
何も入っていなければ○を入れる、○が入っていたら消すの繰り返しです。
これをたくさん作って、それぞれコントロールフォームのボタンに
当て込めば、チェック表のようなものが作れます。
※コントロールフォームの使用方法は後日ご案内いたします。


その2
-------------------------------
Sub test()

Dim i, a, b As Long

For i = 1 To 10
    If Cells(i, 1) <> "" Then
    a = Cells(i, 1)
    b = a * 1.08
    Cells(i, 1).Value = b
    Else
    End If
Next i

End Sub
-------------------------------
その2はA列の1から10に
税抜きの金額が入っていると仮定してください。
ただし、その中には何も入っていないセルもある場合、
そのセルは飛ばします。

先日の記事のFor文を使用します。
カウントの変数はiになります。
で、そのカウントをCellsプロパティに当て込みながら
セルのA1からA10までを指示するFor文を作ります。

一旦、指定したセルに値が入っていないかを確認するため
If文を使い、ダブルクォーテーション2つ""(何も入っていない)という条件を記載し
その条件に当てはまらない<>をクリアした場合、
選択しているセルの値を一旦変数aの箱に代入します。
その変数aに消費税1.08をかけた値をさらに変数bの箱に代入します。
その変数bの値を選択中のセルに上書きすることで
自動で課税金額に上書きすることが出来ます。
例えばとなりのセルに課税した金額を記載したい場合は
Cells(i, 1).Value = bをCells(i, 2).Value = bに変えればOKです。


ちょっとここでは書ききれないので、
色々なサンプルは後日ご案内しますね。

2016年6月7日火曜日

【VBAリファレンス】For文を理解してフォアフォアしてみよう。

大量のデータ処理を行う上で、必要なステートメント(述べること)が
いくつかあります。

その中でも私が現在とても重きを置いているのが

Forステートメント(以下For文って言います)
Ifステートメント(以下If文って言います)があります。

ちなみにIf文は後程ご紹介します。

For文とは
For~Nextという基本構文の~の部分に処理内容を記述します。

では、肝心のFor~Nextとは一体何をするものなのかですが、
まず、ざっくりいうと
カウントするんです。

まず、カウントするという言葉を頭の中に置いておいてください。

記述サンプルは以下の通りです。
-----------------------------------------
Sub test()

Dim i As Long  'ロング型の変数を宣言します

For i = 1 To 10
'ここに処理内容を書く
Next i

End Sub
-----------------------------------------
For i =の後がポイントです。
ここで記述している 1 To 10というのは
1から10までカウントするという意味です。
最初のiには1が入り、処理が行われます。
そして、処理が終わるとNext iに到着。
しかし、カウントはまだ1回目なので、このiは2回目のi、つまり
上に戻り、カウントは2にアップし、2回目の処理が行われます。
そして、それが10回まで繰り返されます。

もちろん、数字の入力は自由です。
2 To 5
これは、2~5カウントします。
1 To 1000
これは、1~1000までカウントします。

さて、ここまでカウントといってはぐらかしてきましたが
このカウントこそが最大のポイントです。

カウントとして使用するこの変数i(もちろん変数名はiじゃなくてもいいです)は
列の値、行の値、処理を行う回数など、
様々な使い方が出来るんです。

だって変数だから

その変数iを直接処理内容のCellsプロパティやRowsプロパティに
当て込んであげれば、もうエクセル内縦横無尽に
行ったり来たり出来ます。
あっちこっちに処理が出来ます。

ただ、For文というのは
掴むまで個人差があり、私は開花するまで数か月かかりました。
そのかわり、一度掴むと結構複雑な動作が出来るようになります。



具体例をコードで記述してみます。
-----------------------------------------
Sub test()

Dim i As Long

For i = 1 To 10
Cells(i, 1).Value = "カウント" & i 
Next i

End Sub
-----------------------------------------
これはCellsプロパティを使って、Rowの値を1つずつ増やし、
尚且つ、指定したセルにカウントというコメントと変数を組み合わせて入れてます。

その結果は以下の通りです。




























先ほどのCells(i, 1).Valueのiと1入れ替えると
RowとColumnが入れ替わるので




























横向きに入力されていきます。
ただし、これは基本的な使用になります。

例えばAとB列に数値が入っていて
その数値に対してC列へ処理を実行したい場合、
また、そのC列の処理が終了したら、
隣の列に移動して別の処理を行いたいなど、
様々な処理が可能になります。

なんだかワクワクしませんか?

また、このカウントは段飛ばしにカウントすることも出来ます。

For i = 1 To 10の後に Step 2とつけると1段飛ばし
For i = 1 To 10の後に Step 3とつけると2段飛ばしが出来ます。
例):For i = 1 To 10 Step 2
※下の図はStep 2を実行したものです。



















もちろん、カウントの逆打ちも出来ます。
逆打ちの場合はToを挟む数字も逆になります。
-----------------------------------------
Sub test()

Dim i As Long

For i = 10 To 1 Step -2
Cells(i, 1).Value = "カウント" & i
Next i

End Sub
-----------------------------------------
逆打ちでStepを使用する場合はマイナスをつけてください。

この、逆打ちは不要な列の削除をする際に
大活躍します。

具体的には後々ご案内しますね。



さて、ここまでカウントの数値を具体数で記述していましたが
ここのカウント値に変数を使用することが出来ます。

ここで??と思う方もいるかもしれません。

→For i = 1 To count (Countが変数とします)

変数には値を代入しなければならないので
結局2度手間じゃないの?と思うかもしれません。

ここで魔法の言葉です。
先日紹介しました記事にも記載しています。

Cells(Rows.Count, 1).End(xlUp).row
Cells(1, Columns.Count).End(xlToLeft).Column

それぞれCellsの後に記述しているの
Cells(Rows.Count, 1).End(xlUp).rowはA列
Cells(1, Columns.Count).End(xlToLeft).Columnは1行目の意味です。
その1の部分はデータ最終行、もしくは列まで入っているところを記述します。
※こちらも詳しくは後日ご案内します。

そして、その左辺に変数を入力してあげれば
最終行が入っている行が変数に代入されます。
例):A列に10行目までデータが入ってた場合、
count = Cells(Rows.Count, 1).End(xlUp).rowと記述すると
変数countには10という値が代入されます。

さて、もうお判りでしょうか。
あとはその変数countをForのカウントとして設定してあげればいいわけですね。

つまり、データが入っている最終までVBAで調べ
その値をForのカウンタに設定するわけです。

なので、Forは慣れればなれるほど
拡張性が増し、よりパフォーマンスの幅が広がってきます。

慣れてくると、エディター内はフォアフォアしまくるようになってくるでしょう。


最後に、先日私がプライベートで調査のために書いた
For文だらけのサンプルコードを乗っけておきます。
参考にはしないでください。

-----------------------------------------
Sub Sample()

Dim cc, re, sc, colcount, rocount, i As Long

cc = Cells(1, Columns.Count).End(xlToLeft).Column
rc = Cells(Rows.Count, 1).End(xlUp).Row
For sc = 1 To Sheets.Count
   Sheets.count(sc)
    For colcount = 1 To cc
        For rocount = 1 To rc
            For i = 1 To 30
            '処理実行
            Next i
        Next rocount
    Next colcount
Next sc
End Sub
-----------------------------------------

2016年6月6日月曜日

【VBAリファレンス】行や列を指定する

以前、セルの指定方法について記事を書きました。

詳しくはこちら:【VBAリファレンス】セルの値を指定する方法は主に2種類あるのです

今回は行や列を指定したり、選択したりする記述方法についてご案内します。

その前にCellsプロパティについて、少し復習してみます。

Cellsプロパティ
------------------------------------------
Cells(1, 1).Select ’A1を選択
Cells(3, 2).Select ’B3を選択
------------------------------------------
列と行を逆に記述するわけですが、
内容は変数、または数字で指定をすることがルールでした。

行や、列を表示する場合も基本的には同じ考え方で大丈夫です。
でも、実は列の場合AやBなどで指定することも可能です。

基本的には
行はRow(ロウ)
列はColumn(カラム)です。

では、さっそく基本的な記述をやってみます。

行の選択
------------------------------------------
'1行目だけを選択
Rows(1).Select 

 '1~5行目をまとめて選択
Rows("1:5").Select 
------------------------------------------
Rows(1)のカッコの中は整数を代入した変数名を指定することも可能です。
なお、複数指定する場合はダブルクォーテーションで囲ったうえで
数値の間をコロンで挟んでください。
変数名を指定する場合の記述はちょっとややこしいですが以下の通りです。
Rows(a & ":" & b).Select (aに1を代入し、bに5を代入した時、1~5行目まで選択されます)


変数と組み合わせてセルの値や指定箇所を記述する詳しい方法は
後日ご紹介します。


列の選択
------------------------------------------
'A列を選択
Columns(1).Select

'同じくA列を選択
Columns("A").Select

'A~D列を選択
Columns("A:D").Select
------------------------------------------
列の場合は、整数での指定や
単独列の時はアルファベットを1文字入力して指定することが可能です。
その場合同じくダブルクォーテーションで囲うようにしてください。


私の場合、行、列を指定したうえで処理を行うことが多く、
For文を使用して特定間隔に処理を実行していくときに使用することが多いです。
その為、カッコの中は変数名が入ることが多いです。


また、お分かりかと思いますが
Select(選択する)だけではないので、Selectの箇所をDeleteに置き換えると
その列が削除されます。
もちろん、Copy&Pasteも可能なので
セルの操作と行列の操作を覚えるだけで、
データの操作性が拡張します。

是非色々と試してみてください。


2016年6月5日日曜日

【VBAリファレンス】初心者だからこそ、MsgBox(メッセージボックス)、結構慣れてきたからこそMsgBox(メッセージボックス)。

メッセージボックス(MsgBox)はVBAをやり始めたときに
メッセージが表示できるので、よく遊んで使っていました。

しかし、簡易的にプログラムの内容を確認するときや
実行コードの処理完了を報告する際など、
さまざま利用用途があります。

なので、初心者だからこそ、結構慣れてきた頃だからこそ、
利用用途を掴んで、活用してみてください。

基本使用例1
------------------------------
Sub test()

MsgBox "こんにちわ"

End Sub
------------------------------
上記コードを実行すると














基本使用例2
------------------------------
Sub test()

MsgBox 123456789

End Sub
------------------------------













直接、文字列を入力する場合はダブルクォーテーションで
囲んであげる必要があります。
しかし、数値や変数の結果を表示させる場合は
そのまま入力をしてあげれば大丈夫です。


基本使用例3
------------------------------
Sub test()

Dim a, b

a = 2  '変数aの箱に2を代入
b = 3  '変数bの箱に3を代入
MsgBox a + b  'aとbを足した結果をメッセージボックスで表示

End Sub
------------------------------












ここまで、基本使用例1~3まで記述してきましたが
主に使用頻度が多いのは1と3です。
1は長いコードを書いて、処理的にも時間がかかる場合、
全ての処理が完了した時、コードの最後に
MsbBox "完了しました"
と記載をすれば、そのメッセージが出たときに作業が完了したと判断できます。

3はForをお試しで使用したとき、カウンターの変動を確認したり
変数の結果を表示してみたりすることが出来ます。
初心者であれば、最初はそのような使い方をして全然良いと思います。
※慣れてきたころには【Debug.Print 変数】を使用して
イミディエイトウィンドウで表示し、確認してください。
Debug.Printとイミディエイトウィンドウの使用方法は後程ご紹介します。


【Excel】小数点の取り扱いにはご注意を…(関連:CSV、インポート、取り込み)

こないだ、とある事象にぶつかりました。

VBAでとかる箇所のデータをもとに
別の箇所からデータを引っ張ってくるコードを書いて
いざ実行してみると、上手く値が返ってこなかったのです。

エクセルの関数でいうとのことの
VLOOKUP関数の要領でやっていたのですが。

あれっ?って思い
今度は個別にMATCH関数を使用して
データの整合性を確認した見たところ、
やはりエラー値が返ってきます。

見た目には同じ値が入っているので、
結果は返ってくるはずなのに、エラー値が出る。
…ということはそれぞれのデータは別ものということです。

さて、何が理由か調べてみました。

まず、データの内容は数字、片方は0から1000くらいまで整数、
もう片方は、小数点以降2桁までの数値がある値で、
その値に100倍掛けして、結果的に整数に変えてます。
例): 0.02×100 =2 / 10.35×100 =1035

元々のデータはCSVから取り込んだデータです。


さて、まず原因について、判明した限りをお話しします。
どうやら、小数点以下の数値というかExcelの機能
悪さをしていたようです。


図込みで、ちょっと説明します。
まず、メモ帳(Text)に0.123456789123456789と入力します。
小数点以下、18桁ですね。

そのテキストをそのままExcelに貼り付けます。
セルの書式は標準です。
セルの幅を自動でワイドにすると、そこで表示される文字は【0.123456789】となります。
しかし、セルの書式を数値にして、小数点以下30桁まで表示とします。
すると、出てきた表示は【0.123456789123456000000000000000】となってました。


































最初にテキストで作成した文字が【0.123456789123456789】で
最終的にExcel内で処理されているのは【0.123456789123456】まで
そして、6の次の7は四捨五入されず、0に置き換えられています。

既にこの段階でユーザーの思いは儚く打ち砕かれているわけですね。
もう、ソッコーパーン!ですよ。

そして、このファイルを一旦CSVファイルとして保存してみます。
そのファイルを開きなおしてみると…






































どうでしょうか。のっけから嫌な予感しかしません。
セルのA1にカーソルを合わせ、数式バーを確認したところ
【0.123456789】と表示が出ています。


そこで、その下にMATCH関数を入れてみます。
B6にはテキストに一番最初に起こした【0.123456789123456789】を入れて
その下のB7にはCSVファイルのA1の値をコピーし、メモ帳に貼り付け、
それを再度コピーし、CSVファイルのB7に貼ったもの、
それに対して=MATCH(B6,$A$1,0)の式を当て込んでみたところ、
何と、元々の値は一致しないというエラー値が返ってきたのです。


ぶべらっ~!! (-3*)

もう、この時点で、元の【0.123456789123456789】は存在しないことになっています。

ところが、A1とA2、同じ値が入っているように見えますが
実際に見直してみると
値が違うことが分かります。
CSV化することで、その時のデータの書式により
保存される内容が変わってきます。

初めてこのファイルを見た人は
すでに真実は夢の彼方なのです。


さてさて、ここまで余計なことを含め、お話してきましたが
そもそもはデータが一致しないというお話でした。
その為、100倍掛けした数値を一旦Int(Integer)に置き換えてみたところ
きっちりとかみ合い、結果希望するデータを導き出すことが出来ました。

原因はおそらく元々のCSVファイルデータにおいて
小数点以下でも取り切れない箇所に、余計なデータが隠れてたとしか
推測することが出来ません。

プログラムの世界ではFloatやDoubleといって
この浮動小数点に対する細かい型が決められており
計算もきっちり行われるのですが、
こと、Excelに関しては、まず書式で小数点以下30桁まで設定できるにも拘らず
小数点15桁までしか表示がされません。
また、関数の一致に関しても同じ扱いになります。
というか入れられないものは入れられないよのスタンスみたいです。
(IEEE 754 仕様に準拠らしい)
結構いい加減。

なお、15桁以上の数字を表示するためには
書式を文字列にすればいらしいのですが
これもいったんCSVファイルにしてしまうと、15桁まで扱いになってしまいます。

関数をかけた結果、あっているはずの答えがエラー値で返ってきてしまうようであれば
まず、この辺りを疑い、
しかるべきデータ型(Int,Double)などに置き換えてみてください。

あと、Rondなどで四捨五入する方法もあります。