MENU > HOME VB.NET VB6 VBA ソフトウェア リンク サイト情報
VB.NET> VB.NET 突撃レポート > 1  2  3  4  5  6  7  8  9  10  11  12 
PART4: ファイルの入出力 その1 (2002年3月24日)

今回はプログラムを作る上で基本的な処理の1つでもある、ファイルの入出力について調べてゆきたいと思います。

いきなりVB.NETでファイルを読んでみろ!といわれてもどこから手をつけてゆけば良いのかわかりませんので、まずはVB6にて簡単なテキストファイルビューワを作成してこれをアップグレードウィザードを使用しVB.NET用に変換した結果をみてみましょう。

今回の簡単な仕様です。
1.メインフォームにテキストボックスを全面配置。
2.スタートアップ時にD:\TEST.TXTを1行づつ読み込み、フォーム上のテキストへと内容を追加してゆきます。
3.フォームはサイズ変更可能とします。

ではVB6にて上記仕様のプログラムを作成してみましょう。
 
Option Explicit

Private Sub Form_Load()
    
    Dim intFNo  As Integer
    Dim strBuf  As String
    
    Text1.Top = 0
    Text1.Left = 0
    Text1.Text = ""
        
    intFNo = FreeFile
    Open "D:\TEST.TXT" For Input As intFNo
    Do While Not EOF(intFNo)
        Line Input #intFNo, strBuf
        Text1.Text = Text1.Text & Format$(strBuf,"00") & "行目" & vbCrLf
    Loop
    Close intFNo
    
End Sub

Private Sub Form_Resize()
    Text1.Height = Me.ScaleHeight
    Text1.Width = Me.ScaleWidth
End Sub             


テキストボックスのプロパティの値に関してはMultiLineプロパティ以外すべてForm_Loadイベントにて設定しました。
多少の書き方の違いはあるとは思いますが、だいたいよく似たコーディングをされると思います。
それではこのプロジェクトを保存してください。保存が完了したら、VB6は閉じてください。

いよいよVB.NETの出番です。
先ほど保存したプロジェクト(VBP)をファイルメニュー→開く→プロジェクトから開いてみましょう。

このようなアップグレードウィザードが自動的に開かれます。
画面の指示に従い、ウィザードを進めてゆくとVB6で作成されたプロジェクトがVB.NETのプロジェクトへと変換された後、プロジェクトとして読み込まれます。

以下が変換後のForm1のコードです。
 

Option Strict Off
Option Explicit On
Friend Class Form1
    Inherits System.Windows.Forms.Form
#Region "Windows Form デザイナによって生成されたコード"
    Public Sub New()
        MyBase.New()
        If m_vb6FormDefInstance Is Nothing Then
            If m_InitializingDefInstance Then
                m_vb6FormDefInstance = Me
            Else
                Try 
                    'スタートアップ フォームについては、最初に作成されたインスタンスが既定インスタンスになります。
                    If System.Reflection.Assembly.GetExecutingAssembly.EntryPoint.DeclaringType Is Me.GetType Then
                        m_vb6FormDefInstance = Me
                    End If
                Catch
                End Try
            End If
        End If
        'この呼び出しは、Windows Form デザイナで必要です。
        InitializeComponent()
    End Sub
    'Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
    Protected Overloads Overrides Sub Dispose(ByVal Disposing As Boolean)
        If Disposing Then
            If Not components Is Nothing Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(Disposing)
    End Sub
    'Windows Fom デザイナで必要です。
    Private components As System.ComponentModel.Container
    Public ToolTip1 As System.Windows.Forms.ToolTip
    Public WithEvents Text1 As System.Windows.Forms.TextBox
    'メモ : 以下のプロシージャは Windows Fom デザイナで必要です。
    'Windows Form デザイナを使って変更できます。
    'コードエディタを使って修正しないでください。

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container()
        Me.ToolTip1 = New System.Windows.Forms.ToolTip(components)
        Me.ToolTip1.Active = True
        Me.Text1 = New System.Windows.Forms.TextBox
        Me.Text = "Form1"
        Me.ClientSize = New System.Drawing.Size(312, 206)
        Me.Location = New System.Drawing.Point(4, 30)
        Me.StartPosition = System.Windows.Forms.FormStartPosition.WindowsDefaultLocation
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.BackColor = System.Drawing.SystemColors.Control
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable
        Me.ControlBox = True
        Me.Enabled = True
        Me.KeyPreview = False
        Me.MaximizeBox = True
        Me.MinimizeBox = True
        Me.Cursor = System.Windows.Forms.Cursors.Default
        Me.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me.ShowInTaskbar = True
        Me.HelpButton = False
        Me.WindowState = System.Windows.Forms.FormWindowState.Normal
        Me.Name = "Form1"
        Me.Text1.AutoSize = False
        Me.Text1.Size = New System.Drawing.Size(265, 185)
        Me.Text1.Location = New System.Drawing.Point(0, 0)
        Me.Text1.MultiLine = True
        Me.Text1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
        Me.Text1.TabIndex = 0
        Me.Text1.Text = "Text1"
        Me.Text1.AcceptsReturn = True
        Me.Text1.TextAlign = System.Windows.Forms.HorizontalAlignment.Left
        Me.Text1.BackColor = System.Drawing.SystemColors.Window
        Me.Text1.CausesValidation = True
        Me.Text1.Enabled = True
        Me.Text1.ForeColor = System.Drawing.SystemColors.WindowText
        Me.Text1.HideSelection = True
        Me.Text1.ReadOnly = False
        Me.Text1.Maxlength = 0
        Me.Text1.Cursor = System.Windows.Forms.Cursors.IBeam
        Me.Text1.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me.Text1.TabStop = True
        Me.Text1.Visible = True
        Me.Text1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
        Me.Text1.Name = "Text1"
        Me.Controls.Add(Text1)
    End Sub
#End Region 
#Region "アップグレード ウィザードのサポート コード"
    Private Shared m_vb6FormDefInstance As Form1
    Private Shared m_InitializingDefInstance As Boolean
    Public Shared Property DefInstance() As Form1
        Get
            If m_vb6FormDefInstance Is Nothing OrElse m_vb6FormDefInstance.IsDisposed Then
                m_InitializingDefInstance = True
                m_vb6FormDefInstance = New Form1()
                m_InitializingDefInstance = False
            End If
            DefInstance = m_vb6FormDefInstance
        End Get
        Set
            m_vb6FormDefInstance = Value
        End Set
    End Property
#End Region 
    
    Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
        
        Dim intFNo As Short
        Dim strBuf As String
        
        Text1.Top = 0
        Text1.Left = 0
        Text1.Text = ""
        
        intFNo = FreeFile
        FileOpen(intFNo, "D:\TEST.TXT", OpenMode.Input)
        Do While Not EOF(intFNo)
            strBuf = LineInput(intFNo)
            Text1.Text = Text1.Text & VB6.Format(strBuf, "00") & "行目" & ControlChars.CrLf
        Loop 
        FileClose(intFNo)
        
    End Sub
    
    Private Sub Form1_Resize(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Resize
        Text1.Height = Me.ClientRectangle.Height
        Text1.Width = Me.ClientRectangle.Width
    End Sub
End Class
                

たったあれだけのVB6プロジェクトなのに、よくもまぁこんなに長くなったものです。(大半はコンポーネントの初期化コードですが)
何だかよくわからないところも多いですが、例によってそんなところは後回しで、肝心の部分に注目して進めていきます。

何はともあれ、出来上がったプロジェクトを実行してみることにします。



「う〜ん...。」

なんだかしっくりきませんね。
というか、なぜテキストボックスがクライアント領域いっぱいに表示されていないのでしょう?

Form_Resizeのコードを見てみましょう。

Text1.Height = Me.ClientRectangle.Height
Text1.Width = Me.ClientRectangle.Width

となっています。

このコードを見る限り正しく設定されていると思われますが...。

もしかして起動時にResizeイベントが発生しないのか、イベントの発生順序がまったく違うのか?
適当にブレイクポイントを設定し、プロジェクトをステップ実行して調べてみることにしましょう。

すると、InitializeComponents プロシージャ内の

Me.ClientSize = New System.Drawing.Size(312, 206)

という行でフォームサイズが変更され、ここで Resize イベントが発生しているにもかかわらず、その後

Me.Text1.Size = New System.Drawing.Size(265, 185)

と、Text1のSizeプロパティがセットされているためと思われます。
アップグレードウィザードも完璧ではないようです。

どうせ、ResizeイベントでText1のSizeは変更されるのですから、この行は削除しても問題ないはずです。
思い切って削除して、さぁ実行です。



今度は予想通りの見た目になりました。

このフォームリサイズ時のテキストボックスのサイズ変更ですが、実はWindows.FormsのTextBoxには新しいプロパティが実装されており、これを利用することで簡単にコンテナにフィットさせるリサイズができるようになっています。
それがDockプロパティです。



上図のプロパティウィンドウのようにDockプロパティにてコンテナにドックする位置を指定します。
真中のボタンをクリックするとDockプロパティはFillとなり、全ての面がドックすることになります。
Dockプロパティの設定ができたら、Form_Resize内のコードは不要ですのですべて削除しましょう。

次にファイル読み込みの実行部分についてVB6とVB.NETのコードをよ〜く見較べてみましょう。
一見同じように見えますが、FileOpenやLineInputといったステートメントはVB6以前にはないものです。
FileのI/Oに関して VB.NETでは FileSystemクラスにまとめられ、各ステートメントもすべてこのクラスのメソッドとして見直されました。
以前の Open ステートメントや Line Input などに比べて、ものすごく読みやすくなったと思いませんか?

しかし、さっきから気になっていたんですが、このプロジェクトで使用していたVB6互換ライブラリの関数の使用時に VB6.Format(〜 という記述でOKなのでしょうか?
PART.2を参考に記述した場合、 Compatibility.VB6.Format(〜 と記述しなければならないはずです。
実はこれ、Namespace(名前空間)の指定の仕方によります。

プロジェクト内で使用する Nemespace の指定はプロジェクトのプロパティダイアログより行います。
ソリューションエクスプローラ内のプロジェクトアイコンを右クリックし、プロパティを選択して下さい



上図のようなダイアログが開きますので名前空間のテキストボックスにインポートするライブラリの Namespace を入力し、インポートの追加ボタンを押します。
これで指定されたNamespaceの使用が可能になります。

(実はこれを Microsoft.VisualBasic.Compatibility.VB6とすれば、VB6と同じような記述で関数を記述することができるのですが、互換ライブラリの関数だか何だかわけがわからなくなってしまうのでお勧めはしません。)

ここで断っておきますが、ここで指定できるインポートとはあくまでも名前空間のインポートのみでライブラリを使用する際には参照設定にて別途行う必要があります。

ひとまずはこれでプロジェクトは完成といったところですが、実は ファイルI/Oに関してはもうひとつ別の方法があります。

少々長くなってしまいましたので、その方法については次回に解説したいと思います。


今日の収穫
1.VB6のプロジェクトをVB.NETに移行する際、アップグレードウィザードにてプロジェクトを変換する必要がある。
2.アップグレードウィザードを信用してはいけない。すべてのコードの動作チェックはもちろんコントロールのレイアウトもやり直しかも?
3.Windows.FormsのTextBox等のコントロールにはコンテナとのドッキング位置を指定するDockプロパティが追加された。
4.VB.NETではNamespace(名前空間)という概念が加わった。


 

Copyright©Sugi. All rights reserved.。