MENU > HOME VB.NET VB6 VBA ソフトウェア リンク サイト情報
VB.NET> VB.NET 突撃レポート > 1  2  3  4  5  6  7  8  9  10  11  12 
PART2: 日付の書式が!?(2002年3月24日)

前回は単にボタンを押したらフォームを閉じるというものを作ってみました。
単純な処理ですが、VB.NETがこれまでのバージョンとは違うものだということがわずかながら体感できたと思います。
もう少しいろいろな機能を付け加えてみましょう。

前回のプロジェクトをもう一度開きます。

ちょっと見づらいかもしれませんが、2度目以降VS.NETを開くと、前回使用していたプロジェクトの一覧が上記のようなスタート ページとしてHTMLで表示されます。
(注)画面はBeta2のものですが、製品版では 開始ページに"スタート"と日本語で表示されているものが、英語で "Start"となっているところ以外、全く同じです。

では、プロジェクト "test" を開いてみましょう。
今回はタイマーコントロールを使用し、タイトルバーに日時を表示する機能を実装してみます。
ツールボックスよりタイマーコントロールをクリックし、フォーム上に配置してみましょう。

「おっ!」


タイマーコントロールはいつものようにフォーム上に配置されるのではなく、別の位置(上記赤丸内)に配置されました。
そうです。VB.NETではフォームデザインに直接関係のない(UIを持たない)コントロールはこの場所に整理されて並びます。
(ちなみに、ここに並ぶ Windown Forms コントロールとしては、この他に イメージリストやツールチップ、トレイアイコン等があります。)

次にタイマーコントロールの Interval プロパティと Enable プロパティを設定してみます。
通常ならば、プロパティウィンドウで値を設定するというのがVB本来の姿でしたが、ちょっと違った方法で設定してみます。

コードを開いてみましょう。



前回はあまり触れませんでしたが、前回お見せした Windows Form Designerにより自動生成されたコード中に
#Region " Windows Form Designer generated code "
    ...
#End Region
という部分がありますが、このコードは初期状態では上記のように折りたたまれています。
コード左のマイナスあるいはプラスボタンを押すことで各コードを展開したり縮小したりできるのも新しい機能のひとつです。
(前回「フォームを閉じる」を実装したボタンのクリックイベントプロシージャも同様に左のマイナスボタンをクリックして縮めることができます。)

では、Windows Form Designer generated code と記述されているコードの左のプラスボタンを押してコードの内容を展開してみてください。

Public Class Form1
    Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        ' この呼び出しは Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' 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
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Timer1 As System.Windows.Forms.Timer
    Private components As System.ComponentModel.IContainer

    ' Windows フォーム デザイナで必要です。
    
    ' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
    ' Windows フォーム デザイナを使って変更してください。  
    ' コード エディタは使用しないでください。
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(80, 40)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(136, 48)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "閉じる(&C)"
        '	
        'Timer1
        '	
        Me.Timer1.Interval = 500	<-- 追加
        Me.Timer1.Enabled = True	<-- 追加
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
        Me.ClientSize = New System.Drawing.Size(292, 118)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button1})
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region
    Private Sub Button1_Click(ByVal sender As System.Object, _
			  ByVal e As System.EventArgs) _
    Handles Button1.Click
        Me.Close()
    End Sub

End Class
グレー表示されている部分が展開されたコードです。
一見、見慣れないコードですが、じっくりみてみるとなんとなく意味がわかるようなコードもちらほらとありますね。
特に中盤あたりの WithEvents 付きでForm1 に貼り付けたコントロールが 定義されているは VB6でコントロールを動的に作成するコートと同様の記述であったり、 その直後に続くInitializeComponent(=コンポーネントの初期化)プロシージャの中は、前半が新規コントロールの作成を行い、後半からコントロールの位置やText等のプロパティのセットのような気がします。
前回はボタンのTextプロパティに"閉じる"という文字列をプロパティウィンドウより指定しましたが、これに関してもここにしっかり Button1.Text = "閉じる"とコーディングされています。
ということはプロパティウィンドウから設定できるプロパティの大半はここでこのような形でコード化されているということなのでしょうか?
コメント中に このプロシージャはコードエディタでは使用しないでくださいと書いてありますが、何事も経験です。
今回はプロパティウィンドウからプロパティを設定するのではなく、ソースが壊れるのを覚悟でこのプロシージャを変更してみることにします。

さっそく上記のコード例を参考に Me.Timer1.Interval = 500Me.Timer1.Enabled = True を記述してみてください。
その後フォームデザイナに戻り、プロパティウィンドウから今変更したプロパティ値が反映されているかどうか確認してみましょう。
Enabled プロパティは True に、Interval プロパティは500になっていましたね。 どうやら予想通りだったようです。
このようにフォームデザイナにて設定した情報はすべてここにコード化されていきます。(私の記憶では Delphi もこのようなスタイルだったはずです)
これは裏を返すとそれなりにきちんとした知識を持ってこれを編集できるようになれば、GUIによるデザインは使わなくてもフォームデザインはできるということではないでしょうか?
現にこのコードと同様のコードを作成し、.NET Flamework SDK でビルドを行っても同様のアプリケーションの作成は可能です。

だんだん話は横道にそれてしまいましたが...。そろそろタイトルバーに日時を表示させるコードを書きはじめたいと思います。

Protected Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
        Me.Text = Format(Now, "yyyy/mm/dd hh:nn:ss")
End Sub

いつものようにこのようなコードを書いてみました。

さて実行です。
特にエラーもなく、一見問題なく実行したように思えましたが、なんと以下のような結果になってしまいました。

この原因は何なのでしょう?早速ヘルプ(MSDN)で Format関数 について調べてみることにします。
すると...
    VB6までの表示書式が 月は m, mm, mmm, mmmm 分は n, nn であったのに対し、
    VB.NETでの表示書式は 月が M, MM, MMM, MMMM 分が m, mm であることが記述されており、
    さらに 時を12時制で表記する場合は h, hh を、24時制で表記する場合は H, HH を記述すると書いてあります。

ゆえに先ほどのコードは以下のように変更する必要があります。

Protected Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
    Me.Text = Format(Now, "yyyy/MM/dd HH:mm:ss")
End Sub


今度は希望通りに表示されました。

ちなみに、これとまったく同じ表示書式をVB6で使用してもVB6では大文字小文字を特に区別しないため、まったく同じ結果を得ることができます。
ということはVB6で作業する際は今後のVB.netへの意向を考え、このような書き方をするような癖をつけておいた方がよいのかもしれません。

しかし、こんな基本的な部分を根こそぎ変えられたのでは使う側もたまったもんではありません。

実はこれらには逃げ道があります。

以前のバージョンとの互換性を維持するために Visual Basic Compatibility Runtime Library というものが用意されており、このライブラリへの参照を追加することにより、VB6と互換性のある関数を利用する事ができるようになります。

具体的には以下のようなコードになります。
Protected Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
    Me.Text = Compatibility.VB6.Format(Now, "yyyy/mm/dd hh:nn:ss")
End Sub
関数(メソッド)の前にクラス名が入りますが、関数の引数などはまったく同じです。

この他にどんなものがあるかはオブジェクトブラウザで Microsoft.VisualBasic.Compatibility.VB6の各メンバクラスについて調べてみましょう。

実際にはVB6のプロジェクトからVB.NETへのプロジェクトへ移行する際は アップグレードウィザード というものを使って行うので恐らくこのあたりのコードも互換性ライブラリを使用したコードに変換されるのでしょう。


今日の収穫
1.Format関数の表示書式がほんのちょっぴり変わった。 (泣)
2.VB6コードとの互換性を補うために Visual Basic Compatibility Runtime Library なるものが存在する。


Copyright©Sugi. All rights reserved.。