第5講 配列の学習

第5話 配列による成績一覧表の改良
第4話問題解答例
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     Dim i As Integer, j As Integer, w As Integer

     '40行追加
     For i = 1 To 45
       DataGridView1.Rows.Add()
     Next

     '1行目に列見出しを入れる。
     DataGridView1(0, 0).Value = "番号 "
     DataGridView1(1, 0).Value = "国語 "
     DataGridView1(2, 0).Value = "社会 "
     DataGridView1(3, 0).Value = "数学 "
     DataGridView1(4, 0).Value = "理科 "
     DataGridView1(5, 0).Value = "英語 "
     DataGridView1(6, 0).Value = "合計 "
     DataGridView1(7, 0).Value = "平均 "
     DataGridView1(8, 0).Value = "最高点"
     DataGridView1(9, 0).Value = "最低点"
     DataGridView1(10, 0).Value = "順位 "
     DataGridView1(11, 0).Value = "合否 "
     DataGridView1(12, 0).Value = "講評 "

     '41行から44行 行見出し
     DataGridView1(0, 41).Value = "合計 "
     DataGridView1(0, 42).Value = "平均 "
     DataGridView1(0, 43).Value = "最高点"
     DataGridView1(0, 44).Value = "最低点"

     '出席番号とランダムデータの発生
     For i = 1 To 40
       DataGridView1(0, i).Value = i
       For j = 1 To 5
         DataGridView1(j, i).Value = Int(101 * Rnd())
       Next
     Next


     '配列へのランダムデータのコピー
     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 DataGridView1(6, i - 1).Value = DataGridView1(6, i).Value Then DataGridView1(10, i).Value = DataGridView1(10, i - 1).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


   End Sub

End Class

どうです。結構難しいでしょう。DataGridView1(*,*)と列行が反対だったり、
dataGridView1(j,i)とa(i,j)のjが1つずれたりずれなかったりと、考えるのが大変です。
一気に直そうとせず、
少しずつ直していくのがこつです。
私は次のように作業を進めることをお勧めします。

まず直そうとしているところを
q
              ・
              ・
              ・
w
をドラッグして、右クリック→切り取りを選びます。
すると、VBのコーティング編集画面は
e
となります。そして、赤い囲いのところから編集して行くのですが、
切り取ったデータを残しておくために、メモ帳を起動して『右クリック→貼り付け』でメモ帳に貼り付けておきます。
r
編集に入る前にいったんビルドし実行し画面を確認します。
t
うまくいったことを確認した上で
赤い囲いに
     '配列へのランダムデータのコピー
     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
     For i = 0 To 39
       For j = 1 To 6
         a(
j, i) = DataGridView1(j, i + 1).Value
       Next
     Next

ビルドには成功しますが、実行ボタンを押すと、
y
トラブルが起きます。
ビルドエラーや実行エラーがなくなるまで新たに加えた部分をよく見直します。

     '配列へのランダムデータのコピー
     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
と直すと、ビルドエラーも実行エラーもしません。
u
さらに編集を続けますが、メモ帳に元のデータが残してありますので、コピペしたい部分をドラッグします。
i
右クリックして、コピーを選び、VBのコーティング場面に戻り右クリック貼り付けを選びます。
o
そして、赤い囲いを編集し直します。
     '各生徒の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

このように編集し直して、ビルドし実行すると
p
で意図通りになっていることがわかります。
このように少しプログラミングをしてから、ビルド実行しうまくいったら、先に進むということを繰り返す習慣をつけてください。
一気にコーティングしてからビルドすることは避けましょう。
ビルドエラーや実行エラー等の原因の解明が難しくなります。
原因がわからずいらいらさせられるものです。

元データをメモ帳に残し、コピペで貼り付けて編集し直していく、
是非とも覚えていただきたいテクニックです。

また、コーティング全体をメモ帳に貼り付けておき、名前をつけて保存すると、
コーティングのバックアップにもなります。
大きく失敗したときは、メモ帳を開き全体をコピペし直せば修復できます。
いろいろな場面で名前をつけて別名で保存しておきたいものです。
ロールプレイングゲームでの必勝法はまめにいろいろな場面で保存しておくことでしたね。
冒険のルートを変更したり、装備アイテムを売ったり、ボスと戦ったりする前に保存しておくことが鉄則ですよね。
自分の隊が全滅してゲームオーバーになっても、保存画面から始められます。
また、冒険のルートや装備アイテムの変更ミスなら、変更する前に戻って冒険を続ければよいのです。
プログラミングもそれと同じでまめにバックアップする習慣をつけたいものです。

尚、解説は次話で。


第4話へ 第6話へ

006

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座

数学研究室に戻る