2015年4月13日月曜日

行・列の非表示と再表示

行を非表示にする為には、行全体のRangeオブジェクトのHiddenプロパティにTrueを設定
する :

行Rangeオブジェクト.Hidden = True

非表示になった行を再表示する為には、HiddenプロパティにFalseを設定する :

行Rangeオブジェクト.Hidden = False

例えば、Activesheetの20~26行目を非表示にする場合は、

Activesheet.Rows("20:26").Hidden = True

再表示するには

Activesheet.Rows("20:26").Hidden = False

とそれぞれ記述する。列の場合についても同様に、非表示、再表示はそれぞれ下記の通り :

列Rangeオブジェクト.Hidden = True
 
列Rangeオブジェクト.Hidden = False




行・列の削除

行を削除するには、(前項の)取得した行全体のRangeオブジェクトのDeleteメソッドを使用
する :

取得した行Rangeオブジェクト.Delete

例えば、Activesheetの20~26行目を削除する場合は

Activesheet.Rows("20:26").Delete

と記述する。列の削除も同様に、

取得した列Rangeオブジェクト.Delete

で列全体を削除することができる。ActivesheetのA~G列を削除する場合は

Activesheet.Columns("A:G").Delete

と記述することで列を削除することができる。 

2015年4月12日日曜日

行・列の取得

ワークシートの行全体を取得する場合は

Set Range変数 = Worksheetオブジェクト.Rows()

と記述する。20行目のみを取得する場合は

Set rng = Activesheet.Rows("20")

20~26行目を取得する場合は

Set rng = Activesheet.Rows("20:26")
 
と、それぞれ記述する(rngRange変数)。また、列全体を取得する場合は

Set Range変数 = Worksheetオブジェクト.Columns()

と記述する。行の場合同様、A列のみ取得する場合は

Set rng = Activesheet.Columns("A")

A~G列を取得する場合は

Set rng = Activesheet.Columns("A:G")

と、それぞれ記述する(rngRange変数)

2015年4月11日土曜日

セルのシリアル値の取得

日付の場合、1900年1月1日を「1」として、以降1日につき1ずつ加算した値をシリアル値
という。例えば、2015年4月10日のシリアル値は「42104」となる。このシリアル値を(使う
場面はそれ程ないが)を取得するにはRangeオブジェクトのValue2プロパティを使用する :

変数 = Rangeオブジェクト.Value2

尚、Value2プロパティに値を設定することも可能だが、

Range("B10").Value2 = 42104

としても、セルには日付が表示されず、数字の「42104」が表示される。また、文字列や
数値の場合はValueプロパティの値とValue2プロパティの値は同一となる。

2015年4月10日金曜日

セルに表示されている値の取得

数値や日付の場合、セルに設定されている値と表示されている内容が異なる場合がある。
例えば、下図のように、小数点以下の桁数を二ケタまでしか表示していないセルがあった
とすると、設定されている値と表示されている数字は異なったものとなる :
















上記の場合のように、セルに表示されている内容を知りたい場合は、Rangeオブジェクト
Textプロパティを使用する :

変数 = Rangeオブジェクト.Text

上の例の場合、Textプロパティで取得される値は「1.24」、Valueプロパティの値は「1.235」
である。尚、Textプロパティは読み取り専用のプロパティなので、値を代入することはでき
ないので要注意。因みに、文字列の場合は、試してみた限りではValueプロパティとText
プロパティで取得できる値は同じであった。

セルへの値の設定と取得

セルに値を設定する場合は、RangeオブジェクトのValueプロパティを使用する :

Rangeオブジェクト.Value =

逆に設定された値を取得したい場合もValueプロパティを使用する :

変数 = Rangeオブジェクト.Value

セルの値の設定と取得をするサンプルコードを下記に記す。

Sub SampleSetAndGetRangeValue
     Range("B2").Value = "abcdefghijklmnopqrstuvwxyz"
     MsgBox Range("B2").Value
End Sub

上記コードの実行結果、メッセージボックスにはaからzの英小文字の羅列
が表示される。

セルの取得

ひとつのセル(オブジェクト)を取得するには下記の二通りの書き方がある :

Set Range変数 = Worksheetオブジェクト.Range(アドレス)
Set Range変数 = Worksheetオブジェクト.Cells(RowIndex, ColumnIndex)

前者の記述の方法の場合、ひとつのセルを取得する場合は

Application.Activesheet.Range("A1")

のように記述する。A1セルからF6セルまで、のようにセルを範囲で取得したい場合は

Application.Activesheet.Range("A1:F6")

と記述する。

2015年4月9日木曜日

指定した名前のワークシートが存在するか確かめる

ひとつのブックの中に同じ名前のワークシートをつくることはできない。従って、ワークシート
の名前を変更する際などは、必ず同じ名前のワークシートが存在しないかを事前に確かめる
必要がある。「Workbookオブジェクト.Worksheets」はブックの中のすべてのワークシートの
集まりなので、For Eachステートメントを使えば容易に特定の名前のワークシートの有無を
確かめることができる。

以下のコードはアクティブなWorkbookの中に、「Sheet2」という名前のワークシートがあるか
否かを確認するものである :

Sub SampleFindSheet2
     Dim bolHit As Boolean
     Dim ws As Worksheet
     bolHit = False
     For Each bk In Application.ActiveWorkbook.Worksheets
          If ws.Name = "Sheet2" Then
               bolHit = True
               Exit For
          End If
     Next 
     If bolHit Then
          MsgBox "あったよ"
     Else
          MsgBox "なかったよ"
     End If
End Sub

指定した名前のブックが開いているか確かめる

既述の通り、自動/手動に関わらず、同じ名前のブックを開こうとするとエラーになって
しまう。その為、ブックを開く前に、特定の名前のブックが既に開いているかどうかを
調べる必要がある。例えば、「Book2」という名前のブックが既に存在する(=開いている)
かどうかを調べるには下記手順で処理を行う :

1.変数を1つ用意する。仮に変数をX(エックス)とする。

2.開いているブックのひとつひとつについて①~②の処理を行う :
  ①ブックの名前が「Book2」のとき、変数Xに値「あった」を代入して処理3.へ
  ②ブックの名前が「Book2」でなかったとき、変数Xに値「なかった」を代入

3.変数Xの値が「あった」の場合は「あったよ」、「なかった」の場合には「なかったよ」
  とそれぞれメッセージを表示する

処理1.と3.については特に難しいことではない。それぞれDimステートメントとMsgBoxステー
トメントを使えば実現できてしまう。問題は処理2.をどうするか。。。

処理2.のように、なにかの集まりの要素ひとつひとつについて処理を行いたい場合、VBA
では、For Each~Nextステートメントを使用する。書式は下記の通り :

For Each 要素を代入する変数 In 要素の集まり
    <<処理>>
Next

既に何度か登場した「Application.Workbooks」とは、実は、「『開いているブック』の集まり」
のことなので、For Eachステートメントを用いると処理2.は以下のように記述できる :

For Each Workbook変数 In Application.Workbooks
    If  Workbook変数.Name = "Book2" Then
        ...
    Else
        ...
    End If
Next

以上のことから、「Book2」が開いているかどうかを調べるコードは以下のようになる :

Sub SampleFindBook2
     Dim bolHit As Boolean
     Dim bk As Workbook
     bolHit = False
     For Each bk In Application.Workbooks
          If bk.Name = "Book2" Then
               bolHit = True
               Exit For
          End If
     Next 
     If bolHit Then
          MsgBox "あったよ"
     Else
          MsgBox "なかったよ"
     End If
End Sub

ワークシートの名前の取得と設定

ワークシートの名前を取得するには、WorksheetオブジェクトのNameプロパティを使用する :

String型変数 = Worksheetオブジェクト.Name

また、Worksheetの名前を設定(変更)する場合にもNameプロパティを用いる :

Worksheetオブジェクト.Name = 名前

ここで、名前には文字列を指定する。

ワークシートの保護/保護の解除

ワークシートを保護する為には、WorksheetオブジェクトのProtectメソッドを使用する :

Worksheetオブジェクト.Protect Password

逆に、保護されたワークシートの(保護の)解除を行うには、Unprotectメソッドを使用
する :

Worksheetオブジェクト.Unprotect Password

Password引数には文字列を設定する

ワークシートの非表示/再表示

ワークシートを非表示にしたり、非表示になっているワークシートを再表示するには、
WorksheetオブジェクトのVisibleプロパティを使用する :

Worksheetオブジェクト.Visible = 定数

定数には、XlSheetVisibilityクラスの下記の定数の何れかを設定する :

XlSheetVisibility.xlSheetHidden : ワークシートを非表示にする。手動で再表示可能
XlSheetVisibility.xlSheetVeryHidden : ワークシートを非表示にする。手動で再表示不可
XlSheetVisibility.xlSheetVisible : 非表示のワークシートを再表示する

XlSheetVisibility.xlSheetVeryHiddenで非表示にした場合は手動で再表示することができない
為、マクロで再表示するしかない。

2015年4月8日水曜日

選択されたセル範囲を取得する(2)

選択されたセル範囲を取得する二つ目の方法として、InputBoxを用いるやり方がある。
InputBoxダイアログの詳細については後日書くとして、とりあえず下記のコードを実行して
みる :

Sub SampleSelectRange()
     Dim rng As Range

     Set rng = Application.InputBox(Prompt:="セルを選択してください", Type:=8) 
     Msgbox "左端は " & rng.Column & " 列目です"
End Sub 

上のコードを実行して下図のようにセルを選択すると、セル範囲がInputBoxに表示される :












例のように、Type引数に「8」を指定すると選択したセル範囲をInputBoxに表示できるように
なるらしい。但し、上記のコードは、何も選択しなかったり、キャンセルボタンをクリックすると
エラーになってしまうので、ユーザーフォームを使った方法の方が実用的なのかも知れない。

選択されたセル範囲を取得する(1)

選択されたセル範囲を取得する方法の一つとして、ユーザーフォームのRefEditコントロール
を利用するやり方がある。RefEditコントロールはツールボックスのコントロール群の一番右下
にあるものである :















このRefEditコントロールをユーザーフォームに貼り付けて実行すると、下図のような画面が
表示される :









RefEditコントロールにフォーカスされた状態で下の図のようにセルを選択していくと、選択
したセル範囲がRefEditコントロールに表示される :












RefEditコントロールに表示されたセル範囲は、RefEditコントロールのTextプロパティによって
取得することができる :

String型変数 = RefEditコントロール.Text

2015年4月7日火曜日

ブックを選択する

今回ももっと最初の方に書くべき内容。。。

ブックを選択するには下記の何れかのように記述する :

Application.Workbooks(ブック番号)

または

Application.Workbooks(ブック名)

複数のブックを同時に開いている場合、ブック番号には、一番左が1、左から2番目が2、
左から3番目が3、...という具合に指定する。
選択したワークシートをWorkbook変数に代入するには

Set Workbook変数Application.Workbooks(ブック番号)

または

Set Workbook変数Application.Workbooks(ブック名)

と記述すればよい。尚、アクティブになっているブックWorkbook変数に代入するには、

Set Workbook変数 =   Application.ActiveWorkbook

と記述すればよい。また、実行しているマクロが含まれるブックをWorkbook変数に代入
するには、

Set Workbook変数 =  Application.ThisWorkbook

と記述する。 

以下のサンプルコードは、新規ブックBook1と、既存のブックD:\Temp\Book1.xlsx
D:\Book3.xlsxを同時に開いた場合の例である :

Sub SampleShowWorkbooks()
     Dim bk1 As Workbook

     Dim bk2 As Workbook
     Dim bk3 As Workbook
    Set bk1 = Application.Workbooks("Book1")
     Set bk2 = Application.Workbooks("Book1.xlsx")
     Set bk3 = Application.Workbooks("Book3.xlsx")
     Msgbox "Workbook1 : " & bk1.FullName & vbCrLf & _
                  "Workbook2 : " & bk2.FullName & vbCrLf & _
                  "Workbook3 : " & bk3.FullName

End Sub 

実行結果は下図の通り :

  
















因みに、ブックを複数開く場合、フルパスが異なっていても同じ名前のブックを開くことは
できないらしい。上記例の場合、一つ目のブックと二つ目のブックが同じBook1であるが
拡張子が異なる為、エラーにならず開くことができるらしい。

ワークシートの選択

本来、この項を最初に書くべきなのだが。。。

ワークシートを削除したり、コピーしたり、移動したりするには、対象となるワークシートの選択
を行う必要がある。ワークシートを選択するには下記の何れかのように記述する :

Workbookオブジェクト.Worksheets(シート番号)

または

Workbookオブジェクト.Worksheets(シート名)

シート番号には、一番左が1、左から2番目が2、左から3番目が3、...という具合に指定する。
選択したワークシートをWorksheet変数に代入するには

Set Worksheet変数Workbookオブジェクト.Worksheets(シート番号)

または

Set Worksheet変数Workbookオブジェクト.Worksheets(シート名)

と記述すればよい。因みにアクティブになっているワークシート(厳密には、アクティブなワーク
シート、または、グラフシート)Worksheet変数に代入するには、

Set Worksheet変数Workbookオブジェクト.Activesheet

または

Set Worksheet変数 =  Application.Activesheet

と記述する。 

2015年4月6日月曜日

ワークシートの移動

ワークシートを移動する場合はWorksheetオブジェクトのMoveメソッドを使用する。

ワークシートを、あるワークシートの手前(左側)に移動する場合はBefore引数を指定する :

Worksheetオブジェクト.Move Before

ワークシートを、あるワークシートの後ろ(右側)に移動する場合はAfter引数を指定する :

Worksheetオブジェクト.Move After

下記のサンプルコードは、アクティブなブックの1枚目のワークシートを3枚目の手前(左側)に、
5枚目のワークシートを8枚目の後ろ(右側)に移動するものである :

Sub SampleMoveWorksheet()
     Dim ws1 As Worksheet

     Dim ws5 As Worksheet
     Set
ws1 = Application.ActiveWorkbook.Worksheets(1)

     ws1.Move Before:=Application.ActiveWorkbook.Worksheet(3)
     Set ws5 = Application.ActiveWorkbook.Worksheets(5)
     ws5.Move After:=Application.ActiveWorkbook.Worksheet(8)
End Sub

ワークシートのコピー

ワークシートをコピーする場合はWorksheetオブジェクトのCopyメソッドを使用する。

ワークシートを、あるワークシートの手前(左側)にコピーする場合はBefore引数を指定する :

Worksheetオブジェクト.Copy Before

ワークシートを、あるワークシートの後ろ(右側)にコピーする場合はAfter引数を指定する :

Worksheetオブジェクト.Copy After

下記のサンプルコードは、アクティブなブックの1枚目のワークシートを3枚目の手前(左側)に、
2枚目のワークシートを5枚目の後ろ(右側)にコピーするものである :

Sub SampleCopyWorksheet()
     Dim ws1 As Worksheet

     Dim ws2 As Worksheet
     Set
ws1 = Application.ActiveWorkbook.Worksheets(1)

     ws1.Copy Before:=Application.ActiveWorkbook.Worksheet(3)
     Set ws2 = Application.ActiveWorkbook.Worksheets(2)
     ws2.Copy After:=Application.ActiveWorkbook.Worksheet(5)
End Sub

ワークシートの削除

ワークシートを削除する場合はWorksheetオブジェクトのDeleteメソッドを使用する。Delete
メソッドの書式は下記の通り :

Boolean型変数 = Worksheetオブジェクト.Delete

Deleteメソッドを実行してワークシートを削除する際に表示される確認用ダイアログで削除
ボタンをクリックした場合はTrueが、キャンセルをクリックした場合はFalseが、それぞれ
戻り値として返される。

アクティブなブックの左から2枚目のワークシートを削除するサンプルコードを以下に記す :

Sub SampleDeleteWorksheet()
     Dim ws As Worksheet
     Set
ws = Application.ActiveWorkbook.Worksheets(2)

     ws.Delete
End Sub

2015年4月5日日曜日

新規ワークシートを挿入する(2)

特定のワークシートの手前(左側)に新たにワークシートを挿入する場合は、Worksheets
オブジェクトのAddメソッドを使用する :

Set Worksheet変数 = Workbookオブジェクト.Worksheets.Add Before

アクティブになっているブックの左から2枚目のワークシートの左側に新規ワークシートを
挿入したい場合のサンプルコードを以下に記す :

Sub SampleCreateNewWorksheet3()
     Dim ws As Worksheet
     Set
ws = Application.ActiveWorkbook.Worksheets.Add _

                   (Before:=Application.ActiveWorkbook.Worksheets(2))
End Sub

特定のワークシートの手前(左側)に複数の新規ワークシートを挿入する場合の書式は下記
の通り :

Workbookオブジェクト.Worksheets.Add Before, Count

下記のサンプルコードは、左から3枚目のワークシートの左側に、新規ワークシートを
4枚追加するコードである :

Sub SampleCreateNewWorksheet4()
    
Application.ActiveWorkbook.Worksheets.Add _

                   Before:=Application.ActiveWorkbook.Worksheets(3), _
                   Count:=4
End Sub

特定のワークシートの後ろ(右側)に新たにワークシートを挿入する場合は、Worksheets
オブジェクトのAddメソッドでAfter引数を指定する :

Set Worksheet変数 = Workbookオブジェクト.Worksheets.Add After

アクティブになっているブックの左から2枚目のワークシートの右側に新規ワークシートを
挿入したい場合のサンプルコードを以下に記す :

Sub SampleCreateNewWorksheet5()
     Dim ws As Worksheet
     Set
ws = Application.ActiveWorkbook.Worksheets.Add _

                   (After:=Application.ActiveWorkbook.Worksheets(2))
End Sub

Before引数を指定する場合と同様、特定のワークシートの後ろ(右側)に複数の新規ワーク
シートを挿入する場合の書式は下記の通り :

Workbookオブジェクト.Worksheets.Add After, Count

左から3枚目のワークシートの右側に、新規ワークシートを4枚追加するコードを下記に記す :

Sub SampleCreateNewWorksheet6()
    
Application.ActiveWorkbook.Worksheets.Add _

                   After:=Application.ActiveWorkbook.Worksheets(3), _
                   Count:=4
End Sub

新規ワークシートを挿入する(1)

ワークシートを新たに挿入する場合は、WorksheetsオブジェクトのAddメソッドを使用する :

Set Worksheet変数 = Workbookオブジェクト.Worksheets.Add

引数を指定せずにAddメソッドを実行した場合、アクティブになっているワークシートの左側
に新たなワークシートが挿入される。

以下にActiveworkbookにワークシートを挿入するサンプルコードを記す :

Sub SampleCreateNewWorksheet1()
     Dim ws As Worksheet
     Set
ws = Application.ActiveWorkbook.Worksheets.Add

End Sub

ワークシートを一気に複数枚挿入する場合は、Count引数を指定したAddメソッドを実行
する :

Workbook変数.Worksheets.Add Count

Count引数を指定しない場合は、Count引数に「1」を指定した場合と同じ結果となる。
尚、Count引数に1より大きい値を指定した場合の戻り値としてどのような値が返されるのか
は、色々試してみたが、よくわからなかった。

以下にCount引数を指定したサンプルコードを記す :

Sub SampleCreateNewWorksheet2()
    
Application.ActiveWorkbook.Worksheets.Add Count:=3

End Sub

上記コードの場合は、3枚のワークシートがアクティブになっているワークシートの左側に
挿入される。

2015年4月3日金曜日

ブックのファイル名とパスを取得する

ブックのファイル名を取得するには、WorkbookオブジェクトのNameプロパティを用いる :

String型変数 = Workbookオブジェクト.Name

ブックが格納されているディレクトリを取得するにはWorkbookオブジェクトのPathプロパティ
を用いる :

String型変数 = Workbookオブジェクト.Path
 
また、フルパスを取得するにはFullnameプロパティを用いる :

String型変数 = Workbookオブジェクト.Fullname

以下に上記プロパティを使用したサンプルコードを記す :

Sub SampleGetWorkbookPathAnd Name()
     Dim bk As Workbook
     Set
bk = Application.Workbooks.Open("D:\Temp\SampleWorkbook.xlsm")

     MsgBox "Workbookの名前 : " & bk.Name & vbCrLf & _
           "Workbookが格納されているディレクトリ : " & bk.Path & vbCrLf & _
           "Workbookのフルパス : " & bk.FullName 

End Sub


上記コードの実行結果は下記の通り :



2015年4月1日水曜日

マクロを含むブックか否かを判定する

Excel 2007以降、ブックがマクロを含まない場合は拡張子.xlsx、マクロを含む場合は
.xlsm、という具合に、マクロの有無によって拡張子を変えなければならなくなった。
その為、前述の(Workbookオブジェクトの)CloseメソッドやSaveAsメソッドで、マクロ
があるにも関わらず、.xlsx形式で保存しようとすると下記エラーが表示されてしまう :













このようなエラーを防ぐ為に、WorkbookオブジェクトのHasVBProjectプロパティを
用いてマクロの有無を判定する必要がある。HasVBProjectプロパティの書式は下記
の通り :

Boolean型変数 = Workbookオブジェクト.HasVBProject

HasVBProjectプロパティを用いて判定を行うコードのサンプルを以下に記す :

Sub SampleWorkbookHasVBProject()
     Dim bk As Workbook
     Set
bk = Application.Workbooks.Open("D:\Sample.xlsm")

     '
     ' <<ブックを更新する処理をここに記述>>
     '
     If bk.HasVBProject = True Then
         bk.SaveAs Filename:="D:\Sample2.xlsm"
     Else

         bk.SaveAs Filename:="D:\Sample2.xlsx"
     End If 
End Sub