第5講 配列の学習
第6話 配列による成績一覧表の改良の解説その1
'配列へのランダムデータのコピー
Dim a(39, 6) As Integer
For i = 0 To 39
For j = 1 To 6
a(i, j) = DataGridView1(j, i + 1).Value
Next
Next
'各生徒の5教科合計・平均・合否・講評の算出と表示
For i = 1 To 40
'合計・平均の算出
a(i - 1, 6) = 0
For j = 1 To 5
a(i - 1, 6) = a(i - 1, 6) + DataGridView1(j, i).Value
Next
'合計・平均の表示
DataGridView1(6, i).Value = a(i - 1, 6)
DataGridView1(7, i).Value = a(i - 1, 6) / 5
'合否の表示
If a(i - 1, 6) >= 250 Then
DataGridView1(11, i).Value = "合格"
Else
DataGridView1(11, i).Value = "不合格"
End If
'講評の表示
If a(i - 1, 6) >= 350 Then
DataGridView1(12, i).Value = "上位合格です。"
Else
If a(i - 1, 6) >= 280 Then
DataGridView1(12, i).Value = "余裕で合格です。"
Else
If a(i - 1, 6) >= 250 Then
DataGridView1(12, i).Value = "ぎりぎり合格です。"
Else
If a(i - 1, 6) >= 230 Then
DataGridView1(12, i).Value = "合格まで後一歩。"
Else
DataGridView1(12, i).Value = "よく勉強して再挑戦!"
End If
End If
End If
End If
Next
'教科合計・平均の算出と表示
For i = 1 To 5
'合計・平均の算出
w = 0
For j = 1 To 40
w = w + a(j - 1, i)
Next
'合計・平均の表示
DataGridView1(i, 41).Value = w
DataGridView1(i, 42).Value = w / 40
Next
'各生徒の最高点・最低点の算出と表示
Dim max As Integer, min As Integer
For i = 1 To 40
max = 0
min = 100
For j = 1 To 5
If a(i - 1, j) > max Then max = a(i - 1, j)
If a(i - 1, j) < min Then min = a(i - 1, j)
Next
DataGridView1(8, i).Value = max
DataGridView1(9, i).Value = min
Next
'各教科の最高点と最低点の算出と表示
For i = 1 To 5
max = 0
min = 100
For j = 1 To 40
If a(j - 1, i) > max Then max = a(j - 1, i)
If a(j - 1, i) < min Then min = a(j - 1, i)
Next
DataGridView1(i, 43).Value = max
DataGridView1(i, 44).Value = min
Next
'成績順並び替え
Dim w1 As String, w2 As String, bn As Integer
For i = 40 To 2 Step -1
min = 500
For j = 1 To i
If a(j - 1, 6) <= min Then
min = a(j - 1, 6)
bn = j
End If
Next
For j = 0 To 6
w2 = a(bn - 1, j)
a(bn - 1, j) = a(i - 1, j)
a(i - 1, j) = w2
Next
For j = 0 To 12
w1 = DataGridView1(j, bn).Value
DataGridView1(j, bn).Value = DataGridView1(j, i).Value
DataGridView1(j, i).Value = w1
Next
Next
'順位付け
For i = 1 To 40
DataGridView1(10, i).Value = i
Next
For i = 2 To 40
If a(i, j - 1, 6) = a(i, j - 2, 6) Then DataGridView1(10, i * 47
+ j + 1).Value = DataGridView1(10, i * 47 + j).Value
Next
'出席番号順並び替え
For i = 40 To 2 Step -1
max = 0
For j = 1 To i
If DataGridView1(0, j).Value > max Then
max = DataGridView1(0, j).Value
bn = j
End If
Next
For j = 0 To 6
w1 = a(bn - 1, j)
a(bn - 1, j) = a(i - 1, j)
a(i - 1, j) = w1
Next
For j = 0 To 12
w1 = DataGridView1(j, bn).Value
DataGridView1(j, bn).Value = DataGridView1(j, i).Value
DataGridView1(j, i).Value = w1
Next
Next
さて、1行1行解説していきましょう。
まず、最初の7行について見ていきましょう。
'配列へのランダムデータのコピー
Dim a(39, 6) As Integer
For i = 0 To 39
For j = 1 To 6
a(i, j) = DataGridView1(j, i + 1).Value
Next
Next
Dim a(39, 6) As Integer は40行7列の配列を用意します。
出席番号1番から40番までで40行分のデータがあります。
列の方は、出席番号・国語・社会・数学・理科・英語・合計の7列です。
合計値まで配列に入れるのは、後に合計値を使って並び替えをするからです。
VC++から入ってきた方は、うっかりすると40行7列に対して、
Dim a(40, 7) As Integer; とされてしまうかもしれません.。
VC++では、int a(40,7); と宣言すれば、40行7列の配列を用意したことになりました。
理由は、39や6は最後の添え字数ではなく、配列変数の個数を意味しているからです。
VC++では、int a[10]; と宣言すれば、
a[0],a[1],a[2],a[3],a[4],a[5],a[7],a[8],a[9]
でa[9]までしか配列は用意されません。int a[10]; の10は最後の添え字の番号でなく用意される変数の個数だからです。
ですから、40行×7列の配列変数を用意したいなら
a[0][0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5],a[0][6],
a[1][0],a[1][1],a[1][2],a[1][3],a[1][4],a[1][5],a[1][6],
・
・
・
・
a[39][0],a[39][1],a[39][2],a[39][3],a[39][4],a[39][5],a[39][6]
40行×7列の配列変数を用意したいなら、int a[40][7]; と宣言しなければならないのです。
ところが、VBでは、Din a(9) As Integerの9は最後の添え字の数を表すのではなく、配列変数個数を表しますので、
a(0),a(1),a(2),a(3),a(4),a(5),a(7),a(8),a(9),a(10)
で11個変数が用意されることになります。
ですから、
a(0,0),a(0,1),a(0,2),a(0,3),a(0,4),a(0,5),a(0,6),
a(1,0),a(1,1),a(1,2),a(1,3),a(1,4),a(1,5),a(1,6),
・
・
・
・
a(39,0),a(39,1),a(39,2),a(39,3),a(39,4),a(39,5),a(39,6)
を用意したければ、Dim a(40,7); ではなくDim a(39,6); としなければならないのです。
ただし、多少変数が余計に用意されても気にする必要はありません。
パソコン初期は、搭載メモリーが少なかったので無駄なメモリーを使うことは避けなければなりませんでしたから、
神経を使う必要がありましたが、現在は豊富なメモリーを積んでいますから、気にする必要がないのです。
むしろ、実行エラー対策としてむしろ少し大きめに用意するぐらいでよいでしょう。
次に気をつけなければならないのは、
a(i, j) = DataGridView1(j, i + 1).Value
の部分です。iとjが反対であり、iは1つずれています。
DataGridViewは、最初の行は0行目と数えます。
'配列へのランダムデータのコピー
Dim a(39, 6) As Integer
For i = 0 To 39
For j = 1 To 6
a(i, j) = DataGridView1(j, i + 1).Value
Next
Next
ですから、DataGridView1(j, i + 1).Valueの行番号と出席番号が一致しています。
列も最初は0列目と数えるので、
1列目2行目すなわち出席番号1の欄は、DataGridView1(0, 1).Valueですし、
2列目2行目すなわち出席番号1番の国語の成績41の欄は、DataGridView1(1, 1).Valueです
1列目2行目すなわち出席番号1の欄は、一番最初のデータですからそれに対応する配列は当然a(0,0)ですし、
2列目2行目すなわち出席番号1番の国語の成績41の欄は、a(0,1)です。
DataGridView1(0, 1).Valueとa[0][0]、DataGridView1(1, 1).Valueとa[0][1]
(列と行が反対ですから、対応も反対です。)
と青が1つずれ、ピンクは一致します。
これが、
a(i, j) = DataGridView1(j, i + 1).Value
となっている理由です。
'各生徒の5教科合計・平均・合否・講評の算出と表示
For i = 1 To 40
'合計・平均の算出
a(i - 1, 6) = 0
For j = 1 To 5
a(i - 1, 6) = a(i - 1, 6) + DataGridView1(j, i).Value
Next
'合計・平均の表示
DataGridView1(6, i).Value = a(i - 1, 6)
DataGridView1(7, i).Value = a(i - 1, 6) / 5
'合否の表示
If a(i - 1, 6) >= 250 Then
DataGridView1(11, i).Value = "合格"
Else
DataGridView1(11, i).Value = "不合格"
End If
'講評の表示
If a(i - 1, 6) >= 350 Then
DataGridView1(12, i).Value = "上位合格です。"
Else
If a(i - 1, 6) >= 280 Then
DataGridView1(12, i).Value = "余裕で合格です。"
Else
If a(i - 1, 6) >= 250 Then
DataGridView1(12, i).Value = "ぎりぎり合格です。"
Else
If a(i - 1, 6) >= 230 Then
DataGridView1(12, i).Value = "合格まで後一歩。"
Else
DataGridView1(12, i).Value = "よく勉強して再挑戦!"
End If
End If
End If
End If
Next
2番目を考究しましょう。
a(i - 1, 6)は改良前ではwでした。これは、7列目(列は0列目から始まるから)
の合計です。a(i - 1, 6)は上図の緑の枠の欄を表すます。
したがって、
a(i - 1, 6) = 0
For j = 1 To 5
a(i - 1, 6) = a(i - 1, 6) + DataGridView1(j, i).Value
Next
は、各行の合計を計算しています。
'合計・平均の表示
DataGridView1(6, i).Value = a(i - 1, 6)
DataGridView1(7, i).Value = a(i - 1, 6) / 5
'合否の表示
If a(i - 1, 6) >= 250 Then
DataGridView1(11, i).Value = "合格"
Else
DataGridView1(11, i).Value = "不合格"
End If
'講評の表示
If a(i - 1, 6) >= 350 Then
DataGridView1(12, i).Value = "上位合格です。"
Else
If a(i - 1, 6) >= 280 Then
DataGridView1(12, i).Value = "余裕で合格です。"
Else
If a(i - 1, 6) >= 250 Then
DataGridView1(12, i).Value = "ぎりぎり合格です。"
Else
If a(i - 1, 6) >= 230 Then
DataGridView1(12, i).Value = "合格まで後一歩。"
Else
DataGridView1(12, i).Value = "よく勉強して再挑戦!"
End If
End If
End If
End If
各行は、a(i - 1, 6)を使った合計・平均・合否・講評の処理と表示です。
'教科合計・平均の算出と表示
For i = 1 To 5
'合計・平均の算出
w = 0
For j = 1 To 40
w = w + a(j - 1, i)
Next
'合計・平均の表示
DataGridView1(i, 41).Value = w
DataGridView1(i, 42).Value = w / 40
Next
の部分は改良前と基本的に同じですが、合計の算出に配列a(行,列)を使用しています。
以後の解説は次話で。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
数学研究室に戻る