teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

サンプルコードの追加

2017/01/17 00:55

投稿

rrryutaro
rrryutaro

スコア146

answer CHANGED
@@ -31,18 +31,67 @@
31
31
 
32
32
  配列が`0,1`の時と`0,1,2`の時とがあることが分かっていますので、配列の上限を返す`UBound`を使うことで判断できます。
33
33
  `LBound`は下限を返す関数です。
34
+ `Bound`は境界。
35
+ `LBound`の`L`はたぶんLowerで下を示すのでLower Boundで下限(下界?)。
36
+ `UBound`の`U`はたぶんUpperで上を示すのでUpper Boundで上限(上界?)。
37
+ という意味合いになるかと思います。
34
38
 
39
+ #追記:ついでなので、こんな書き方もありますという例です。
35
- 例えば次のように、配列のインデックスを指定できます。
40
+ まず、Excelのシートは次のようにしています。
41
+ ![イメージ説明](e1ad2c5a6b99b537b9d980825e2f56ef.png)
42
+
43
+ コードは次の通りです。
36
44
  ```VBScript
37
45
  Sub Hoge()
46
+ On Error GoTo Err
47
+ Dim targetCells As Range
48
+ Dim readCell As Range
49
+ Dim writeCell As Range
38
- Dim v(2 To 4) As Variant
50
+ Dim readArray As Variant
51
+ Dim writeArray As Variant
52
+ Dim i As Long, j As Long
53
+
54
+ Set targetCells = Range("F2", "F" & ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Row)
55
+ Set writeCell = Range("T2")
56
+
57
+ Application.ScreenUpdating = False
58
+ For Each readCell In targetCells
59
+ ReDim writeArray(2)
39
- Debug.Print (LBound(v)) //イミディエイトウィンドウに 2 が出力される
60
+ readArray = Split(readCell, "x")
61
+ j = 2
62
+ For i = 0 To UBound(readArray)
63
+ writeArray(j) = readArray(i)
64
+ j = j - 1
65
+ Next
40
- Debug.Print (UBound(v)) // イミディエイトウィンドウに 4 が出力される
66
+ Range(writeCell, writeCell.Offset(, 2)) = writeArray
67
+ Set writeCell = writeCell.Offset(1)
68
+ Next
69
+ Err:
70
+ Application.ScreenUpdating = True
41
71
  End Sub
42
72
  ```
73
+ 実行結果は次のようになります。
43
- このように、ンデックスの範囲を指定した場合、インデックスの開始を0などで始めようとするとエラとなるため、`LBound`、`UBound`を使います。
74
+ ![ジ説明](28de05754637acae36169e012bf8e136.png)
44
75
 
76
+
45
- `Bound`は境界
77
+ 逆にわかりづらくて混乱させるかもしれませんが、いくつか知って欲しいポイントがありますが、そんな方法もあるんだ程度に思ってください
78
+
46
- `LBound`の`L`はたぶんLowerで下を示のでLower Boundで下限(下界?)
79
+ まず、セル範囲を知る方法は色々とありますが、`UsedRange`があります。
47
- `UBound`の`U`はたぶんUpperで上のでUpper Boundで上限(上界?)
80
+ 例では、`UsedRange`から、使われている最後の行の行番号取得しています。
81
+ ただし、この方法は`F`列以外の列で`F`列以上のデータがあると正しい範囲を得られませんので、元々の方法である、`.End(xlUp)`で最後に入力のあるセルを得る方がよいかもしれません。
82
+
83
+ `ScreenUpdating`は、VBAを使い出した際に、大量データで処理が遅い時にかならずといっていいほど使う手段です。
84
+ `ScreenUpdating`が`False`だと画面の描画を一切更新しなくなります。`True`にすることで、通常通り更新されるようになります。つまり、セルへの書き込みなどを描画しないので速くなりますが、`True`にし忘れると、何も反応が無くなったようになり、戻し方が分からなければExcelを終了せざる終えなくなりますので、注意が必要です。
85
+
86
+ このため、`On Error Goto Err`として、エラーが発生した場合、`Err:`ラベルへジャンプするようにして、必ず`ScreenUpdating`をTrueにするようにしています。
87
+
88
+ 後は配列は`0 to 2`固定と考えて、書き込み用の配列を作成し、後ろから値を入れて、セル範囲に配列で書き込んでいます。
89
+
90
+ セルの操作は相対参照するようにしています。まず最初に`Set writeCell = Range("T2")`として書き込みするセルの開始点を設定します。
91
+
92
+ 値を貼り付ける時は、T~Vとなるように、`.Offset(, 2)`として、自身から2列離れたセルを参照させています。
48
- という意味合いなるかいます。
93
+ 最後、`.Offset(1)`してひとつしたのセルへと設定しています。
94
+
95
+ この辺のセル操作はそれぞれに好みのやり方もあるかと思いますが、Excel VBAでもっとも重要といってもよいくらい`Range`オブジェクトは重要だと自分は考えています。
96
+
97
+ 以上