【VBA】小ネタ

# 小ネタ
## プロシージャを書く場所
シート内で完結するものはシートの中に書く。
シートをまたぐ場合などはモジュールに書く。

## 定数の書き方

```vbnet
Const HOGE As Integer = 1000
```

## 配列番号の始まりを1にする
```vbnet
Option Base 1
```

## 参照渡しと値渡し
[【参考】](http://www.k1simplify.com/vba/tipsleaf/leaf340.html)
プロシージャへの変数の渡し方は二通りある。

### 参照渡し（ByRef）
デフォルトはこっち。
変数を渡されたプロシージャ側で引数の値を変更すると、呼び出し元のプロシージャーの変数の値も変わる。

### 値渡し（ByVal）
プロシージャに値を提供するだけで、ByRef のように呼び出し元のプロシージャーに影響することはない。

## 改行コードはvbLf
[【参考】](http://www.tipsfound.com/vba/04001)

```vbnet
Range("A1").Value = "一行目" & vbLf & "二行目"
```
![alt](http://c.tipsfound.com/vba/04001/1.png)

## オブジェクト変数に代入するときはSetを使う
[【参考】](http://officetanaka.net/excel/vba/variable/04.htm)

### 一般的な変数の場合
```vbnet
Sub Sample13()
    Dim tmp As String
    tmp = "tanaka"
    MsgBox tmp
End Sub
```

### オブジェクト変数の場合
```vbnet
Sub Sample14()
    Dim ws As Worksheet
    Set ws = Sheets("Sheet1")
    MsgBox ws.Name
End Sub
```

## With ~ End Withステートメント
[【参考】](http://excelvba.pc-users.net/fol6/6_5.html)

```vbnet
With オブジェクト名
     処理１
     処理２
     処理３
End With
```

同じオブジェクトに対して複数の処理を実行する。

## テキストファイルから読み込む
**[※CSVファイルはテキストファイルとして開く！](http://www.moug.net/tech/exvba/0060086.html)**

[【参考】](http://officetanaka.net/excel/vba/file/file08.htm)

```vbnet
Sub Sample2()
    Dim buf As String
    Open "C:\Sample\Data.txt" For Input As #1
        Do 読み取りポイントが終端に達するまで
            Line Input #1, buf
            セル = buf
        Loop
    Close #1
End Sub
```

### 簡単な流れ
1. ファイルを開く
2. ファイルの読み書きをする
3. ファイルを閉じる

### ファイルを開く
```vbnet
Open ファイル名 For 開き方 As #ファイル番号
```
**開き方**は次のとおり。

| キーワード | モード | 処理 |
|:-:|:-:|:-:|
| Input | 入力 | 読み込み |
| OutPut | 出力 | 書き込み |
| Append | 追加 |  書き込み |

複数ファイルを開くことはほとんどないので、**ファイル番号**は「#1」でOK。

### ファイルから読み込む
テキストファイルから一行ずつ読み込むには

```vbnet
Line Input #番号, 変数
```
を用いる。
Line Inputステートメントは、1行分のデータを読み込むと、読み込みポイントを次の行に移す。
つまり、Line Inputステートメントを繰り返すことで、テキストファイルの中を、1行ずつ、すべて読み込むことができる。

### ファイルを閉じる
```vbnet
Close #1    ''1番のファイルを閉じる
Close       ''現在開いているすべてのファイルを閉じる
```

### アクティブシート以外のシートのセルを参照する
```vbnet
// = 取得したい値
WorksheetFunction.Index(Range("Sheet1!A:B"), WorksheetFunction.Match(検索値, Range("Sheet1!A:A"), 0), 2)
```

sheet1↓

| A | B |
|:-:|:-:|
| ... | ... |
| 検索値 | 取得したい値 |
| ... | ... |

# 配列
[【参考】](http://www.atmarkit.co.jp/ait/articles/1504/01/news012.html)

## 配列のインデックスの最小値/最大値を取得する
`arrayname`は配列の名前。

```vbnet:例
For i = LBound(名前) To UBound(名前)
  Cells(i + 2, 2) = 名前(i)
Next
```

### 最小値
```vbnet
LBound(arrayname,dimension)
```

### 最大値
```vbnet
UBound(arrayname,dimension)
```

## 文字列から配列を生成する
```vbnet
Split(expression,delimiter)
```
- expression
    - 配列にしたい文字列。
- delimiter
    - 省略可。expressionに含まれる区切り文字。

## For Each～Nextで指定したフォルダ内のファイルを全てを参照する
[【参考リンク】](http://tonari-it.com/for-each-next/)

```vbnet
'folderFullPathは指定したフォルダのフルパス
'例)　USersフォルダの場合、C:\Users
Sub Hoge(folderFullPath As String)
    Dim objFSO As Object
    Dim objFile As Object
    Dim filePath As String
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
 
    filePath = folderFullPath & "\"
    
    For Each objFile In objFSO.getfolder(filePath).Files
        'ファイルに対する処理を記述
    Next objFile
End Sub
```


## csvファイルのデータをシートにコピーする

```vbnet
Function csvToSheet(csvPath As String, objSheet As Worksheet) As Worksheet
    With Workbooks.Open(fileName:=csvPath)
        With .Worksheets(1)
            .Cells.Copy objSheet.Cells
        End With
        
        .Close SaveChanges:=False
    End With
    
    Set csvToSheet = objSheet
End Function
```