パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

セル関連の基本的なマクロ(範囲指定、セルに入力、値の取得

 

EXCELのオブジェクト(セル指定)のところでも、セルへの値の代入、取得について基本的なことを
やりましたが、ここではセル関連の基本的なマクロ例をいくつかとりあげていきます。

1 セル範囲の指定   ・ある範囲のセルに値を代入
2 行、列の指定     ・ある列、行のデータを全て消す   ・ある列、行の幅、高さの変更
3 セルへの値の代入  ・数値を文字列としてセルに入力   ・数式をセルに入力
4 アクティブセル     ・アクティブセルの列、行の取得    ・あるセルをアクティブにする
5 セレクション      ・ある範囲を選択し、データ消去する
6 データ範囲の取得  ・データ数不定のシートで、データ範囲(終端セル)を取得する    


1 セルの範囲指定

1つのセルではなくある範囲のセルを指定するには以下のようにします。
例えば、Sheet1のA1からD5まで(長方形の領域)に全て5を入力するには以下の2つの記述の仕方
があります。
Worksheets("sheet1").Range(Cells(1,1),Cells(5,4)).Value=5
Worksheets("sheet1").Range("A1:D5").Value=5



2 行、列の指定

C列とか3行目とか、列や行を指定したい時には、Columns( ), Rows( )を使います。
列についてはINDEXは、A列から順に1,2,3・・・となります。例えばD列を指定する時は
Columns(4)となります。
あるいは、Rangeを使ってRange("A:A") (A列)のように指定することもできます。
Rangeを使うと複数列、行を指定できます。例えばB列からD列ならRange("B:D")です。

Sheet1のC列のデータを全部消したい(クリア)する。
Worksheets("sheet1").Range("C:C").Clear
Worksheets("sheet1").Columns(3).Clear

Sheet1のB列の幅を変更する(30文字分)
Worksheets("sheet1").Range("B:B").ColumnWidth=30
Worksheets("sheet1").Columns(2).ColumnWidth=30
ColumnWidthの1単位は標準スタイルの一文字分です

Sheet1の2行目の高さを変更(20ポイント)
Worksheets("sheet1").Range("2:2").RowHeight=20
Worksheets("sheet1").Rows(2).RowHeight=20
RowHeightの1単位は1ポイント=(0.35mm)です。

複数行(あるいは列)にわたって操作する時はRangeをつかうのが便利ですが、RowsやColumnsを
使っても、For ・・・・ next で処理できます。

Sheet1の3行目から10行目の高さを変更(20ポイント)
For i =3 To 10
Worksheets("sheet1").Rows(i).Rowheight=20
Next

BASICやVB、あるいは他の言語の経験があれば、この方が書きやすいかと思います。



3 セルへ値の代入
セルの値を表すプロパティは Value です。
Sheet1のセルA1に5を代入するには、次のように書きます。
Worksheets("sheet1").Cells(1,1).Value=5

ところで、標準の状態で、セルに値を代入すると、EXCELは値が数字だけなら、その値は数値、
数字以外の文字があると文字列と判断します。標準状態では、数値はセルに右詰め、文字列は左詰め
で表示されます。
例えば、以下のようにA1に5、A2にabcを代入すると
Worksheets("sheet1").Cells(1,1).Value=5
Worksheets("sheet1").Cells(2,1).Value="abc"

  A B C
1     5              
2 abc    
3      

上記のように表示されます。


数値の文字列としての代入

ところで、数値を文字列として代入したい時がありますが、EXCELの場合少し注意が必要です。
例えば、5を文字列として代入したい時に
Worksheets("sheet1").Cells(1,1).Value="5"
としても、セルには数値の5として代入されてしまいます。
それではということで、数値を文字列に変換する関数STR$を使てみても、やはり数値の5として
代入されてしまいます(下記の例)
Worksheets("sheet1").Cells(1,1).Value=str$(5)

数値を文字列として代入する時は、「 ' 」を先頭につけてください。以下の通りです。
Worksheets("sheet1").Cells(1,1).Value="'5"


数式の代入
セルに数式を代入するには、Formula プロパティを使います。
Sheet1のセルA1にA2とA3の和を入力する数式を代入
Worksheets("sheet1").Cells(1,1).Formula="=A2+A3"



4 アクティブセル
EXCELのセルをマウスでクリックすると、下の表のようになり(ここではB1を選択)、そのセルが選択された状態
になります。これが、アクティブセルです。アクティブセルを表す(オブジェクト)はactivecell です。

  A B C
1         
2      

アクティブセルに値を代入する
Activecell.Value=5

アクティブセルの列、行はColumn, Rowプロパティで取得することができます。
アクティブセルの列、行をメーセージボックスで表示するプロシージャ
Sub get_Column&Row( )
c=Activecell.Column
r=Activecell.Row
MsgboX "アクティブセルは"+Str(c)+"列"+Str(r)+"行"
End Sub

あるセルをアクティブセルにするには、activateメソッドを使います。
セルB2をアクティブにする
Cells(2,2).Activate


5 セレクション
Activecellは現在アクテイブな1つのセルだけをさします。
例えばA1からC3までの範囲が選択されていても、アクティブセルはその中の1つのセルだけ(通常
この場合はA1)をさします。

  A B C D
1            
2        
3        
4        

従って、選択範囲全部を指すにはActivecellは使えません。
選択範囲全部をさすにはSelectionを使います。
また、あるセルの範囲を選択するにはSelectメソッドを使います。
Sheet1のセルA1からC3までを選択し、値をクリアするプロシージャ
Sub myclear( )
Worksheets("sheet1").Range("A1:C3").Select
Selection.Clear
End Sub

もちろん、選択されたセルが1つだけなら、ActivecellとSelectionは同じものをさします。



6 データ範囲の取得
あるワークシートに存在するデータの範囲が不定のことはよくあります。このように、データ範囲が不定の時
その範囲を取得するのには、いくつかの方法がありますが、便利な方法にEndメソッドの使用があります。
Endはある、列または行の終端のセルを返すメソッドです。構文は以下の通りです。

object.End(direction)

objectには基準になるセルを指定
directionは検索の方向を」指定
       xlToLeft: 左へ
       xlToRight: 右へ
       xlUp: 上へ
       xlDown: 下へ

Sheet1のA列の終端セルの行を取得する
e=Worksheets("sheet1").Range("A1").End(xlDown).Row

Sheet1のA列(A1からはじまる)選択範囲を、空白のセルに達するまで延長するプロシージャ
つまり、A列でデータのあるセル全てを選択する
Sub allselect( )
e=Worksheets("sheet1").Cells(1,1).End(xlDown).Row
Worksheets("sheet1").Range(Cells(1,1),Cells(e,1)).Select
End Sub


このようにデータ範囲が不定の場合も、Endメソッドによりデータのある範囲を調べて、全てのデータ
に処理を施すことが可能になります。
ただし、Endメソッドは空白のセルに出会うとそこを終端と判断するので、空白の先にまたデータの
あるセルが続く場合、別の工夫が必要になります。例えば下表のような場合、A2がA列の終端セル
となってしまいます。

  A B C
1    5            
2    7    
3      
4    6    

さて、空白が途中にあっても、空白セルを飛び越えて本当に最後のセルをみつけるには、どうしたらいいで
しょうか。まあ、定番の技のよになっていますが、下からさかのぼって調べれば、ばっちりです。
A列の終端セルの行の取得は
e=Worksheets("sheet1").Range("A65536").End(xlUp).Row

セルの行数は65536なので(*EXCEL97〜EXCEL2003)、尻の行からさかのぼって終端セルをみつけます。
(*EXCEL95はもっと行数が少ないかもしれません。 EXCEL2007〜2013は1048576行)


ここらへんは、まさにEXCELのVBAらしいテクニックというか、EXCELのVBAスペシャル技という感じ
です。BASIC流に考えると、下記のような感じでしょうか。おじさんなどは、ついこんなBASIC流のコーディング
をしてしまいますが、EXCELのVBAに用意されているスペシャルな命令を知っていると、1行で用が足りて
しまうんですね。素晴らしい!
このBASIC流のコーディングでは、コードも数倍になるだけでなく、スピードもかなり遅いです。
上のスペシャル技を使えば、一瞬で終端セルを見つけますが、下記のBASIC流では1万行さかのぼるのに
数秒かかります。
Sub Get_LastRow()
For i =65536 to 1 step -1
If Worksheets("sheet1").Cells(i,1)<>"" Then
e=i
Exit For
EndIf
Next
MsgBox "Last Row"+str(e)
End Sub

でも、おじさんはBASIC流もすき。これでもちゃんと終端セルの行を取得してくれます。
まあ、BASIC流が好きな理由の一つは、おじさんが新しい命令を覚えるのが面倒くさいという、
ものぐさな性格のためですが。EXCELのVBAのオブジェクト、プロパティ、メソッドの数はものすごいです
から。

 

TopPage > Visual BasIc&Excel活用研究目次