As Range, As Worksheetなどデータ型を添えて宣言すればプロパティ名を覚える必要がぐっと減るという話

http://officetanaka.net/excel/vba/variable/03.htm

``` vb
Dim 変数 As 変数型
```
初心者のうちはデータ型は覚えなくて良いと思っていましたが、最近少し考えが変わってきました。

**オブジェクトは宣言すべきだと。**

### 型宣言をするメリット
`As Worksheet`等、変数型つきで宣言した変数`ws`などの後に`.`(ドット)を打つと
**プロパティの候補リストが表示されます。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/2ae39f80-29f3-7d0e-8000-2eb803170d69.png)

`.`(ドット)は助詞の**「の」**です。
上図の例だと

- `wb`というブック**の**`ws`というシートを巡回する
- `ws`というシート**の**`名前`というプロパティ

という意味になります。

型宣言なにそれおいしいの？という方に紹介したいメリットはまずはこの一言に尽きます。

`Set`の際や引数に入れ込む際に型違いエラーが検出できるなど他にもメリットはありますが、書く上で最初に得られる最大のメリットはこれです。


体系的にまとめるべきとも思いましたが、

Workbook
　└ Worksheet
　　　└ Range

突き詰めるとシンプルにこの構図に集約されてしまうのと、体系的にまとまった記事は他にもっといい記事があるので、端的によく使う事例を紹介しつつ、体感できるような列挙方式でまとめてみました。

### 例１：シート名変更とか複数シートのセル一括編集

``` vb
Sub WbWs練習1_シート名変更とか複数シートのセル一括編集()
  Dim wb As Workbook
  Dim ws As Worksheet
  
  Set wb = ActiveWorkbook
  
  Dim k
  k = 1
  For Each ws In wb.Sheets
    With ws
      .Name = "Sh" & k
      .Cells(1, 1) = k
      k = k + 1
    End With
  Next
End Sub
```

早速ですが、上のコード書くにあたっては、`wb`や`ws`のあとに`.`を打ってプロパティ名の頭文字を数文字打っていくとこんな感じで候補が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/55017105-450b-f243-cae4-9711d2b4d8cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/2ae39f80-29f3-7d0e-8000-2eb803170d69.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/2ccc3fc7-0383-86ef-03cd-390ee78338e3.png)
候補の中からこれだというものをクリックで選ぶもよし、上下キーで選んで`Tab`キーで決定するもよしです。



### 例２：Range練習1_範囲指定でよくやるやつ

セル範囲を指定するとき、僕がよくやるのが左上と右下の2セルを指定して、それを`Range`につっこむというやり方です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/748a53b4-377a-f2b1-548a-d1a6f2d43457.png)

``` vb
Option Explicit

Type Rng_
  左上 As Range
  右下 As Range
  Area As Range
End Type
Dim Rng As Rng_

Sub Rng練習1_範囲指定でよくやるやつ()
  With Rng 
    Set .左上 = Cells(1, 2)
    Set .右下 = Cells(3, 4)
    Set .Area = Range(.左上, .右下)
    
    .左上.Interior.Color = vbYellow
    .右下.Interior.Color = vbGreen
        
    Dim k: k = 1
    Dim r As Range
    For Each r In .Area
      r.Value = k
      k = k + 1
    Next
  End With
  
End Sub
```

この例には他にも楽できる要素をいくつか詰め込んだので併せて紹介します。

#### 色も覚えないで`vb`なんちゃらで出せます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/e24f1632-7ab8-ebe6-e2d7-b26104ad61ee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/6a784700-ac7f-2806-b8f1-8f35eba28afd.png)



#### `Type`で構造化した子オブジェクトも候補リストで呼べます
``` vb
Type Rng_
  左上 As Range
  右下 As Range
  Area As Range
End Type
Dim Rng As Rng_
```
こうしてまとめておくと「Rng」の中に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/95c1bff6-22f2-2b1a-1610-a19d3dc9039a.png)
というグループが作れて可読性や書きやすさが上がります。

#### `With`構文内はどこでも`.`で候補リストが出せます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/ca9c7d19-dbb2-5c58-0e11-4f7fb04e4848.png)




### 例３：Range練習2_起点セルから相対距離とか範囲拡張とか

型宣言から少し脱線しますがこれもよく使うのですおまけで紹介。

例えば表の左上に起点を置いておき、

- `.Resize(行の幅, 列の幅)`
- `.Offset(行の相対距離, 列の相対距離)`

で拡張や移動が簡単に書けます。

``` vb
Sub Rng練習2_起点セルから相対距離とか範囲拡張とか()
  Dim Cel起点 As Range
  Dim CelOffset As Range
  Dim Area As Range
  
  Set Cel起点 = Cells(1, 1)
  With Cel起点
    .Value = 1
    
    '範囲拡張
    Set Area = .Resize(2, 3)
      With Area
        .ShrinkToFit = True
        .Value = 12345
      End With
    
    '相対距離
    Set CelOffset = .Offset(4, 5)
      With CelOffset
        .Interior.Color = vbYellow
        .Value = 54321
      End With
  End With
  
  
End Sub
```


オブジェクトではありませんが候補リストを使える例がまだまだあるのでまたまた列挙で失礼します。


### VBA関数は何もないところで`Ctrl`+`Space`を押すと候補が出るぞ

`IsEmpty`とか`IsMissing`とか、`Is`なんだっけと思い出せなくなる時がありますが、接頭語さえ類推すればVBE上で辞書が引けてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/156ebb0e-e2d8-bafa-903c-376c5f3d76b2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/2975ed27-5a18-2229-fb45-1a3cebe6998e.png)



### `As WorksheetFunction`もいいぞ
これは一度`Set`する必要がありますがコードが短く見えて若干すっきりします。

途中まで打って`Ctrl`+`Space`で予測変換させても十分といえば十分ですが、好き好きです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/ce371423-6a54-126b-b0af-17e73e3a0105.png)


``` vb
Sub WSFもいいぞ()
  Dim WSF As WorksheetFunction
  Set WSF = WorksheetFunction
  
  With WSF
    Debug.Print .RoundDown("123.456", 1)
    Debug.Print .RoundUp("123.456", 2)
    
    Dim Area As Range
    Set Area = Selection.Cells
    Debug.Print .Sum(Area)
  End With
End Sub
```

### 同Project内の別モジュールも候補リストにできるぞ
モジュール名を指定すれば`Private`でない`Sub`や`Function`が候補リストに出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/c8760f4b-d18b-53e0-af64-13bab2f6da67.png)

モジュール名も候補リストに出しやすいように`bas`といったお決まりの接頭語をつけておくといいかなと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/2ff9fa06-8a8a-0146-65c9-1f0e39c4c37b.png)


``` vb
Sub 同Project内の別モジュールも候補リストにできるぞ()
  Debug.Print bas汎用関数.testFunction("aaa", "bbb")
End Sub

```

``` vb:bas汎用関数
Option Explicit

Function testFunction(値1, 値2) As String
  testFunction = 値1 & 値2
End Function
```


以上です。
まとめるの難しい！