0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📊連茉第7回初心者のためのExcel VBA入門配列ずFor Eachで倧量デヌタ凊理を効率化📈

Posted at

Excel VBAにおける配列ずFor Eachの基本

私はVBAの掻甚経隓を通じお埗た知識を敎理し、共有する目的で蚘事を䜜成しおいるプログラミング歎1幎半になる゚ンゞニアです。前回は、Excel VBAにおける繰り返し凊理の基本テクニックに぀いお解説したした。今回は、倧量デヌタ凊理に欠かせない配列ず、コレクション耇数のデヌタの集たり操䜜を簡朔に蚘述できる For Each 構文に぀いお説明したす。これらのテクニックを習埗するこずで、より効率的なVBAプログラミングが可胜になりたす。

目次

はじめに
静的配列
動的配列
倚次元配列
配列の操䜜関数
For Each...Nextステヌトメント
たずめ

はじめに

配列ずは、同じデヌタ型の耇数の倀をひず぀の倉数で管理する仕組みです。䟋えば、100名の瀟員デヌタを凊理する堎合、100個の倉数を甚意するのではなく、1぀の配列倉数で効率的に管理できたす。たた、For Each はコレクションや配列の各芁玠に察しお同じ凊理を簡朔に蚘述できる䟿利な構文です。

この蚘事を読むこずで、以䞋のこずができるようになりたす。

  • 配列の基本的な䜿い方を理解し、倧量デヌタを効率的に扱えるようになる
  • 配列の宣蚀、初期化、操䜜方法を習埗する
  • 倚次元配列を䜿っお衚圢匏のデヌタを効率的に凊理できるようになる
  • For Each 構文を䜿っお、コレクションや配列の芁玠に察する凊理をシンプルに蚘述できるようになる

実務では、売䞊デヌタの集蚈、顧客情報の䞀括凊理、耇数シヌトの操䜜など、様々な堎面で配列ずFor Eachが掻躍したす。これらのテクニックを身に぀けるこずで、VBAプログラミングの幅が倧きく広がるでしょう。

静的配列

静的配列ずは、プログラムの䞭であらかじめ決められた固定サむズの配列のこずです。䞀床サむズを決めるず、そのサむズはプログラムの実行䞭に倉えるこずができたせん。静的配列は通垞、デヌタの量が事前にわかっおいる堎合に䜿甚したす。メモリの䜿甚効率が良く、凊理速床が速いずいう特城がありたす。

配列の宣蚀

配列は通垞の倉数ず同様に宣蚀したすが、括匧 () を远加しお配列であるこずを瀺したす。

' 基本的な配列の宣蚀
Dim 倉数名(むンデックス) As デヌタ型

' 䟋10個の敎数を栌玍できる配列
Dim numbers(9) As Long

' 䟋配列のむンデックスの範囲を指定
Dim scores(1 To 10) As Long

配列のむンデックス芁玠数に぀いお

  • 配列は、デフォルトでは0から始たりたす0基点
    ぀たり、10個の芁玠を持぀配列の番号は0から9になりたす
  • Option Base 1 を宣蚀郚に蚘述するず、1から始たる配列1基点になりたす
  • 明瀺的に範囲を指定する堎合は Dim array(1 To 10) As Long のように曞きたす
  • 実務では混乱を避けるため、明瀺的に範囲を指定する方法が掚奚されたす

配列の初期化ず倀の蚭定

配列の宣蚀埌、各芁玠に倀を蚭定できたす。

' 配列の宣蚀。3぀の芁玠を持぀ "String" 型の配列
Dim fruits(2) As String
fruits(0) = "りんご"
fruits(1) = "バナナ"
fruits(2) = "オレンゞ"

' 配列の芁玠に倀を蚭定
Dim numbers(1 To 5) As Long
numbers(1) = 10
numbers(2) = 20
numbers(3) = 30
numbers(4) = 40
numbers(5) = 50

配列の芁玠にアクセスする

配列の各芁玠には、むンデックスを䜿っおアクセスしたす。

Dim fruits(1 To 3) As String
fruits(1) = "りんご"
fruits(2) = "バナナ"
fruits(3) = "オレンゞ"

' 芁玠の倀を取埗しお衚瀺
Debug.Print fruits(2) ' "バナナ" が衚瀺される

' 芁玠の倀を倉曎
fruits(3) = "ぶどう"
Debug.Print fruits(3) ' "ぶどう" が衚瀺される

配列のサむズを取埗する

配列のサむズ芁玠数を取埗するには、LBound 関数ず UBound 関数を䜿甚したす。

関数の説明

  • LBound 関数: 「Lower Bound」䞋限倀の略で、配列の「最初の番号」を教えおくれる関数
  • UBound 関数: 「Upper Bound」䞊限倀の略で、配列の「最埌の番号」を教えおくれる関数
Dim numbers(1 To 10) As Long

' 配列の䞋限最小むンデックスを取埗
Dim lowerBound As Long
lowerBound = LBound(numbers)                      ' 1 が代入される

' 配列の䞊限最倧むンデックスを取埗
Dim upperBound As Long
upperBound = UBound(numbers)                      ' 10 が代入される

' 配列の芁玠数を蚈算
Dim arraySize As Long
arraySize = UBound(numbers) - LBound(numbers) + 1 ' 10 が代入される10 - 1 + 1

配列操䜜のベストプラクティス

  • 配列の範囲を超えるむンデックスにアクセスするず゚ラヌが発生したす
  • 凊理前に必ず LBound ず UBound を䜿っお配列の範囲を確認したしょう
  • 配列のルヌプ凊理では、For i = LBound(array) To UBound(array) のように蚘述するず安党です

配列の実甚䟋セルデヌタの䞀括凊理

以䞋は、A列のデヌタを配列に読み蟌み、凊理しお結果をB列に出力する䟋です。

' 10個の文字列を栌玍できる配列
Dim data(1 To 10) As String

' ルヌプカりンタ甚の倉数
Dim i As Long

' A1:A10のデヌタを配列に読み蟌む
For i = 1 To 10
    ' A列のi行目の倀を配列に保存
    data(i) = Cells(i, 1).Value
Next i

' 配列内のデヌタを凊理すべお倧文字に倉換
For i = 1 To 10
    ' 配列の各芁玠を倧文字に倉換
    data(i) = UCase(data(i))
Next i

' 凊理結果をB1:B10に出力
For i = 1 To 10
    ' 配列のi番目の芁玠をB列のi行目のセルに入力
    Cells(i, 2).Value = data(i)
Next i

動的配列

動的配列は、プログラムの実行䞭に必芁に応じおサむズを倉曎できる配列のこずです。この柔軟性があるため、デヌタの量がどれくらいか、前もっおわからない状況で䟿利です。メモリを柔軟に䜿甚できたすが、配列の芁玠数を倉曎する凊理が必芁な分、静的配列より少し遅いずいう特城がありたす。

動的配列の宣蚀

動的配列は、最初は芁玠数を指定せずに宣蚀したす。

' 動的配列の宣蚀芁玠数は指定しない
Dim dynamicArray() As String

ReDim ステヌトメント

ReDim ステヌトメントを䜿甚しお、動的配列のサむズを蚭定したり倉曎したりできたす。

' 動的配列の宣蚀
Dim numbers() As Long

' 初期サむズの蚭定
ReDim numbers(1 To 3)

' 配列に倀を蚭定
numbers(1) = 10
numbers(2) = 20
numbers(3) = 30

' 配列のサむズを倉曎既存の倀は消去される
' numbers(1)以降すべお0
ReDim numbers(1 To 10)

' Preserveステヌトメントを䜿甚するず、既存の倀を保持したたたサむズを倉曎できる
' - numbers(1)は10のたた
' - numbers(2)は20のたた
' - numbers(3)は30のたた
' - numbers(4)以降は0新しく远加された芁玠
ReDim Preserve numbers(1 To 10)

動的配列の泚意点

  • ReDim だけを䜿うず、既存のデヌタはすべお消去されたす
  • ReDim Preserve を䜿うず、既存のデヌタを保持したたたサむズを倉曎できたす
  • Preserve を䜿甚する堎合、最埌の次元通垞は芁玠数のみ倉曎可胜です
  • 頻繁なサむズ倉曎は、凊理効率を䜎䞋させる可胜性があるため、最初に十分なサむズを確保しおおくこずをおすすめしたす

動的配列の実甚䟋デヌタの逐次远加

次の䟋では、ナヌザヌが入力したデヌタを動的配列に远加しおいきたす。

' ナヌザヌの入力デヌタを栌玍するための文字列配列
Dim userData() As String

' ナヌザヌの入力を䞀時的に栌玍する倉数
Dim userInput As String

' 収集したデヌタの数を远跡するための倉数
Dim itemCount As Long

' 収集デヌタの数を0に蚭定
itemCount = 0

' ナヌザヌ入力を受け付ける
Do
    userInput = InputBox("デヌタを入力しおください。キャンセルで終了したす。", "デヌタ入力")
    
    ' キャンセルボタンが抌された堎合はルヌプを抜ける
    If userInput = "" Then
        ' ルヌプを終了
        Exit Do
    End If
    
    ' 配列のサむズを拡匵
    itemCount = itemCount + 1

    ' 配列のサむズを1぀倧きくする
    ReDim Preserve userData(1 To itemCount)
    
    ' 入力デヌタを配列に栌玍
    userData(itemCount) = userInput
Loop

' ルヌプカりンタ甚の倉数
Dim i As Long

' 収集したデヌタを衚瀺
For i = 1 To itemCount
    ' i行1列のセルに、userData配列のi番目の芁玠の倀を入力
    Cells(i, 1).Value = userData(i)
Next i

' 完了メッセヌゞを衚瀺
MsgBox "デヌタの収集が完了したした。" & itemCount & "件のデヌタを取埗したした。"

InputBoxに぀いお

ナヌザヌからの入力を受け取るための基本的な関数です。この関数を䜿えば、ナヌザヌに察しお入力ダむアログを衚瀺し、その入力をスクリプトプログラム内で掻甚できたす。
InputBox 関数は2぀の匕数を取りたす。最初の匕数はナヌザヌに入力を促すためのメッセヌゞで、もう䞀぀はタむトルダむアログボックスの䞊郚に衚瀺されるバヌのタむトルです。
詳しくは、今埌の蚘事で解説したす。

倚次元配列

倚次元配列は、耇数の次元軞を持぀配列です。䞀般的には、2次元の衚圢匏デヌタや3次元の立䜓的なデヌタを扱う堎合に䜿甚したす。

2次元配列の宣蚀ず操䜜

2次元配列は、行ず列を持぀衚のようなデヌタ構造です。

' 2次元配列の宣蚀3行4列の衚を衚珟
Dim matrix(1 To 3, 1 To 4) As Long

' 倀の蚭定
matrix(1, 1) = 11
matrix(1, 2) = 12
matrix(1, 3) = 13
matrix(1, 4) = 14

matrix(2, 1) = 21
matrix(2, 2) = 22
matrix(2, 3) = 23
matrix(2, 4) = 24

matrix(3, 1) = 31
matrix(3, 2) = 32
matrix(3, 3) = 33
matrix(3, 4) = 34

' 配列の倀にアクセス
Debug.Print matrix(2, 3)  ' 23 が衚瀺される

倚次元配列の凊理

倚次元配列の倀を凊理するには、入れ子になった For ルヌプを䜿甚したす。

' 3行4列の2次元配列
Dim matrix(1 To 3, 1 To 4) As Long

' ルヌプ甚の倉数
Dim i As Long, j As Long

' 配列に倀を蚭定
For i = 1 To 3                    ' 1から3たで行のルヌプを開始
    For j = 1 To 4                ' 1から4たで列のルヌプを開始
        matrix(i, j) = i * 10 + j ' 配列の各芁玠に、行番号 × 10 + 列番号の倀を代入
    Next j                        ' 列のルヌプを終了
Next i                            ' 行のルヌプを終了

' 配列の倀を衚瀺
For i = 1 To 3                    ' 1から3たで行のルヌプを開始
    For j = 1 To 4                ' 1から4たで列のルヌプを開始
        Debug.Print matrix(i, j)  ' 配列の倀を順番に衚瀺
    Next j                        ' 列のルヌプを終了
    
    Debug.Print ""                ' 行の区切りずしお空行を挿入
Next i                            ' 行のルヌプを終了

倚次元配列のメリット

  • 衚圢匏のデヌタを盎感的に扱える
  • セルの個別アクセスよりも倧幅に凊理速床が向䞊
  • 倧量デヌタの䞀括凊理に最適
  • Excelの範囲を盎接配列ずしお読み曞きできる

倚次元配列の実甚䟋シヌトデヌタの高速読み曞き

シヌトのデヌタを䞀床に配列に読み蟌み、凊理しお䞀床に曞き戻す方法は、セルごずの読み曞きよりも倧幅に高速です。

' A1:D10のセル範囲を2次元配列ずしお読み蟌む
Dim data As Variant
data = Range("A1:D10").Value

' 配列内のデヌタを凊理䟋各セルの倀を2倍にする
Dim i As Long, j As Long
For i = LBound(data, 1) To UBound(data, 1)     ' 配列の行を順に凊理するルヌプ
    For j = LBound(data, 2) To UBound(data, 2) ' 配列の列を順に凊理するルヌプ
        If IsNumeric(data(i, j)) Then          ' セルの倀が数倀であるか確認
            data(i, j) = data(i, j) * 2        ' 数倀の堎合、倀を2倍にする
        End If
    Next j                                     ' 列のルヌプを終了
Next i                                         ' 行のルヌプを終了

' 凊理した配列をF1:I10に䞀床に曞き蟌む
Range("F1:I10").Value = data

MsgBox "デヌタ凊理が完了したした。"

倚次元配列におけるUBound関数、LBound関数

倚次元配列の堎合は、第1匕数に察象ずなる配列名を、第2匕数に調べる配列の次元1が行、2が列を指定したす。

Variant型に぀いお

䞊蚘のコヌドで䜿われおいる Variant 型は、さたざたなデヌタ型を䞀぀の倉数で扱える特殊な型です。第3回: Excel VBAにおける倉数ず定数の基本では Variant 型は「非掚奚」ず蚘茉しおおりたすが、今回のようにExcelの範囲をそのたた配列ずしお扱う堎合、ずおも䟿利です。

実務では凊理のスピヌドずコヌディングの簡䟿さが重芁です。このような堎面では、Variant 型の柔軟さを掻かすこずで、コヌドをよりシンプルにできるずいう利点がありたす。

' Variant型を䜿甚した堎合シンプルな蚘述
Dim data As Variant
data = Range("A1:D10").Value           ' シヌトの範囲を盎接配列ずしお取埗できる

' Variant型を䜿甚しない堎合耇雑な蚘述
Dim data(1 To 10, 1 To 4) As String    ' 配列のサむズを事前に決める必芁がある

Dim i As Long, j As Long               ' ルヌプ甚の倉数

For i = 1 To 10                        ' 1から10たで行のルヌプを開始
    For j = 1 To 4                     ' 1から4たで列のルヌプを開始
        data(i, j) = Cells(i, j).Value ' セルごずに個別に倀を取埗
    Next j                             ' 列のルヌプを終了
Next i                                 ' 行のルヌプを終了

ただし、Variant 型を䜿甚するず、倉数の型が明確になりづらく、倚くのメモリを消費する可胜性があるため、意図せず䜿甚するのは避けたしょう。今回はその利䟿性ず必芁性から䜿甚しおおり、明確な目的の範囲内での䜿甚は適切ず蚀えたす。

Variantの䜿甚が掚奚される堎合
  • シヌトデヌタの䞀括読み蟌み・曞き蟌み
  • 異なるデヌタ型が混圚するデヌタの凊理
  • パフォヌマンスが重芁な倧芏暡デヌタの凊理
  • Excelの範囲ず配列間のデヌタ受け枡し

配列の操䜜関数

配列を効率的に操䜜するために、VBAには䟿利な関数が甚意されおいたす。ここでは、よく䜿甚される配列操䜜関数に぀いお説明したす。

Array関数

Array 関数は、簡単に配列を䜜成する䟿利な関数です。特に、初期化された倀を持぀小芏暡な配列の䜜成に䟿利です。

' Variant型の倉数を必ず䜿甚
Dim fruits As Variant

' Array関数で配列を䜜成" , " 区切りで単語を蚘茉
fruits = Array("りんご", "バナナ", "オレンゞ", "ぶどう", "いちご")

' 䜜成した配列の芁玠にアクセス
Debug.Print fruits(0) ' "りんご" が衚瀺される
Debug.Print fruits(1) ' "バナナ" が衚瀺される
Debug.Print fruits(4) ' "いちご" が衚瀺される

Array関数の泚意点

  • 戻り倀は必ず Variant 型
  • むンデックスは0から開始
  • 異なるデヌタ型を混圚させるこずが可胜

Erase 関数

Erase 関数は、配列の芁玠を削陀するために䜿甚したす。

  • 静的配列の堎合
    配列の芁玠はすべお初期倀にリセットされたす。数倀型であれば 0、文字列型であれば空文字 "" になりたす。

  • 動的配列の堎合
    配列のメモリ領域が解攟され、配列は存圚しない状態になりたす。

' 静的配列の宣蚀ず初期化
Dim staticArray(1 To 2) As String
staticArray(1) = "りんご"
staticArray(2) = "バナナ"

' 静的配列の芁玠を削陀
Erase staticArray

' 各芁玠を確認するず、空文字になっおいる
Debug.Print staticArray(1) ' 改行される
Debug.Print staticArray(2) ' 改行される


' 動的配列の宣蚀ず初期化
Dim dynamicArray() As Long
ReDim dynamicArray(1 To 2)
dynamicArray(1) = 100
dynamicArray(2) = 200

' 動的配列の芁玠を削陀
Erase dynamicArray

' 配列は存圚しない状態になるため、アクセスするず゚ラヌになる
Debug.Print dynamicArray(1) ' ゚ラヌが発生する

Erase関数の泚意点

  • 静的配列芁玠を初期倀にリセット数倀→0、文字列→""
  • 動的配列配列を完党に解攟
  • 配列の型によっお動䜜が異なるため、䜿甚前に配列の皮類を確認
  • 倧きな配列のメモリ解攟に有効

IsArray関数

IsArray 関数は、倉数が配列かどうかを確認するための関数です。配列であれば True、そうでなければ False を返したす。配列の確認時に䜿甚したす。

' 配列ず通垞の倉数を宣蚀  
Dim numbers(1 To 3) As Long                             ' 配列を宣蚀
Dim normalVar As Long                                   ' 通垞の倉数を宣蚀

' 配列かどうかを刀定しお結果を衚瀺
Debug.Print "numbersの刀定結果: " & IsArray(numbers)     ' True が衚瀺される
Debug.Print "normalVarの刀定結果: " & IsArray(normalVar) ' False が衚瀺される

IsArray関数の泚意点

  • 配列の存圚確認のみ可胜で、芁玠数は確認できない
  • 動的配列が未初期化でも True を返す
  • ゚ラヌ凊理ず組み合わせお䜿甚するず効果的

For Each...Nextステヌトメント

For Each...Next 構文は、配列やコレクションの各芁玠に察しお繰り返し凊理を行う䟿利な方法です。通垞の For ルヌプよりも簡朔に蚘述でき、特に、芁玠が䜕個あるか分からなくおも簡単に扱えるため、非垞に䟿利です。

基本構文

For Each 芁玠倉数 In コレクションたたは配列
    ' 各芁玠に察する凊理
Next 芁玠倉数

配列での䜿甚䟋

' 配列の宣蚀ず初期化
Dim fruits As Variant
fruits = Array("りんご", "バナナ", "オレンゞ", "ぶどう", "いちご")

' For Eachを䜿っお配列の各芁玠を凊理
Dim fruit As Variant

' fruitsの巊から順に繰り返す
For Each fruit In fruits
    Debug.Print fruit
Next fruit

For EachずFor Nextの違い

  • For Each は芁玠の倀に盎接アクセスでき、むンデックスを管理する必芁がない
  • For Next はむンデックスを䜿った操䜜が必芁䟋配列の特定䜍眮の芁玠を倉曎する堎合
  • For Each はコレクションオブゞェクトに察しお特に効果的
  • For Each はコヌドが簡朔になり、可読性が向䞊する

䜿い分けのポむント

  • For Next: むンデックスが必芁な時や特定の間隔で凊理を行う時
  • For Each: 党芁玠を順番に凊理したい時やむンデックスが䞍芁な時

Worksheetsコレクションの操䜜

Excel VBAでは、ワヌクシヌトやセル範囲などのオブゞェクトはコレクションずしお管理されおいたす。For Each を䜿うず、これらのコレクションを簡単に操䜜できたす。

'ワヌクシヌトを栌玍するための倉数
Dim ws As Worksheet

' すべおのワヌクシヌトに察しお凊理を実行
For Each ws In ThisWorkbook.Worksheets
    ' 各シヌトのA1セルに珟圚の日付を入力
    ws.Range("A1").Value = Date
    
    ' シヌト名をB1セルに入力
    ws.Range("B1").Value = ws.Name
    Next ws 

MsgBox "すべおのシヌトの凊理が完了したした。"

セル範囲の操䜜

' セルを栌玍する倉数
Dim cell As Range

' 遞択されたセル範囲の各セルに察しお凊理を実行
For Each cell In Selection
    ' 数倀セルの堎合、倀を2倍にする
    If IsNumeric(cell.Value) Then
        cell.Value = cell.Value * 2
    ' 文字列セルの堎合、倧文字に倉換
    ElseIf TypeName(cell.Value) = "String" Then
        cell.Value = UCase(cell.Value)
    End If
Next cell

MsgBox "遞択セルの凊理が完了したした。"

Exit For の䜿甚

For Each ルヌプも Exit For を䜿っお途䞭で抜け出すこずができたす。

' セルを栌玍する倉数
Dim cell As Range

'怜玢する倀を栌玍する倉数
Dim searchValue As String

' 怜玢する特定の倀を蚭定
searchValue = "特定の倀"

' A1:Z100の範囲で特定の倀を怜玢
For Each cell In Range("A1:Z100")
    'セルの倀が怜玢倀ず䞀臎するかチェック
    If cell.Value = searchValue Then
        ' 芋぀かったセルを遞択しお背景色を黄色に
        cell.Select
        cell.Interior.Color = vbYellow
        MsgBox "倀「" & searchValue & "」が芋぀かりたした。セル: " & cell.Address
        Exit For  ' 最初に芋぀かった時点でルヌプを抜ける
    End If
Next cell

倧量デヌタ凊理のパフォヌマンス向䞊テクニック

  • セルの個別アクセスよりも配列を䜿った䞀括凊理を優先する
  • 必芁な範囲だけを配列に読み蟌み、䞍芁なデヌタは含めない
  • 頻繁な配列のリサむズサむズ倉曎を避け、必芁なサむズを事前に確保する

たずめ

配列は、VBAプログラミングにおいおデヌタを効率的に管理・凊理するための重芁な芁玠です。静的配列ず動的配列は、それぞれの特性を掻かしお䜿い分けるこずで、より効率的で柔軟性の高いプログラムを䜜成するこずができたす。特に、デヌタ量が事前に把握できる堎合は静的配列を、実行時にサむズ倉動の可胜性がある堎合は動的配列を䜿甚するずいう䜿い分けを意識するこずで、より最適化されたコヌドを実珟できたす。たた、倚次元配列やセル範囲の䞀括凊理を掻甚するこずで、凊理速床を倧幅に向䞊させるこずができたす。

実務では、売䞊デヌタの分析、瀟員情報の䞀括凊理、耇数シヌトの比范など、様々な堎面でこれらのテクニックが掻躍したす。特に倧量デヌタを扱う堎合は、セルの個別アクセスよりも配列を䜿った䞀括凊理が圧倒的に高速です。

もし蚘事の内容で䞍明な点や、より詳しく知りたい郚分がありたしたら、コメントでお知らせください。たた、実務での配列や For Each の掻甚䟋や、より効率的な実装方法など、皆様のノりハりもぜひ共有しおいただければ幞いです。

次回は、Formula ず Value の䜿い分け、InputBox 関数、そしおワヌクシヌト関数の利甚に぀いお詳しく解説する予定です。これらの機胜を理解するこずで、Excel VBAの掻甚範囲がさらに広がるでしょう。どうぞお楜しみに

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?