[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『VBAの二次元配列の文字列化について』(にゅるん)
お世話になっております。
Excel VBAでよく使う
Dim Data as Variant
Data = Range("A1:C3")
のような二次元配列データを任意の区切り文字で、単一の文字列化する関数Join2()を自作してみました。
(デフォルト値はCSV向けの設定ですが、あくまで汎用的のものを作るのが目的です)
質問1.もっと高速に二次元配列を結合する方法はありますか?
質問2.VBAには二次元配列を一気に代入する構文はないのでしょうか。
たとえば一次元配列向けのArray()を使って記述を簡素化する方法はありますか?
拙いですが現時点で完成済みのコード全文を載せます。
'二次元配列をCSV等の文字列に変換する。 Function Join2(arr As Variant, Optional Delimiter1 As String = ",", Optional Delimiter2 As String = vbCrLf) As Variant Dim i As Long, j As Long Dim arr1() As Variant Dim arr2() As Variant ReDim arr1(1 To UBound(arr, 1)) ReDim arr2(1 To UBound(arr, 2)) For i = 1 To UBound(arr, 1) For j = 1 To UBound(arr, 2) arr2(j) = arr(i, j) Next arr1(i) = Join(arr2, Delimiter1) Next Join2 = Join(arr1, Delimiter2) End Function
'テスト用コード Sub test_Join2() Debug.Print vbLf & "test_Join2 - " & Format(Now, "hh:mm:ss")
Dim TestPattern As Dictionary Dim arr() As Variant Dim S As Variant Dim V As Variant
Set TestPattern = New Dictionary
ReDim arr(1 To 3, 1 To 3) arr(1, 1) = "aaa": arr(1, 2) = "bbb": arr(1, 3) = "ccc" arr(2, 1) = "ddd": arr(2, 2) = "eee": arr(2, 3) = "fff" arr(3, 1) = "ggg": arr(3, 2) = "hhh": arr(3, 3) = "iii" TestPattern.Add "Normal", arr
ReDim arr(1 To 3, 1 To 3) arr(1, 1) = "aaa": arr(1, 2) = "": arr(1, 3) = "ccc" arr(2, 1) = "ddd": arr(2, 2) = "eee": arr(2, 3) = "" arr(3, 1) = "": arr(3, 2) = "hhh": arr(3, 3) = "iii" TestPattern.Add "Irregular", arr
For Each S In TestPattern.Keys V = Join2(TestPattern(S)) Debug.Print "[" & S & "]" & " >> [" & V & "]" Next End Sub
以上、よろしくお願いいたします。
< 使用 Excel:Excel2016、使用 OS:unknown >
速くしたいのか、記述を簡素化したいのかわからないけど。
Sub test_Join2() Debug.Print vbLf & "test_Join2 - " & Format(Now, "hh:mm:ss") Dim TestPattern As Dictionary Dim i As Long, txt As String, e Dim arr() As Variant Const delim As String = "," Set TestPattern = New Dictionary ReDim arr(1 To 3, 1 To 3) arr(1, 1) = "aaa": arr(1, 2) = "bbb": arr(1, 3) = "ccc" arr(2, 1) = "ddd": arr(2, 2) = "eee": arr(2, 3) = "fff" arr(3, 1) = "ggg": arr(3, 2) = "hhh": arr(3, 3) = "iii" TestPattern.Add "Normal", arr arr(1, 1) = "aaa": arr(1, 2) = "": arr(1, 3) = "ccc" arr(2, 1) = "ddd": arr(2, 2) = "eee": arr(2, 3) = "" arr(3, 1) = "": arr(3, 2) = "hhh": arr(3, 3) = "iii" TestPattern.Add "Irregular", arr For Each e In Array("Normal", "Irregular") For i = 1 To UBound(TestPattern(e)) txt = txt & IIf(txt <> "", vbCrLf, "") & Join(Application.Index(TestPattern(e), i, 0), delim) Next MsgBox txt, , e: txt = "" Next End Sub (seiya) 2018/08/04(土) 14:38
arr(1, 1) = "aaa": arr(1, 2) = "bbb": arr(1, 3) = "ccc" arr(2, 1) = "ddd": arr(2, 2) = "eee": arr(2, 3) = "fff" arr(3, 1) = "ggg": arr(3, 2) = "hhh": arr(3, 3) = "iii" と書きましたが、C#とかでは {{"aaa","bbb","ccc"},{"ddd","eee","fff"},{"ggg","hhh","iii"}} と、添字を書かないで代入出来ますよね。
VBAでも一次元配列であれば
arr = Array("aaa","bbb","ccc")
のようにして一括で代入できるので、二次元配列の代入方法も実はあるのだろうか?
というのが質問2になります。
質問1の解については頂いたコードを関数化して試したいと思います。
(にゅるん) 2018/08/04(土) 16:16
文字数に制限(256)はありますが、
arr1 = [{"aaa","bbb","ccc";"ddd","eee","fff";"ggg","hhh","iii"}]
こんな感じでできます。 (seiya) 2018/08/04(土) 16:22
それと頂いたコードを検証してみました。
よく見ると「txt = txt & ○」を使っているのでとてつもなく遅いですね。
10文字データを10000件×100列のデータ結合を10回したところ
私のものは0.04秒
頂いたものは70.1秒
他に良い方法がありましたらよろしくお願いいたします。
(にゅるん) 2018/08/04(土) 17:00
その部分は私も配列に入れてJoinする方法を取ります。 もう一つは文字列の Memeory Management という方法もありますが速度的に速くなるかはわかりません。
参考にしてください。 http://www.moug.net/tech/exvba/0140045.html (seiya) 2018/08/04(土) 17:11
Evaluate 以外にこんなこともできます。 この方法では要素が1つでも256文字以上になるとTransposeメソッドがエラーになりますが、それ以外は 此方の方が使い勝手が良いでしょう。
arr1 = Application.Transpose(Array(Array("aaa", "ddd", "ggg"), _ Array("bbb", "eee", "hhh"), Array("ccc", "fff", "iii"))) (seiya) 2018/08/04(土) 17:51
ひとまずこの質問は〆ますが、時々確認に来ますので他に情報がありましたらよろしくお願いいたします。
(にゅるん) 2018/08/04(土) 18:59
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.