• Thứ Sáu, 22/04/2011 16:06 (GMT+7)

    Lập trình Dùng VB.Net cập nhật dữ liệu Access

    Nguyễn Văn Hiệp
    Một bạn đọc hỏi về việc lập trình truy xuất dữ liệu theo mô hình máy khách (client) – máy chủ (server) nhưng không cập nhật được dữ liệu.

    Cụ thể, trường hợp của bạn là “dùng Visual Studio 2005, ngôn ngữ VB.net thiết kế một trang edit.aspx truy xuất từ file database VNH.mdb trong Microsoft Access. Lấy dữ liệu tên của tất cả các bảng có trong database lên 1 dropdown list đặt tên là dllTenBang, khi click tên của bảng nào thì toàn bộ bảng đó được hiển thị trên một gridview đặt tên là gvTenBang. GridView này được thiết lập ở chế độ cho phép thực hiện thao tác thêm, xóa, sửa dữ liệu trong bảng. Nhưng khi người dùng sửa nội dung trong GridView thì hàm cập nhật dữ liệu vào database VNH.mdb không được”.

    Quý bạn đọc có thể tham khảo chi tiết vấn đề này tại trang Cộng đồng Tạp chí TGVT forum.pcworld.com.vn/default.aspx?g=posts&t=7668.
    Bài viết sẽ trình bày ở dạng tổng quát vấn đề mà bạn đọc đã gặp phải và đưa ra những đề xuất khắc phục ứng với các chi tiết gây lỗi.

    Để giải thích lỗi sai trong hàm cập nhật dữ liệu gvTenBang_RowUpdating() do bạn viết, chúng tôi xin giới thiệu sơ lược lại cơ chế hoạt động của các trang ASP .Net. Mỗi trang ASP .Net do bạn viết được đặt trên máy server, mỗi lần người dùng truy xuất nó, server sẽ chạy code được viết trong trang ASP .Net và gởi kết quả của việc chạy này về máy khách (client) để trình duyệt web (browser) hiển thị cho người dùng xem kết quả. Thí dụ: trang web hiển thị GridView chứa dữ liệu ở từng trạng thái làm việc mà người dùng thấy trên máy của họ chỉ là kết quả của việc chạy trang ASP .Net của bạn. Cụ thể trang web ở chế độ hiệu chỉnh dữ liệu của 1 hàng trong GridView chứa nhiều textBox, mỗi textbox chứa 1 trường thông tin trong hàng hiệu chỉnh. Khi người dùng hiệu chỉnh nội dung ở trường nào thì kết quả sẽ được chứa tạm vào textbox tương ứng. Khi người dùng click vào button Update của hàng hiệu chỉnh, browser mới gởi kết quả hiệu chỉnh về server để được xử lý tiếp ở đó. Lúc này server sẽ kích hoạt hàm gvTenBang_RowUpdating() do bạn viết, hàm này có tham số e là 1 đối tượng chứa các thông tin từ client gởi về như:

    - e.RowIndex: chỉ số hàng dữ liệu mà client hiệu chỉnh nội dung. 

    - e.NewValues: là danh sách các nội dung mới của các trường thông tin trong hàng hiệu chỉnh

    - e.OldValues: là danh sách các nội dung cũ (trước khi hiệu chỉnh) của các trường thông tin trong hàng hiệu chỉnh.

    Tuy nhiên, 2 danh sách e.NewValues và e.OldValues chỉ chứa giá trị đúng khi GridView dùng kỹ thuật data-binding (kết hợp tĩnh với database tại thời điểm thiết kế). Trong trường hợp của bạn, bạn tự viết lấy đoạn code kết hợp động GridView với database tại từng thời điểm chạy, trong trường hợp này 2 danh sách e.NewValues và e.OldValues đều rỗng và không có giá trị sử dụng.

    Bây giờ, chúng tôi chỉ ra lỗi trong hàm gvTenBang_RowUpdating() do bạn viết: bạn dùng bảng dữ liệu trong gvTenBang¬.DataSource để cập nhật file database của bạn, bảng dữ liệu này đang rỗng chứ không phải bảng dữ liệu mà hàm gvTenBang¬_RowEditing() đã thiết lập cho trang Web trước đó (đã gởi về cho client xem và hiệu chỉnh). Hơn nữa, đối tượng GridView gvTenBang mà bạn truy xuất chỉ tồn tại trên máy server, máy client không hề biết và truy xuất được, do đó dữ liệu người dùng cập nhật không thể có trong gvTenBang¬.DataSource.

    Làm sao để biết các nội dung mà người dùng cập nhật? Cách cơ bản nhất là truy xuất đối tượng Request, đây là đối tượng mà server đã thiết lập các thông tin do client gởi về. Cụ thể, đối tượng Request.Form là 1 danh sách các phần tử được trả về từ client, mỗi phần tử chứa 2 thông tin thiết yếu là tên nhận dạng của nó và giá trị hiện hành. Nếu nghiên cứu chi tiết mã HTML do server tạo ra ta sẽ thấy tên các textbox của hàng hiệu chỉnh đều có tiếp đầu ngữ là gvTenBang (là tên của GridView của bạn). Duyệt tìm trong Request.Form ta sẽ có được các giá trị mới của các trường hiệu chỉnh trong hàng hiệu chỉnh hiện hành mà client gởi về, dùng chúng để cập nhật bảng dữ liệu tương ứng trên file database. Cụ thể code của hàm gvTenBang_RowUpdating() được viết lại như sau:

    'Hàm cập nhật dữ liệu từ gvTenBang vào database VNH.mdb

    Protected Sub gvTenBang_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvTenBang.RowUpdating
    'định nghĩa các biến cần dùng
    Dim i As Integer
    Dim j As Integer
    Dim pos As Integer
    Dim sbuf() As String
    Dim buf As String
    'cấp phát động danh sách chứa các trường của hàng cần hiệu chỉnh
    ReDim sbuf(0 To Request.Form.Count)
    'khởi động chỉ số trường đầu tiên
    j = 0
    'duyệt tìm các textbox chứa nội dung người dùng đã hiệu chỉnh
    For i = 0 To Request.Form.Count - 1
    'xác định tên đối tượng giao diện
    buf = Request.Form.Keys(i)
    'kiểm tra có chứa tiếp đầu ngữ gvTenBang ?
    pos = InStr(1, buf, "gvTenBang", 1)
    'nếu đúng textbox thì lưu vào danh sách
    If pos = 1 Then
    sbuf(j) = Request.Form(i)
    'tăng j lên 1 để chuẩn bị cho trường kế tiếp
    j = j + 1
    End If
    Next
    'tạo bảng dữ liệu gốc cần cập nhật
    Bang = kn.GetData("select * from " + dllTenBang.Text)
    If j = Bang.Columns.Count Then
    'copy nội dung mới vào trường tương ứng của bảng dữ liệu
    For i = 0 To j - 1
    Bang.Rows(e.RowIndex).Item(i) = sbuf(i)
    Next
    'cập nhật bảng dữ liệu lên file database
    kn.SetData(Bang, "select * from " + dllTenBang.Text)
    End If
    'thiết lập lại chế độ xem dữ liệu
    gvTenBang.EditIndex = -1
    'đọc lại bảng dữ liệu mới và gán cho GridView để gởi về cho client xem kết quả hiệu chỉnh
    gvTenBang.DataSource = kn.GetData("select * from " + dllTenBang.Text)
    gvTenBang.DataBind()
    End Sub 

    ID: A1103_97