エクセルVBAを始めたきっかけは
いくつかのシートの特定セルを使って計算をして結果を新規シートに作成したい。
自分で作成した関数を使って計算させたい
ユーザID、パスワードを入力して特定の人に操作させたい
などの質問をされたことがあります。そのときはマクロを使ったら とか エクセルにはいろいろの機能があるので検討します とかいって質問に答えられなかったことがありました。
一通りのエクセルの知識はあるつもりでいたのですが、ショックでした。それからインターネットで色々調べてエクセルVBAにたどり着き、自分なりに学習を始めたのがきっかけです。
あくまで自己流です
インターネットで「エクセルVBA」を検索して少しずつ知識をえて、簡単なプロシージャを作っては
変数の理解、IF、select case といった構文、及び操作を理解していきました。VB(ビジュアルベーシック)とかJAVAの知識も必要と思い手を広げて学習したのですが、たまにしか学習しなかった為に理解がうやむやになり、結局エクセルVBAに絞って、不明点はエクセルベーシックのヘルプ機能で調べながら学習したので効率が悪かったようです。解りやすい本が出ていると思います。(最近本を買ったことがありません。金をかけてやるつもりはない 趣味のレベルで充分 が私の本心で何でもネットで調べる癖がついています。)
こんな調子なので、知識の断片化があり、又たまにしか学習しなかったので忘れてしまいます。
しかし、そんなに覚えることはなさそうです。自分の使うコマンドなどは基本的なことだけでした。。忘れたときや再度理解しなければならなかった事項を勘所として以下にまとめてみました。
少しは参考になると思います。 windowsの操作とエクセル基本機能は事前理解を前提
として、プロシージャーの作成及び基本的なデバック操作は出来ることを前提に以下を書いています
ユーザホーム を使ってエクセルとのユーザーインターフェースを作成する時に、コントロールのオプションボタン、テキストボックス、コマンドボタン、チェックボックスを使って入力の制御や必要な箇所の設定、入力のチェックをしますが、大方動作するのですがエラーになってしまうときがあり、(データ型の不一致など)ほとんど入力時のチェック漏れでした。ここではインプットチェックの要点を取り上げます。
テキストボックスはテキストであり、インプットボックスやエクセルのセル内容の表示、プロシージャーの変数の表示に注意しましょう
変数の宣言は省略できますが、デバック時に解るように必ずする。変数の初期化は必ずする癖をつけておくと後のデバックが楽になります。
変数の型の一覧
データ型 | 記述 | 説明 |
バイト型 | Byte | |
ブール型 | Boolean | TrueかFalse 真、偽 |
整数型 | Integer | −32768〜32767 |
長整数型 | Long | Integerで扱えない大きい整数 |
単精度浮動少数点型 | Single | 小数点を含む実数 |
倍精度浮動小数点型 | Double | |
文字列型 | String | |
日付型 | Date | 日付、時刻を扱う |
バリアント型 | Variant | あらゆる種類のデータを扱う |
テキストボックスに数値以外が入力されたかのチェックに
入直が数値かどうか調べるにはIsNumeric(Textbox)関数を使って判断する
””や” ”の場合もあるのでこららの入力チェックも忘れずに
if (textbox="") or (textbox" ") then
エラー処理など
変数=Csng(textbox)などの関数をつかって変数に渡す(例では変数が単精度浮動小数点型)
同様に日付、時間のチェックにはIsdate()関数を使い
If Isdate(Textbox) =False Then
エラー処理など
変数=Cdate(Textbox)関数を使いDate値に変換して変数に渡す
変数がテキストタイプの場合は Cstr(textbox)
変数が長整数型の場合は Clng(textbox)
変数をエクセルにRange(”xx”)セル指定して
Selection.value=変数 で書き込む場合にはセルの書式にあわせたデータ型使用しなければなりません。
その他の入力チェック(論理的な入力の上限、加減など)にはセルの入力規則と組み合わせて
警告、注意、停止のメッセージを表示させるなどして作業の効率化、使いやすさを図ることができると思います。又、Msgbox関数で独自の表現も必要です。
データ型 | データ型に対応する関数 |
Integer | Cint() |
Long | Clng() |
Single | Csng() |
Double | Cdbl() |
String | Cstr() |
Date | Cdate() |
など
日付、時間の計算は、一度整理をしておかないと、迷うことがしばしばありました。このパターンではこれを使い、書式はこれでと整理しておかないと、健忘症の私にはそのたびに調べることになり作業効率が悪く、その防止を含めて以下まとめてみました。ヘルプ機能の日付、時間計算で調べておくことをお勧めします。
エクセルでの日付計算、時間計算を最初にまとめて整理しておかないと後のVBAとごっちゃになってしまう場合があり、注意が必要です。
エクセルの場合
Date(年、月、日) | 1900年1月1日がシリアル値1 例Date(2008,14,2)はDate(2009,2,2)と同じシリアル値 引数年、月、日が数式の場合に便利 注 時刻の情報は無視される |
Datevalue(日付文字列) | 日付を表す文字列を、Excelの組み込みの日付表示形式で指定 例 =Datevalue(”2008/8/22”) |
Time(時,分,秒) | 引数は0から32767で指定 計算結果は0から0.99999999の範囲にある値 例 TIME(0,750,0)はTIME(12,30,0)と同じ 例 TIME(27,0,0)はTIME(3,0,0)と同じ 注 日付の情報は無視される |
TIMEVALUE(時刻文字列) | 文字列で表された時刻を少数に変換 例 TIMEVALUE(”2:24:AM”)は0.1 |
TODAY() | 現在の日付に対応するシリアル値を返す |
NOW() | 現在の日付と時刻に対応するシリアル値を返す |
WEEKDAY(シリアル値、種類) | 種類 1(または省略) 1(日曜)〜7(土曜) 2 1(月曜)〜7(日曜) 3 0(月曜)〜6(日曜) |
時間計算の例
=TEXT(B2-A2、”h”) 2つの時刻間の時間数を求める
=TEXT(B2-A2、”h:mm”) 2つの時刻間の時間数と分数を求める
=TEXT(B2-A2、”h:mm:ss”) 2つの時刻間の時間数、分数,秒数を求める
メモ 時刻、日付には,]TEXT関数を使用する代わりに、日付または時刻の表示形式を設定することも出来る。但し、TEXT関数と表示形式の両方を使用した場合、TEXT関数が優先
=INT(B2-A2)*24 ) 開始時刻から終了時刻までの総時間を求める(INT関数)
=(B2-A2)*1440 開始から終了時刻までの総分数を求める
=(B2-A2)*86400 開始から終了時刻までの総秒数を求める
=HOUR(B2-A2) 差分が24以内の2つの時刻間の時間数を求める(HOUR関数)
=MINUTE(B2-A2) 差分が59以内の2つの時刻間の分数を求める(MINUTE関数)
=SECOND(B2-A2) 差分が59以内の2つの時刻間の秒数を求める(SECOND関数)
メモ 日付、時間計算は、シリアル値で実施すれば、特別な関数は必要ありません。
又、負の値のときはセルに######と表示されますが、計算値はそのまま使用可能です。
エクセルVBAの場合
DATE | "YYYY/MM/DD"という文字列形式で日付を返す 例 Range("A1"),Value=Date |
NOW | パソコン内部のとけいの日付と時刻をシリアル値の情報として返す YEAR、Month、Day関数とセットで使うと年、月、日の取得可 |
TIME | "HH:MM:SS"という文字形式で時刻を返す HOUR,MINUTE,,SECOND関数で時間、分、秒の取得が可 |
Datediff(<間隔、日付1、日付2>) | 日付1,2の間隔を文字列で指定 日付は"d”週は”ww” 例 keika=Datediff("d",2000/01/01、DATE) |
Dateadd(<間隔,経過数、日付>) | 例 mirai=DateAdd(”d”、365、"2007/01/01”) |
例 MIRAI=NOW + Timeserial(時、分、秒)
未来=Format(MIRAI、”AM/pm h時、mm分、ss秒”)
とか 未来=Format(MIRAI、”yyyy年、mm月、dd日”)
ユーザーフォーム上にテキストボックスを多数配置するような設計をした場合、追加、変更をなんどか実施します。その後、動作確認の段階で入力部(テキストボックス)をTABで送っていくとフォーム上の位置が飛び飛びになって作業しずらい。
この場合、テキストボックスのプロパティーのTabindexをレイアウト順に、連番になるように変更することにより回避できる。又、フレームを使い、テキストボックスを整理すると作業しやすくなります。
こんなことは解説書に書かれていると思いますが、一切解説書などみたことがなく、試行錯誤でたどりついた結果です。
ユーザーフォームのテクストボックスを処理するプロシージャを作成するとき、iイベントの規定値はchangeになっています。その他beforeupdate、afterupdate、enter、exit、keydown、keyup、keypress、mousedown、mouseup、などがありその意味とか使い方が理解しにくい。
そこで、ヘルプ機能を読んで少しずつまとめてみました。
テキストボックスに入力した値をエクセルシートの特定セルに書き込む場合を例にとって話を進めてみます。
Range(”a1").Select
Selection.Value=Cint(Textbox1)
Changeイベントの場合
テキストボックスに一文字入力するたびにセルの内容が変化します。
Valueプロパティの設定値が変更されるたびにイベントが発生するため
Beforeupdateイベント、AfterUpdateイベントの場合
テキストボックスにデータ入力後、タブキー、エンタキーを押すとセルの内容が書き換えられる。
フォーカスは次に移り、今回の例では差がありません。
Beforeupdate(Byval Change As MSforms.ReturnBoolean)
BeforeUpdateイベントは上記の引数があり、ChangeをTrue(既定値はFalse)にするとフォーカスは元のコントロールに残り、AfterupdateイベントもExitイベントも発生しない
Exitイベントも同様の引数があり、ChangeをTrueにするとフォーカスが別のコントロールに移動しない。
イベントの発生順序について
Enterイベント、Beforeイベント、afterイベント、Exitイベントの順
例を上げて説明すると次のようになります。
TextboxA、TextboxBに入力する場合
マウスでTaxtboxAをフォーカスするとTextboxAのコントロールでEnterイベントが最初に発生
KEY入力でBeforeUpdadeイベント、その後Afterupdateイベント。TextboxBをフォーカスすると
TextboxAコントロールのExitイベント後TextboxBのEnterイベントが発生するようです。
始めは理解しにくいと思います。実際に各々コントロールを作って、やってみて初めて理解できるのでは。コマンドボタン、オプションボタン、などの組み合わせでも同様に理解していけばいい様な気がします。
Clickイベント、MouseDownイベント、MouseUPイベント
直感的に解りやすいコントロールとしてコマンドボタンがあります。マウスでクリックすると発生。
MouseのDown,Upのイベントと関連しておりますが、自分はClickイベントしか使ったことがないのでヘルプ機能の説明を簡単にまとめておくだけにします。
MouseDown、Mouseupイベント
Mousedownイベントはマウスボタンを押したとき、MouseUpイベントはマウスボタンを離したときに発生
構文
Private Sub Object_Mousedown(Index As Long、Byval Button As fmButtan、
Byval Shift As FmshiftState、Byval x As Single、Byval Y As Single)
Index 例 イベントが発生したMultiPageコントロールのページのインデックス
Button イベントを発生させるマウスボタンを識別する整数値
fmbuttonLeft 1 左ボタンが押された
fmbuttonRight 2 右ボタンが押された
Shist shiftキー、ctrlキー、Altキーの状態を指定
1 Shiftキーが押された
2 Controlキーが押された
3 Shiftキーと同時にctrlキーが押された
4 Altキーが押された
5 Altキーと同時にShiftキーが押された
6 Altキーと同時にctrlキーが押された
7 altキー、Shiftキー、Ctrlキーが同時に押された
MouseDownイベント、MouseUpイベントが発生したときの格キーの状態を識別する 為に使う。
x、y フォーム、フレーム、ページページコントロールの左端からの水平位置、及びその 上端からの垂直位置をポイント単位で指定
KeyDownイベント、KeyUpイベント、KeyPressイベント
これらのイベントも使ったことがないが、理解するうえで必要と思い、まとめてみました.
次の順序で発生します。
1 KeyDown
2 Keypress
3 KeyUp
KeyDownイベントとKeyUpイベントは、フォーム及びフォーム上にあるコントロールでのみ発生。
KeyDownイベント、KeyUpイベントは次のキーを認識したり、区別するときに使う。
注 フォーカスの移動を引き起こすキーを押した場合、フォーカスの移動前のコントロールでKeydownイベントが発生し、移動後のコントロールでKeyPressイベントとKeyUpイベントが発生
ANSIコードまたはシフトJISコードを解釈するとき、または押されたキーに対応するANSIコードまたはシフトJISコードを調べるときに、KeyPressイベントを使う。
Tabキー、Enterキー、方向キーを押したときはKepressイベントは発生しません。
構文
Private Sub Object_Keydown(ByVal Keycode As MSForms.ReturnInteger、ByVal Shift
As fmShiftState)
Private Sub Object_Keypress(ByVal KeyANSI As MSForms.ReturnInteger)
KeyCode 押したキー、離したキーのキーコードを指定
Shift Shift、Ctrl、Altキーの状態を指定
KeyANSI ANSIまたはシフトJISコードを表す整数値を指定
概要
変数、プロシージャー、定数についていえる事ですが、VBAのパブリック、プライベイトの理解が必要です。
Bisual Basicのプロジェクトウインドウを開くと
VBAProject(XXX.xls)
Module1
sheet1(シート名)
sheet2(シート名)
ThisWorkbook
Userform1
と表示されています。Moduleは、いくつかのSubプロシージャー、ファンクションプロシージャー、
及び、Declations(宣言部)で構成されており、Userformも1つのモジュールと考えてよさそうです。Subプロシージャ内での変数は
Dim 変数名 As データ型
と宣言し、そのプロシージャ内でのみ使用します。
同一モジュール内で共通に使用する場合は、モジュール宣言セクションで
Private 変数名 As データ型
と記述します。
他のモジュール全てから使用できるようにするには、モジュール宣言セクションで
Public 変数名 As データ型
と記述します。当初この辺が理解しづらい箇所でした。自分でサンプルプログラムを作成して、
確認する必要があります。
定数について
定数はConstステートメントで宣言します。
例 Const 定数 As データ型=値
プロシージャ内または宣言セクションの先頭で定義します。
パブリックモジュールレベルの宣言は変数同様ConstのまえにPublicステートメントをしていします。Public Const 定数名 As データ型=値
Staticステートメントとは
私は未だStaticステートメントは使ったことがありません。Dimステートメントの代わりにStaticステートメントを記述することによりモジュールの実行中値を保持するとのこと。
通常Dimステートメントで宣言した場合、1つのSubプロシージャを抜けると変数はクリアされます。
その他、理解の難しい箇所
Byval、Byref
関数の引数にByval、Byrefを指定するときのByval、Byrefの違いは
あるSubプロシージャから他のプロシージャを呼び出した場合(変数をセットして)引数の前に
Byval 変数 As データ型
は呼び出しもとの引数で使用した変数は、呼び出し先で変更されてもその影響を受けず
Byref 変数 As データ型
は呼び出し元の変数は、呼び出し先で変更されると影響を受ける
といった違いがあります。ファンクション関数と同じ働きをします。Byvalは値渡し(コピーしたものを渡す。)Byrefは参照渡しといって直接変更されるとのこと
この辺も理解しづらく自分でサンプルを作って確認する必要があります。
クラスモジュール、Propertyプロシージャなど
この辺は自分としてはまず使うことがない箇所では?
なんとなく理解していますが何せやったことがないので今後の課題にしておきます。
ジャバ言語のクラス(オブジェクトの、プロパティ、メッソドを設計してそのインスタンスをつくり?)
と同様に理解したらいいのかどうか、興味がある箇所です。
オブジェクト型の場合の変数
ここでオブジェクトとは、プロパティとは、メソッドとは について再確認しておく必要があります。
エクセルでのオブジェクトは
Applicationオブジェクト Excel本体
プロパティ
ActiveCell アクティブなセル
ActiveSheet アクティブなワークシート
Workbooks 開いているブックのコレクションを示す
Worksheets アクティブなブックに含まれるワークシートのコレクション
Workbookオブジェクト ブックを示す
プロパティ
ActiveSheet アクティブなシートを示す
Fullname ブックのパスを含んだファイル名
Name ブックの名前
Sheets 含まれているワークシートのコレクション
メソッド
Active アクティブにする
Close ブックを閉じる
Printout 印刷する
PrintPreview 印刷プレヴュー
Save 保存
WorkSheetオブジェクト ワークシートを示す
プロパティ
Cells ワークシートの全てのセルを示す
Columns ワークシートに含まれる全ての列
Index ワークシートのコレクション内での順番
Name ワークシートの名前
Rows ワークシートに含まれる全てのセル
Range 特定範囲のセルを示す
メソッド
Active アクティブにする
Copy ワークシートをコピーする
Delete ワークシートを削除する
Move ワークシートを移動する
Select ワークシートを選択状態にする
Printout 印刷する
Rangeオブジェクト 1つのセル、または範囲指定した複数のセルを示す
プロパティ
たとえば Borders セルの罫線の状態を保持するBordersコレクション
Characters セル内で選択されているテクストを示す
ColumnWidth セル幅
Font セルのホント
Offset 現在のセル位置より指定した数にあるセルを示す
Style セルのスタイルを示すStyleオブジェクトを示す
Text セル内の文字
Value セル内の値
メソッド
Active アクティブにする
BorderAround 罫線を設定する
Copy コピーする
Delete 削除する
Find 検索する
Sort 並び替える
Printout 印刷する
Select 選択する
その他オブジェクトの階層、プロパティ、メソッドはVisual Basicのヘルプで確認
オブジェクト変数をさくせいするには (以下の箇所は、実際使用した経験がありません。今後の課題)
オブジェクト変数を宣言 例 Dim Myobject AS Obuject
オブジェクト変数にオブジェクトへの参照を代入(Setステートメントを使用)
Set MYBook=Workbooks(”Mybook.xls”)
Set Mysheet=Worksheets.(”Sheet1”)
Set Myrange=Range("A1:b10”)
オブジェクトのプロパティの値を取得または設定したり、そのオブジェクトのメソッドを使用することができる
キーワードNewを使用すると、オブジェクト変数の宣言とオブジェクトへの参照の代入を同時に記述できる
Set Myobject=New Object
オブジェクト変数にnothingを代入すると、オブジェクト変数と参照していたオブジェクトとの関係が無効になる
Set Myobject=Nothing
配列変数について
同じ形式の変数を多数使用する場合以下の書式で、使用する
Dim MyBOX(50) As データ型
この場合 変数Mybox(0)、mybox(1)、以後Mybox(49)迄、50個の変数を示し、( )内は、Indexとして使用する。
IF Then 文、For Next文、Select Case、文が繰り返し処理、判定処理としてよく使います。
比較条件(比較演算子)など確実にマスターが必要ですが、なにも難しいことはないようです。
INPUTBOX関数、Msgbox関数もよく使います。
Msgbox関数,Inputbox関数
Msgbox関数
単にメッセージを表示する場合 Msg ”メッセージ文”
メッセージを表示して判断させる 変数=Msgbox(”メッセージ”、表示ボタン,タイトル)
組み込み定数 (VBAがあらかじめ用意している値)
表示ボタン | 値 | 戻り値 | 値 |
vbOKnly | 0 | vbOK | 1 |
vbOKCancel | 1 | vbCancel | 2 |
vbAbortREtryIgnore | 2 | vbAbort | 3 |
vbYesNoCancel | 3 | vbRetry | 4 |
vbYesNo | 4 | vbIgnore | 5 |
vbRetryCancel | 5 | vbYes | 6 |
vbNo | 7 |
Inputbox関数
変数=Inputbox(メッセージ、タイトルなど)
戻り値は文字列のため 変数はString型になります。変数を数値型にする場合
変数=Val(Inputbox(メッセージ、タイトル、 ))とVal関数(文字列を数値に変換する)を使用する
繰り返し処理 For To Step Next 及び中断
For 変数名=変数の初期値 To 変数の終了値 Step 変数の増加分
実行処理文
If (中断条件式) Then
Exit For
End If
Next 変数名
次の処理
のパターンになります。
その他の繰り返し処理として、Do While(条件式) Loop 、Do Until(条件式) Loop
などがあります。
エラー発生時の処理 On Error Goto 、Resume
マクロ実行時、あらかじめ起こりそうなエラーに対し、エラー処理を記述できます。
書式
On Erroe Goto (エラー処理ラベル 例 Myerror)
(エラーの発生が予測される処理)
Modori: (エラー復帰ラベル 例 Modori)
On Error Goto 0 エラー処理解除
他の処理
Exit Sub
Myerror:
エラー処理
Resume Modori:
End Sub
以上のパターンになります。
数の切捨て、四捨五入、など
Int(式 )関数
計算結果、小数点以下をきりすて
Roundup、Rounddown、Round(式、桁数)
小数点以下桁数を残し切捨て、切り上げ、四捨五入をする
Abs(式)
その数値の絶対値を返す
Mod演算子
余り=A Mod B AをBで割った余りを求めるとき
コントロール(チェックボックス、コンボボックス、リストボックス)などについては
働き、使い方など日々操作上でお目にかかったっことがあると思います。自分で実際に使って
活用すると理解が早いし、面白みが沸くと思います。
以後私の健忘症たいさくとして、知っていると役にたつ 便利だと思われる事項を取りとめもなく書いていきます。(参考になれば)
(現在の日付ー生年月日)/10000 小数点以下無視
例 (20070828−19490712)/10000 現在の日付2007年8月28日 生年月日1949年7月12日 満58歳