thucgia > 18-10-15, 01:12 PM
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
Private Sub Form_Open(Cancel As Integer)
Set Me.Recordset = MyAdo.getRs("select * from phieu")
End Sub
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
ongke0711 > 18-10-15, 02:00 PM
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"
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"
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
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é.
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
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
Minh Tiên > 23-10-15, 09:46 PM
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./.
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
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
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
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
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
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
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