9月中旬からぼちぼち作ってきた検索システムですが、やっと必要な機能を実装し終わったのでメモを残します。しかし、1つの記事にすると大変な長さになるので、一つずつメモしていきます。この記事では検索システムのユーザフォームに関する事柄をまとめます。
今までの記事は以下のとおりです。
また、GitHubのレポジトリは以下のリンクから見れます。
1. 検索システムのユーザフォームのコード全体
2. 科目のみ検索
前回から大きな変更はありません。
3. 氏名のみ検索
3-1. 文字列の部分一致
InStr関数を用います。構文は以下のとおりです。
InStr([ start ], string1, string2, [ compare ])
string1が検索元の文字列式、string2が検索したい文字列式です。
3-2. 科目と可能/不可能を一覧表示したい
リストボックスにあるように一覧表示させたいです。しかし、検索対象であるシートとコンボボックスのために作っているシートでは科目が一致していない部分があります。これは最初の設計が甘かったことが原因ですが、検索対象のシートをいじる場合GoogleスプレッドシートやGoogleフォームから変更しないといけないため、修正箇所が大きくなります。
そのため、検索対象のシートに合わせることにしました。そして一覧表示を実現するために力技でなんとかしました。
一覧表示するために22行6列の配列を用意しました。そして、奇数行目には科目、偶数行目にはその科目が可能/不可能という情報を逐次格納していきました。
規則的に現れない学年の情報は予め配列の要素として代入しておきます。さらに、科目が一致しない部分の科目も代入しておきます。
その後、二重ループで、外側ループのindexが奇数なら科目を配列に代入、偶数なら可能/不可能を配列に代入していきます。
ただし、中学受験の右の項目は何も入れない場所なので、4行2列目に値が代入されないようにしています。また、現代社会のあとを改行したように見せたかったので、それより後ろの要素4つには何も代入されないようにしています。
3-3. VBAでの余剰
VBAでの余剰計算はModを使います。そのままです。
Dim number As Long
number = 4
If number Mod 2 = 0 Then
MsgBox "偶数" '4は偶数なので偶数とポップアップされる'
End If
3-4. break文,continue文
VBAにはbreak文もcontinue文もありません。break文はExit文、continue文はGoTo文を用いて実現させることが多いようです。
'break文の代用'
Dim i As Long
For i = 1 To 10
If i = 8 Then
Exit For 'i==8のときFor文を抜ける'
End If
Next i
'continue文の代用'
Dim i As Long
For i = 1 To 10
If i = 8 Then
GoTo Continue
End If
Continue:
Next i
3-5. リストボックスのColumnWidthsの数値の区切りはセミコロン
With ListBox1
.ColumnCount = 6
.ColumnWidths = "50;60;60;60;60;60" '区切りはセミコロン!!'
.List = showList
End With
区切りをコロンにするとエラーになります。
3-6. 配列内から指定の要素を削除したい
VBAの配列にeraseなんて実装されていません。そのため自分で実装する必要があります。
配列から指定の要素を削除したい場合は、その要素の次の要素を前にずらして・・・ということを繰り返した後に、配列全体をresizeします。
Dim numberList As Variant
Dim i As Long
numberList = Array(0,1,2,3,4) '1を削除したい'
For i = 1 To UBound(numberList) - 1
numberList(i)=numberList(i + 1) '前に要素をずらしていく'
Next i
ReDim Preserve numberList(UBound(numberList) - 1) 'resize'
要素を前にずらすところの書き方で範囲外参照エラーが出たりするので注意が必要です。経験的にindexを+1などしていると範囲外参照しやすいので、私はその部分は次のように書くことが多いです。
Dim numberList As Variant
Dim i As Long
numberList = Array(0,1,2,3,4) '1を削除したい'
For i = 2 To UBound(numberList)
numberList(i - 1)=numberList(i) 'i-1なら範囲外参照エラーしていてもすぐに気がつける'
Next i
ReDim Preserve numberList(UBound(numberList) - 1) 'resize'
3-7. メッセージボックスの出し方
MsgBox関数を使用します。構文は次のとおりです。
MsgBox (prompt, [ buttons, ] [ title, ] [ helpfile, context ])
promptがメッセージボックスに表示されるメッセージです。
buttonsは表示させるボタンを指定します。
titleはメッセージボックスのウィンドウのタイトルに表示させる文字列を指定します。
構文はカッコで囲っていますが、次のように書いても表示されます。
MsgBox "message", vbYesNo, "messageBox"
さらにメッセージに変数の値と文字列を表示させたい場合は次のように書きます。
Dim x As Long
x = 100
MsgBox "value=" & x
変数の前にスペースがないとエラーが出たりします。
3-9. ユーザフォームのクリアボタンを実装
UserForm_Initializeを呼び出します。
3-10. テキストボックスやリストボックスの初期化
テキストボックスは次のように初期化します。
TextBox1.Text = ""
リストボックスは次のように初期化します。
ListBox1.Clear
4. おわりに
アセンブリ言語を書いたとき以来初めてGoTo文を使いました。なんでcontinue文ないんだ・・・。