質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

445閲覧

Transeposeの配列数が多い場合の#N/A挙動について

King_of_Flies

総合スコア382

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2022/10/05 02:10

発生している問題

wsKey1Colはキーとなる項目が格納されている列数のカラム番号です。
この列に格納されているデータの総数が115693件以下の場合は後述のプログラムでうまくいきます。

130460件の場合はTransposeの貼り付け先に#N/Aが出力されて貼り付け自体中途半端な行で終わっている状況になります。

貼り付け先のシートに#N/Aが存在する。(8044行目以降すべてのセルにN/A)

調べたところ
Transposeの元データと貼り付け先の範囲が異なるとエラーとなるとありますが、
ディクショナリのデータ格納数でResizeしているので、その線は薄いです。

https://answers.microsoft.com/ja-jp/msoffice/forum/all/transpose%e9%96%a2%e6%95%b0%e3%82%92%e7%94%a8/5d7db3f0-9165-4e93-9a67-7044f5722820

別のサイトでは、配列数が多い場合にTransposeはうまくいかないといった記述を見つけました。

https://excel-ubara.com/excelvba4/EXCEL268.html

処理速度を変えることなく
Transposeの代用として使用できる関数はありますでしょうか。

該当のソースコード

VBA

1Dim rngA As Range 2Set rngA = Worksheets("作業シート合算").Cells(1).CurrentRegion.Offset(1) 3Set rngA = rngA.Resize(rngA.Rows.Count - wsGassanHeadder) 4 5Dim D1 As Object 6Set D1 = CreateObject("Scripting.Dictionary") 7 8Dim r As Range 9For Each r In rngA.Rows 10  D1(r.Cells(1, wsKey1Col).Text) = D1(r.Cells(1, wsKey1Col).Text) + r.Cells(1, wsFileSumCol) 11Next 12 13With Worksheets("作業シート合算") 14 'Dictionaryのキー配列を作業シート合算に出力 15 .Range("K2").Resize(D1.Count).Value = WorksheetFunction.Transpose(D1.Keys) 16 'Dictionaryのアイテム配列(集計値)を作業シート合算に出力 17 .Range("M2").Resize(D1.Count).Value = WorksheetFunction.Transpose(D1.items)

試したこと

件数が少ない場合は上記コードで意図した動きができることの確認

件数が多い場合は上記コードでTransposeの貼り付け先に#N/Aが出現することの確認

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

処理速度は変わりますが、普通に配列に入れてセットするので問題ないと思います。

簡単ですが、一応コードを書きますと

VBA

1Dim v1 As Variant 2Dim v2 As Variant 3Dim tmpKeys As Variant 4Dim tmpItems As Variant 5ReDim v1(D1.Count - 1, 0) 6ReDim v2(D1.Count - 1, 0) 7tmpKeys = D1.Keys 8tmpItems = D1.Items 9 10Dim i As Long 11For i = 0 To D1.Count - 1 12 v1(i, 0) = tmpKeys(i) 13 v2(i, 0) = tmpItems(i) 14Next 15 16With Worksheets("作業シート合算") 17 .Range("K2").Resize(D1.Count).Value = v1 18 .Range("M2").Resize(D1.Count).Value = v2 19End With

あと、質問とは関係のない所ですが
この処理速度の変化よりも、Dictionaryに値をセットする所を修正することによる速度改善の方が大きいと思います。

VBA

1Dim r As Range 2Dim tmpKey As String 3For Each r In rngA.Rows 4 tmpKey = r.Cells(1, wsKey1Col).Text 5 D1(tmpKey) = D1(tmpKey) + r.Cells(1, wsFileSumCol).Value 6Next

劇的に早くなるわけではありませんが、テストした所
元のコードでは1分30秒ちょっとかかったのが1分10秒で処理が終わりました。

投稿2022/10/05 12:17

kts2634

総合スコア42

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問