第8講 Functionプロシージャ

第2話 重複判定ソフトのFunctionプロシージャによる改良

前話問題解答例
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Dim x, y1, y2, y3, y4 As Integer
     x = TextBox1.Text
     y1 = f(x)
     y2 = g(x)
     y3 = h(x)
     y4 = i(x)

     TextBox2.Text = y1.ToString
     TextBox3.Text = y2.ToString
     TextBox4.Text = y3.ToString
     TextBox5.Text = y4.ToString
   End Sub

   Function f(ByVal x As Integer)
     f = 2 * x
   End Function

   Function g(ByVal x As Integer)
     g = x * x
   End Function

   Function h(ByVal x As Integer)
     h = x * x * x
   End Function

   Function i(ByVal x As Integer)
     i = 3 * x * x * x + 2 * x * x + 3 * x + 5
   End Function

End Class


では皆さん、第7講の作成した重複チェックソフトをFuncitonプロシージャで改良しましょう。
Form1

コード
Public Class Form1
   Dim a(4, 4) As Integer, h As Integer  'hはf2()においてループを継続するかどうかの判定に使う。h=1なら継続でh=0なら中断という設定にしてある。
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     f1() 'ランダム行列の作成
     h = 1
     f2() '行列内の数字の重複の検査
   End Sub

   Sub f1()
     '変数の宣言
     Dim i As Integer, j As Integer
     Dim w As String

     'ランダム行列の発生
     For i = 0 To 4
       For j = 0 To 4
         a(i, j) = Int(400 * Rnd()) '400は実験して適当な値にする。
       Next
    Next

    'ランダム行列の表示
    For i = 0 To 4
      For j = 0 To 4
        If a(i, j) < 10 Then w = w + "00" + a(i, j).ToString + " "
        If a(i, j) >= 10 And a(i, j) < 100 Then w = w + "0" + a(i, j).ToString + " "
        If a(i, j) >= 100 Then w = w + a(i, j).ToString + " "
      Next
      w = w + vbNewLine
    Next
    Label1.Text = w
   End Sub

   Sub f2()
    '変数の宣言
    Dim i As Integer, j As Integer

    '重複検査
    For i = 0 To 4
      For j = 0 To 4
        f3(i, j)
        If h = 0 Then Exit Sub
      Next
    Next

    Label2.Text = "数字の重複がありませんでした。"
   End Sub

   Sub f3(ByVal p As Integer, ByVal q As Integer)
    '変数の宣言

    Dim i As Integer, j As Integer

    '重複検査
    For i = 0 To 4
      For j = 0 To 4
        If p <> i Or q <> j Then  'セルが自分自身と比較しないために必要 セルは常に他のセルと比較しなければならない。
          If a(p, q) = a(i, j) Then
            Label2.Text = "数字の重複がありました。" & vbNewLine + "その数字は" + a(p, q).ToString + "です。"
            h = 0
            Exit Sub
          End If
        End If
      Next
    Next
   End Sub

End Class

実行例


Sub f3は戻り値をもっていませんので、やむを得ずグローバル変数Dim a(4, 4) As Integer, h As Integerのhを用意しましたが、
今回はグローバル変数はDim a(4, 4) As Integerにすることが出来ます。
コードを考えてみてください。
解答例は30行下。































コード例
Public Class Form1
   Dim a(4, 4) As Integer 'グローバル変数hを削除
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     f1() 'ランダム行列の作成
     h = 1
     f2() '行列内の数字の重複の検査
   End Sub

   Sub f1()
     '変数の宣言
     Dim i As Integer, j As Integer
     Dim w As String

     'ランダム行列の発生
     For i = 0 To 4
       For j = 0 To 4
         a(i, j) = Int(400 * Rnd()) '400は実験して適当な値にする。
       Next

    Next

    'ランダム行列の表示
    For i = 0 To 4
      For j = 0 To 4
        If a(i, j) < 10 Then w = w + "00" + a(i, j).ToString + " "
        If a(i, j) >= 10 And a(i, j) < 100 Then w = w + "0" + a(i, j).ToString + " "
        If a(i, j) >= 100 Then w = w + a(i, j).ToString + " "
      Next
      w = w + vbNewLine
    Next
    Label1.Text = w
   End Sub

   Sub f2()
    '変数の宣言
    Dim i As Integer, j As Integer

    '重複検査
    For i = 0 To 4
      For j = 0 To 4
         If f3(i, j) = 0 Then Exit Sub
      Next
    Next

    Label2.Text = "数字の重複がありませんでした。"
   End Sub

   Function f3(ByVal p As Integer, ByVal q As Integer)
    '変数の宣言
    Dim i As Integer, j As Integer

    '重複検査
    For i = 0 To 4
      For j = 0 To 4
        If p <> i Or q <> j Then  'セルが自分自身と比較しないために必要 セルは常に他のセルと比較しなければならない。
          If a(p, q) = a(i, j) Then
            Label2.Text = "数字の重複がありました。" & vbNewLine + "その数字は" + a(p, q).ToString + "です。"
            Retutn(0)
          End If
        End If
      Next
    Next

    Return(1)

   End Sub

End Class


また、Funcitonプロシージャを利用して、第7講第3講で作った

コード
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1(0)
   End Sub

   Sub f1(ByVal w As Integer)
     Dim i As Integer
     For i = 1 To 100
       w = w + i
     Next
     TextBox1.Text = w.ToString
     f2(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

   Sub f2(ByVal w As Integer)
     Dim i As Integer
     For i = 2 To 100 Step 2
       w = w + i
     Next
     TextBox2.Text = w.ToString
     f3(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

   Sub f3(ByVal w As Integer)
     Dim i As Integer
     For i = 1 To 100
       w = w + i * i
     Next
     TextBox1.Text = w.ToString
     f4(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

   Sub f4(ByVal w As Integer)
     Dim i As Integer
     For i = 2 To 100 Step 2
       w = w + i * i
     Next
     TextBox4.Text = w.ToString
     TextBox5.Text = w.ToString
   End Sub

End Class
を少し改良して、解答TextBox5.Text = w.ToStringのようにf4の中で表示するのではなく、
f3kの中で表示させるようにしましょう。
解答例は30行下。



























解答例
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1(0)
   End Sub

   Sub f1(ByVal w As Integer)
     Dim i As Integer
     For i = 1 To 100
       w = w + i
     Next
     TextBox1.Text = w.ToString
     f2(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

   Sub f2(ByVal w As Integer)
     Dim i As Integer
     For i = 2 To 100 Step 2
       w = w + i
     Next
     TextBox2.Text = w.ToString
     f3(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

   Sub f3(ByVal w As Integer)
     Dim i As Integer
     For i = 1 To 100
       w = w + i * i
     Next
     TextBox1.Text = w.ToString
     TextBox5.Text = f4(w).ToString
   End Sub

   Function f4(ByVal w As Integer) As Integer
     Dim i As Integer
     For i = 2 To 100 Step 2
       w = w + i * i
     Next
     TextBox4.Text = w.ToString
     Return (w)
   End Sub

End Class


注 前話ではうっかり、Functionプロシージャの返す値の型を示すのを忘れましたが、
  As Integerのように返す型を入れるようにしましょう。これを入れなても、型指定がない場合VBが自動的に型を割り振りますが、
  わかりやすさ優先で、入れるようにしたいものです。


では、次に文字を返すFuncitonプロシージャを作ってみましょう。
まず、簡単なソフトから。
Form1

コード
Public Class Form1
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Label1.Text = f()
   End Sub
   Function f() As String
     Return ("VBの学習")
   End Function
End Class
実行例

では、引数付きの関数に変更して、
TextBox1に入力された値によって、

評価の右のTextBox2の内容が変わるようにソフトに改良されてください。
評価は、『
80点以上なら大変優秀です。
80点未満70点以上なら優秀です。
70点未満60点以上ならぎりぎり合格です。
60点未満50点以上なら合格まであと少しの努力が必要です。
50点未満ならかなりのがんばりが必要です。
』としましょう。コーティング例は30行下。


























Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Dim n As Integer
     n = TextBox1.Text
     TextBox2.Text = f(n)
   End Sub

   Function f(ByVal n As Integer) As String
     Dim w As String
     If n >= 80 Then w = "大変優秀です。"
     If n < 80 And n >= 70 Then w = "優秀です。"
     If n < 70 And n >= 60 Then w = "ぎりぎり合格です。"
     If n < 60 And n >= 50 Then w = "合格まだ後一歩の努力が必要です。"
     If n <= 50 Then w = "かなりのがんばりが必要です。"
     Return w  ’()入れなくてもよい。
   End Function

End Class


それでは、Funcitonプロシージャを利用したやや本格的なソフト作りに入りましょう。
第5講の第8話で作った成績一覧表作成ソフトをSubプロシージャとFunctionプロシージャによって改良しましょう。
実行画面例

コード
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


    
 '出席番号とランダムデータの発生
     Dim a(3, 39, 6) As Integer, k As Integer
     For i = 0 To 3
       For j = 1 To 40
         a(i, j - 1, 0) = j
       Next
     Next
     For i = 0 To 2
       For j = 1 To 40
         For k = 1 To 5
           a(i, j - 1, k) = Int(101 * Rnd())
         Next
       Next
     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


 
   '各学期合計値・平均値の算出・表示
    For i = 0 To 2
      For j = 1 To 40
        a(i, j - 1, 6) = 0
        For k = 1 To 5
          a(i, j - 1, 6) = a(i, j - 1, 6) + a(i, j - 1, k)
        Next
        DataGridView1(6, i * 47 + j + 1).Value = a(i, j - 1, 6)
        DataGridView1(7, i * 47 + j + 1).Value = a(i, j - 1, 6) / 5
      Next
    Next


 
   '各学期各生徒の最高点・最低点の算出・表示
    Dim max As Integer, min As Integer
    For i = 0 To 2
      For j = 1 To 40
        max = 0
        min = 100
        For k = 1 To 5
          If a(i, j - 1, k) > max Then max = a(i, j - 1, k)
          If a(i, j - 1, k) < min Then min = a(i, j - 1, k)
        Next
        DataGridView1(8, i * 47 + j + 1).Value = max
        DataGridView1(9, i * 47 + j + 1).Value = min
      Next
    Next


    '各学期合否・講評の算出・表示
    For i = 0 To 2
      For j = 1 To 40
        If a(i, j - 1, 6) >= 250 Then DataGridView1(11, i * 47 + j + 1).Value = "合格"
        If a(i, j - 1, 6) < 250 Then DataGridView1(11, i * 47 + j + 1).Value = "不合格"
      Next
      For j = 1 To 40
        If a(i, j - 1, 6) >= 350 Then DataGridView1(12, i * 47 + j + 1).Value = "上位合格です。"
        If a(i, j - 1, 6) < 350 And a(i, j - 1, 6) >= 280 Then DataGridView1(12, i * 47 + j + 1).Value = "余裕で合格です。"
        If a(i, j - 1, 6) < 280 And a(i, j - 1, 6) >= 250 Then DataGridView1(12, i * 47 + j + 1).Value = "ぎりぎり合格です。"
        If a(i, j - 1, 6) < 250 And a(i, j - 1, 6) >= 230 Then DataGridView1(12, i * 47 + j + 1).Value = "合格まで後一歩です。"
        If a(i, j - 1, 6) < 230 Then DataGridView1(12, i * 47 + j + 1).Value = "よく勉強して再挑戦!"
      Next
    Next


   
 '各学期各教科の合計・平均の算出・表示
    For i = 0 To 2
      For j = 1 To 6
        w = 0
        For k = 1 To 40
          w = w + a(i, k - 1, j)
        Next
        DataGridView1(j, i * 47 + 42).Value = w
        DataGridView1(j, i * 47 + 43).Value = w / 40
      Next
      DataGridView1(7, i * 47 + 42).Value = DataGridView1(6, i * 47 + 42).Value / 5
      DataGridView1(7, i * 47 + 43).Value = DataGridView1(7, i * 47 + 42).Value / 40
    Next

   
 '各学期各教科の最高点・算出の算出・表示
     For i = 0 To 2
      For j = 1 To 6
        max = 0
        min = 500
        For k = 1 To 40
          If a(i, k - 1, j) > max Then max = a(i, k - 1, j)
          If a(i, k - 1, j) < min Then min = a(i, k - 1, j)
        Next
        DataGridView1(j, i * 47 + 44).Value = max
        DataGridView1(j, i * 47 + 45).Value = min
      Next
    Next


    '各学期の成績順並び替え
     Dim bn As Integer, w1 As String
     For i = 0 To 2
       For j = 40 To 2 Step -1
         min = 500
         For k = 1 To j
           If a(i, k - 1, 6) < min Then
             min = a(i, k - 1, 6)
             bn = k
           End If
        Next
        For k = 0 To 6
           w = a(i, bn - 1, k)
           a(i, bn - 1, k) = a(i, j - 1, k)
           a(i, j - 1, k) = w
        Next
        For k = 0 To 12
           w1 = DataGridView1(k, i * 47 + bn + 1).Value
           DataGridView1(k, i * 47 + bn + 1).Value = DataGridView1(k, i * 47 + j + 1).Value
           DataGridView1(k, i * 47 + j + 1).Value = w1
        Next
      Next
    Next


    '各学期順位付け
    For i = 0 To 2
      For j = 1 To 40
        DataGridView1(10, i * 47 + j + 1).Value = j
      Next
      For j = 2 To 41
        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
    Next


 
   '各学期出席番号順並び替え
    For i = 0 To 2
      For j = 40 To 2 Step -1
        max = 0
        For k = 1 To j
          
If a(i, k - 1, 6) < min Then
            min = a(i, k - 1, 6)

            bn = k
          End If
        Next
        For k = 0 To 6
          w = a(i, bn - 1, k)
          a(i, bn - 1, k) = a(i, j - 1, k)
          a(i, j - 1, k) = w
        Next
        For k = 0 To 12
          w1 = DataGridView1(k, i * 47 + bn + 1).Value
          DataGridView1(k, i * 47 + bn + 1).Value = DataGridView1(k, i * 47 + j + 1).Value
          DataGridView1(k, i * 47 + j + 1).Value = w1
        Next
      Next
    Next

   End Sub

End Class
(もし成績一覧表作成ソフトを上書きされて、それがない場合は、Form1.txt
からコピペされてください。)

色の付いている部分をすべてプロシージャとして独立させて、
Public Class Form1

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

     '187行追加
     f1()

     
     '見出しを入れる
     
f2()

    
 '出席番号とランダムデータの発生
     f3()

 
    
 '出席番号とランダムデータをDataGridViewに表示させる
     f4()


 
    '各学期合計値・平均値の算出・表示
     f5()

 
 
    '各学期各生徒の最高点・最低点の算出・表示
     f6(
)

     '各学期合否・講評の算出・表示
     f7()


    
 '各学期各教科の合計・平均の算出・表示
     f8()

    
 '各学期各教科の最高点・算出の算出・表示
     f9()


     '各学期の成績順並び替え
     f10()


     '各学期順位付け
     f11()


 
   '各学期出席番号順並び替え
     f12()


   End Sub

End Class
のように変更しましょう。上の記述では、引数が入っていませんが必要なら入れてください。
配列は、すべてのプロシージャで使うのでDim a(3, 39, 6) As Integerをグローバル配列にしてください。
解答例は次話で。



第1話へ 第3話へ

006

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

数学研究室に戻る