-
Tại sao Ado recordset inner join readonly
thucgia > 18-10-15, 01:12 PM
Có bạn nào giúp với :
1, Code kết nối như sau
Mã:Option Compare Database
Public conn As ADODB.Connection
Function get_constrN() As String
Dim myPath As String
Dim myPass As String
myPath = CurrentProject.Path & "\" & "van_de_ado_be.accdb"
myPass = ""
get_constrN = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & myPath & ";Jet OLEDB:Database Password=" & myPass & ";"
End Function
Function getRs(sql As String) As ADODB.Recordset
'Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Set conn = New ADODB.Connection
If conn.State = adStateClosed Then
conn.ConnectionString = get_constrN
conn.Open
Else
End If
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sql, conn
Set getRs = rs
End Function
2, thực hiện với table thì ok, thêm xóa sửa được
Mã:Private Sub Form_Open(Cancel As Integer)
Set Me.Recordset = MyAdo.getRs("select * from phieu")
End Sub
3, Thực hiện với Que ry có inner join thì tắt tịt , readonly ? làm sao đây?
Mã:Private Sub Form_Open(Cancel As Integer)
Dim sql As String
sql = " SELECT phieu.phieu_id, phieu.khach_id, phieu.loai, khach.ten, khach.tel"
sql = sql & " FROM khach INNER JOIN phieu ON khach.khach_id = phieu.khach_id"
Set Me.Recordset = MyAdo.getRs(sql)
End Sub -
RE: Tại sao Ado recordset inner join readonly
ongke0711 > 18-10-15, 02:00 PM
Bạn thử đổi câu lệnh sql xem thử.
Mã PHP:sql = " SELECT T2.phieu_id, T2.khach_id, T2.loai, T1.ten, T1.tel"
sql = sql & " FROM khach T1, phieu T2 WHERE T1.khach_id = T2.khach_id" -
RE: Tại sao Ado recordset inner join readonly
thucgia > 18-10-15, 02:18 PM
(18-10-15, 02:00 PM)ongke0711 Đã viết: Bạn thử đổi câu lệnh sql xem thử.
Mã PHP:sql = " SELECT T2.phieu_id, T2.khach_id, T2.loai, T1.ten, T1.tel"
sql = sql & " FROM khach T1, phieu T2 WHERE T1.khach_id = T2.khach_id"
không được bạn à vẫn read only!!!
search mấy ngày rồi mình thấy là vô phương, nhưng mình nghĩ nó khoá là có lý của nó
Nên mình tìm thấy một hướng mới đó là cho nó updateable bằng cách ngắt kết nối
Mã:Private Sub Form_Open(Cancel As Integer)
Dim sql As String
Dim rs As ADODB.Recordset
sql = " SELECT phieu.phieu_id, phieu.khach_id, phieu.loai, khach.ten, khach.tel"
sql = sql & " FROM khach INNER JOIN phieu ON khach.khach_id = phieu.khach_id"
Set rs = MyAdo.getRs(sql)
rs.ActiveConnection = Nothing
Set Me.Recordset = rs
End Sub
nhưng lúc này ta phải tự cập nhật sự thay đổi bằng cách dùng hàm Di rty
Đang nghiên cứu, có cách nào thì cùng trao đổi nhé. -
RE: Tại sao Ado recordset inner join readonly
thucgia > 18-10-15, 03:06 PM
(18-10-15, 02:18 PM)thucgia Đã viết:
(18-10-15, 02:00 PM)ongke0711 Đã viết: Bạn thử đổi câu lệnh sql xem thử.
Mã PHP:sql = " SELECT T2.phieu_id, T2.khach_id, T2.loai, T1.ten, T1.tel"
sql = sql & " FROM khach T1, phieu T2 WHERE T1.khach_id = T2.khach_id"
không được bạn à vẫn read only!!!
search mấy ngày rồi mình thấy là vô phương, nhưng mình nghĩ nó khoá là có lý của nó
Nên mình tìm thấy một hướng mới đó là cho nó updateable bằng cách ngắt kết nối
Mã:Private Sub Form_Open(Cancel As Integer)
Dim sql As String
Dim rs As ADODB.Recordset
sql = " SELECT phieu.phieu_id, phieu.khach_id, phieu.loai, khach.ten, khach.tel"
sql = sql & " FROM khach INNER JOIN phieu ON khach.khach_id = phieu.khach_id"
Set rs = MyAdo.getRs(sql)
rs.ActiveConnection = Nothing
Set Me.Recordset = rs
End Sub
nhưng lúc này ta phải tự cập nhật sự thay đổi bằng cách dùng hàm Di rty
Đang nghiên cứu, có cách nào thì cùng trao đổi nhé.
Có lẽ làm được rồi
1, ở sự kiện open frm -> ngắt kết nối cho phép rs có thể updateable
Mã:Private Sub Form_Open(Cancel As Integer)
Dim sql As String
Dim rs As ADODB.Recordset
sql = " SELECT phieu.phieu_id, phieu.khach_id, phieu.loai, khach.ten, khach.tel"
sql = sql & " FROM khach INNER JOIN phieu ON khach.khach_id = phieu.khach_id"
Set rs = MyAdo.getRs(sql)
rs.ActiveConnection = Nothing
Set Me.Recordset = rs
End Sub
2,Ở sự kiện before update nếu là me.Dirty = true
Mã:Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me.Dirty Then
'MsgBox "ban phai luu su thay doi"
'MsgBox Me.phieu_id & Me.khach_id & Me.loai
'hien thi thong bao co muon thay doi if yes
Dim p As dto_phieu
Set p = New dto_phieu
p.phieu_id = Me.phieu_id
p.khach_id = Me.khach_id
p.loai = Me.loai
Call ado2_phieu.Sua(p) 'tien hanh sua phieu
Dim k As dto_khach
Set k = ado2_khach.TimKiem(p.khach_id)
Me.ten = k.ten
Me.tel = k.tel 'hien thi lai khach tuong ung
Set k = Nothing 'giai phong obj
Set p = Nothing
'if no thì Cancel = True
End If
End Sub
3, Làm như thế thì access chẳng thua kém gì tụi víial studio cả
4, Chuyển đổi giao diện từ access truyền thống sang Ado thì khá phức tạp nhưng tận dụng được tính năng visible và một số tính năng wizard!!!!
Có gì thì cùng thảo luận nhé các bạn. -
RE: Tại sao Ado recordset inner join readonly
Minh Tiên > 23-10-15, 09:46 PM
Chào bạn !
ADO chạy với table hay Query đều ổn cả. Nhưng hơi chậm hơn chạy DAO và chạy trực tiếp.
Hiện mình đã chuyển toàn bộ PM bán hàng của mình sang ADO. Đã gần xong rồi.
Rất mong được trao đổi và chia sẽ cũng các Pro.
Thân./. -
RE: Tại sao Ado recordset inner join readonly
thucgia > 24-10-15, 12:15 AM
(23-10-15, 09:46 PM)Minh Tiên Đã viết: Chào bạn !
ADO chạy với table hay Query đều ổn cả. Nhưng hơi chậm hơn chạy DAO và chạy trực tiếp.
Hiện mình đã chuyển toàn bộ PM bán hàng của mình sang ADO. Đã gần xong rồi.
Rất mong được trao đổi và chia sẽ cũng các Pro.
Thân./.
Bạn biết cái UpdateBatch không? chỉ mình với!!!
Mình tìm thấy đoạn này
Mã:Set rstName = New ADODB.Recordset
With rstName
.ActiveConnection = cnnName
.CursorType = adKeyset
.CursorLocation = adUseClient
.LockEdits = adBatchOptimistic
.Open ";SELECT * FROM TableName WHERE Criteria", Options:=adCmdText
Set .ActiveConnection = Nothing 'Disconnect the Recordset
'Close the connection to the server, if desired
'Edit the field values of multiple records here
'You also can append and delete records
'Reopen the server connection, if closed
Set .ActiveConnection = cnnName
.UpdateBatch 'Send all changes to the data source
End With
rstName.Close
nhưng nó chỉ update 1 dòng!!!!
chứ không cập nhật toàn bộ recordset (bao gồm thêm, xóa,sửa)
cái kiểu này nó gọi là ngắt kết nối hoàn toàn trong lúc user thêm xóa ....
Đến khi muốn lưu thì bấm nút một cái , dữ liệu sẽ cập nhật vào csdl, rồi lại đóng kết nối
Bạn có làm theo cái hướng này không, nếu có cho mình xin cái bản demo -
RE: Tại sao Ado recordset inner join readonly
MTNQ > 25-10-15, 03:59 AM
(24-10-15, 12:15 AM)thucgia Đã viết: Bạn biết cái UpdateBatch không? chỉ mình với!!!
Mình tìm thấy đoạn này
Mã:Set rstName = New ADODB.Recordset
With rstName
.ActiveConnection = cnnName
.CursorType = adKeyset
.CursorLocation = adUseClient
.LockEdits = adBatchOptimistic
.Open ";SELECT * FROM TableName WHERE Criteria", Options:=adCmdText
Set .ActiveConnection = Nothing 'Disconnect the Recordset
'Close the connection to the server, if desired
'Edit the field values of multiple records here
'You also can append and delete records
'Reopen the server connection, if closed
Set .ActiveConnection = cnnName
.UpdateBatch 'Send all changes to the data source
End With
rstName.Close
nhưng nó chỉ update 1 dòng!!!!
chứ không cập nhật toàn bộ recordset (bao gồm thêm, xóa,sửa)
cái kiểu này nó gọi là ngắt kết nối hoàn toàn trong lúc user thêm xóa ....
Đến khi muốn lưu thì bấm nút một cái , dữ liệu sẽ cập nhật vào csdl, rồi lại đóng kết nối
Bạn có làm theo cái hướng này không, nếu có cho mình xin cái bản demo
Theo mình biết thì Access không hỗ trợ UpdateBatch đối với form Recordset
MTNQ cũng đang viết một ứng dụng Access sử dụng ADO nhưng bận quá nên bỏ dở khá lâu rùi. Thấy các bác "châm ngòi " nên lại lao vào
Cái UpdateBatch này cũng hay nhưng lột sạch quần áo của bác Google cũng chẵng thấy lòi ra được phương án nào khả thi cho BoundForm(MTNQ thường dùng cho Subform Datasheet hoặc Continuous )
Mất cả buổi tối cuối cùng cũng tìm ra được một phương án có vẻ khả quan: đó là sử dụng một Recordset trung gian
-Khi mở form thiết lập kết nối, lấy về bản ghi làm nguồn cho form đồng thời tạo thêm một bản sao (Tạm gọi là rst1)
-Ngắt kết nối đến CSDL
-Mỗi khi thêm, xóa, sửa ta đều update vào rst1, khi người dùng nhấn nút Lưu thì thiết lập kết nối cho rst1 và gọi UpdateBatch
Đây là bản Demo mình mới làm, bạn xem thử và cùng thảo luận nhé
Demo UpdateBatch.rar -
RE: Tại sao Ado recordset inner join readonly
thucgia > 25-10-15, 12:13 PM
(25-10-15, 03:59 AM)MatTroiNguQuen Đã viết:
(24-10-15, 12:15 AM)thucgia Đã viết: Bạn biết cái UpdateBatch không? chỉ mình với!!!
Mình tìm thấy đoạn này
Mã:Set rstName = New ADODB.Recordset
With rstName
.ActiveConnection = cnnName
.CursorType = adKeyset
.CursorLocation = adUseClient
.LockEdits = adBatchOptimistic
.Open ";SELECT * FROM TableName WHERE Criteria", Options:=adCmdText
Set .ActiveConnection = Nothing 'Disconnect the Recordset
'Close the connection to the server, if desired
'Edit the field values of multiple records here
'You also can append and delete records
'Reopen the server connection, if closed
Set .ActiveConnection = cnnName
.UpdateBatch 'Send all changes to the data source
End With
rstName.Close
nhưng nó chỉ update 1 dòng!!!!
chứ không cập nhật toàn bộ recordset (bao gồm thêm, xóa,sửa)
cái kiểu này nó gọi là ngắt kết nối hoàn toàn trong lúc user thêm xóa ....
Đến khi muốn lưu thì bấm nút một cái , dữ liệu sẽ cập nhật vào csdl, rồi lại đóng kết nối
Bạn có làm theo cái hướng này không, nếu có cho mình xin cái bản demo
Theo mình biết thì Access không hỗ trợ UpdateBatch đối với form Recordset
MTNQ cũng đang viết một ứng dụng Access sử dụng ADO nhưng bận quá nên bỏ dở khá lâu rùi. Thấy các bác "châm ngòi " nên lại lao vào
Cái UpdateBatch này cũng hay nhưng lột sạch quần áo của bác Google cũng chẵng thấy lòi ra được phương án nào khả thi cho BoundForm(MTNQ thường dùng cho Subform Datasheet hoặc Continuous )
Mất cả buổi tối cuối cùng cũng tìm ra được một phương án có vẻ khả quan: đó là sử dụng một Recordset trung gian
-Khi mở form thiết lập kết nối, lấy về bản ghi làm nguồn cho form đồng thời tạo thêm một bản sao (Tạm gọi là rst1)
-Ngắt kết nối đến CSDL
-Mỗi khi thêm, xóa, sửa ta đều update vào rst1, khi người dùng nhấn nút Lưu thì thiết lập kết nối cho rst1 và gọi UpdateBatch
Đây là bản Demo mình mới làm, bạn xem thử và cùng thảo luận nhé
Demo UpdateBatch.rar
thank for share, ý tưởng tuyệt vời, 1 rs dùng hiển thị, 1 rs dùng lưu trữ, ...à nếu không xài cái rst1 này thì chuyện gì xảy ra nhỉ?
phát hiện 1 vấn đề : khi bấm del -> chọn no nó vẫn xử luôn -
RE: Tại sao Ado recordset inner join readonly
MTNQ > 27-10-15, 02:17 AM
(25-10-15, 12:13 PM)thucgia Đã viết: thank for share, ý tưởng tuyệt vời, 1 rs dùng hiển thị, 1 rs dùng lưu trữ, ...à nếu không xài cái rst1 này thì chuyện gì xảy ra nhỉ?
phát hiện 1 vấn đề : khi bấm del -> chọn no nó vẫn xử luôn
-"không xài cái rst1" thì... không xài cái UpdateBatch
-"khi bấm del -> chọn no nó vẫn xử luôn":
Cái vụ này thì đơn giản:
Code:
Mã:Private Sub Form_Delete(Cancel As Integer)
DoCmd.SetWarnings False
If MsgBox("Ban co dong y xoa ma khach hang: " & Me.Makhachhang, vbYesNo, "luu y") = vbYes Then
Up_To_rstData "xoa"
Else
Cancel = True
DoCmd.SetWarnings True
End If
End Sub
Private Sub Form_AfterDelConfirm(Status As Integer)
DoCmd.SetWarnings True
End Sub
-Thực ra Demo trên chỉ viết để test cái vụ UpdateBatch thui. Nếu áp dụng vào thực tế thì không đơn giản vậy, cần phải kiểm soát chặt chẽ hơn khi xóa, sửa, đặc biệt là thêm mới . Trong môi trường nhiều người dùng càng phải cân nhắc về xung đột dữ liệu, cả vấn đề về tốc độ và tài nguyên khi cùng lúc mở ra 2 Recordset (Requery cũng phải làm cà 2 thằng)...
-> Up lại cái Demo, thêm vào code trên, Requery sau khi lưu, thêm luôn cái nút hủy cho dễ test (lần này không dại load hết dữ liệu lên form nữa mà chỉ đưa lên top 10 thui test cho nhanh)
Demo UpdateBatch(2).rar -
RE: Tại sao Ado recordset inner join readonly
thucgia > 27-10-15, 02:03 PM
(27-10-15, 02:17 AM)MatTroiNguQuen Đã viết:
(25-10-15, 12:13 PM)thucgia Đã viết: thank for share, ý tưởng tuyệt vời, 1 rs dùng hiển thị, 1 rs dùng lưu trữ, ...à nếu không xài cái rst1 này thì chuyện gì xảy ra nhỉ?
phát hiện 1 vấn đề : khi bấm del -> chọn no nó vẫn xử luôn
-"không xài cái rst1" thì... không xài cái UpdateBatch
-"khi bấm del -> chọn no nó vẫn xử luôn":
Cái vụ này thì đơn giản:
Code:
Mã:Private Sub Form_Delete(Cancel As Integer)
DoCmd.SetWarnings False
If MsgBox("Ban co dong y xoa ma khach hang: " & Me.Makhachhang, vbYesNo, "luu y") = vbYes Then
Up_To_rstData "xoa"
Else
Cancel = True
End If
DoCmd.SetWarnings True
End Sub
-Thực ra Demo trên chỉ viết để test cái vụ UpdateBatch thui. Nếu áp dụng vào thực tế thì không đơn giản vậy, cần phải kiểm soát chặt chẽ hơn khi xóa, sửa, đặc biệt là thêm mới . Trong môi trường nhiều người dùng càng phải cân nhắc về xung đột dữ liệu, cả vấn đề về tốc độ và tài nguyên khi cùng lúc mở ra 2 Recordset (Requery cũng phải làm cà 2 thằng)...
-> Up lại cái Demo, thêm vào code trên, Requery sau khi lưu, thêm luôn cái nút hủy cho dễ test (lần này không dại load hết dữ liệu lên form nữa mà chỉ đưa lên top 10 thui test cho nhanh)
Demo UpdateBatch(2).rar
vô vàn cảm kích...quá chuẩn luôn.
-1,Nhưng còn vấn đề table có primary key hoặc autonumber thì chắc là phức tạp hở bạn.
-2,Nếu ADO ngon rồi thì tại sao Microsoft ra cái thằng ADO.net để làm gì!!!!
-3, Bạn có nghiên cứu cái này chưa?
link : http://www.databasejournal.com/features/...rdsets.htmMã:Dim rstADO As ADODB.Recordset
Dim fld As ADODB.Field
Set rstADO = New ADODB.Recordset
With rstADO
.Fields.Append "EmployeeID", adInteger, , adFldKeyColumn
.Fields.Append "FirstName", adVarChar, 10, adFldMayBeNull
.Fields.Append "LastName", adVarChar, 20, adFldMayBeNull
.Fields.Append "Email", adVarChar, 64, adFldMayBeNull
.Fields.Append "Include", adInteger, , adFldMayBeNull
.Fields.Append "Selected", adBoolean, , adFldMayBeNull
.CursorType = adOpenKeyset
.CursorLocation = adUseClient
.LockType = adLockPessimistic
.Open
End With
Mình thắc mắc là tại sao nó không cho add dữ liệu ? thk.
- ps định phân trang giống web luôn hả?