-
Em xin phép chia se Hàm dlockup ạ?
Nguyen SVN > 04-11-19, 02:20 PM
em xin phép chia sẻ đoạn code hàm dlockup ạ. nếu có cách nào hay hơn mong cách anh chỉ giáo thêm ạ
Public Function DBLookup(pSelItem, pDBNM, pWhere, ByRef rs As ADODB.Recordset) As Variant
On Error GoTo ERR_TRAP
Dim sSql As String
DBLookup = False
sSql = "SELECT " & pSelItem & " FROM " & pDBNM
sSql = sSql & " WHERE " & pWhere
Call SYS_ADO.ExecSQL(sSql, rs:=rs)
If rs.EOF Then
DBLookup = Null
Else
DBLookup = rs(0)
End If
Exit_Section:
Exit Function
ERR_TRAP:
DBLookup = False
End Function
Public Function ExecSQL(ByVal pSQL As String, _
Optional ByVal AdoType As Integer = adOpenForwardOnly, _
Optional ByVal AdoReadType As Integer = adLockReadOnly, _
Optional ByRef rs As ADODB.Recordset = Nothing, _
Optional ByRef rtid As Long = -1) As Boolean
'SQLServerConnect
On Error GoTo ERR_TRAP
Dim sInt As Long
Dim blnSelect As Boolean
If InStr(1, pSQL, "INSERT", vbTextCompare) > 0 Then
blnSelect = False
ElseIf InStr(1, pSQL, "DELETE", vbTextCompare) > 0 Then
blnSelect = False
ElseIf InStr(1, pSQL, "UPDATE", vbTextCompare) > 0 Then
blnSelect = False
ElseIf InStr(1, pSQL, "SELECT", vbTextCompare) > 0 Then
blnSelect = True
End If
If Not SYS_ADO.CheckConnection Then
GetConnection:
If Not Connect_Cur Then
Exit Function
End If
End If
On Error GoTo ERR_TRAP
If blnSelect = True Then
'SELECT
If Not rs Is Nothing Then
If rs.State <> 0 Then rs.Close
End If
rs.Open pSQL, cn, AdoType, AdoReadType
Else
'DELETE,INSERT,UPDATE
Dim raf As Long
cn.Execute pSQL, raf
If raf = 0 Then
'do nothing
End If
End If
ExecSQL = True
Exit_Section:
Exit Function
ERR_TRAP:
If Err.Number = -2147467259 Then
If InStr(1, Err.Description, "Communication link failure", vbTextCompare) > 0 Then
cn.Close
GoTo GetConnection
End If
End If
MsgBox Err.Number & Space(1) & Err.Description, vbCritical, SYSTEM_NAME
Resume Exit_Section
ConnectionError:
End Function -
RE: Em xin phép chia se Hàm dlockup ạ?
ongke0711 > 04-11-19, 03:42 PM
Hàm còn lủng củng nhiều lắm nha bạn.
Bạn có test thử hàm chưa?
Một số ý kiến:
1. Hàm DBLookup() As Variant:
- Hàm nên trả về zero - length string chứ đừng nên trả về NULL. Khỏi phải mắc công bẫy lỗi Null trong các Sub có sử dụng trị trả về của hàm này.
Mã PHP:If rs.EOF Then
DBLookup = ""
Else
DBLookup = rs(0)
End If
- Xem lại các tham số:
+ Tại sao dùng rs As ADODB. Recordset mà không phải là truyền tên Table dạng string thôi được rồi. Còn việc dùng DAO hay ADO thì viết trong hàm.
+ Tham số "rs" này tôi thấy chỉ sử dụng nội bộ trong hàm để gán trị cho hàm thôi thì cần gì đưa vào danh sách các tham số cần truyền.
2. Hàm ExecSQL():
- Nếu đã xác định là SELECT rồi thì bẫy INSERT, DELETE.. chi cho tốn code vậy? Câu lệnh "Select..." đã thiết kế cố định trong hàm DBLookup rồi.
- Nếu vẫn dùng biến blnSelect thì sau một loạt IF, nếu blnSelect = False thì Exit Sub/Func ngay và luôn để máy khỏi phải đi tiếp mấy dòng code bên dưới cho tốn tài nguyên.
- Không thấy hàm .checkconection
Còn nhiều cái nữa để ý kiến sau.
Nếu bạn có file demo thì up lên cho đầy đủ các hàm. -
RE: Em xin phép chia se Hàm dlockup ạ?
ongke0711 > 04-11-19, 11:14 PM
Nói thêm về cái hàm ExecSQL().
Bạn muốn gộp tất cả các loại câu lệnh SQL xử lý vô chung trong 1 hàm này đúng không?
Theo tôi tốt nhất là nên tách ra các hàm:
- Chuyên xử lý các Action query (Insert, Delete, Update) vào 1 hàm riêng dùng Command Object.
- Hàm truy vấn dữ liệu (Select).
Việc tách hàm này để tốc độ thực thi tốt hơn, tránh ôm đồm, 1 hàm làm đủ thứ việc. Muốn thực thi 1 công việc C phải duyệt qua các cách A, B rồi mới xác định C là cách xử lý đúng cho trường hợp đặt ra. Thay vào đó bạn viết thẳng cái hàm chỉ xử lý việc C cho nhanh (Đang nói về các query trên).
Vấn đề khác là về thứ tự thực thi các code.
Trong hàm ExecSQL() bạn chạy các code Instr() để xác định biến blnSelect xong rồi mới CheckConnection?
Nếu Connection = False => Thoát. Vậy có phải đã lãng phí mấy dòng code chạy trước đó không.
If Not SYS_ADO.CheckConnection Then
GetConnection:
If Not Connect_Cur Then
Exit Function
End If
End If
-
RE: Em xin phép chia se Hàm dlockup ạ?
Nguyen SVN > 06-11-19, 10:29 AM
Em cam on anh nhe.
dưới đây la toàn bộ code em đã chỉnh sửa lại
'----------------------------------------------------------------------------------------------------
'---・CREATE : 2019/11/06 11:25 Nguyen
'----------------------------------------------------------------------------------------------------
Private Const C_REF_LOCAL_TABLE As Boolean = False
'---・IsTable
Public Function IsTable(ByVal strTable As String) As Boolean
Dim myTDef As DAO.TableDef
IsTable = False
For Each myTDef In CurrentDb.TableDefs
If myTDef.NAME = strTable Then
IsTable = True
Exit Function
End If
Next
End Function
'---・MyDLookup
Public Function MyDLookup(ByVal strITerm As String, ByVal strTable As String, Optional ByVal STRWHERE As String = "") As Variant
On Error GoTo Err_Step
Dim rs As ADODB.Recordset
Dim sSql As String
MyDLookup = Null
If C_REF_LOCAL_TABLE And IsTable(strTable) Then
MyDLookup = DLookup(strITerm, strTable, STRWHERE)
Else
sSql = "SELECT " & strITerm & " AS ITEM FROM " & strTable
If STRWHERE <> "" Then
sSql = sSql & " WHERE " & STRWHERE
End If
Set rs = New ADODB.Recordset
Call SYS_ADO.ExecSQL(sSql, rs:=rs)
If rs.EOF Then
MyDLookup = Null
Else
MyDLookup = rs(0)
End If
Set rs = Nothing
End If
Exit_Step:
Exit Function
Err_Step:
MsgBox Err.Description, vbCritical
Resume Exit_Step
End Function
'---・ExecSQL
Public Function ExecSQL(ByVal pSQL As String, _
Optional ByVal AdoType As Integer = adOpenForwardOnly, _
Optional ByVal AdoReadType As Integer = adLockReadOnly, _
Optional ByRef rs As ADODB.Recordset = Nothing, _
Optional ByRef rtid As Long = -1) As Boolean
'SQLServerConnect
On Error GoTo ERR_TRAP
Dim sInt As Long
Dim blnSelect As Boolean
If InStr(1, pSQL, "INSERT", vbTextCompare) > 0 Then
blnSelect = False
ElseIf InStr(1, pSQL, "DELETE", vbTextCompare) > 0 Then
blnSelect = False
ElseIf InStr(1, pSQL, "UPDATE", vbTextCompare) > 0 Then
blnSelect = False
ElseIf InStr(1, pSQL, "SELECT", vbTextCompare) > 0 Then
blnSelect = True
End If
If Not SYS_ADO.CheckConnection Then
GetConnection:
If Not Connect_Cur Then
Exit Function
End If
End If
On Error GoTo ERR_TRAP
If blnSelect = True Then
'SELECT
If Not rs Is Nothing Then
If rs.State <> 0 Then rs.Close
End If
rs.Open pSQL, cn, AdoType, AdoReadType
Else
'DELETE,INSERT,UPDATE
Dim raf As Long
cn.Execute pSQL, raf
If raf = 0 Then
'do nothing
End If
End If
ExecSQL = True
Exit_Section:
Exit Function
ERR_TRAP:
If Err.Number = -2147467259 Then
If InStr(1, Err.Description, "Communication link failure", vbTextCompare) > 0 Then
cn.Close
GoTo GetConnection
End If
End If
MsgBox Err.Number & Space(1) & Err.Description, vbCritical, SYSTEM_NAME
Resume Exit_Section
ConnectionError:
End Function
'---・CheckConnection
Public Function CheckConnection()
If cn Is Nothing Then
Exit Function
End If
If cn.State = 0 Then
Exit Function
End If
CheckConnection = True
End Function -
RE: Em xin phép chia se Hàm dlockup ạ?
ongke0711 > 06-11-19, 01:38 PM
Hàm MyDlookup em muốn dùng cho cả Local Table (DAO) và table kết nối qua ADODB luôn đúng không?
Nếu vậy thì:
- Tham số: C_REF_LOCAL_TABLE phải đưa vô Optional của hàm luôn. Không để nằm ngoài module được. Khi sử dụng hàm, nếu xác định tìm kiếm ở Local table thì truyền giá trị True cho tham số này.
- Hàm xác định có phải Table không (DAO):
+ Phải bẫy lỗi để thông báo "Không tìn thấy Table tên ...." nếu người dùng cung cấp tham số sai.
+ Có thể dùng cách khác để xác định có phải là table không mà không cần dùng vòng lặp để tăng tốc xử lý.
1. Dùng table hệ thống: MsysObjects.
Vd: SELECT MSysObjects.Name FROM MSysObjects WHERE Name='" & strTable & "'"
2. Dùng TableDef: bắt lỗi nếu Set tdf Error
On Error Resume Next
Set tdf = DBEngine(0)(0).TableDefs(strTableName)
IsTable = (Err.Number = 0) -
RE: Em xin phép chia se Hàm dlockup ạ?
Nguyen SVN > 06-11-19, 04:41 PM
(06-11-19, 01:38 PM)ongke0711 Đã viết: Hàm MyDlookup em muốn dùng cho cả Local Table (DAO) và table kết nối qua ADODB luôn đúng không?
Nếu vậy thì:
- Tham số: C_REF_LOCAL_TABLE phải đưa vô Optional của hàm luôn. Không để nằm ngoài module được. Khi sử dụng hàm, nếu xác định tìm kiếm ở Local table thì truyền giá trị True cho tham số này.
- Hàm xác định có phải Table không (DAO):
+ Phải bẫy lỗi để thông báo "Không tìn thấy Table tên ...." nếu người dùng cung cấp tham số sai.
+ Có thể dùng cách khác để xác định có phải là table không mà không cần dùng vòng lặp để tăng tốc xử lý.
1. Dùng table hệ thống: MsysObjects.
Vd: SELECT MSysObjects.Name FROM MSysObjects WHERE Name='" & strTable & "'"
2. Dùng TableDef: bắt lỗi nếu Set tdf Error
On Error Resume Next
Set tdf = DBEngine(0)(0).TableDefs(strTableName)
IsTable = (Err.Number = 0)
cam on anh dong gop y kien , de em chinh sua lai tiep hihihi