VBAの必須知識


オートマクロでは生成できない必須記述法です。

実現したい機能

書式(R=行,C=列)

セルの値を求める

x = Cells(R,C) Rは行・Cは列

セルに値を入れる

Worksheets("シート名").Cells(R,C) = A

セルに数式を書き込む

Cells(1,2).Formula = "=today()"
式を”で囲みます。

文字列切り出し

Right(文字列,文字数)
Left(文字列,文字数)
Mid(文字列,開始位置,文字数)

文字列操作

 文字列から、特定の文字の位置を見つける   Instr(文字列,検索文字)

文字列中の文字を置換
Replace
(文字列、置換前、置換後)

文字種の変換
 StrConv(文字列, vbKatakana)
  vbHiraganaでひらがなに
 vbWide で全角に
 vbNarrow で半角に 変換します。

文字をコードで指定

Chr(数字) ですが、
ChrW(数字) と指定すると、
ユニコードの文字が指定できる。
例:Replace(文字列,ChrW(160),Chr(32))
で、ユニコードのスペースを通常のスペースに

文字列・数値の変換
*結構シビアです

数値→文字列  CStr(数値)
文字列→数値  Val(文字列)

日付・時間の計算

Dateadd (種別,加算値,日付)
種別は、"yyyy" "m" "d" など
引く場合は加算値をマイナスで

実現したい機能

書式(R=行,C=列)

アクティブなセル情報を求める

行番号: R = ActiveCell.Row
列番号: C = ActiveCell.Column

アクティブなファイルの情報

ファイルのパス:ActiveWorkbook.Path
ファイル名:ActiveWorkbook.Name
パス+ファイル名:ActiveWorkbook.FullName
シート名:ActiveSheet.Name
シート番号:ActiveSheet.Index
シートのコードネーム:ActiveSheet.CodeName

最終行を求める

gyo = Range("C1").End(xlDown).Row
gyoに、C行のデータの最終行が求められます。

OSやExcelのバージョンを求める

Application.OperatingSystem OSのバージョン
Application.Version エクセルのバージョン
 msgboxで表示させ、書式を確認してください

今日の日付を求める

Date (today()の代わり)

日付・時間の計算

Dateadd (種別,加算値,日付)
種別は、"yyyy" "m" "d" など
引く場合は加算値をマイナスで

今日の和暦の年数を求める

Format(Now,"ggge年")
Nowを、日付の入ったセルを指定しても良い
マクロでどのように記述したらよいか分からないときに、オートマクロで記述させ、その内容を確認し利用します。例えば、1行削除するマクロの場合、オートマクロでは
 Rows("1:1").Select
Selection.Delete Shift:=xlUp
と記述されます。これを見て、1行目全体を指定するのはRows("1:1")であり、削除後上に移動するのが、Shift:=xlUp だと分かります。Selectは不要なので、
Rows("1:1").Delete Shift:=xlUp のように、SelectとSelectionを削除してつなげます。こうすることで、マクロの実行時に選択の操作が実行されて画面が変わるのを止められます。スピードも速くなります。

オートマクロを修正する

オートマクロで作成したマクロは、コピー・貼り付けの際に、選択範囲を移動するので、画面表示がうるさくなります。マクロを実行している際に、この移動を表示させないようにすれば、スピードも速くすっきりします。以下の2行で、作成したマクロを挟んでください。(*subとend subの間を挟みます)

Application.ScreenUpdating = False
 ここに、オートマクロで作成したコマンドが入る。
Application.ScreenUpdating = True  で戻す。

Application.Run"ブック名!マクロ名( )"  または、 Call マクロ名 でも構いません。

オートマクロでは生成できないマクロは、自分で書きます。ここでは、セルの値を1増やすマクロを例に、説明します。このマクロは、index関数でデータを呼び出す際の、参照行番号を繰り上げるのに使っています。

VBAのツールバーを表示する。

 このようなツールボタンを表示させるために、表示・ツールバーの
Visual Basic にチェックを入れます。図の矢印のボタンが、Visual Basic のエディターを表示させるものです。これをクリックします。

Visual Basic エディターを開く。

エクセルのシートとは別のウインドウが開きます。このウインドウの、挿入メニューを開き、標準モジュールをクリックします。(オートマクロを記述していれば、標準モジュールシートは、既にあるので、これに書き足しても構いません。)

コードを書く。

ここでは、シートのセルの数字を1増やすマクロを書く例で説明しています。マクロ名は、nextd()とします。(次のデータという意味)

モジュールシートに、sub nextd()と書いてエンターを押すと、End Subが自動で記述され、subもSubと大文字になります。

Sub nextd() と End Sub の間に、コードを記述します。

数字が1ずつ増えるセルは、座標がI2(アイ・2)なので、VBAで使う座標は(2,9)になります。
1行目は、今入っている数値を読み取り、これをnbという変数に取り込みます。
nb=Cells(2,9)
If nb>10 then nb=0   データが10行しか無く、nbが10を超えたら、1に戻したいので
nb=nb+1           nbに1足します。

この3行でおしまいです。

マクロを実行する。

ツール・マクロ、実行で、動作を確認します。

マクロ実行ボタンを作る。

このメニューでマクロを実行するのは面倒なので、実行用のボタンを作ります。

そのためのツールバーを、表示・ツールバー・フォームで表示します。

右のようなツールバーの、赤枠で囲ったボタンが、コマンドボタン作成です。

これをクリックし、適当な位置にボタンをドラッグで作ると、先ず最初に、マクロの登録を聞いてきます。

ここで、nextdをクリックして選択します。最初に、この選択をしておきます。

ボタンのデザイン・位置・名前などは、後で設定します。

ボタンが、このようになっているときが、編集モードです。
名前をドラッグして、選択し上書きで「次へ」と書き直します。編集モードになっているときは、ドラッグで大きさ・位置を変更できます。

 このように、選択枠が外れると、ボタンは生きているので、クリックするとマクロが実行されます。編集モードに戻したい場合は、右クリックします。

モジュールシート以外の場所にマクロを記述する(プライベートサブ)。

実は、マクロは、標準モジュールだけでなく、各シートやブックにも記述できます。これらは、実行がそのシートなどに特定されるもの(プライベートサブ)です。プロジェクト一覧の下にある標準モジュールでなく、その上のThis Workbookやsheetをクリックして、シートを表示します。

例1:このbookを開いたときは、エンターキィのカーソル移動が横(右)にするが、閉じたときは元の下に戻しておく、というマクロです。

例2:特定のシートのセルが変化したときに実行されるマクロです。入力されると自動実行される。

Changeを選び、 If Target.Column=* and Target.Row=* then を追加して、特定のセルが変化(入力された)したときのみ実行されるようにできます。

 

実現したい機能

書式

警告窓 (音と情報ウインドウ)

Msgbox ”文字列”または数値

OKをクリックして先に進む

確認窓(Yes・Noを確認する)
内容は、カッコ内に

kakunin = MsgBox("質問文 ?", vbYesNo)

Yesボタンをクリックすると kakuninの値が6
vbYesNoCancel にするとキャンセルボタン付
など、各種オプションがある

入力ボックスの配置

x0 = InputBox("ここにメッセージ")

警告ダイアログを出さない

削除などのマクロを実行すると、自動で確認・警告のダイアログが出ますが、これを止める方法です。
Application.DisplayAlerts = False と
Application.DisplayAlerts = True で挟む。
ファイル操作
いずれもファイル名は、フルパスで指定します

簡単な命令で、様々なファイル操作ができます。

ファイルがあるかどうか調べる
        If Dir(filename)<>"" then  **    ファイルがあれば、**する

ファイルの削除    Kill filename

ファイルのコピー貼付け      Filecopy 元ファイル,コピー先ファイル

ファイルの移動・リネーム  Name 元ファイル As 新ファイル
 (このとき、パスを変えれば移動になります) 

フォルダの作成と削除は、 MkDir path  と、RmDir path で可能です。

ファイルの有無     Dir(パス+ファイル名) で、あればファイル名を、無ければヌルを返します。

フォルダの有無  Dir(パス,vbDirectory) で、あればフォルダ名を、フォルダが無ければヌルを返します。空のフォルダの存在も分かります。  

セルの指定には、Cells(行、列)という行や列の番号で指定するものと、Range("座標 ") の形式があります。
Rangeの座標は、A1やB1:B10などのシートでの表記法がそのまま使えます。

変数で範囲指定したい場合は、Range(Cells(g1,r1),Cells(g2,r2)).Select や Rows(r1&":"&r2).などの書き方ができます。

列全体・行全体の指定は、

Range(Columns(2), Columns(4)).Select  または、 Columns(2).Resize(, 3).Select ( 2列目からもう3列(4列まで)選択の意味 )
ColumnsをRowsに変えると、行全体の選択です。
 

範囲の名前で指定する場合は、 Application.Goto Reference:="範囲名" とした後で、Selection. を使います。

ワークシートに設定した範囲を使う

Application.Goto Reference:="範囲名"

選択された範囲の情報を得る

Selection.Rows.Count で、選択されている行数を、Selection.Columns.Count で、同じく列数が得られます。

セルの範囲指定コピー貼り付け   範囲指定してコピー貼り付けします。

 Worksheets("シート名1").Range("A1:AB1").Value = Worksheets("シート名2").Range("A5:AB5").Value

シート名2の範囲A5:AB5を、シート名1の範囲A1:AB1に貼り付けます。

 


 

1.書き出しと書き終わり

Function 名前(引数1,引数2,・・)    *名前・引数はアルファベットで、

End Function                 *これが、書き終わり

2.名前について

定義したい関数名は、シート関数で既に使われているものは使えません。定義済みの関数は英語名なので、ローマ字表記の日本語を使うと、殆どダブりません。この名前が、そのまま戻り値の変数名として使われます。従って、構文の中に、必ず関数名を定義する文が入っているはずです。

例:hirituという関数を定義するとき、

Function hiritu(分子,分母)
  hiritu=分子/分母
End function

3.引数について

定義したい関数を計算するために必要な変数を、引数といいます。引数が無い場合でも( )は必要です。引数が複数ある場合は、,(カンマ)で区切って並べます。上の例のように日本語(全角)は使えません。半角英数のみ使用可能です。

例:hirituという関数を定義するとき、

Function hiritu(bunsibunbo
  hiritu=bunsi / bunbo
End function

注:本来は、変数はdim分で、種類の定義が必要です。整数(±32000の範囲)や小数点以下も含まれる数とか、あらかじめ数の種類によって定義します。しかし、これをしなくとも、自動で定義されます。メモリーを有効に使うためには、細かく定義した方が良いのですが、さほど大きくないマクロでは、自動変数でも構いません。

4.定義された関数を使う

使い方は、シート関数と同じです。引数には、直接セルの座標を書き込みます。関数の書かれたセルに、計算された返り値が入ります。

例:      =hiritu(A4,B4)

5.シート関数(組込関数)とfunction関数(マクロ関数)の違い

シート関数も、マクロ関数も使い方の上では、全く同じです。マクロが組み込まれているシートでないと、マクロ関数は使えないのに対し、シート関数はすでにワークシートに組み込まれているので、定義無しで使えます。マクロ関数を全てのシートで使いたいときは、これをpersonal.xlsというブック名で保存しておきます。エクセルの起動時に、このファイルがあるとbookに組み込んでくれます。この機能を利用して、エクセルのマクロウイルスは、personal.xlsの名前で保存されています。このため、personal.xlsのファイルはウィルスの温床のようになってしまっています。

function文の中では、VBAの関数を使います。これが、組込関数と同じ名前であったりするので混乱しますが、あくまで、別物です。構文が異なるので注意して下さい。例えば、if文は

if 条件式 then ○ else × で書き、行を変えて書く場合は、最後に end if が必要になります。組込関数のif とは、全く別物です。

フォームツールバーのボタンで、複数のボタンを作成し、これらの名前をマクロで変更したい場合は、以下のように指定することで、変数を使えます。
ボタンを選択して、名前ツールバーの表示を確認します。これは、後から付けた名前とは異なるエクセル内部で使うオブジェクト名です。作成時に付けられますが、途中で削除したり移動すると、続き番号にならないので注意して下さい。
更に、マクロで使う場合の名前は、コード名になり、英語名になっています。

 

For i = 1 to 10
 Sheet1.Shapes("Button " & i).Select
 Selection.Characters.Text = Sheet1.Cells(1,i)
Next i
これで、セルのデータから順番に名前を付けられます。コード名が、Button 1 のようになっていて、番号は日本語表示の数字と同じです。

エクセルのシートは、シート名・コード名・インデックス番号の3つで管理されています。
シート名というのは、タブに見えているシートの名前です。コード名というのは、シートが作られたときに自動的に付けられたsheet1sheet2などの名前です。 更に、インデックス番号というのは、並んだシートの順番です。
コード名以外は、後から変更可能です。また、シートを指定するには、どれも使えますが、後から変更されると、シート関数は自動で対応しますが、マクロの記述は自動で変わりません。従って、基本的には、コード名で指定する方が良いのです。
ここでは、コード名Sheet1からSheet3の3つのシートがあります。それぞれ以下のようになっています。

インデックス番号は、ブックを開いたときに並ぶ順番です。ドラッグで変わります。

コード名 シート名 インデックス番号 セルの指定例
Sheet1 Sheet1 3 Sheet1.Cells(1,1)
Sheet2 挿入シート3 1 Worksheets("挿入シート3").Cells(1,1)
Sheet3 名前を変えた 2 Worksheets(2).Cells(1,1)
右は、それぞれのシートのセルを、コード名・シート名・インデックス番号で指定する例です。 挿入などで、名前を付けなかったシートは、Sheet2などの名前が付きますが、これがコード名と同じとは限らないので注意して下さい。
セルの結合は、見かけは便利ですが、VBAで処理する場合は、様々なトラブルが起こります。これを多用することは避けたほうが良いのです。
結合されているセルを選択して、Deletを押せば、結合されていることも無関係に消えてくれます。 この操作は、オートマクロでは
Range("A1").Select
Selection.ClearContents
ですが、これを Range("A1").ClearContents とまとめると、「結合されているセルの一部を変更できません」というエラーになります。A1が結合されていなければ問題ないのですが、結合されているセルがあると、シートをアクティブにして、選択してからでないとクリアできません。

以下は、別のシートから、Sheet2の1列から2列までの1行目をクリアする例です。ポイントは、セルが結合されているときといないときを、MergeCellsで判定し、結合されているときは.MergeArea.ClearContents 、そうでないときは普通に .ClearContents とすることです。

 With Sheet2
 For i = 1 To 2
  If .Cells(1, i).MergeCells Then
 . Cells(1, i).MergeArea.ClearContents
 Else
  .Cells(1, i).ClearContents
 End If
Next i
End With
ちなみに、値を代入するときは、結合されたセルの先頭に代入すれば大丈夫ですが、先頭でない場合は表示もされずエラーも出ません。
簡易には、Cells(1,1)="" と、ヌルを代入すると、結合があってもエラーになりません。
セル結合がある場合、座標を間違えると、マクロを実行しても、表示されないので、トラブル発見に手間取ることがあります。だから、できるだけ使わない方が良いのです。

ワークシート関数を呼び出す

Application.WorksheetFunction.関数名( )

VBAの関数とエクセルのワークシート関数は、記述法が異なります。基本的には、VBAでワークシート関数は使わない方が良い (使えないものや、引数の表記が異なる場合がある)のですが、上のように記述すれば使えます。
範囲の指定は、Range(Cells(g1,r1),Cells(g2,r2)) の表記が使えます。
SUMを使う場合の例: Application.WorksheetFunction.Sum(Range(Cells(1,1),Cells(1,10))
Phoneticを使う例:Application.WorksheetFunction.Phonetic(Cells(1,1))