第5講 配列の学習

第7話 配列による成績一覧表の改良の解説その2

残りの部分を解説していきましょう。 

    '各生徒の最高点・最低点の算出と表示
    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

  

まず、最初
    '各生徒の最高点・最低点の算出と表示
    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

も教科合計の算出とときと同様に、a(行,列)を算出基準に使っている点以外は基本的に改良前と同じです。
つまり、DataGridView1(列, 行).Valueの代わりにa(行,列)を使っているだけです。
ですが、列数は同じですが行数が一つ少なくなっていることに注意が必要です。
以後の
    '各教科の最高点と最低点の算出と表示
    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)
        (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

についても列数は同じですが行数が一つ少なくなっていることに注意しなければならない点は同じです。

    '成績順並び替え
    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 j = 0 To 6
        w2 = a(bn - 1, j)
        a(bn - 1, j) = a(i - 1, j)
        a(i - 1, j) = w2
      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


      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 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
の部分にも解説を入れておきましょう。
最初の3行
    For i = 1 To 40
      DataGridView1(10, i).Value = i
    Next

では単純に1から40まで順位付けをしています。
しかし、これだと同点なのに違う順位がついてしまう場合があります。
見出し
配列
その問題を解決するのが次の3行です。
    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

合計得点が同じ場合、1つ前の出席番号の生徒の順位をその生徒の順位としてつけ直せば問題は解消します。

では、最後に課題です。
出席番号順成績一覧表の下に、
成績順別成績一覧表も表示させてみましょう。
その際、配列a(i,j)を使うことを条件とさせていただきます。

もし、40行7列の配列が中途半端だとお思いなら、
成績一覧表と同じ45行13列の配列を用意されても結構です。
40行7列の配列だと、再度合計点や講評などを処理しなければならないので非合理的かもしれません。
プログラミングは試行錯誤です。
自分で、あうでもないこうでもない、と思案を繰り返さないと上達はできません。
次話では、申し訳ありませんが模範解答例は示しません。
プログラミングは、プログラマーが意図した通りに動けば、正解です。
ですから、同じ課題であってもプログラマーの数だけ正解があるのです。
本講座で示してきた解答例は、あくまで例に過ぎないのです。

次話では、3次元配列を用意して、成績一覧表を3学期まで拡大し、
年間成績も処理してみたいと思います。
途中までのコーティングを掲載しておきますので、
それを参考に年間成績も考えてください。
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

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

     For i = 0 To 3
       '見出しを入れる
       If i = 0 Then DataGridView1(0, 47 * i).Value = "1学期"
       If i = 1 Then DataGridView1(0, 47 * i).Value = "2学期"
       If i = 2 Then DataGridView1(0, 47 * i).Value = "3学期"
       If i = 3 Then DataGridView1(0, 47 * i).Value = "1年間"

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

       '行見出し
       DataGridView1(0, 42 + 47 * i).Value = "合計 "
       DataGridView1(0, 43 + 47 * i).Value = "平均 "
       DataGridView1(0, 44 + 47 * i).Value = "最高点"
       DataGridView1(0, 45 + 47 * i).Value = "最低点"
     Next
 
     '出席番号とランダムデータをDataGridViewに表示させる
     For i = 0 To 3
       For j = 1 To 40
         DataGridView1(0, i * 47 + j + 1).Value = a(i, j - 1, 0)
       Next
     Next
     For i = 0 To 2
       For j = 1 To 40
         For k = 1 To 5
           DataGridView1(k, i * 47 + j + 1).Value = a(i, j - 1, k)
         Next
       Next
    Next

   End Sub

End Class

実行結果例
行間
改良





第6話へ 第8話へ

006

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

数学研究室に戻る