by h-fuji ちょっと、メモがわりに。 <EXCEL97> |
|
[初歩のはじめ] | [サンプル(ダウンロード)] | 「〜をするには」のモジュール例 | [
Excel VBA Memo へ ] | TopPageへ |
_
■ 初歩のはじめ
(1) VB_EDITORを開く: 表示(V) 〜 ツールバー 〜 VisualBasicEditorを選択。 または、ツールバー上で右クリック〜VisualBasicを選択。
エクセルウインドウとは、別にVBのウインドウが開きます。画面下部のタスクバーにエクセルとVBEの2つがあることになります。
VBEのウインドウを閉じても、エクセルは終わりませんがエクセルを終了すると、VBEのウインドウも閉じられます。
これから作成するマクロ(VBA)は、そのブックに含まれます.(マクロの保存場所は、ブック内です。)
(2) 挿入(I)〜標準モジュールを選択.
□ Book1-Module1(コード)のウインドウ内に、手続きを記入して、マクロを作成していきます。
まず、やることはマクロの名前を記入します。
SUB TEST( )
※ SUB は決まりごと。その次の「TEST」がマクロの名前.何でも、自分に分かりやすい言葉を付けることができます。
最後の( )も、決まりごと。マクロの名前には、漢字も使用可能。でも、お勧めは、英字。
SUB TEST() と入力して、enterキーを押すと、自動的に END SUB が下に追加される。
----------------------------------
SUB TEST()
'
END SUB
----------------------------------
SUB TEST()とEND SUBの間に、マクロを定義する。
----------------------------------
SUB TEST()
'
range("a1")=5*range("b1") ' B1セルの値に5倍した値がA1に代入されます。
END SUB
----------------------------------
「END SUB」の下に、SUB TEST1() と入力すると、「END SUB」と「SUB TEST1()」の間に、罫線が自動的に
引かれます。
■ とりあえずは、やってみるということで。
モジュール・ウインドウ内に、以下のように入力します。
sub 数を入れる() ' <-- 数を入れる というマクロ名になる
Range("a5")=12 ' <-- 手続き
end Sub ' <-- マクロの終了
そのままの状態で、エクセルウインドウをアクティブにします。
ツールバー上にマウスポイントを置いて、右クリックしてツールバーメニューからフォームを左クリックします。
シート上にフォームのツールバーが表示されるので、その中からボタンをクリックします。
シート上で左ボタンを押したまま、ボタンの大きさを決定します。
適当な大きさで左クリックを離すと、マクロ登録ウインドウが表示される。先ほど、記述した 数を入れる という
マクロ名があるので、それをクリックで選択してOKボタンをクリックします。 <--- これでボタンとマクロの関連付けが完了。
ボタンの中で、カーソルが点滅するので、ボタンの名前を入力します。
今はテストですから、そのままでもOKです。ボタン以外のシート上のどこかで、クリックするとボタンが確定します。
では、ボタンを押してみましょう.
A5のセルに 12が入りましたか?
OKなら、次に、VBEのウインドウに切り替えます。(タスクバーにあるVBEをクリックして、VBEウインドウをアクティブにします。
Range("A5")=12 を Range("A5")=Range("a3")+range("a4") に変更します。
※ 英文字の大小はどちらでもOKです。VBEが勝手に,変更してくれます。
シート上のボタンとVBAである 数を入れる()とのリンクはそのままなので、
セルA3とA4に適当な数を入れて,ボタンを押します。
A5セルに、乗算の結果が表示されましたか? あとは、想像力次第かな!?(^^/
■ 条件に応じていろいろ処理を自動化する とか 繰り返しは機械にさせる ことができると、
いかにもパソコンを操っているという、ちょっといい感じがします。
if文: if関数に似ているので,すぐにわかりますね。
*もし、セルA3が4だったら、セルB5に、セルA5×5の値を代入する。
(例)
IF RANGE("A3")=4 THEN RANGE("B5")=RANGE("A5")*5
*もし、セルA1の値が1だったら、モジュール1の処理1マクロを実行し、
セルA1の値が1以外だったら、モジュール1の処理2マクロを実行せよ。
(例)
IF RANGE("A1")=1 THEN
MODULE1.処理1
ELSE
MODULE1.処理2
END IF
case文: 条件に応じて、複数分岐して処理を行わせることができます。
for〜next文: 繰り返しは,この文を使います。
*A列の1行から10行まで、連番を付ける。
dim i as long
' i という変数を使用するという宣言
for i=1 to 10 ' i は1から始まり,10になると、繰り返しを終了する。
range("a"&i)=i ' 繰り返す内容(処理)
next ' i に1を加算して、forに処理を戻す。
操作をどんどんやっていくと、どの機能を使うと、どのようになるのかが推測できるようになります。
そして、機能の組み立てが推測できるようになると、より効果的なマクロが組めるようになります。
例: ホストデータを、外部プログラムをshellで実行して、csvファイルに落とし込み、エクセル表にし、
ピボットテーブルで、集計単位を一意データにし、そのピボットテーブルをテキストに複写して、
出来あがっている出力表に、VLOOKUPで必要な列を貼り付ける。
このような通常操作を出来るだけ詳しく文書化して、その一つ一つの処理をマクロに置き換えていくと、
定型的な処理の自動化ができます。
■ しかし、実際に「形」のある(起承転結のある)マクロを作ろうとしたときは,VBAの技術的なこととは、
別に、業務の「流れ」というものを理解していなければなりません。さらに、その業務(仕事=作業)を
EXCEL+VBAでどのように置き換えるかの「想像力」が必要となります。
たとえば、家計簿というものをエクセル+VBAで作ろうとした場合, いつ、どのデータをもとにして、
(通常、この場合だと、レシート+普通預金通帳などでしょうか)だれが入力して、何を「管理」したいかを
明確にしておく必要があります。家計簿が欲しいと思いながらも,実際は資金管理がしたかったりして、
せっかく費用の使途がわかり、削減できるものとそうでないものがわかっても、あまり評判がよくなかった
りします。
マクロ化すると・・・
☆ 手順が長い表作成などを行う場合は、マクロ化(ボタンで処理が始まる)しておくと、非常に楽になる。
作成するのが大変ではありますが。たとえば、ホストからのデータを取得して、分析表などを作成する場合など。
*データシートにフィルターをかけて、その結果をピボットで分析し、ピボット結果に、VLOOKUPで値貼り付けし、
印刷プレビューまでを自動化したり、グラフ表示までを自動化したりできます。
☆ 入力用の表(入力画面)とデータベース用の表(フィルターやビボットテーブルが利用しやすいような表形式)を
別にすることができる。〜 データを貯めこむシートとそれを元に分析する手順を分けることができる。
☆ 計算式ではなくて、マクロでその値のみを代入すると、表が必要に以上に大きくならない。
● キー記録を理解して、汎用化する。
と言う前に、基本文
セルA1の値をC1に貼り付ける。
キー記録だと、
Range("A1").Select
Selection.Copy
Range("C1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("C3").Select
となるが、
(1)=(イコール文)
VBAでは、
range("C1").value = range("A1").value
range()は、セルに読み替え。
=(イコール)文は、右の値が左に代入される。
セルA1というとき、前提として、シートがアクティブになっている
わけで、シート名をクリックする場合、VBAでは、
sheets("sheet1").activate
とする。
何気に行っている操作を、VBAでは指定する必要がある。
VBAでシート指定をしない場合は、アクティブになっているシートに
対して処理が実行される。
シートAAAのセルA1の値をシートBBBのセルC1にコピーするなら、
sheets("BBB").range("C1").value=sheets("AAA").range("A1").value
workbooks("a").sheets("BBB").range("C1").value=workbooks("B").sheets("AAA").range("A1").value
とすると、
ワークブックB.xlsのシートAAAのA1セルを、ワークブックa.xlsのシートBBBのC1セルに代入する。
前もって、ブックa.xlsとB.xlsをオープンしておくことが必要だけど。
(2)for〜next文
=文のほかに、繰り返しを憶えるといい。
dim i as long
for i=1 to 10
range("a" & i).value=i
next
for 〜 nextが繰り返しの基本。
iは変数
dimは変数定義をすること。
longは変数の型。数値とする。
文字型にする場合は、dim i as string とする。
これを実行すると、
A1からA10までのセルに、数字が順番に1〜10代入される。
上の他シートへの代入(コピー)の場合であれば、
dim i as long
for i=1 to 10
sheets("BBB").range("C" & i).value=sheets("AAA").range("A" & i).value
next
iは行番地の変数となっている。
(3)if文
if range("c1").value > 0 then
range("c1").value=range("a1").value * 10
else
range("c1").value=range("a1").value
end if
基本文はこのようになる。
if 条件式 then
条件が合致した場合の処理を記載
else
条件を満たさない場合の処理を記載
end if
で、先ほどの文は、C1セルの値が正の場合は、
A1セルの値を10倍して、セルC1に代入し、
そう出ない場合は、
A1セルの値をそのまま、セルC1に代入する
となる。
(4)キー記録の汎用化
VLOOKUP関数をセルに代入するマクロです。
Range("D1").Select
ActiveCell.Value = "=VLOOKUP(C1,$A$1:$B$12,2,0)"
Range("D7").Select
下記のようになった場合は、
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-1],RC[-3]:R[11]C[-2],2,0)"
相対座標で記録されたので、これではわかりづらいので、
これを上のように、
ActiveCell.Value = "=VLOOKUP(C1,$A$1:$B$12,2,0)"
とします。
最終行が可変である場合が多いので、vlookupの参照先の行数を変数にします。
上の式では、b12までの範囲でしたので、この12行を変数にして、マクロ内で
行数を設定できるようにします。
sub macro1()
dim i as long
Range("D1").Select
i=20
ActiveCell.Value = "=VLOOKUP(C1,$A$1:$B$" & i & ",2,0)"
end sub
セルD1の内容が、=VLOOKUP(C1,$A$1:$B$20,2,0) と変わっているのを確認。
これで、VLOOKUP()関数を使った場合に、参照先のデータ増えても対応できることに
なります。
参照先の最終行=B列の最終データ行の取得は、
gyou = ActiveSheet.Range("a65535").End(xlUp).Rows
又は、
gyou=ActiveSheet.Range("a1").currentregion.rows.count
などを利用して、最終行番号を取得します。
この場合h、gyouという変数に最終行番号が代入されます。
gyou = ActiveSheet.Range("a65535").End(xlUp).Rows は、
セルa65535から、ctrlを押したまま上矢印キーを押した時に選択されるセルの
行番号がgyouに代入されます。
gyou=ActiveSheet.Range("a1").currentregion.rows.count は、
a1セルを選択した状態で、ctrl+shift各キーをおして、*キーを押した場合の
領域の最終行番地がgyou変数に代入されます。