PART3 まだまだあるマクロ作成時に一寸見たいコマンド使用例

前章までの、第1章のマクロ作成便利資料で一覧表にして見やすくして効率よくコマンド使用方法を探
せるようにしました。また第2章の高速化マクロ作成テクニックでは過去の経験に基づくマクロ例を紹介
しました。
 しかし、記述した2章のみではマクロ作成のテクニック及びマクロ作成のとき参考にしたいコマンド
使用例を全部書くことはとても出来ませんでした。 したがって、第1章のマクロ作成便利資料と厳格な
区別はありませんが、よく使用する重要なコマンドでまだ記載してないケースを漏れなく記載する為に
本章を作成しました。


■3-1 配列を使いこなすための便利資料
同じ種類のデータを番号付きで格納できるのが「配列」です。配列を覚えると同じような内容の変数なら
それをまとめることによりマクロがスッキリするし、処理した配列データを一瞬にしてシートのセルへ
貼り付ける等マクロ実行速度の向上にも役立ちます。
[1] 配列を使用のときは、必ず宣言が必要です。
[2] 配列の宣言は「Dim(インデックス最大値)」で行う。
  (aa(100) As Integer 、aa(5 To 100) As Integer の指定方法があります)
[3] 配列の型宣言は変数と同じです。宣言をしない場合はバリアント型です。
[4] 配列のインデックスは「0」から始まります。
   (モジュールシートの先頭に「Option Base 1」と記載すればインデックスは1から始まります。
なお、aa(5 To 100) As Integer と宣言ではは5が先頭)




(1)配列データを効率よく初期化すれば幅広く活用できます
同じ配列変数をマクロ内の各所で使用する場合、必要に応じ初期化してから新たなデータを代入します。
初期化の各種方法を知っていれば効率の良いマクロを作成できます。
Sub 配列1_1()
Dim da(5, 100) As String
da(1, 1) = "AAA"
 
For i = 0 To 5
    For j = 0 To 100
        da(i, j) = ""
    Next
Next
MsgBox "データチェック(" & da(1, 1) & ")"
End Sub
--------------------------------------------------------
Sub 配列1_2()
ReDim da(5, 100) As String
da(1, 1) = "AAA"
 
ReDim da(5, 100) As String
MsgBox "データチェック(" & da(1, 1) & ")"
End Sub
--------------------------------------------------------
Sub 配列1_3()
Dim da(5, 100) As String
da(1, 1) = "AAA"
 
Erase da
MsgBox "データチェック(" & da(1, 1) & ")"
End Sub




(2)配列データをつないで1個の文字変数にする例
Join関数は文字列型の配列に含まれる要素の文字列を、指定した区切り文字で連結させ、1つの文字列とし
て返します。配列変数を普通の変数に変えて処理したい時使用できる便利な関数です。

Sub 配列2()
 
Dim dat(2) As String
Dim datstr As String
dat(0) = "ABC"
dat(1) = "DEF"
dat(2) = "GHI"
 
    datstr = Join(dat) & vbCrLf                    '結果→ABC DEF FHI
    datstr = datstr & Join(dat, "") & vbCrLf   '結果→ABCDEFFHI
    datstr = datstr & Join(dat, "|")               '結果→ABC|DEF|FHI
 
    MsgBox datstr
End Sub
※区切り文字の指定を省略した場合は半角スペースが区切り文字となります
 




(3)Array関数は配列へデータを一括代入できます
通常配列にデータを代入する場合、インデックス番号を指定して1つ1つ代入します。しかし、バリアント
型の変数を用意して、配列の中身をArray関数を使ってまとめて指定することが可能です。このマクロ
の実行結果は画面1に示す。

Sub 配列3()
Dim w  As Integer
Dim week As Variant
  week = Array("日", "月", "火", "水", "木", "金", "土")
    hia = InputBox("「年/月/日」を入力して下さい")
    If IsDate(hia) Then
        hi = CDate(hia)
        hi = Format(hi, "yyyy""年""mm""月""dd""日""")
    Else
        MsgBox "「年/月/日」を入力して下さい"
        Exit Sub
    End If
        w = Weekday(hi)
    MsgBox hi & " は " & week(w - 1) & "曜日です"
End Sub


画面1 曜日を配列へ代入して実行例




(4)セルデータをまとめて配列へ代入する例
セルデータをまとめて、バリアント型の2次元の配列へ代入できます。このマクロ例は画面2のExcelシート
のセルデータを配列へ取り込んみ、その配列を処理して別のシートに貼り付けた例です(画面3参照)


画面2 配列へ一括取り込んだExcel元シート


画面3配列を処理して別のシートに貼り付けた例


Sub 配列4()
Dim dbd As Variant      'セルデ−タ処理
Dim i As Integer       'カウンタ
Dim endr As Integer    '最終行
Dim endc As Integer    '最終列
 
ThisWorkbook.Sheets("Sheet1").Select
Application.ScreenUpdating = False
 
セル範囲
  Selection.SpecialCells(xlCellTypeLastCell).Select
      endr = ActiveCell.Row
      endc = ActiveCell.Column
 
ReDim dbd(endr, endc)
 
dbd = Range("A1").CurrentRegion.Value
 
ThisWorkbook.Sheets("Sheet3").Select
    Cells(1, 1) = "dt=new Array();"
For i = 1 To endr
    Cells(i + 1, 1) = "dt[" & i & "]=" & "'" & dbd(i, 1) & _
    "|" & dbd(i, 2) & "'"
Next
 
End Sub
※CurrentRegionプロパティは空白行と空白列で囲まれたセル範囲の値を取得




(5)配列データをまとめてセルへ書き込んだ例
前述(4)ではExcelセルデータを配列へ代入しましたが、この項目は代入された配列データをExcelシート
へ貼り付けた例です。なお、マクロの内容としては画面4のようなテキストファイルデータを配列へ
取りこみ、一括でExcelシートへ貼り付けた例です。

画面4 テキストファイルデータ例


画面5 Excelシートに貼り付け例


Sub 配列5()
Dim txtpas As String           'サンプルtxtファイル保存場所
Dim dat(224, 1) As String      '2次配列宣言
Dim i As Integer               'カウンター
 
ThisWorkbook.Sheets("Sheet1").Select
Application.ScreenUpdating = False
 
txtpas = ThisWorkbook.Path & "\" & "Listsanple.txt"
txtデ−タ取り込み
    i = 0
    Open txtpas For Input As #1
Do Until EOF(1)
    Input #1, dat(i, 0), dat(i, 1)
    i = i + 1
Loop
Close #1
 
r = UBound(dat, 1)
c = UBound(dat, 2)
 
セルへ書き込み
Cells(1, 1) = "銘柄コード": Cells(1, 2) = "名称":
Range(Cells(2, 1), Cells(i + 1, 2)).Value = dat
 
Range(Cells(2, 1), Cells(r + 2, c + 1)).Value = dat
 
 
End Sub
※上記はサンプルの入っているブック(ThisWorkbook)と同じフォルダに"
  Listsanple.txtファイルがある前提となっています




(6)配列内データを処理するマクロ例
複雑なデータの処理や加工を行う場合、セルデータをそのまま制御するより、1度配列へ格納して配列
変数を処理すれば一般的には実行速度は数倍早くなります。ここでは配列データ処理マクロ例を紹介。

[1]配列内のランダムなデ - タを若番順に並び替えるマクロ例
別のファイルにあるデータを配列変数へ代入した場合、データを若番順に並び替えたいケースがあり
ますが、本例は配列内のデ - タを若番順に並び替えるマクロ例 です。なお1次元配列のサンプルです
が、2次元配列の場合はキーワード以外の配列要素も同時に動かせばこのマクロ例を2次元配列の並
べ替えにも使用できます。画面6 配列データ若番順並べ替え例(右実行後)



Sub 配列6_1()
Dim dat(10) As Integer
dat(1) = 3: dat(2) = 1: dat(3) = 8: dat(4) = 0: dat(5) = 9  'サンプル数字
dat(6) = 4: dat(7) = 2: dat(8) = 5: dat(9) = 7: dat(10) = 6
 
For j = 1 To 10
    For r = j + 1 To 10
      If dat(j) > dat(r) Then
         datm = dat(j)
         dat(j) = dat(r)
         dat(r) = datm
      End If
     Next
Next
 
MsgBox dat(1) & " " & dat(2) & " " & dat(3) & " " & dat(4) & " " & dat(5) _
& " " & dat(6) & " " & dat(7) & " " & dat(8) & " " & dat(9) & " " & dat(10)
End Sub


[2]配列内のランダムなデ - タを老番順に並び替えるマクロ例
別のファイルにあるデータを配列変数へ代入した場合、データを老番順に並び替えたいケースがあり
ますが、本例は配列内のデ - タを老番順に並び替えるマクロ例 です。

画面7 配列データ老番順並べ替え例(右側画面が実行後)


Sub 配列6_2()
Dim dat As Variant
dat = Array(3, 1, 8, 0, 9, 4, 2, 5, 7, 6)    'サンプル数字
 
For j = 0 To 9
    For r = 9 To j Step -1
      If dat(j) < dat(r) Then
         datm = dat(j)
         dat(j) = dat(r)
         dat(r) = datm
      End If
     Next
Next
 
MsgBox dat(0) & " " & dat(1) & " " & dat(2) & " " & dat(3) & " " & dat(4) _
& " " & dat(5) & " " & dat(6) & " " & dat(7) & " " & dat(8) & " " & dat(9)
End Sub

 配列要素の若番から処理と老番から処理の2サンプルを掲載しましたが、
  実施の結果は、Ifの<>を逆にすれば同じ機能のマクロになります。


[3]配列要素の特定番へデ−タを入れ以降は1個後にずらした例
配列要素の"y番"へ別なデ−タを入れる関係で、y番以降を1個後ろへずらすマクロ例です。
本例では3番目(0からであり4個目)以降をずらし3番目に"x"を入れてあります。

画面8 3番目要素の入れ替え例(右側画面は実行後)


Sub 配列6_3()
Dim dat As Variant
dat = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "")  'サンプル文字
 
    For J = 9 To 3 Step -1
        dat(J + 1) = dat(J)
    Next
    dat(3) = "x"
 
MsgBox dat(0) & " " & dat(1) & " " & dat(2) & " " & dat(3) & " " & dat(4) _
& " " & dat(5) & " " & dat(6) & " " & dat(7) & " " & dat(8) & " " & dat(9)
 
End Sub


[4]配列内の途中にあるブランクデータを詰めた例
配列データの中に余分なデータがある場合、そのデータを削除して配列要素を詰めたい場合があります。
本例は余分なデータとしてよくあるブランクデータを削除して配列をつめるマクロ例です。

画面9 5番目要素のブランク詰めた例(右側画面は実行後例)


Sub 配列6_4()
Dim dat As Variant
dat = Array("A", "B", "C", "D", "E", "", "F", "G", "H", "I", "J") 'サンプル文字
 
   For i = 0 To 9
      If dat(i) = "" Then
         For j = i To 9
             dat(j) = dat(j + 1)
         Next
      End If
   Next
 
MsgBox dat(0) & " " & dat(1) & " " & dat(2) & " " & dat(3) & " " & dat(4) _
& " " & dat(5) & " " & dat(6) & " " & dat(7) & " " & dat(8) & " " & dat(9)
End Sub


[5]配列内データをセルに1行5列に記入例
これは配列データの内容を処理するマクロ例ではありませんが、配列データをセルへ書き込む例として、
算術演算子の"\"(割り算(整数)[余りはカット])とMod(割り算(余り)[整数部カット])を使って行/列を指定
すれば簡単に表にして記入できるサンプルです。

画面10 セルに6行*5列で記入例


Sub 配列6_5()
Dim dat As Variant
dat = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", _
   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", _
   "A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
 
For i = 1 To 30
    C = (i - 1) Mod 5 + 1
    r = (i - 1) \ 5 + 1
    Cells(r, C) = dat(i - 1)
Next
End Sub


[6]各要素ごとの区切られた配列データを分割または結合する例
Split 関数は、各要素ごとに区切られた文字列から 1次元配列を作成します。Join関数は、配列に含ま
れる各要素の内部文字列を結合し文字列を返します。

この2個の関数の使用方法を紹介しますが、本例ではインターネット上にあるWebページのURLを、自分
のPCに保管してあるファイル場所にリンクを直したサンプルです。自分のPC上のファイルをそのPCの
IEへ開いた場合はソースの修正が出来るので便利です。

(実行例は画面11参照)

画面11配列データの分割結合実行例 


Sub 配列7()
Dim i As Integer
Dim haiur As Variant
 
haiur = Split(Cells(1, 2), "/")
 
On Error Resume Next
Do
    Cells(i + 3, 1) = i
    Cells(i + 3, 2) = haiur(i)
        If Err = 9 Then Exit Do
    i = i + 1
Loop
Cells(i + 3, 1) = ""
 
haiur(0) = "": haiur(1) = "": haiur(2) = "C:\2第2HP"
Cells(i + 5, 2) = Mid(Join(haiur, "\"), 3)
Cells(i + 5, 1) = "PC上URL⇒"
 
End Sub


【参考311】 Split関数-文字列から1次元配列を作成
Split 関数は、各要素ごとに区切られた文字列から 1次元配列を作成し返します。たとえば、文字の
区切りを識別する文字として("/")を指定した場合は、("/")区切りごとに配列へ代入します。
(使用例は配列7プロシージャに示す)。なお、区切りを識別する文字を省略した場合は、区切り
文字にスペース("")が使用されます。
下記例は、HTTPオブジェクトでWebページのソースを、文字変数dathamlへ代入し、それを
vbCrLf(キャリーリターンとラインフィード)の区切りを識別し一次配列に変換しセルへ表示した例
tmp = Split(dathaml, vbCrLf)
For i = 1 To UBound(tmp)
   Cells(i, 1) = tmp(i)
Next
ただし、vbCrLfで識別できないWebページがあったが、tmp = Split(dathaml, Chr(10))のASCII
コードで指定したら上手く行ったケースがあった。


【戻る】    【Top画面】   【HPへ】