
該当の行のみを2次元配列に入れる方法について教えて下さい
最初は、フィルターで絞って、コピー→別シートに貼り付け、2次元配列にいれていましたが
ややこしいことがあり、同じシートのみを使用することになりました。
また、そのシートのセルの削除とかも出来ない状態です
めちゃくちゃデータ数が多いので、出来ればフィルーター→どこかに貼り付けはしたくないのですが。。。。
一様別の2次元配列に格納も考えたのですが、要素数の上限を宣言する必要があるらしく
この場合は焼肉の数は把握できますが、実際に使用するデータはその時によって、焼肉の数が変わるので、上限数を宣言するのは出来なくて出来ません
Redimで上限数を何回も変えるのも気持ち悪いし・・・
何かいい方法はないでしょうか?
よろしくお願いします。
Option Explicit
Sub input_yakiniku()
Dim i As Long
Dim yakiniku_rows As Long
Dim yakiniku_col As Long
Dim all_hairetsu As Variant
Dim yakiniku_haretsu As Variant
Dim maxrow As Long
Dim maxcol As Long
Cells(1, 1) = "名前"
Cells(1, 2) = "金額"
Cells(1, 3) = "ランク"
For i = 2 To 10000
If i Mod 2 = 0 Then
_Cells(i, 1) = "焼肉"
_If i Mod 3 = 0 Then
__Cells(i, 2) = 500
__Cells(i, 3) = "A"
_ElseIf i Mod 4 = 0 Then
__Cells(i, 2) = 600
__Cells(i, 3) = "B"
_Else
Cells(i, 2) = 1000
Cells(i, 3) = "C"
_End If
Else
_Cells(i, 1) = "すき焼き"
_If i Mod 3 = 0 Then
__Cells(i, 2) = 200
__Cells(i, 3) = "D"
_Else
__Cells(i, 2) = 300
__Cells(i, 3) = "F"
_End If
End If
Next
maxrow = Cells(Rows.Count, 1).End(xlUp).Row
maxcol = Cells(1, Columns.Count).End(xlToLeft).Column
all_hairetsu = Range(Cells(1, 1), Cells(maxrow, maxcol)).Value
yakiniku_rows = 0
For i = 1 To maxrow
_If Cells(i, 1) = "焼肉" Then
__For yakiniku_col = 1 To 3
___Cells(yakiniku_rows, yakiniku_col) = all_hairetsu(i, yakiniku_col)
__Next
_End If
Next
End Sub
No.4ベストアンサー
- 回答日時:
#1です
>For i = 2 To 10000 はデモデータを作る為のものと解釈しています。
処理速度の問題だったのでしょうか?
配列でソートする方法も色々とありますが、
>めちゃくちゃデータ数が多いので、出来ればフィルーター→どこかに貼り付けはしたくないのですが。。。。
ちょっとなさりたい事が分からないのですが、
したくないExcelの機能のソートとフィルタを使ってコピーする方法です
元データは初めに配列に入れて最後に戻しています。ソートやフィルターの結果は元に戻ります。
ループは使わずに済みます。
Sub Extraction_Data()
Dim allhairetsu As Variant
Dim yakiniku_Ary As Variant
Dim ws As Worksheet
Set ws = ActiveSheet
allhairetsu = Range("A1").CurrentRegion
Application.ScreenUpdating = False
With ws.Sort
With .SortFields
.Clear
.Add Key:=ws.Range("A1"), Order:=xlAscending
End With
.SetRange ws.Range("A1").CurrentRegion
.Header = xlYes
.Apply
End With
Range("A1").AutoFilter 1, "焼肉"
With Range("A1").CurrentRegion.Offset(1, 0)
' yakiniku_Ary = .Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
.Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Copy Range("E2")
End With
ws.Range("A1").CurrentRegion.AutoFilter
Cells(1, 1).Resize(UBound(allhairetsu, 1), UBound(allhairetsu, 2)) = allhairetsu
' Cells(2, 5).Resize(UBound(yakiniku_Ary, 1), UBound(yakiniku_Ary, 2)) = yakiniku_Ary
Application.ScreenUpdating = True
End Sub
コピーならソートする必要はないように思いますが、配列を作る事を
想定して連続データにしています。
書式などをコピーしたくない場合はコピー部分をコメントにして、
現在コメントにしている部分(配列)で実行してください。
>2次元配列に入れる方法について教えて下さい
デモデータ作成部分も配列で行うと処理速度は速くなりますね
Sub Make_DemData()
Dim i As Long, n As Long
Dim DemoAry(9999, 2)
DemoAry(0, 0) = "名前"
DemoAry(0, 1) = "金額"
DemoAry(0, 2) = "ランク"
For i = 1 To 9999
If i Mod 2 = 0 Then
DemoAry(i, 0) = "焼肉"
If i Mod 3 = 0 Then
DemoAry(i, 1) = 500
DemoAry(i, 2) = "A"
ElseIf i Mod 4 = 0 Then
DemoAry(i, 1) = 600
DemoAry(i, 2) = "B"
Else
DemoAry(i, 1) = 1000
DemoAry(i, 2) = "C"
End If
Else
DemoAry(i, 0) = "すき焼き"
If i Mod 3 = 0 Then
DemoAry(i, 1) = 200
DemoAry(i, 2) = "D"
Else
DemoAry(i, 1) = 300
DemoAry(i, 2) = "F"
End If
End If
Next
Application.ScreenUpdating = False
Cells(1, 1).Resize(UBound(DemoAry, 1) + 1, UBound(DemoAry, 2) + 1) = DemoAry
Application.ScreenUpdating = True
End Sub
No.5
- 回答日時:
No3です
お礼を読みました。
>シート操作だと、かなり時間がかかるので、出来れば配列でやりたいのが本音ですね。
というのに、はなはだ疑問を感じました。(私の予想とは真逆なので)
シート上のデータをソートしても良いものと仮定して(データ順を保存しなくても良いものと仮定)
ご提示の10000行のデータで試してみました。
Time関数で測定してみると、私の環境では、
・ご提示のデータを作成するのに約50~60秒程度
・シートのソートに0秒
という結果です。
どうやらTime関数では測定できないので、Windows APIでミリ秒単位で測定してみると、ソートには
・0.17~0.18秒
程度を要しているようです。
これを遅いと考えるのか速いと考えるのかは、質問者様の判断によりますけれど・・・
少なくとも、VBAで処理するのと同等以上ではあるものと想像します。
>不要なすき焼きのデータも含むことになるのと
xlDescendingでソートして、「すき焼き」の最初の行をFINDで探せば、「焼肉」の範囲がわかりますので、変数配列に値を代入するのが目的の場合でも一発で処理は終わります。
仮に「すき焼き」といワードが不明の場合でも、目的とする「焼肉」の最初の行と最後の行を探せば良いので、ほぼ同様の処理で終わるでしょう。
>配列でソートが出来ればいいのですが
こちらは試していませんけれど、多分、シートのソートの方が速いのではないかと想像します。
(理由としては、VBAそのものが遅いので・・・)
言葉足らずで失礼しました。
確かにこれだけの処理では、ソートの方が早いですが
焼肉のデータでもっといろんなことをするので・・・配列じゃないと処理時間がかかるのです
また、findで最初の行を探すのも参考になります。
No.3
- 回答日時:
こんばんは
横からで、失礼いたします。
ざっとしかみていないので、勘違いかも知れませんけれど・・・
データを上書きしているようなのと、
>1万ループして、さらに3回るーぷですが、~~
とあるので、最終的にはA列の内容別にまとめて並べ替えたいのかと解釈しました。
もしそうであるなら、シート上でそのままソートしたほうが簡単なのではないでしょうか?
単純な昇順・降順などではなく順序を指定順にしたいのであれば、ひと手間増えますけれど「CustomOrder」を利用すれば好きな順にすることも可能なはずです。
実行時間を比較してはいませんけれど、エクセルの内部計算で行ってくれるので、インタプリタ型のVBAでいろいろ処理をするよりも速いのではないかと想像します。
あるいは、シートのデータはそのまま残しておきたくて、あくまでも変数配列上にデータが欲しいというのであるなら、all_hairetsuを直接ソートしてしまうという方法もあるかもしれません。
VBAには配列のソートメソッドがないので(シートのソートはありますけれど)、VBAで記述する必要が出てきますが…
こちらの場合は、既回答との時間的な優劣は不明です。
(採用するソートのロジックにもよると思いますが、3回やるのならソートの方が速いのではないかと)
※ 私の勘違いでしたなら、無視してください。
ご回答ありがとうございます。
ソートだと、不要なすき焼きのデータも含むことになるのと
シート操作だと、かなり時間がかかるので、出来れば配列でやりたいのが本音ですね。
そうですね・・・配列でソートが出来ればいいのですが
No.2
- 回答日時:
#1です
試してみたら、少し(だいぶ)違いました
訂正します
#1の方法
正
Dim n As Long, j As Long
Dim TestAry()
For i = 1 To UBound(all_hairetsu, 1)
If all_hairetsu(i, 1) = "焼肉" Then
For j = 0 To UBound(all_hairetsu, 2) - 1
ReDim Preserve TestAry(UBound(all_hairetsu, 2) - 1, n)
TestAry(j, n) = all_hairetsu(i, j + 1)
Next
n = n + 1
End If
Next
確認してください
>素早くいけました。
セルに書き出すのを一度に行っている為と思われます。
わざわざすいません、有難うございます。
はい、こちらの希望していた形になりました。
1万ループして、さらに3回るーぷですが、こちらもスムーズにできて良かったです。
No.1
- 回答日時:
こんばんは
>この質問をまとめると、焼肉(名前、金額、ランク)専用の配列を作る
For i = 1 To maxrow
If Cells(i, 1) = "焼肉" Then
For yakiniku_col = 1 To 3
Cells(yakiniku_rows, yakiniku_col) = all_hairetsu(i, yakiniku_col)
Next
End If
Next
個々の部分と解釈すると
Dim n As Long, j As Long
Dim TestAry()
For i = 1 To UBound(all_hairetsu, 1)
If all_hairetsu(i, 1) = "焼肉" Then
For j = 1 To UBound(all_hairetsu, 2)
ReDim Preserve TestAry(UBound(all_hairetsu, 2), n)
TestAry(j, n) = all_hairetsu(i, j)
Next
n = n + 1
End If
Next
Cells(2, 5).Resize(UBound(TestAry, 2) + 1, UBound(TestAry, 1) + 1) = Application.Transpose(TestAry)
こんな感じかな
E2セルより行方向に出力しています
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【VBA】特定のワードが入っている行全体を塗りつぶしたい 4 2022/04/20 15:22
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) VBA 請求書自動作成 3 2022/04/24 01:58
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Visual Basic(VBA) vba 重複データ合算 5 2023/07/05 18:55
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
System.IO.Directory.GetFiles...
-
C# DataGridView のヘッダーセ...
-
C言語・要素除去
-
C# DataTableの行をソートしてD...
-
VB.NETでファイル名順にファイ...
-
GridViewで列のソートを無効に...
-
データ数が多い場合のソート
-
ソートについて(その他質問あ...
-
DirectoryInfo型配列ソート(C#)
-
excel VBA の条件をつけての列...
-
(VBA) Dir 関数で取得するファ...
-
Double型ソート方法
-
int num[10]という配列に、適当...
-
VB6 任意の順番でのソート
-
VBA基本構文の作り方 2列の...
-
Excel VBA テキストボックス内...
-
リスト構造のソートで悩んでま...
-
VB6でデータを昇順に並べ替える
-
C言語でのソート方法
-
構造体配列の並べ替え
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
System.IO.Directory.GetFiles...
-
C# DataGridView のヘッダーセ...
-
VB.NETでファイル名順にファイ...
-
C# DataTableの行をソートしてD...
-
VBA基本構文の作り方 2列の...
-
ファイル名「1.jpg ~10.jpg~...
-
あるディレクトリ内のファイル...
-
GridViewで列のソートを無効に...
-
C言語・要素除去
-
excel VBA の条件をつけての列...
-
Excelですべての組合せ(重複組...
-
VBScriptで配列のソートをする...
-
配列の問題
-
ブック.csvを開かずに他のブッ...
-
2次元配列を複数項目でソートし...
-
構造体配列のソート
-
listboxの並び替え
-
構造体のリストをソートしたい。
-
リスト構造のソートで悩んでま...
-
文字列をソートする方法
おすすめ情報
excel 2016です。
この質問をまとめると、焼肉(名前、金額、ランク)専用の配列を作る