問題1
1)For~Next文とIf文を用いて実現せよ
2)For~Next文とSelect文を用いて実現せよ
3)配列とFunctionプロシージャを用い、For文とDo While文を用いて実現せよ
4)配列とサブルーチンを用いて、For文とサブルーチンのなかにDo Until文を仕込んで実現せよ
5)CurrentRegionとサブルーチンを用いて実現せよ。繰り返しと分岐処理はサブルーチンのなかで行うものとする
6)CurrentRegionとFunctionプロシージャを用い、Do Until文を用いて実現せよ
解答
1)
Sub main()
Dim i As Integer
For i = 2 To 7
If Cells(i, 2) >= 1000000 Then
Cells(i, 4) = "A"
ElseIf Cells(i, 2) >= 800000 Then
Cells(i, 4) = "B"
ElseIf Cells(i, 2) >= 600000 Then
Cells(i, 4) = "C"
ElseIf Cells(i, 2) >= 400000 Then
Cells(i, 4) = "D"
ElseIf Cells(i, 2) >= 200000 Then
Cells(i, 4) = "E"
Else
Cells(i, 4) = "ランク外"
End If
Next i
End Sub
ElseIf文があれば、どれだけ長い分岐処理でもIf文で書けるが、分岐が4つ以上あれば、通常は2)の方法を取るべきである。
2)
Sub main1()
Dim i As Integer
For i = 2 To 7
Select Case Cells(i, 2)
Case Is >= 1000000
Cells(i, 4) = "A"
Case Is >= 800000
Cells(i, 4) = "B"
Case Is >= 600000
Cells(i, 4) = "C"
Case Is >= 400000
Cells(i, 4) = "D"
Case Is >= 200000
Cells(i, 4) = "E"
Case Else
Cells(i, 4) = "ランク外"
End Select
Next i
End Sub
Case文は多数の分岐処理を記述するのに最適な方法である。If文との優劣はないにせよ、どちらもケースバイケースで使えるようになって欲しい。
3)
Sub main2()
Dim myarry(6) As Integer, i As Integer
For i = 1 To 6
myarry(i) = Cells(i + 1, 2) / 1000
Next i
i = 1
Do While Cells(i + 1, 2) <> ""
Cells(i + 1, 4) = getMoneydt(myarry(), i)
i = i + 1
Loop
End Sub
ーーーーーーーーーーーーーーーーーーーーーーー
Function getMoneydt(myarry() As Integer, i As Integer) As String
Select Case myarry(i)
Case Is >= 1000
getMoneydt = "A"
Case Is >= 800
getMoneydt = "B"
Case Is >= 600
getMoneydt = "C"
Case Is >= 400
getMoneydt = "D"
Case Is >= 200
getMoneydt = "E"
Case Else
getMoneydt = "ランク外"
End Select
End Function
1000で割っているのはInteger型を使うためである。いまはメモリーがふんだんにあるので、Long型を使うのが普通になっているが、昔の癖である。Long型を普通に使うのがいまの流行らしい。
このルーチンは、一度配列に1000で割った配列の値を代入し、それをDo While文で空白ではない間(〇〇ではない間はWhileを使う)、Functionプロシージャを使ってセルに値を入れている。カウンター変数のiは入力するセルを制御している。
4)
Sub main3()
Dim myarry(6) As Integer, i As Integer
For i = 1 To 6
myarry(i) = Cells(i + 1, 2) / 1000
Next i
Call getMoney(myarry())
End Sub
ーーーーーーーーーーーーーーーーーーーーーーー
Sub getMoney(myarry() As Integer)
Dim i As Integer
i = 1
Do Until Cells(i + 1, 2) = ""
If myarry(i) >= 1000 Then
Cells(i + 1, 4) = "A"
ElseIf myarry(i) >= 800 Then
Cells(i + 1, 4) = "B"
ElseIf myarry(i) >= 600 Then
Cells(i + 1, 4) = "C"
ElseIf myarry(i) >= 400 Then
Cells(i + 1, 4) = "D"
ElseIf myarry(i) >= 200 Then
Cells(i + 1, 4) = "E"
Else
Cells(i + 1, 4) = "ランク外"
End If
i = i + 1
Loop
End Sub
配列にFor文でまわして変数を入れ、サブルーチンでセルに値を入れている。If文をDo Until文で回している、すこし保守性が悪いサブルーチンである。
5)
Sub main4()
Dim myarry As Variant
myarry = Range("A1").CurrentRegion
Call getMoneyList(myarry)
End Sub
ーーーーーーーーーーーーーーーーーーーーーーー
Sub getMoneyList(myarry As Variant)
Dim i As Integer
For i = 2 To UBound(myarry)
If myarry(i, 2) / 1000 >= 1000 Then
Cells(i, 4) = "A"
ElseIf myarry(i, 2) / 1000 >= 800 Then
Cells(i, 4) = "B"
ElseIf myarry(i, 2) / 1000 >= 600 Then
Cells(i, 4) = "C"
ElseIf myarry(i, 2) / 1000 >= 400 Then
Cells(i, 4) = "D"
ElseIf myarry(i, 2) / 1000 >= 200 Then
Cells(i, 4) = "E"
Else
Cells(i, 4) = "ランク外"
End If
Next i
End Sub
名前(String型)と数値が混在している表を一発でとる(CurrentRegion)にはVariant型が必要である。そのVariant型を引数としてサブルーチンへ渡して、その中で処理をしている例である。サブルーチンのUBoundはVariant型の最終行を取り、If文のなかで1000で割ることで、Integer型を使えるようにしている。
6)
Sub main5()
Dim myarry As Variant
Dim i As Integer
myarry = Range("A1").CurrentRegion
i = 1
Do Until Cells(i + 1, 2) = ""
Cells(i + 1, 4) = getMoneyListdt(myarry, i)
i = i + 1
Loop
End Sub
ーーーーーーーーーーーーーーーーーーーーーーー
Function getMoneyListdt(myarry As Variant, i As Integer) As String
Select Case myarry(i + 1, 2) / 1000
Case Is >= 1000
getMoneyListdt = "A"
Case Is >= 800
getMoneyListdt = "B"
Case Is >= 600
getMoneyListdt = "C"
Case Is >= 400
getMoneyListdt = "D"
Case Is >= 200
getMoneyListdt = "E"
Case Else
getMoneyListdt = "ランク外"
End Select
End Function
5)と同様にVariant型で表を一発でとり、Functionプロシージャを使って、Do Until文でセルに値を入れ、制御カウンターiで入力セルを確定している。