第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(行,列)を使用しています。
以後の解説は次話で。



第5話へ 第7話へ

006

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

数学研究室に戻る