讀者問題與解答:如何於 DataGridView 中使用計算欄位

摘要:讀者問題與解答:如何於 DataGridView 中使用計算欄位


圖表
1
 


圖表2
 

讀者呆呆詢問了好幾次如何於DataGridView控制項中使用計算欄位的問題。在此我們就透過一個完整的範例一次清楚呈現。事實上,如果繫結至一個資料來源的DataGridView控制項還必須內含計算欄位的話,必須讓DataGridView控制項採用虛擬模式(也就是必須將 VirtualMode 屬性設定成 True),而且您必須自行在CellValueNeeded事件處理常式中完成運算欄位值的擷取作業。 

圖表1所示者是我們所撰寫的程式範例,您可以在其中的DataGridView控制項中新增、修改與刪除資料,重點在於,其中的「年齡」資料行是根據「出生日期」計算而來。而且每當您更改「出生日期」資料行中的日期值,則在移出該儲存格(Cell)後,年齡就會立即計算出來即使是新增的資料記錄也會如此。以下我們說明本程式範例的設計技巧。 

首先,您必須如圖表2所示,在表單上加入所需的各個控制項,然後撰寫下列程式碼。我們是將表單的程式碼全數列出,其中已加上完整的註解,另外,本程式使用到frmStatus.vb,因此請務必記得將此檔案匯入您的專案中:(請特別注意CellValueNeededCellEndEdit事件處理常式的寫法 

Option Strict On
Imports
System.Data.SqlClient
Imports System.IO
Public Class CH13_DemoForm001

  Private myDataSet As DataSet

  Private Sub CH13_DemoForm001_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
    '
呼叫 LoadDataToDataSet() 函式來連接至資料來源並傳回所需的 DataSet 物件。
    myDataSet = LoadDataToDataSet()

    If myDataSet IsNot Nothing Then

      '
BindingSource 元件繫結至資料集物件中的「章立民研究室」資料表。
      Me.BindingSource1.DataMember = "章立民研究室"
      Me.BindingSource1.DataSource = myDataSet

      '
BindingNavigator 控制項的資料來源也設定成 BindingSource 元件,如此一來,
      ' 就可以使用 BindingNavigator 控制項去導覽 DataGridView 控制項中的資料列。
      Me.BindingNavigator1.BindingSource = Me.BindingSource1

      '
自訂 DataGridView 控制項。
      CustomizeMyDataGridView()
    End If
  End Sub

  Private Sub CustomizeMyDataGridView()

    '
由於我們要自訂各個資料行型別,因此必須
    ' AutoGenerateColumns 屬性設定成 False
    DataGridView1.AutoGenerateColumns = False

    '
設定奇數資料列的背景色。
    DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = _
      SystemColors.InactiveCaptionText

    '
設定使用者一次只能選取一個儲存格、資料列或資料行。
    DataGridView1.MultiSelect = False

    '
設定採用儲存格選取模式。
    DataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect

    '
設定資料列的高度。
    Me.DataGridView1.RowTemplate.Height = 30

    '
由於我們的 DataGridView 控制項將會內含未繫結資料行,因此必須
    '
VirtualMode 屬性設定成True,也就是必須啟用虛擬模式。
    DataGridView1.VirtualMode = True

    ' DataGridView 控制項的資料來源設定成 BindingSource 元件。
    Me.DataGridView1.DataSource = Me.BindingSource1

    '
接下來的程式碼要自訂各個資料行型別.....

    '
    '
資料行:員工編號,文字方塊
    '
    '
建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
    '
    Dim colEmployeeId As New DataGridViewTextBoxColumn()
    '
設定來源欄位。
    colEmployeeId.DataPropertyName = "員工編號"
    ' 設定資料行標題。
    colEmployeeId.HeaderText = "編號"
    colEmployeeId.Name = "員工編號"
    ' 將此資料行設定成唯讀的。
    colEmployeeId.ReadOnly = True
    '
設定資料行的寬度。
    colEmployeeId.Width = 60
    '
DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colEmployeeId)

    '
    '
資料行:姓名,文字方塊
    '
    '
建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
    '
    Dim colName As New DataGridViewTextBoxColumn()
    '
調整資料行的寬度使其足以顯示出最寬的可見儲存格(包括標題在內)。
    colName.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
    '
設定來源欄位。
    colName.DataPropertyName = "姓名"
    ' 設定資料行標題。
    colName.HeaderText = "員工姓名"
    colName.Name = "姓名"
    colName.ReadOnly = False
    '
DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colName)

    '
    '
資料行:性別,下拉式清單方塊
    '
    '
建立一個 DataGridViewComboBoxColumn 物件並設定其相關屬性。
    '
    Dim colGender As New DataGridViewComboBoxColumn()
    '
調整資料行的寬度使其足以顯示出標題。
    colGender.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
    '
設定來源欄位。
    colGender.DataPropertyName = "性別"
    ' 設定下拉式清單中的選項。
    colGender.Items.AddRange(New String() {"", ""})
    '
排序下拉式清單方塊的內容。
    colGender.Sorted = True
    '
停用資料行的排序功能。
    colGender.SortMode = DataGridViewColumnSortMode.NotSortable
    colGender.HeaderText = "
性別"
    colGender.Name = "性別"
    colGender.ReadOnly = False
    '
DataGridViewComboBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colGender)

    '
    '
資料行:出生日期,自訂格式化的文字方塊
    '
    '
建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
    '
    Dim colBirthday As New DataGridViewTextBoxColumn()
    '
調整資料行的寬度使其足以顯示出最寬的可見儲存格(包括標題在內)。
    colBirthday.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
    '
設定來源欄位。
    colBirthday.DataPropertyName = "出生日期"
    ' 設定日期顯示格式。
    colBirthday.DefaultCellStyle.Format = "MM-dd-yyyy"
    colBirthday.HeaderText = "
出生月日年"
    colBirthday.Name = "出生日期"

    ' DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colBirthday)

    '
    '
資料行:年齡,未繫結的資料行
    '
    '
建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
    '
    Dim colAge As New DataGridViewTextBoxColumn()
    '
調整資料行的寬度使其足以顯示出標題。
    colAge.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
    colAge.HeaderText = "
年齡"
    colAge.Name = "
年齡"

    '
將此資料行設定成唯讀,畢竟年齡是根據出生日期所計算出來。
    '
如果沒有將此資料行設定成唯讀,則必須透過 CellValuePush 事件處理常式
    '
將所輸入的資料寫入資料來源。
    colAge.ReadOnly = True

    '
設定當引發 DataGridView 控制項的 CellValueNeeded 事件時所要執行的
    '
事件處理常式。請特別注意,未繫結資料行是透過CellValueNeeded 事件
    '
來擷取資料。
    AddHandler DataGridView1.CellValueNeeded, AddressOf colAge_CellValueNeeded

    '
DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colAge)

    '
    '
資料行:婚姻狀況,下拉式清單方塊
    '
    '
建立一個 DataGridViewComboBoxColumn 物件並設定其相關屬性。
    '
    Dim colMaritalStatus As New DataGridViewComboBoxColumn()
    '
調整資料行的寬度使其足以顯示出標題。
    colMaritalStatus.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
    '
設定來源欄位。
    colMaritalStatus.DataPropertyName = "婚姻狀況"
    ' 設定下拉式清單中的選項。
    colMaritalStatus.Items.AddRange(New String() {"已婚", "未婚"})
    '
排序下拉式清單方塊的內容。
    colMaritalStatus.Sorted = True
    '
停用資料行的排序功能。
    colMaritalStatus.SortMode = DataGridViewColumnSortMode.NotSortable
    colMaritalStatus.HeaderText = "
婚姻狀況"
    colMaritalStatus.Name = "婚姻狀況"
    colMaritalStatus.ReadOnly = False
    '
DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colMaritalStatus)

    '
    '
資料行:部門,下拉式清單方塊
    '
    '
建立一個 DataGridViewComboBoxColumn 物件並設定其相關屬性。
    '
    '
請注意,此資料行之下拉式清單方塊的選項內容是來自資料集 myDataSet
    '  當中的「公司部門」資料表。
    '
    Dim colDepartment As New DataGridViewComboBoxColumn()
    colDepartment.DataPropertyName = "
部門"
    ' 將下拉式清單方塊繫結至資料集 myDataSet 當中的「公司部門」資料表。
    colDepartment.DataSource = myDataSet.Tables("公司部門")
    colDepartment.ValueMember = "
部門"
    colDepartment.DisplayMember = "部門"
    colDepartment.HeaderText = "任職部門"
    colDepartment.Name = "部門"
    colDepartment.ReadOnly = False
    colDepartment.Width = 120
    '
DataGridViewComboBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
    DataGridView1.Columns.Add(colDepartment)
End Sub

'
此事件處理常式負責替未繫結資料行擷取資料。
Private Sub colAge_CellValueNeeded(ByVal sender As Object, _
  ByVal e As DataGridViewCellValueEventArgs)

  If e.ColumnIndex = CType(sender, DataGridView).Columns("
年齡").Index Then
      Dim age As Integer
      Dim birthDate As DateTime = _
        CDate(CType(sender, DataGridView).Rows( _
        e.RowIndex).Cells("
出生日期").Value)
      age = DateTime.Today.Year - birthDate.Year

      If (DateTime.Today.DayOfYear < birthDate.DayOfYear) Then
          age -= 1
      End If
      e.Value = age
  End If
End
Sub

Private
Sub DataGridView1_CellEndEdit(ByVal sender As Object, _
  ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
  Handles DataGridView1.CellEndEdit
  If e.ColumnIndex = CType(sender, DataGridView).Columns("
出生日期").Index Then
      Dim age As Integer
      Dim birthDate As DateTime = CDate(CType( _
        sender, DataGridView).Rows(e.RowIndex).Cells("
出生日期").Value)
      age = DateTime.Today.Year - birthDate.Year

      If (DateTime.Today.DayOfYear < birthDate.DayOfYear) Then
          age -= 1
      End If
      CType(sender, DataGridView).Rows( _
        e.RowIndex).Cells("
年齡").Value = age.ToString

  End If
End
Sub

'
本程序會連接至資料來源並建立所需的 DataSet 物件。
Private Function LoadDataToDataSet() As DataSet
  '
利用 SqlConnectionStringBuilder 物件來構建連接字串。
  Dim sqlStringBuilder As New SqlConnectionStringBuilder()
  sqlStringBuilder.DataSource = "(local)SQLEXPRESS"
  sqlStringBuilder.InitialCatalog = "
北風貿易"
  sqlStringBuilder.IntegratedSecurity = True

  '
建立一個資料集。
  Dim ds As New DataSet()

  '
顯示一個狀態訊息對話方塊來表示我們目前要嚐試連結至 SQL Server Express
  Dim frmStatusMessage As New frmStatus

  frmStatusMessage.Show("
連接至SQL Server Express ....")

  Try
      Using northwindConnection As _
        New SqlConnection(sqlStringBuilder.ConnectionString)

        Dim cmdLiming As New SqlCommand( _
          "SELECT DISTINCT
部門FROM dbo.章立民研究室;" & _
          "SELECT
員工編號,姓名,性別,婚姻狀況,部門,出生日期,玉照 " & _
          "FROM dbo.
章立民研究室"
, northwindConnection)

        northwindConnection.Open()

        Using drLiming As SqlDataReader = cmdLiming.ExecuteReader()

            ds.Load( _
             drLiming, _
             LoadOption.OverwriteChanges, _
             New String() {"
公司部門", "章立民研究室"})

        End Using
      End Using

      '
設定「出生日期」欄位的預設值。

      ds.Tables("章立民研究室").Columns("出生日期").DefaultValue = DateTime.Now

  Catch exc As Exception

      frmStatusMessage.Close()

      MessageBox.Show( _
        "
要能夠順利執行本範例程式,您的電腦必須已安裝SQL Server " & _
        "Express
,並且必須已附加了本書所附的「北風貿易」資料庫。" & _
        "
關於如何安裝SQL Server Express,請參閱附錄或相關文件說明。")

      '
無法連接至SQL Server
      Return Nothing
  End Try

  frmStatusMessage.Close()
  Return ds
End Function

End
Class

章立民研究室 / Xuite日誌 / 回應(1) / 引用(0) / 好文轉寄 /  
本文的引用網址  http://blog.xuite.net/alwaysfuturevision/liminzhang/9319913/track
第一頁  上一頁  1 下一頁  最後頁 
  • 回應
  • 2007-11-30 18:27:09 arlin

    您範例內的DataGridViewComboBoxColumn其DsiplayMember與ValueMember是相同的,如果我的ValueMember是代碼的話,要如何做,又如何回存到Dataset與後端DB呢

    第一頁  上一頁  1 下一頁  最後頁 

    

               


    圖表2
     

     

     


    讀者呆呆詢問了好幾次如何於DataGridView控制項中使用計算欄位的問題。在此我們就透過一個完整的範例一次清楚呈現。事實上,如果繫結至一個資料來源的DataGridView控制項還必須內含計算欄位的話,必須讓DataGridView控制項採用虛擬模式(也就是必須將 VirtualMode 屬性設定成 True),而且您必須自行在CellValueNeeded事件處理常式中完成運算欄位值的擷取作業。 

    圖表1所示者是我們所撰寫的程式範例,您可以在其中的DataGridView控制項中新增、修改與刪除資料,重點在於,其中的「年齡」資料行是根據「出生日期」計算而來。而且每當您更改「出生日期」資料行中的日期值,則在移出該儲存格(Cell)後,年齡就會立即計算出來即使是新增的資料記錄也會如此。以下我們說明本程式範例的設計技巧。 

    首先,您必須如圖表2所示,在表單上加入所需的各個控制項,然後撰寫下列程式碼。我們是將表單的程式碼全數列出,其中已加上完整的註解,另外,本程式使用到frmStatus.vb,因此請務必記得將此檔案匯入您的專案中:(請特別注意CellValueNeededCellEndEdit事件處理常式的寫法 

    Option Strict On
    Imports
    System.Data.SqlClient
    Imports System.IO
    Public Class CH13_DemoForm001

      Private myDataSet As DataSet

      Private Sub CH13_DemoForm001_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
        '
    呼叫 LoadDataToDataSet() 函式來連接至資料來源並傳回所需的 DataSet 物件。
        myDataSet = LoadDataToDataSet()

        If myDataSet IsNot Nothing Then

          '
    BindingSource 元件繫結至資料集物件中的「章立民研究室」資料表。
          Me.BindingSource1.DataMember = "章立民研究室"
          Me.BindingSource1.DataSource = myDataSet

          '
    BindingNavigator 控制項的資料來源也設定成 BindingSource 元件,如此一來,
          ' 就可以使用 BindingNavigator 控制項去導覽 DataGridView 控制項中的資料列。
          Me.BindingNavigator1.BindingSource = Me.BindingSource1

          '
    自訂 DataGridView 控制項。
          CustomizeMyDataGridView()
        End If
      End Sub

      Private Sub CustomizeMyDataGridView()

        '
    由於我們要自訂各個資料行型別,因此必須
        ' AutoGenerateColumns 屬性設定成 False
        DataGridView1.AutoGenerateColumns = False

        '
    設定奇數資料列的背景色。
        DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = _
          SystemColors.InactiveCaptionText

        '
    設定使用者一次只能選取一個儲存格、資料列或資料行。
        DataGridView1.MultiSelect = False

        '
    設定採用儲存格選取模式。
        DataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect

        '
    設定資料列的高度。
        Me.DataGridView1.RowTemplate.Height = 30

        '
    由於我們的 DataGridView 控制項將會內含未繫結資料行,因此必須
        '
    VirtualMode 屬性設定成True,也就是必須啟用虛擬模式。
        DataGridView1.VirtualMode = True

        ' DataGridView 控制項的資料來源設定成 BindingSource 元件。
        Me.DataGridView1.DataSource = Me.BindingSource1

        '
    接下來的程式碼要自訂各個資料行型別.....

        '
        '
    資料行:員工編號,文字方塊
        '
        '
    建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
        '
        Dim colEmployeeId As New DataGridViewTextBoxColumn()
        '
    設定來源欄位。
        colEmployeeId.DataPropertyName = "員工編號"
        ' 設定資料行標題。
        colEmployeeId.HeaderText = "編號"
        colEmployeeId.Name = "員工編號"
        ' 將此資料行設定成唯讀的。
        colEmployeeId.ReadOnly = True
        '
    設定資料行的寬度。
        colEmployeeId.Width = 60
        '
    DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colEmployeeId)

        '
        '
    資料行:姓名,文字方塊
        '
        '
    建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
        '
        Dim colName As New DataGridViewTextBoxColumn()
        '
    調整資料行的寬度使其足以顯示出最寬的可見儲存格(包括標題在內)。
        colName.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
        '
    設定來源欄位。
        colName.DataPropertyName = "姓名"
        ' 設定資料行標題。
        colName.HeaderText = "員工姓名"
        colName.Name = "姓名"
        colName.ReadOnly = False
        '
    DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colName)

        '
        '
    資料行:性別,下拉式清單方塊
        '
        '
    建立一個 DataGridViewComboBoxColumn 物件並設定其相關屬性。
        '
        Dim colGender As New DataGridViewComboBoxColumn()
        '
    調整資料行的寬度使其足以顯示出標題。
        colGender.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
        '
    設定來源欄位。
        colGender.DataPropertyName = "性別"
        ' 設定下拉式清單中的選項。
        colGender.Items.AddRange(New String() {"", ""})
        '
    排序下拉式清單方塊的內容。
        colGender.Sorted = True
        '
    停用資料行的排序功能。
        colGender.SortMode = DataGridViewColumnSortMode.NotSortable
        colGender.HeaderText = "
    性別"
        colGender.Name = "性別"
        colGender.ReadOnly = False
        '
    DataGridViewComboBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colGender)

        '
        '
    資料行:出生日期,自訂格式化的文字方塊
        '
        '
    建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
        '
        Dim colBirthday As New DataGridViewTextBoxColumn()
        '
    調整資料行的寬度使其足以顯示出最寬的可見儲存格(包括標題在內)。
        colBirthday.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
        '
    設定來源欄位。
        colBirthday.DataPropertyName = "出生日期"
        ' 設定日期顯示格式。
        colBirthday.DefaultCellStyle.Format = "MM-dd-yyyy"
        colBirthday.HeaderText = "
    出生月日年"
        colBirthday.Name = "出生日期"

        ' DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colBirthday)

        '
        '
    資料行:年齡,未繫結的資料行
        '
        '
    建立一個 DataGridViewTextBoxColumn 物件並設定其相關屬性。
        '
        Dim colAge As New DataGridViewTextBoxColumn()
        '
    調整資料行的寬度使其足以顯示出標題。
        colAge.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
        colAge.HeaderText = "
    年齡"
        colAge.Name = "
    年齡"

        '
    將此資料行設定成唯讀,畢竟年齡是根據出生日期所計算出來。
        '
    如果沒有將此資料行設定成唯讀,則必須透過 CellValuePush 事件處理常式
        '
    將所輸入的資料寫入資料來源。
        colAge.ReadOnly = True

        '
    設定當引發 DataGridView 控制項的 CellValueNeeded 事件時所要執行的
        '
    事件處理常式。請特別注意,未繫結資料行是透過CellValueNeeded 事件
        '
    來擷取資料。
        AddHandler DataGridView1.CellValueNeeded, AddressOf colAge_CellValueNeeded

        '
    DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colAge)

        '
        '
    資料行:婚姻狀況,下拉式清單方塊
        '
        '
    建立一個 DataGridViewComboBoxColumn 物件並設定其相關屬性。
        '
        Dim colMaritalStatus As New DataGridViewComboBoxColumn()
        '
    調整資料行的寬度使其足以顯示出標題。
        colMaritalStatus.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
        '
    設定來源欄位。
        colMaritalStatus.DataPropertyName = "婚姻狀況"
        ' 設定下拉式清單中的選項。
        colMaritalStatus.Items.AddRange(New String() {"已婚", "未婚"})
        '
    排序下拉式清單方塊的內容。
        colMaritalStatus.Sorted = True
        '
    停用資料行的排序功能。
        colMaritalStatus.SortMode = DataGridViewColumnSortMode.NotSortable
        colMaritalStatus.HeaderText = "
    婚姻狀況"
        colMaritalStatus.Name = "婚姻狀況"
        colMaritalStatus.ReadOnly = False
        '
    DataGridViewTextBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colMaritalStatus)

        '
        '
    資料行:部門,下拉式清單方塊
        '
        '
    建立一個 DataGridViewComboBoxColumn 物件並設定其相關屬性。
        '
        '
    請注意,此資料行之下拉式清單方塊的選項內容是來自資料集 myDataSet
        '  當中的「公司部門」資料表。
        '
        Dim colDepartment As New DataGridViewComboBoxColumn()
        colDepartment.DataPropertyName = "
    部門"
        ' 將下拉式清單方塊繫結至資料集 myDataSet 當中的「公司部門」資料表。
        colDepartment.DataSource = myDataSet.Tables("公司部門")
        colDepartment.ValueMember = "
    部門"
        colDepartment.DisplayMember = "部門"
        colDepartment.HeaderText = "任職部門"
        colDepartment.Name = "部門"
        colDepartment.ReadOnly = False
        colDepartment.Width = 120
        '
    DataGridViewComboBoxColumn 物件新增至 DataGridView 控制項的資料行集合中。
        DataGridView1.Columns.Add(colDepartment)
    End Sub

    '
    此事件處理常式負責替未繫結資料行擷取資料。
    Private Sub colAge_CellValueNeeded(ByVal sender As Object, _
      ByVal e As DataGridViewCellValueEventArgs)

      If e.ColumnIndex = CType(sender, DataGridView).Columns("
    年齡").Index Then
          Dim age As Integer
          Dim birthDate As DateTime = _
            CDate(CType(sender, DataGridView).Rows( _
            e.RowIndex).Cells("
    出生日期").Value)
          age = DateTime.Today.Year - birthDate.Year

          If (DateTime.Today.DayOfYear < birthDate.DayOfYear) Then
              age -= 1
          End If
          e.Value = age
      End If
    End
    Sub

    Private
    Sub DataGridView1_CellEndEdit(ByVal sender As Object, _
      ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
      Handles DataGridView1.CellEndEdit
      If e.ColumnIndex = CType(sender, DataGridView).Columns("
    出生日期").Index Then
          Dim age As Integer
          Dim birthDate As DateTime = CDate(CType( _
            sender, DataGridView).Rows(e.RowIndex).Cells("
    出生日期").Value)
          age = DateTime.Today.Year - birthDate.Year

          If (DateTime.Today.DayOfYear < birthDate.DayOfYear) Then
              age -= 1
          End If
          CType(sender, DataGridView).Rows( _
            e.RowIndex).Cells("
    年齡").Value = age.ToString

      End If
    End
    Sub

    '
    本程序會連接至資料來源並建立所需的 DataSet 物件。
    Private Function LoadDataToDataSet() As DataSet
      '
    利用 SqlConnectionStringBuilder 物件來構建連接字串。
      Dim sqlStringBuilder As New SqlConnectionStringBuilder()
      sqlStringBuilder.DataSource = "(local)SQLEXPRESS"
      sqlStringBuilder.InitialCatalog = "
    北風貿易"
      sqlStringBuilder.IntegratedSecurity = True

      '
    建立一個資料集。
      Dim ds As New DataSet()

      '
    顯示一個狀態訊息對話方塊來表示我們目前要嚐試連結至 SQL Server Express
      Dim frmStatusMessage As New frmStatus

      frmStatusMessage.Show("
    連接至SQL Server Express ....")

      Try
          Using northwindConnection As _
            New SqlConnection(sqlStringBuilder.ConnectionString)

            Dim cmdLiming As New SqlCommand( _
              "SELECT DISTINCT
    部門FROM dbo.章立民研究室;" & _
              "SELECT
    員工編號,姓名,性別,婚姻狀況,部門,出生日期,玉照 " & _
              "FROM dbo.
    章立民研究室"
    , northwindConnection)

            northwindConnection.Open()

            Using drLiming As SqlDataReader = cmdLiming.ExecuteReader()

                ds.Load( _
                 drLiming, _
                 LoadOption.OverwriteChanges, _
                 New String() {"
    公司部門", "章立民研究室"})

            End Using
          End Using

          '
    設定「出生日期」欄位的預設值。

          ds.Tables("章立民研究室").Columns("出生日期").DefaultValue = DateTime.Now

      Catch exc As Exception

          frmStatusMessage.Close()

          MessageBox.Show( _
            "
    要能夠順利執行本範例程式,您的電腦必須已安裝SQL Server " & _
            "Express
    ,並且必須已附加了本書所附的「北風貿易」資料庫。" & _
            "
    關於如何安裝SQL Server Express,請參閱附錄或相關文件說明。")

          '
    無法連接至SQL Server
          Return Nothing
      End Try

      frmStatusMessage.Close()
      Return ds
    End Function

    End
    Class