回答編集履歴
4
説明の改善
answer
CHANGED
@@ -4,20 +4,21 @@
|
|
4
4
|
|
5
5
|
[Office TANAKA - Excel VBA Tips(オートフィルタ(結果をコピーする))](http://officetanaka.net/excel/vba/tips/tips155c.htm)
|
6
6
|
|
7
|
+
---
|
7
8
|
配列の要素数を動的に増やすには、`ReDim Preserve`を使いますが、
|
8
9
|
2次元配列では増やせるのは最後の次元のみという制限があります。
|
9
10
|
`ReDim Preserve buf2(r, c)` だと増やせるのは c のみ。
|
10
11
|
質問の要件では増やしたいのは、r の方ですよね。
|
11
12
|
|
12
|
-
方法1
|
13
|
+
**方法1**
|
13
|
-
`WorksheetFunction.Transpose`(行列変換関数)を使うと一次元と二次元を入れ替えることでできます
|
14
|
+
`WorksheetFunction.Transpose`(行列変換関数)を使うと一次元と二次元を入れ替えることでできます。まず、r, c を入れ替えて、`ReDim Preserve buf2(c, r)` でrを増やせることができます。
|
14
15
|
シートに出力する前に`WorksheetFunction.Transpose`で入れ替えて`buf2(r, c)`にしてから出力します。
|
15
16
|
|
16
|
-
ただ、`WorksheetFunction.Transpose`には処理できる要素数の制限があるらしいです。
|
17
|
+
ただ、`WorksheetFunction.Transpose`には処理できる要素数の制限があるらしいです。(5000件ぐらいなら大丈夫だと思いますが)
|
17
18
|
|
18
19
|
[動的2次元配列の次元を入れ替えてシートへ出力(Transpose)|VBA技術解説](https://excel-ubara.com/excelvba4/EXCEL258.html)
|
19
20
|
|
20
|
-
方法2
|
21
|
+
**方法2**
|
21
22
|
配列のサイズを想定できる最大サイズで確保しておく。
|
22
23
|
そこに条件にあう行を順に放り込んでいく。
|
23
24
|
シートに出力するときには、
|
@@ -37,7 +38,7 @@
|
|
37
38
|
Sheets("Outpot").Range("A1").Resize(Cnt, 12).Value = buf2
|
38
39
|
```
|
39
40
|
|
40
|
-
方法3
|
41
|
+
**方法3**
|
41
42
|
|
42
43
|
方法2と同じ考え方ですか、配列は一つだけにして、
|
43
44
|
配列内で、条件にあう行を順に前に移動させていく。
|
@@ -63,4 +64,5 @@
|
|
63
64
|
Next n
|
64
65
|
Sheets("output").Range("a2").Resize(cnt, 12).Value = buf
|
65
66
|
End Sub
|
66
|
-
```
|
67
|
+
```
|
68
|
+
この方法だとメモリを無駄に使うこともなく、シンプルかつ高速です。
|
3
書式改善
answer
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
高速化が目的なら、VBAでオートフィルタを使用するのが、たぶん一番高速だと思います。
|
2
2
|
|
3
|
-
[Office TANAKA - Excel VBA Tips
|
3
|
+
[Office TANAKA - Excel VBA Tips(オートフィルタ(書き方の基本)](http://officetanaka.net/excel/vba/tips/tips155.htm)
|
4
4
|
|
5
|
-
[Office TANAKA - Excel VBA Tips
|
5
|
+
[Office TANAKA - Excel VBA Tips(オートフィルタ(結果をコピーする))](http://officetanaka.net/excel/vba/tips/tips155c.htm)
|
6
6
|
|
7
7
|
配列の要素数を動的に増やすには、`ReDim Preserve`を使いますが、
|
8
8
|
2次元配列では増やせるのは最後の次元のみという制限があります。
|
2
誤字修正
answer
CHANGED
@@ -10,8 +10,8 @@
|
|
10
10
|
質問の要件では増やしたいのは、r の方ですよね。
|
11
11
|
|
12
12
|
方法1
|
13
|
-
`WorksheetFunction.Transpose`(
|
13
|
+
`WorksheetFunction.Transpose`(行列変換関数)を使うと一次元と二次元を入れ替えることでできますので、r, c を入れ替えて、`ReDim Preserve buf2(c, r)` でrを増やせることができます。
|
14
|
-
シートに出力する前に
|
14
|
+
シートに出力する前に`WorksheetFunction.Transpose`で入れ替えて`buf2(r, c)`にしてから出力します。
|
15
15
|
|
16
16
|
ただ、`WorksheetFunction.Transpose`には処理できる要素数の制限があるらしいです。
|
17
17
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
配列のサイズを想定できる最大サイズで確保しておく。
|
22
22
|
そこに条件にあう行を順に放り込んでいく。
|
23
23
|
シートに出力するときには、
|
24
|
-
セル範囲のサイズを条件に合った件数のサイズに指定して代入すれば、そのサイズ分だけ出力できる。
|
24
|
+
出力先のセル範囲のサイズを条件に合った件数のサイズに指定して代入すれば、そのサイズ分だけ出力できる。
|
25
25
|
|
26
26
|
こちらの方がシンプルだし、高速だと思います。
|
27
27
|
ただ、余分にメモリを使うことになりますが、現在のPCの標準的なスペックなら気にする必要はないでしょう。
|
1
コード追記
answer
CHANGED
@@ -41,4 +41,26 @@
|
|
41
41
|
|
42
42
|
方法2と同じ考え方ですか、配列は一つだけにして、
|
43
43
|
配列内で、条件にあう行を順に前に移動させていく。
|
44
|
-
出力は方法2と同じ方法で。
|
44
|
+
出力は方法2と同じ方法で。
|
45
|
+
|
46
|
+
方法3のコード例
|
47
|
+
```vba
|
48
|
+
Sub 配列化して項目で抽出テスト()
|
49
|
+
Dim i As Long, n As Long
|
50
|
+
Dim buf() As Variant
|
51
|
+
Dim cnt As Long: cnt = 0
|
52
|
+
|
53
|
+
buf() = Sheets("data").Range("a2:l100").Value
|
54
|
+
|
55
|
+
'条件にあったら前に移動
|
56
|
+
For n = 1 To UBound(buf, 1)
|
57
|
+
If buf(n, 12) = "〇" Then
|
58
|
+
cnt = cnt + 1
|
59
|
+
For i = 1 To 12
|
60
|
+
buf(cnt, i) = buf(n, i)
|
61
|
+
Next i
|
62
|
+
End If
|
63
|
+
Next n
|
64
|
+
Sheets("output").Range("a2").Resize(cnt, 12).Value = buf
|
65
|
+
End Sub
|
66
|
+
```
|