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

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

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

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

Q&A

解決済

4回答

4209閲覧

Excel VBA 二次元配列

mmm_x

総合スコア10

VBA

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

0グッド

0クリップ

投稿2019/06/28 07:42

編集2019/07/05 07:16

値の貼り付けを各シートに1行ずつ貼り付けをしていて(Do Loop文を使用して繰り返し文でセルに値をはりつけています。)

遅い原因になっているので
二次元配列を使用して高速化したいのですが書き方がわかりません。

1000行あります。

どうすれば二次元配列に値を記憶させるのでしょうか・・・?

質問の仕方も初心者でわかりづらくなってしまい申し訳ございません。

追記
テキストファイルからinstr関数を使用したあと文字の抽出mid関数などを用いてString文を読み取りそれをセルに挿入します。

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

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

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

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

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

ttyp03

2019/06/28 08:04

まずは現状のコードを提示してください。
papinianus

2019/06/28 09:51

やりたいことを平たく説明していただけませんか?1セルずつ、1行ずつコピーするのは必須でしょうか?
hatena19

2019/07/01 06:56

せっかくコードを追記したのなら、中途半端なのものでなく、 テキストファイルを読み込む部分のコード、 それをシート上のセルへ代入する部分のコード、 を含む動作するコードを提示してください。 あと、コード部分は、選択してから<code>ボタンをクリックしてください。
guest

回答4

0

テキストファイルからinstr関数を使用したあと文字の抽出mid関数などを用いてString文を読み取りそれをセルに挿入します。

テキストファイルと一括りでいっても様々な種類があるんですが、
とりあえずエクセルでもテキストファイルが開けます。
単にエクセルでテキストファイルを開くと、どうなりますか?

それから、エクセルには、「テキストファイルのインポート」という機能も
付いてますので、そちらで上手くエクセルに取り込めないでしょうか?

それで上手く行くようなら、その操作をマクロ化したほうが
コードが簡単になります。

投稿2019/07/01 06:53

mattuwan

総合スコア2136

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

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

mmm_x

2019/07/01 06:56

その点に関してですが、とても良案ですが、今回は二次元配列で値を挿入が絶対の条件としたいです・・・。 .log のテキストファイルを読み取っています。
hatena19

2019/07/01 07:01

そのテキストファイルのデータ例も出してもらえますか。 csvフォーマットなのか、そうでないのか、によっても方法が異なりますので。
mmm_x

2019/07/01 07:06

一応、テキストファイルのデータ抽出には成功しています。 csvフォーマットではないです。 . . 値 "AAAA"をダウンロードしています
guest

0

ベストアンサー

配列を使って高速化したいということですね。

とりあえず、下記を理解して、自分でできるとこまでコードを書いてください。
話はそれからです。

VBA 高速化テクニック ~ 配列とセルの相互転記 - t-hom’s diary


提示のコードをみても、
テキストデータがどのようなもので、それをどのようにしたいのか結局分かりませんので、
概要を回答しておきます。

テキストファイルを1行ずつではなく、一気に読み込みます。
(1行ずつだと何行なのか分からないので、二次元配列のサイズを決定できないため)
FileSystemObjectのReadAllを使うといいでしょう。

読み込んだテキストを、Split関数で改行で分割して配列にします。
Splitの配列は一次元配列なので、
別にSplitの要素数×2列の二次元配列を確保します。

Splitの一次元配列をループで1行ずつ読み込んで、必要データを取り出して、二次元配列に格納します。

二次元配列を、シートの指定範囲に代入します。

上記の方法にすれば、シートへのアクセスは1回ですみ、それ以外はメモリ上の操作ですので高速になります。


コメントにテキストデータ例が出たので、そこから必要データを取り出してセルに出力するコード例

テキストファイル C:\test\test.log
データ

text

1. . 値 "AA"をダウンロードしています 2. . 値 "AB"をダウンロードしています 3. . 値 "AC"をダウンロードしています 4. . 値 "AD"をダウンロードしています

値 "" の間のテキストを取り出して、A2セル以降に出力するコード例

vba

1Public Sub テキストインポート() 2 Dim FSO As Object, Log As String 3 Set FSO = CreateObject("Scripting.FileSystemObject") 4 With FSO.GetFile("C:\test\test.log").OpenAsTextStream 5 Log = .ReadAll 'Log変数に全文読み込み 6 MsgBox buf 7 .Close 8 End With 9 Set FSO = Nothing 10 11 Dim ar As Variant 12 ar = Split(Log, vbCrLf) '改行で分割して一次元配列に変換 13 14 For i = LBound(ar) To UBound(ar) 15 ar(i) = Split(Split(ar(i), "値 """)(1), """")(0) '値 " と " の間を取り出す 16 Next 17 18 '一次元配列を2次元配列に変換してA2以降に出力 19 Range("A2").Resize(UBound(ar) + 1).Value = WorksheetFunction.Transpose(ar) 20End Sub

投稿2019/06/28 11:10

編集2019/07/02 03:40
hatena19

総合スコア33715

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

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

mmm_x

2019/07/01 06:42

かなり近い内容のページでした! しかしこのようなサンプルコードを元に作成 したところ配列の次元が一致していませんとでて、唸っております。
hatena19

2019/07/01 06:57

その作成したコード全体を回答に追記してください。 一部分ではどこで間違えているか、わかりません。
mmm_x

2019/07/01 07:33

追記しました。かなり変数をしようしています><
mmm_x

2019/07/02 00:39

テキストファイルを一行ずつ読み込む場合二次元配列は使用できないということでしょうか?
mmm_x

2019/07/02 00:44

. . 値 "AAAA"をダウンロードしています  テキストファイル内に書かれている文ですが . . 値 "AAAA"をダウンロードしています が1000行ほど羅列してあり "AAAA"を抜きだしセルにAAAAを入れようとしています。
hatena19

2019/07/02 02:36

> テキストファイルを一行ずつ読み込む場合二次元配列は使用できないということでしょうか? そうするより一気に読み込んで、Splitで行分割すれば、行数を取得できますので、その方が効率的だという意味です。 データ例をもう少し実際のものに近いいくつかの例を出してください。 値 " と " の間を抜き出したいということですか。値の部分は一種類で固定ですか。 また、抜き出すデータは、1行につき1つですか。
mmm_x

2019/07/02 02:44

. . 値 "AA"をダウンロードしています . . 値 "AB"をダウンロードしています . . 値 "AC"をダウンロードしています . . 値 "AD"をダウンロードしています .. .. .. と続いており instrで". . 値"と"をダウンロードしています" を検索し、Mid関数で一行ずつAA,AB,ACを抽出します。 セルには A列の2行目にAA A列の3行目にABという風に A列固定で下に値を追記していくような感じです。
hatena19

2019/07/02 03:22

ということは印ボートするデータは1列(A列のみ)ということですね。 なら、一次元配列でいいのでは。二次元配列する必要はないです。 ただし、一次元配列はセルに代入すると横になるので、WorksheetFunction.Transpose で二次元配列に変換すれば縦に代入できます。
hatena19

2019/07/02 03:41

上記のコード例を回答に追記しておきました。
mmm_x

2019/07/02 06:14

ありがとうございます。抽象的な質問が多く困らせてしまいすみませんでした。お陰様で助かりました。
guest

0

質問者さんが感じてますように、VBAのセルへの書き込みはかなりおそいです。

元のコードとは離れてしまいそうですが、
100列、1000行の範囲にセル番地を書き込む処理の場合の例を提示しておきます。
手元の環境だとtest1に比べてtest2は10分の1程度の時間ですみます。

vba

1 2' 普通にループ 3Sub test1() 4 Dim startTime As Double 5 Dim processTime As Double 6 Dim row As Long 7 Dim col As Long 8 9 ActiveSheet.Cells.Clear 10 startTime = Timer 11 12 For row = 1 To 1000 13 For col = 1 To 100 14 Cells(row, col).Value = Cells(row, col).Address(False, False) 15 Next col 16 Next row 17 18 processTime = Timer - startTime 19 MsgBox "Time: " & processTime & " sec." 20End Sub 21 22' 配列に入れて書き込みを1回にした場合 23Sub test2() 24 Dim startTime As Double 25 Dim processTime As Double 26 Dim row As Long 27 Dim col As Long 28 29 ActiveSheet.Cells.Clear 30 startTime = Timer 31 32 ' 配列をRedimで1000 x 100のサイズに再定義 33 Dim arrayData() As String 34 ReDim arrayData(1 To 1000, 1 To 100) 35 36 For row = 1 To 1000 37 For col = 1 To 100 38 arrayData(row, col) = Cells(row, col).Address(False, False) 39 Next col 40 Next row 41 42 ' 1000行、100列のRangeオブジェクトを取得してArrayを代入 43 Range(Cells(1, 1), Cells(1000, 100)).Value = arrayData 44 45 processTime = Timer - startTime 46 MsgBox "Time: " & processTime & " sec." 47End Sub

後はすでにやっているかもしれませんが、
Application.ScreenUpdating = False しておくとかでしょうか。

投稿2019/07/01 17:58

Eggpan

総合スコア2727

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

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

mmm_x

2019/07/02 01:12

Dim arrayData() As String ReDim arrayData(1 To 1000, 1 To 100) For row = 1 To 1000 For col = 1 To 100 arrayData(row, col) = Cells(row, col).Address(False, False) Next col Next row ' 1000行、100列のRangeオブジェクトを取得してArrayを代入 Range(Cells(1, 1), Cells(1000, 100)).Value = arrayData   この部分ですね、ありがとうございます。
guest

0

Excel VBA 二次元配列

私のお勧めは、Dictionaryオブジェクト(連想配列)ですが、二次元配列ならこんな感じで。

vba

1 '二次元配列 2 Dim strName() As String 3 ReDim strName(N, N) 4 '値を入れていく 5 strName(0, 0) = Worksheets("Sheet2").Cells(2, 2).Value

お勧めはDictionaryオブジェクト(キーの名称で値を取得出来ます)

VBA

1 Dim objName As Object 2 Set objName = CreateObject(“Scripting.Dictionary”) 3 objName.Add "キーの名称", 値 4 5 '取り出しループ 6 For Each Var In myDic 7 str = str & Var & " : " & objName.Item(Var) & vbCrLf 8 Next Var

投稿2019/06/28 08:16

hide0128

総合スコア245

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問