§6 計算(3) 1 vb2005 プログラミング実習 [Menu]
 back next 

 複数のデータを計算するプログラムについて学習する。
 これまでは、計算に使用するデータを入力するため、データの個数だけテキストボックスで入力欄を用意した。しかし、データの個数が10個、20個と増えた場合に対応することができない。1つのテキストボックスに複数のデータが入力できるようにプログラムする。

計算3のプログラム @:ラベル
   入力欄の説明用
 A:テキストボックス
   データ入力欄等
 B:ボタン

【1】 プログラム作成の準備

(1) Windowsアプリケーションを作成するためのプロジェクトを作成する。
 プロジェクト名は「計算3」とする。

(2) フォーム(Form1)のプロパティを次のように設定する。

Size 360,300
Text 計算3

(3) 上の図を参考にして、必要なオブジェクトを配置し、プロパティを設定する。

@ ラベル
(Name) Label1   (Name) Label2
Text 数値データ Text 計算結果

A テキストボックス
(Name) Data1   (Name) Kotae
Text 0 Text 0
Multiline True
ScrollBars Vertical(垂直)

B ボタン
(Name) KeisanButton   (Name) EndButton
Text 計 算 Text 終 了

(4) プログラムを保存する。

 [ファイル(F)] → [すべてを保存(L)]

(5) プログラムを実行する。

結果 数値は入力できるが、どのボタンをクリックしても何も起こらない。

 

【2】 複数データの処理

 データ入力用のテキストボックス(Data1)は、複数行にわたってデータが入力できるように、MultilineプロパティをTrueに設定する。ここで問題になるのが、複数のデータをどのように処理するかである。

@
1▽
2▽
3▽
4▽
5▽
6▽
7▽
8▽
9▽
10
A
1,2,3,4,5,6,7,8,9,10
B
1,2,3▽
4,5,▽
6,7,8▽
9▽
10
▽ は改行文字(見えない)

 例えば、1,2,3,4,5,6,7,8,9,10の10個のデータを処理する場合を考える。
 まず、入力の方法であるが、@「1行に1つずつ」、A「1つずつカンマ(,)で区切る」、B「@A混在」という方法が考えられる。方法としては3種類であるが、Bの方法で入力できるようにプログラミングすれば、@Aの両方に対応できるので、ここではB「@A混在」の入力方法に対応できるようにする。

 Bの場合、データの区切りがカンマと改行文字の2種類あるので、どちらか一つにまとめると後の処理が簡単になる。つまり、Bのように入力されたデータを@またはAのように変換する。ここでは、Aのように変換することにする。

(6) まず、Bのように入力したデータを表示する。表示用に[計算](KeisanButton)のクリックイベントに対応するメソッドを次のように作成する。

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KeisanButton.Click
        Dim moto As String
        moto = Data1.Text
        MsgBox(moto)
    End Sub
結果 Bのように入力して[合計]ボタンをクリックすると、Bと同じようにメッセージボックスに表示される。
実行結果

(7) 次に、Bのように入力したデータをAのように変換する。つまり、改行文字をカンマに変換する。[計算](KeisanButton)のメソッドに次のように追加する。

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KeisanButton.Click
        Dim moto As String, pt As Integer
        moto = Data1.Text & ","        'データの最後にカンマを追加
        pt = 1        '検索開始位置(1文字目)
        Do        '永久ループ
            pt = InStr(pt, moto, vbCrLf)    '改行文字(VbCrLf)を検索
            If pt = 0 Then        '改行文字なし
                Exit Do                'ループを抜ける
            End If
            moto = Mid(moto, 1, pt - 1) & "," & Mid(moto, pt + 2)
        Loop
        MsgBox(moto)
    End Sub

 まず、使われている関数について簡単にまとめておく。

InStr(検索開始位置, 被検索文字列, 検索文字)
 被検索文字列検索開始位置 から 検索文字 と一致する文字を検索して、そのの位置を返却する。見つからなければ 0 を返却する。

Mid(文字列, 開始位置, 文字数)
 文字列開始位置 から 文字数 だけの文字列を返却する。

Mid(文字列, 開始位置)
 文字列開始位置 から末尾までの文字列を返却する。

 改行文字の位置を調べて変数ptに記憶させる。改行文字より前半部は「Mid(moto, 1, pt-1)」で、改行文字より後半部は「Mid(moto, pt+2)」で取り出している。ここで、後半部でpt+2としているのは、改行文字が半角2文字分であるためである。

 次に、変数の値の変化を次に示す。(プログラムの「トレース」という)

ループ
回数
moto pt Mid(moto, 1, pt-1) Mid(moto, pt+2)
1,2,3▽4,5,▽6,7,8▽9▽10, 1 ↑前半部 ↑後半部
1 1,2,3▽4,5,▽6,7,8▽9▽10, 6 1,2,3 4,5,▽6,7,8▽9▽10,
2 1,2,3,4,5,▽6,7,8▽9▽10, 11 1,2,3,4,5, 6,7,8▽9▽10,
3 1,2,3,4,5,,6,7,8▽9▽10, 17 1,2,3,4,5,,6,7,8 9▽10,
4 1,2,3,4,5,,6,7,8,9▽10, 19 1,2,3,4,5,,6,7,8,9 10,
5 1,2,3,4,5,,6,7,8,9,10, 0    
結果 Bのように入力して[計算]ボタンをクリックすると、Aと同じようにメッセージボックスに表示される。しかし、よく見ると、5の後にカンマが2つある。
実行結果 データの5の後にはすでにカンマがあり、続いて改行文字(▽)があるため、2回目のループのところでカンマが連続することになる。

(8) 「4,5,▽」のようにカンマと改行が連続しているデータに対応する。[計算](KeisanButton)のメソッドを次のように追加・修正する。

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KeisanButton.Click
        Dim moto As String, pt As Integer
        moto = Data1.Text & ","        'データの最後にカンマを追加
        pt = 1        '検索開始位置(1文字目)
        Do        '永久ループ
            pt = InStr(pt, moto, vbCrLf)    '改行文字(VbCrLf)を検索
            If pt = 0 Then    '改行文字なし
                Exit Do            'ループを抜ける
            End If
            If Mid(moto, pt - 1, 1) = "," Then    '改行文字の直前がカンマ
                moto = Mid(moto, 1, pt - 1) & Mid(moto, pt + 2)    '改行文字削除
            Else
                moto = Mid(moto, 1, pt - 1) & "," & Mid(moto, pt + 2)    '連結
            End If
        Loop
        MsgBox(moto)
    End Sub

結果 Bのように入力して[計算]ボタンをクリックすると、Aと同じようにメッセージボックスに表示される。
実行結果

 変換されたデータは、変数motoに次のように1つの文字列データとして記憶されている。

"1,2,3,4,5,6,7,8,9,10,"

 このデータを1つ1つのデータに分ける必要がある。その処理手順を次に示す。

  1. カンマの位置(先頭から何文字目)を調べて、変数ptに格納する。
     pt = InStr(moto, ",")
  2. カンマの直前までの文字を取り出して数値に変換して、変数dに格納する。
     d = Val(Mid(moto, 1, pt - 1))
  3. カンマまでの文字を元のデータから削除する。
     moto = Mid(moto, pt + 1)

 以上、データがなくなるまで繰り返す。

(9) カンマで区切られたテータを1つずつ分ける。[計算](KeisanButton)のメソッドを次のように追加・修正する。

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KeisanButton.Click
        Dim moto As String, pt As Integer, d As Integer
        moto = Data1.Text & ","    'データの最後にカンマを追加
        pt = 1    '検索開始位置(1文字目)
        Do        '永久ループ
            pt = InStr(pt, moto, vbCrLf)    '改行文字(VbCrLf)を検索
            If pt = 0 Then    '改行文字なし
                Exit Do        'ループを抜ける
            End If
            If Mid(moto, pt - 1, 1) = "," Then    '改行文字の直前がカンマ
                moto = Mid(moto, 1, pt - 1) & Mid(moto, pt + 2)    '改行文字削除
            Else
                moto = Mid(moto, 1, pt - 1) & "," & Mid(moto, pt + 2)    '連結
            End If
        Loop
        Do Until Len(moto) = 0
            pt = InStr(moto, ",")    'カンマを検索
            d = Val(Mid(moto, 1, pt - 1))    '先頭からカンマ直前まで
            MsgBox(d)     '確認用
            moto = Mid(moto, pt + 1)    'カンマ直後をmotoに
            MsgBox(moto) '確認用
        Loop
    End Sub

 関数Lenは文字列の長さ(文字数)を返却する関数である。
 「Do 〜 Loop」で永久ループになるが、「Do Until 条件式 〜 Loop」とすると条件式が真になるまで繰り返し、条件式が真になったらループを終える。
 同じような繰り返しに「Do While 条件式 〜 Loop」は条件式が真の間、繰り返す。また、「Do 〜 Loop Until 条件式」や「Do 〜 Loop While 条件式」のように条件をLoopの後に書くこともできる。

結果 Bのように入力して[計算]ボタンをクリックすると、メッセージボックスに取り出したデータ、残りのデータの順に繰り返し表示される。

「1」→「2,3,4,5,6,7,8,9,10,」→「2」→「3,4,5,6,7,8,9,10,」→「3」→「4,5,6,7,8,9,10,」→「4」→「5,6,7,8,9,10,」→「5」→「6,7,8,9,10,」→「6」→「7,8,9,10,」→「7」→「8,9,10,」→「8」→「9,10,」→「9」→「10,」→「10」→「なし」

 以上で@、A、Bのどのような入力方法にも対応できるようになった。



 back next 
 §6 計算(3) 1 vb2005 Copyright©2007 Hiroshi Masuda 
inserted by FC2 system