• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:エクセルVBAで配列の追加)

エクセルVBAで配列の追加

end-uの回答

  • end-u
  • ベストアンサー率79% (496/625)
回答No.5

念の為追記しておきます。 FormulaArrayプロパティを使って、一応はできますし、 2000で配列制限に引っ掛かる時、簡略化できるメリットはあります。 でもセル書き込みの効率は格段に落ちます。 VBAコーディングについてシンプルなものがイコール効率的とは限りません。 その点を理解した上で最適な手法を選択してください。 Option Explicit '--------------------------------------------------------------------- Sub test()   Const rn As Long = 1000   Const cn As Long = 4   Dim i As Long   Dim t As Single   Dim w(1 To rn)      With Sheets.Add.Cells(1).Resize(rn, cn)     .Formula = "=ADDRESS(ROW(),COLUMN(),4)"     .Value = .Value     For i = 1 To rn       w(i) = .Rows(i).Value     Next   End With   t = Timer   test1 w   Debug.Print Timer - t   t = Timer   test2 w   Debug.Print Timer - t   t = Timer   test3 w   Debug.Print Timer - t End Sub '--------------------------------------------------------------------- Sub test1(w)   Dim z      With Application     z = .Transpose(.Transpose(w))   End With   Sheets.Add.Cells(1).Resize(UBound(z, 1), UBound(z, 2)).Value = z End Sub '--------------------------------------------------------------------- Sub test2(w)   Sheets.Add.Cells(1) _      .Resize(UBound(w, 1), UBound(w(1), 2)).FormulaArray = w End Sub '--------------------------------------------------------------------- Sub test3(w)   Dim i As Long   Dim j As Long   Dim x As Long   Dim y As Long      y = UBound(w, 1)   x = UBound(w(1), 2)   ReDim z(1 To y, 1 To x)   For i = 1 To y     For j = 1 To x       z(i, j) = w(i)(1, j)     Next   Next   Sheets.Add.Cells(1).Resize(y, x).Value = z End Sub

merlionXX
質問者

お礼

end-uさま、締め切った後までご指導いただき有難うございます。 先ほど戻ってまいりました。 さっそく試したところ、おっしゃる通りFormulaArrayだと随分遅くなるんですね、おどろきました。 ほんとにシンプルなものが効率的とは限らないんですね。 ご指導有難うございました。

関連するQ&A

  • エクセルVBAでTransposeの不思議

    MS Officeのエクセル2000です。 下記Sub test01はRange("A1:I1")に文字列を入力し、一旦配列に取り込んでからワークシートに貼り付けるものです。 試験用のコードですので意味はありません。 このコードで255文字まではまったく問題はありません。 ところが、256文字以上の場合、横に貼り付けは問題ないのですが、 Transposeで縦に変換すると型が一致しません。(Error 13)となります。 どうしてでしょうか? 試行錯誤の結果、Sub test02のように一旦横に貼ったデータをコピーしてTransposeして貼り付けるのは大丈夫のようですので不思議でしょがありません。 またこの方法は列数256より要素が多い配列には使えないので解決策にはなりません。 ご教示くださいませ。 Sub test01() Dim myAr As Variant Dim i As Integer, n As Integer n = 256 '文字数 With ActiveSheet .UsedRange.ClearContents For i = 1 To 9 .Cells(1, i).Value = Application.Rept(Left(.Cells(1, i).Address(0, 0), 1), n) Next myAr = .Range("A1:I1").Value .Range("A3").Resize(, UBound(myAr, 2)).Value = myAr .Range("A5").Resize(UBound(myAr, 2)).Value = Application.Transpose(myAr) '256文字の場合エラー End With End Sub Sub test02() Dim myAr As Variant Dim i As Integer, n As Integer n = 256 '文字数 With ActiveSheet .UsedRange.ClearContents For i = 1 To 9 .Cells(1, i).Value = Application.Rept(Left(.Cells(1, i).Address(0, 0), 1), n) Next myAr = .Range("A1:I1").Value .Range("A3").Resize(, UBound(myAr, 2)).Value = myAr .Range("A3").Resize(, UBound(myAr, 2)).Copy .Range("A5").PasteSpecial Paste:=xlValues, Transpose:=True '256文字の場合もOK Application.CutCopyMode = False End With End Sub

  • エクセルVBAで配列内に空白データを入れる場合

    エクセル2000です。 ある大きな表のうち、0値を非表示ではなく完全に削除するために以下のようなマクロを書いてみました。 一旦配列に取り込んでいるのは高速化のためです。 これで見た目には目的を達しているのですが、実際には0値が長さ0の文字列に変わっただけで完全な空白にはなっていません。 配列にとりこまず、セルをループして0値のセルをClearすれば解決するのはわかるのですが、ほかにいい方法はないでしょうか? Sub TEST0値() Dim myAr With ActiveSheet x = .Range("A" & Rows.Count).End(xlUp).Row myAr = .Range("A4:AP" & x).Value For i = LBound(myAr, 1) To UBound(myAr, 1) For n = LBound(myAr, 2) To UBound(myAr, 2) If myAr(i, n) = 0 Then myAr(i, n) = "" Next n Next i .Range("A4:AP" & x).Value = myAr End With End Sub

  • VBA 配列について

    配列の使い方について教えてください 1つの配列をどんどん追加したりしたいので1つの mybox で追加していきたいと思っています。 (下記コードが実現できればと思います。) (1)配列を広げ追加したい (2)繰返しを使わず一気に書き込みたい (3)一部をクリアしたりしたい のですがよろしくお願いします。 Sub Macro1() Range("A1").Value = "A" Range("A2").Value = "B" Range("A3").Value = "A" o = Range("A1").End(xlDown).Row mybox = Range(Cells(1, 1), Cells(o, 1)).Value 'myBox(1,1)=A 'myBox(2,1)=B 'myBox(3,1)=A ←このような表示になります。 '------------------------------------------------- '(1)配列を広げ追加したい ReDim Preserve mybox(o, 2) For i = 1 To UBound(mybox) If mybox(i, 1) = A Then mybox(i, 2) = 0 Else mybox(i, 2) = 1 End If Next i '------------------------------------------------- '(2)(1)をC列に「myBox(?,2)を「繰返しを使わず一気に」書き込みたい 'Transposeは限界(65536個)を超えるので使えません。 Range(Cells(1, 3), Cells(UBound(mybox), 3)) = mybox '(3)配列myBox(?,1)は残したままmyBox(?,2)はクリアにしたい End Sub

  • エクセルVBAで配列?

    以下は、文字列"t", "e", "s", "t"を配列に取り込み、セルに表示する例ですが、 ar = Array("t", "e", "s", "t") なら作動しますが、セル範囲から取り込もうと、 ar = Range("A1:D1").Value とするとエラーになります。 どうしてでしょうか? Sub test() Dim ar As Variant Dim n As Integer ar = Array("t", "e", "s", "t") 'ar = Range("A1:D1").Value For n = LBound(ar) To UBound(ar) Cells(n + 1, 5) = ar(n) Next n End Sub

  • EXCEL VBAの配列でわかりません。

    こんなコードがあるのですが、最後の他のシート(作業中シート)に書き込もうとするとエラーになってしまいます。”Sheets("作業中").”を抜くと同じシートに結果は返ってくるのですが…。コードの内容は、ある範囲のある列から空白ではないセルを探し出してその行のデータを配列で汲み取り、他のシートに一括で洗い出すというものです。 Sub 作業中() Dim myRow As Long Dim Data As Variant Dim WC() As Variant Dim WCE() As Variant myRow = Range("H1").CurrentRegion.Rows.Count Data = Range("H1:M" & myRow).Value For i = 1 To myRow If Data(i, 5) <> "" Then a = a + 1 Else b = b + 1 End If Next ReDim WC(a) ReDim WCE(b) c = 0 d = 0 For i = 1 To myRow If Data(i, 5) <> "" Then WC(c) = Range("H" & i & ":K" & i).Value c = c + 1 Else WCE(d) = Range(Cells(i, 8), Cells(i, 11)).Value d = d + 1 End If Next For i = 0 To a Range(Cells(i + 1, 15), Cells(i + 1, 18)).Value = WC(i) Next For i = 0 To b Range(Cells(i + 1, 19), Cells(i + 1, 22)).Value = WCE(i) Next e = Range(Cells(1, 15), Cells(a, 18)).Value Sheets("作業中").Range(Cells(1, 1), Cells(a, 4)).Value = e End Sub ちなみに同じシートから↓のコードを実行するとうまくいきます。 なぜ~??わからな~い??おしえてくださーい!! Sub test() Dim a As Variant a = Range("H1:K4") Sheets("作業中").Range("N1:Q4") = a End Sub

  • VBA DictionaryオブジェクトのItemについての質問です。

    エクセル2000です。 A列からE列までの1行から最終行不特定の表があります。 A列はすべて文字列で、B~Gは数値、E列は文字列です。 A列の文字列には重複があります。 この表を別シートにA列の重複がない表として作成したいと思います。 その際、列が重複する場合にはB~G列は合計数値、E列は文字列を結合させます。 Dictionaryオブジェクトを用い、A列データをKey、B~E列データを配列でItemとして下記のコードを書きました。 このコードで目的は達成しました。 質問はKeyが重複する場合、B~E列のデータを配列として取り込んだItemに次のB~E列のデータを加算あるいは結合する方法の簡略化です。 このコードではItem内の配列データを、さらに配列変数のmyArに代入して、要素ごとにForNextで回しましたが、配列変数にわざわざ代入しなくとも出来る方法があるかどうかが知りたいのです。 あるいはまったく別な方法でもかまいません。 ご教示いただければ幸いです。 Sub ItemsTest() Dim myDic As Object, ns As Worksheet '変数宣言 Dim c As Range, cc As Range, i As Integer Dim myAr Set myDic = CreateObject("Scripting.Dictionary") 'myDicを用意 For Each c In Range(Cells(1, "A"), Cells(Rows.Count, "A").End(xlUp)) 'A列の各データについて If Not myDic.exists(c.Value) Then 'myDicになければ myDic.Add c.Value, Array(c.Offset(0, 1).Value, c.Offset(0, 2).Value, c.Offset(0, 3).Value, c.Offset(0, 4).Value) '追加しB~E列データを配列でItemに Else 'myDicにあれば myAr = myDic(c.Value) 'Itemを配列myArに For i = LBound(myAr) To UBound(myAr) myAr(i) = myAr(i) + c.Offset(0, i + 1).Value '配列の要素ごとに加算 Next i myDic(c.Value) = myAr '配列myArをItemにもどす End If Next c '繰り返し Set ns = Worksheets.Add(After:=ActiveSheet) 'シートを追加 ns.Range("A1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Keys) 'A列にKeyデータ転記 For Each cc In ns.Range("A1:A" & myDic.Count) cc.Offset(0, 1).Resize(, UBound(myAr) + 1).Value = myDic.Item(cc.Value) 'B~E列にItemデータ転記 Next End Sub  (o。_。)oペコッ

  • VBAの配列の格納について

    エクセルのVBAで、セルのデータを配列に格納するスピードを向上したいと思います。 例えば、A1~A10000のセルにデータを書き出す場合、 For 行番号 = 1 To 10000 Cells(行番号, 1).Value = 1 Next よりも、一旦、配列に書き込んだ後、一気にセルに書き込んだ方法が早いのですが、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = 1 Next Range("A1:A10000").Value = HAIRETU() 今度は、A1~A10000に書き込んだデータを、再度、配列に格納する場合、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = Cells(行番号, 1).Value Next とすると時間がかかるので、 HAIRETU() = Range("A1:A10000").Value というような処理をしたいのですが、うまくいきません。 よい方法がありましたら、ご教授ください。 よろしくお願いします。

  • VBAのソートで

    お世話になります。 初歩的な質問なのですが・・。 表のソートをしたいのですが、 表は2行目に見出しがあり3列で100行の構成です。 下記の様な記述で表の範囲をセットするところでエラー がかかってしまうのですが、どうしたらうまくいくでしょうか。 どなたかご教示頂きたく宜しくお願い致します。    記 Sub ソート() Dim myrhg As Range Dim myar As Variant Dim i As Long Sheets("台帳").Range("A1").CurrentRegion.Select Selection.Offset(1, 0).Select Set myrng = Selection.Resize(Selection.Rows.Count - 1).Select myar = Array(1, 2, 3) With myrng For i = 0 To UBound(myar) .Sort key1:=Cells(1, myar(i)), Order1:=xlAscending, header:=xlYes Next End With Set myrng = Nothing End Sub

  • EXCEL VBA 配列のIndex番号書きかわり

    こんばんは。 EXCEL VBA で困っております。 シートから配列にコピーさせると、ReDimで設定してあったIndex番号が なぜか替ってしまうらしいのです。 いろいろと検索してみましたが、どうしても見つからず、ここで質問させていただくことにしました。 下記のコードで確認してみてください。 Sub test() Dim A As Variant ReDim A(1 To 1, 0 To 4) For j = 0 To 4 A(1, j) = j Next j Range("A1:E1") = A MsgBox A(1, 0) 'ちゃんと機能して(1, 0)の位置で[0]と表示 'MsgBox A(1, 5) '←インデックスが有効範囲にありません A = Range("A1:E1") Range("A2:E2") = A 'MsgBox A(1, 0) 'さっき機能したのに今度はエラー MsgBox A(1, 1) '(1, 1)はセルでは2列目の[2]が取得されない MsgBox A(1, 5) 'さっきエラーになった(1, 5)は今度はエラーにならない End Sub なぜ、A(1 to 1, 0 to 4) が A(1 to 1, 1 to 5) と替ってしまうのか? シート範囲全体をいっぺんに配列に格納するとこういうことが起こるのが仕様なのか?? 自分の推測では、配列は[0]から始めることができますが、 シート上では[0]という開始位置を認識できないため、 Variant変数型のなかで自動的に書き換えちゃってくれてるのかな? なんて思ったりしました。 理由がわかる方、おりましたらご教授くださいませ。 また、どうしても、この2次元配列で、 てっとり早いこのコピーコードを使いセル範囲から配列へコピーさせて、 列方向へのIndexを (0 to 4)とさせたいのですが、 何かよい方法はありますでしょうか?? For文やEach文でひとつずつセルから配列へ格納という方法もあるかもしれませんが、 実際に打ち込んでいるコードは、行列ともかなり範囲が広いために、 処理時間を気にしてしまいます。 そこそこ使い慣れてきたのに、よもやこんなところで、躓くの!?といった心境です。 ご指南のほど、どうぞよろしくお願いいたします。

  • 配列変数 インデックス番号の最小値

     特に指定しない場合、配列変数のインデックス番号の最小値は0から始まるはずですが、下記のプロシージャでは、abの最小インデックス番号は1,2次元とも「0」でなく「1」から始まります(ウォッチ式で見ても「1」から始まっています)。 「0」から始まらない理由が分かりません。 ご教授を よろしくお願いいたします。 Public Sub セル参照() ' "A1:B10"のセル範囲のデータを順番にメッセージボックスに表示する。 Dim ab As Variant Dim i As Integer, j As Integer ab = Worksheets("Sheet1").Range("A1:B10").Value For i = 1 To UBound(ab, 1) For j = 1 To UBound(ab, 2) MsgBox ab(i, j) Next j Next i End Sub