2-3.銘柄コード選択(コンボボックス使用例)

(1) 概略
ダウンロードは銘柄コードで実施するが、コードを指定する時比較のため 同一業種の銘柄を多数見たい場合があり、こんな時解析ツールに業種を選択 すれば、その業種が全部表示されれば便利です。
ここでは下図のようなユーザーフォームを自作して、業種を選択してその中の銘柄を選択する 方法を説明します



なお、選択に使用する基データが必要ですが、本例の場合Sheet2へ東証1部の 業種・コード番号・銘柄を貼り付けてあります。(下図参照)


・マクロでの業種リスト作成は、同一業種が並んでいる前提になっています

・左図では罫線が付いていますが、罫線は特に必要ありません





(2)メインオブジェクト
ユーザーフォーム表示前にデータを取り込み、業種についてはフォームが表示された 時直ぐ選択することが出来ます。

Dim motod(2, 3000) As String   '元データ
Dim meigara() As String        '業種別銘柄
Dim cbo2d() As String          'コンボ2個へ登録データ

Sub コード選択()
Application.ScreenUpdating = False        '[1]

If motod(1, 0) <> "取込済み" Then                '[2]
    ThisWorkbook.Worksheets("Sheet2").Activate   
    Cells(10000, 1).End(xlUp).Select
    endr = Selection.Row
    Range("A1").Select

    For i = 1 To endr                            '[3]
        motod(0, i) = Cells(i, 2)
        motod(1, i) = Cells(i, 3)
        motod(2, i) = Cells(i, 1)
    Next
        motod(0, 0) = endr                       '[4]  
        motod(1, 0) = "取込済み"
End If
    Worksheets("Sheet1").Select
    Call 選択登録                                '[5]
        
    UserForm1.Show 0                             '[6]
End Sub
[1] スクリーンの動きをとめる
[2] マクロを実行した時東証一覧を配列へ入れているが、配列に既にある場合はパス
[3] 配列へ取り込み
[4] データは1以降に取り込んであり、後で使用の関係で0にはデータ量と"取込済み"を記録
[5] コンボボックス1へ業種データを登録プロシージャへ
[6] ユーザーフォーム表示(モ-ドレスの0指定の場合Excel2000以降が対象)

(3)ユーザーフォームモジュール
ユーザーフォームのプロパティに付けた名称は下図参照のこと。

'-------------------------------------------------------------------------
Private Sub cbo1_Change()             '[1]
    Call 業種別配列
End Sub
'-------------------------------------------------------------------------
Private Sub cbo2_Change()             '[2]
 With UserForm1.cbo2
        ino1 = .ListIndex
        If ino1 = -1 Then
            UserForm1.txt1 = ""
        Else
            meino1 = .List(ino1)
            mmm = Mid(meino1, 2, 4)
            UserForm1.txt1 = mmm
            
            ksu = InStr(meino1, "]")
            neigara = Mid(meino1, ksu + 1)
        End If
    End With
End Sub
'--------------------------------------------------------------------------
Private Sub cmb1_Click()             '[3]
 Call 次へ
End Sub
'-------------------------------------------------------------------------
Private Sub cmb2_Click()             '[4]  
    Call 戻る
End Sub
'-------------------------------------------------------------------------
[1] コンボボックス(cbo1)に変化のあった時実行イベントで、「業種別配列」コール
[2] コンボボックス(cbo2)に変化のあった時実行イベント
・ ino1 = .ListIndex → 選ばれているリスト番号取得 
・ If ino1 = -1 Then → 「-1」の時は選択なし 
・ meino1 = .List(ino1) → リスト番号のデータを変数(meino1) へ代入
・ mmm = Mid(meino1, 2, 4) → 文字列の2個目から4個取り出し(例[1234] ⇒1234)
・ UserForm1.txt1 = mmm  → 銘柄コードをテキストボックス(txt1)へ記入
・ neigara = Mid(meino1, ksu + 1) → 文字列(meino1)から銘柄名取出し(例[1301]極洋⇒極洋)
[3] コマンドボタン(cmb1)に変化のあった時実行イベントで、「次へ」コール
[4] コマンドボタン(cmb2)に変化のあった時実行イベントで、「戻る」コール


(4)コンボボックス1へ業種登録
Sheet2の一覧表の業種名をチェックし、コンボボックス1へ登録

Sub 選択登録()
Dim gyousyu As String  '業種名仮保存
Dim n As Integer       '数字
gyousyu = "": n = 1

'数量チェック
For i = 1 To motod(0, 0)
    If motod(2, i) <> gyousyu Then     '[1]
        n = n + 1
        gyousyu = motod(2, i)
    End If
Next

'コンボボックス1へ
ReDim cbo2d(n - 1) As String            '[2]
n = 1
For i = 1 To motod(0, 0)
    If motod(2, i) <> gyousyu Then      '[3]
        cbo2d(n) = motod(2, i)
        gyousyu = motod(2, i)
        n = n + 1
    End If
Next
UserForm1.cbo1.List = cbo2d             '[4]

' 選択なしの場合は0
With UserForm1.cbo1
        ino1 = .ListIndex
        If ino1 = -1 Then
           UserForm1.cbo1.ListIndex = (0)   '[5]
        End If
End With
End Sub

[1] コンボボックス1(cbo1)登録する数量チェック
[2] コンボへ登録するための動的配列(cbo2d)宣言⇒内容は初期化
[3] 動的配列(cbo2d)へデータ代入(1からスタートで0は空白)
 ・業種に変化があるか配列(motod)の若番号から順次チェック
 ・業種が変わった場合、配列(cbo2d)へ代入
 ・n = n + 1 → 次に入れる配列番号
[4] コンボボックス1(cbo1)へ一括登録
[5] 選択なしの場合は空白表示 → リスト(0)は空白になっている

(5)同一業種を抽出
コンボボックス1の業種を選ぶと、本ポロシージャが実行され、その業種ないの 銘柄をコンボボックス2へ登録する。

Sub 業種別配列()
Dim selctdat As String

'選択番号                          '[1]
    With UserForm1.cbo1 
        ino1 = .ListIndex 
        If ino1 = -1 Then
            UserForm1.lbl1.Caption = "選択ボックスの項目を指定して下さい"
            Exit Sub
        End If
        selctdat = .List(ino1)
    End With

If ino1 = 0 Then                    '[2]
    Exit Sub
End If

endcbo = motod(0, 0)
ReDim meigara(1, endcbo)            '[3]
na = 1
    
' 同一業種の銘柄を配列へ            '[4]
    For i = 1 To endcbo
        If motod(2, i) = selctdat Then
            meigara(0, na) = motod(0, i)
            meigara(1, na) = motod(1, i)
            na = na + 1
        End If
    Next
        meigara(0, 0) = na - 1      '[5]
        meigara(1, 0) = selctdat
'コンボボックス2へ
    Call コンボ2                    '[6]

End Sub
[1] コンボボックス1(cbo1)の選ればれているリスト番号チェック
 ・「-1」の場合は選択なしでありメセージを表示
 ・selctdat = .List(ino1) → 選ばれた業種名を変数(selctdat)へ代入
[2] 選ばれた番号が「0」の場合は空白であり以降の処理は行わない
[3] 同一業種内の銘柄記録するための動的配列(meigara)宣言⇒内容は初期化
[4] 同一業種の銘柄を配列(meigara)へ
 ・業種に変化があるか配列(motod)の若番号から順次チェック
 ・業種が同じ場合、配列(meigara)へ代入、0列→コード、1列→銘柄
[5] 配列(meigara)の0列へ、記録した銘柄数量、業種名を入れる
[6] コンボボックス2へ登録するため、「コンボ2」コール

(6)コンボボックス2へ銘柄登録

Sub コンボ2()
ReDim cbo2d(meigara(0, 0))                               '[1]
For i = 1 To meigara(0, 0)                               '[2]
    cbo2d(i) = "[" & meigara(0, i) & "]" & meigara(1, i)
Next
    UserForm1.cbo2.List = cbo2d                          '[3]
    
UserForm1.cbo2.ListIndex = (1)                           '[4]
UserForm1.lbl1.Caption = meigara(1, 0) & "の[" & meigara(0, 0) & "]件「銘柄指定」ボックスに登録しました。"

End Sub
[1] コンボへ登録するための動的配列(cbo2d)宣言⇒内容は初期化
[2] 動的配列(cbo2d)へデータ代入(1からスタートで0は空白)
 ・コードと銘柄の登録であるが、見やすくする為コードを[]で括ってある
[3] コンボボックス1(cbo2)へ一括登録
[4] 登録した初期の時点は、リスト(1)を選ぶ

(7)コンボボックス2の次の銘柄表示
連続して銘柄を指定したい場合、毎回コンボボックス2から選ぶのは面倒であり、 「次へ」ボタンを付けた。ボタンが押された時このポロシージャを実行。

Sub 次へ()

With UserForm1.cbo2
    ino1 = .ListIndex               '[1]
    inonx = ino1 + 1                               '[2]
    inoen = .ListCount - 1                         '[3]
        If inonx > inoen Then                      '[4]
            MsgBox "リストにこれ以上入っていません"
            Exit Sub
        Else
            meino1 = .List(inonx)
            mmm = Mid(meino1, 2, 4)
            UserForm1.txt1 = mmm                   '[5]
            .ListIndex = inonx                     '[6]
        End If
End With
    
End Sub
[1] 選択されているリスト番号を変数(ino1)へ代入
[2] リスト番号を+1
[3] リストの最終番号確認
[4] 最終番号を越した場合はメッセージ表示
[5] +1されたリスト番号の銘柄コードを、テキストボックス(txt1)へ表示
[6] +1されたリスト番号を、コンボボックス2の選択番号にする

(8)コンボボックス2の1個前の銘柄表示
連続して銘柄を指定したい場合、毎回コンボボックス2から選ぶのは面倒であり、 「戻る」ボタンを付けた。ボタンが押された時このポロシージャを実行。

Sub 戻る()
With UserForm1.cbo2
    ino1 = .ListIndex                      '[1]
    inonx = ino1 - 1                       '[2]
        If inonx <= -1 Then                '[3]
            MsgBox "リストにこれ以上入っていません"
            Exit Sub
        Else
            meino1 = .List(inonx)
            mmm = Mid(meino1, 2, 4)
            UserForm1.txt1 = mmm           '[4]
            .ListIndex = inonx             '[5]    
        End If
    End With
End Sub
[1] 選択されているリスト番号を変数(ino1)へ代入
[2] リスト番号を+1
[3] マイナスになった場合はメッセージ表示
[4] -1されたリスト番号の銘柄コードを、テキストボックス(txt1)へ表示
[5] -1されたリスト番号を、コンボボックス2の選択番号にする



【戻る】