Đánh giá chủ đề:
  • 1 Votes - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Làm thế nào để dùng SQL trong lập trình?
#1
Tôi mạn phép mở ra chủ đề này và mong tất cả các bạn cùng đóng góp viết tiếp. Thực tế là có vài người bạn tôi cứ loay hoay không biết phải chuyển sang làm việc với SQL thế nào đặc biệt là khi ta mới chỉ chập chững bước vào VBA và đang quen với việc dùng Excel.


Bài viết còn dở dang. Mong chúng ta cùng phối hợp hoàn thiện để các anh em mới vào nghề có đủ tự tin bước sang SQL với Access.
Xin chân thành cảm ơn.
(Tiện thể để minh chứng - xin gửi một đoạn mã chương trình liên quan đến việc thao tác với DAO/ADODB từ Excel)
===========================================================


Đoạn mã sau đây làm các việc sau:
1. Tạo CSDL theo 2 giao thức DAO/ADODB
2. Tạo bảng dữ liệu

và các thủ tục kết nối hỗ trợ 2 giao thức


Mã:
Option Explicit
' Duong dan den csdl
Private dbPath As String
' Doi tuong de ket noi voi CSDL
Private dbObject As Object

' Const for ADODB
Private Const Jet10 = 1
Private Const Jet11 = 2
Private Const Jet20 = 3
Private Const Jet3x = 4
Private Const Jet4x = 5

' Const for DAO
Private Const dbVersion10 = 1
Private Const dbVersion11 = 8
Private Const dbVersion20 = 16
Private Const dbVersion30 = 32
Private Const dbVersion40 = 64

' Cach thuc ket noi
Private ConnectByADODB As Boolean

Sub LoadForm()
    ' Mo form ra nao
    frmSearch.Show vbModal
End Sub

Sub CreateDb()
    ' Khoi tao CSDL Access
    dbPath = ThisWorkbook.Path & "\Data.mdb"
        
    ' Kiem tra xem CSDL da co khong, neu co thi xoa di
    If FileOrDirExists(dbPath, True) Then Kill dbPath
    
    'Tao CSDL phien ban Access 2000 (ho tro Unicode)
    If Range("dbType") = "DAO" Then
        ' Dung DAO
        CreateDbDAO dbPath
    Else
        ' Dung ADO
        CreateDbAdo dbPath
    End If
    
    ' Khoi tao cac bang so lieu
    CreateTable
    
    ' Them so lieu vao cac bang
    AddData2Table
    
    ' Dong CSDL
    dbObject.Close
End Sub

' Them so lieu tu Excel vao cac bang trong CSDL
Private Sub AddData2Table()
    ' Tien hanh nap du lieu bang Ma canbo
    Dim dbRange As Range, ptrCell As Range, SqlTxt As String
    Set dbRange = Range("tblCanbo")
    Set ptrCell = dbRange.Cells(1)
    While ptrCell <> ""
        SqlTxt = "INSERT INTO tblCanbo(fldMaCanbo, fldMaDiaban) VALUES('" & ptrCell & "','" & ptrCell.Offset(0, 1) & "');"
        Call ExcuteSQL(SqlTxt)
        Set ptrCell = ptrCell.Offset(1)
    Wend
    ' Tao bang dia ban
    Set dbRange = Range("tblDiaban")
    Set ptrCell = dbRange.Cells(1)
    While ptrCell <> ""
        SqlTxt = "INSERT INTO tblDiaban(fldMaDiaban, fldTenDiaban, fldDoi) VALUES('" & ptrCell & "','" & ptrCell.Offset(0, 1) & "'," & ptrCell.Offset(0, 2) & ");"
        Call ExcuteSQL(SqlTxt)
        Set ptrCell = ptrCell.Offset(1)
    Wend
    
    ' Xoa cac bien khoi bo nho
    Set dbRange = Nothing
    Set ptrCell = Nothing
End Sub

'======================================
' Phan chen so lieu vao bang thi giong
' nhau giua DAO va ADODB

'-------------TAO BANG CSDL-------------
' Nhom cac thu tuc lam viec voi ADODB
Private Sub CreateTable()
    Dim SqlTxt As String
    SqlTxt = "Create Table tblCanbo(fldMaCanbo Text(20), fldMaDiaban Text(20));"
    Call ExcuteSQL(SqlTxt)
    SqlTxt = "Create Table tblDiaban(fldMaDiaban Text(20), fldTenDiaban Text(255), fldDoi Long);"
    Call ExcuteSQL(SqlTxt)
End Sub

Private Function ExcuteSQL(SqlStr As String) As Boolean
    On Error GoTo ErrHandler
    dbObject.Execute SqlStr
    ExcuteSQL = True
ErrHandler:
End Function
'================END======================

'======================================
' Nhom cac thu tuc lam viec voi ADODB
Private Sub CreateDbAdo(FileName As String, Optional Format As Long = Jet4x)
    Dim Catalog As Object
    ' Khoi tao mot phien lam viec voi ADO
    Set Catalog = CreateObject("ADOX.Catalog")
    ' Tao csdl dang Access 2000
    Catalog.Create "Provider=Microsoft.Jet.OLEDB.4.0;" & _
     "Jet OLEDB:Engine Type=" & Format & ";Data Source=" & FileName
    Set Catalog = Nothing
    Set dbObject = CreateObject("ADODB.Connection")
    
    ' Mo CSDL
    dbObject.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & ";"
End Sub
'================END======================

'======================================
' Nhom cac thu tuc lam viec voi DAO
Sub CreateDbDAO(FileName As String, Optional Format As Long = dbVersion40)
    Dim Engine As Object
    Set Engine = CreateObject("DAO.DBEngine.36")
    Engine.CreateDatabase FileName, ";LANGID=0x0409;CP=1252;COUNTRY=0", Format
    
    ' Mo CSDL
    Set dbObject = Engine.Workspaces(0).OpenDatabase(FileName)
End Sub
'================END======================

'======================================
' Khoi tao ket noi voi CSDL
Property Get ConnectDatabase(dpPath As String, Optional ConnectAsADODB As Boolean = True) As Object
    Dim dbs As Object
    On Error GoTo ErrHandler
    If ConnectAsADODB Then
        Set dbs = CreateObject("ADODB.Connection")
        dbs.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dpPath & ";"
        Set ConnectDatabase = dbs
    Else
        Set dbs = CreateObject("DAO.DBEngine.36")
        Set ConnectDatabase = dbs.Workspaces(0).OpenDatabase(dpPath)
    End If
    ConnectByADODB = ConnectAsADODB
ErrHandler:
End Property

' Khoi tao ket noi voi recordset -
' tuy thuoc vao kieu ket noi nhe
Property Get GetRecordset(dbObj As Object, SqlText As String) As Object
    On Error GoTo ErrHandler
     
    If ConnectByADODB Then
        ' Voi ADODB, Like '*abc*' phai la '%abc%' nhe
        Set GetRecordset = CreateObject("ADODB.Recordset")
        GetRecordset.Open Replace(SqlText, "*", "%"), dbObj
    Else
        ' Voi DAO, Like '*abc*' de tim kiem
        Set GetRecordset = dbObj.Openrecordset(SqlText)
    End If
    Debug.Print GetRecordset.EOF
ErrHandler:
End Property

'================END======================

'======================================
' Nhom cac thu tuc lam viec voi Thu muc
Function FileOrDirExists(PathName As String, Optional FileObject As Boolean = False) As Boolean
    'Kiem tra xem file hoac folder co ton tai hay khong?
    Dim Fso As Object
    Dim FilePath As String, lRet As Boolean

    Set Fso = CreateObject("Scripting.FileSystemObject")
    If PathName = "" Then Exit Function
    If FileObject Then
        FileOrDirExists = Fso.FileExists(PathName)
    Else
        FileOrDirExists = Fso.FolderExists(PathName)
    End If
    Set Fso = Nothing
End Function
'================END======================
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Che_Guevara , jason , Minh Tiên , maidinhdan
#2
(06-05-16, 12:27 PM)paulsteigel Đã viết: ==========================BÀI 1=================================
1.Đặt vấn đề
Nói về lập trình mà thiếu công cụ SQL thì giống như người tù đi bộ mà tay và chân đều bị xiềng xích.
Có rất nhiều công việc liên quan đến xử lý số liệu mà để thực hiện được nhiệm vụ đơn giản phải lập trình kha khá trong khi với SQL chỉ cần thực hiện một lệnh truy vấn.
Hãy lấy một ví dụ: Có một danh sách khách hàng trong đó tên khách hàng có thể bị trùng nhau. Yêu câu lấy danh sách khách hàng không bị trùng. Danh sách khách hàng có 2 cột: Số thứ tự và Tên khách hàng trong bảng Danhsach
Có 2 cách giải:
·        Cách 1 thuần về lập trình ta làm như sau
+ Duyệt qua từng khách hàng trong danh sách
+ Tạo môt mảng phụ/ biến phụ để lưu khách hàng đầu tiên
+ Kiểm tra với khách hàng thứ 2 nếu trùng thì bỏ qua và chuyển tiếp, nếu không trùng thì lưu vào mảng phụ/ biến phụ;
+ Chuyển qua khách hàng thứ 3 và so sánh với các tên có trong mảng phụ, nếu không có thì thêm tiếp, nếu có rồi thì bỏ qua và chuyển sang khách hàng tiếp theo.....
Chỉ như vậy cũng mệt nhoài với một số anh chị mới làm quen với lập trình, nhiều khi phải mất hàng tiếng đồng hồ.
·        Cách 2: Dùng SQL
Để lấy được danh sách nói trên ta chỉ cần chạy 1 truy vấn
“Select distinct [Tên khách hàng] From [Danhsach];”
Và đã có ngay kết quả.
Như vậy ta có thể thấy SQL giúp cho cuộc sống của dân lập trình dễ dàng hơn rất nhiều, đặc biệt là các bạn làm việc nhiều với tổ chức Cơ sở dữ liệu.

2.Các bước chuẩn bị
Bản chất SQL là các tập lệnh và chỉ thực thi được nếu ta có bộ công cụ nhận lệnh hay nói khác hơn là Database Engine (DBE – Trình quản trị CSDL) và VBA thao tác với Cơ sở dữ liệu thông qua Database Engine.
Có nhiều loại DbE khác nhau nhưng xin phép được gọi tên 2 loại khá phổ biến đó là DAO và ADO (sau này là ADODB).
Để làm việc được với SQL trong môi trường thiết kế VBA, ta cần phải có một số chuẩn bị sau đây:

2.1.Bước 1: Tạo lập kết nối với DbE
Cách 1: Kết nối sớm – Early bind
Kết nối này có thể thiết lập được thông qua việc đặt tham chiếu Refercences của Dự án VBA (VBA Project) bằng cách nhấn Tools/References và chọn Microsoft DAO (phiên bản mới nhất là 3.6) hoặc Microsoft ActiveX Data Objects  (chọn 1 trong các phiên bản 2.0 đến 6.1).
Sau đó khởi tạo kết nối với các đối tượng của bộ thư viện DAO hoặc ADODB thông qua khai báo các biến.
Cách 2: Kết nối muộn – Late bind
Dùng các câu lệnh khởi tạo kết nối với 1 trong 2 loại đối tượng trên bằng câu lệnh CreateObject. The cách này bạn không cần phải thiết lập References tới 1 trong 2 đối tượng như nói ở trên.
Thứ tự tạo kết nối bao giờ cũng phải có 2 việc sau:
+ Tạo kết nối với trình quản trị (DbEngine, Database, Connection): Đây là trình cho phép ta thao tác với bảng dữ liệu và toàn cơ sở dữ liệu.

a.   Sử dụng kết nối sớm (đòi hỏi phải thiết lập References tới các bộ thư viện – Early bind
·        Bước 1: Khởi tạo biến kết nối
Với DAO: Dim dbs as Database
Với ADODB:
Cách 1:
Dim dbs as ADODB.Connection
Set dbs = new ADODB.Connection
Cách 2:
Dim dbs as New ADODB.Connection

·        Bước 2: Kết nối CSDL
Với DAO: Set dbs=OpenDatabase(“Đường dẫn tới CSDL Access”)
Với ADODB: dbs.Open "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = Đường dẫn tới CSDL Access” & ";"

b.   Sử dụng kết nối – Late bind
·        Bước 1: Khởi tạo biến kết nối
Với DAO: Dim dbs As Object
Với ADODB: 
Dim dbs As Object
Set dbs = CreateObject("ADODB.Connection")
·        Bước 2: Kết nối CSDL
Với DAO: Set dbs = CreateObject("DAO.DBEngine.36")
Với ADODB:
Set ConnectDatabase = dbs.Workspaces(0).OpenDatabase(“Đường dẫn tới CSDL Access”)
dbs.Open "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = Đường dẫn tới CSDL Access;"

Đến đây chúng ta đã kết nối được với Cơ sở dữ liệu và đối tượng dbs đã được thiết lập để thực hiện công việc ta cần.
Với Access, thao tác với CSDL hiện tại ta có thể sử dụng ngay đối tượng CurrentDb (DAO) hoặc CurrentProject.Connection.
Phần lớn các thao tác liên quan đến SQL về tạo bảng, xóa bảng, sửa đổi cột số liệu, xác lập quan hệ ...vv bổ sung số liệu đã có thể làm tại bước này với đối tượng dbs thông qua lệnh dbs.Execute “Lệnh SQL”.
Tuy nhiên để thao tác trực tiếp với các bản ghi thì cần nắm được bước 2 nữa.

2.2.Bước 2: Thiết lập kết nối với bảng số liệu (nếu cần)
Cả DAO và ADODB đều có đối tượng RecordSet để đại diện cho bảng số liệu và chúng có các thuộc tính cơ bản giống nhau. Để làm việc với chúng, ta cần khai báo.
Dim rcs as DAO.RecordSet hoặc Dim rcs as ADODB.RecordSet
+ Với DAO:
Set rcs = dbs.OpenRecordset("Tên bảng cần mở hoặc câu lệnh SQL");
+ Với ADODB:
Set rcs = New ADODB.RecordSet
rcs.Open "Tên bảng cần mở hoặc câu lệnh SQL", dbs
Và ta có thể thao tác với đối tượng RecordSet với các thuộc tính thông dụng nhất sau đây:

rcs.EOF: Trả về xem con trỏ bản ghi rcs đang ở cuối bảng hay chưa. Nếu khi vừa mở bảng ra mà EOF trả về True thì có nghĩa là bảng đó không có bản ghi nào.
rcs.BOF: Trả về xem con trỏ bản ghi đang ở đầu bảng dữ liệu hay không
rcs.MoveNext/ rcs.MovePrevious/ rcs.MoveFirst/ rcs.MoveLast: Di chuyển sang bản ghi tiếp theo/ trước/ đầu/ cuối
rsc.Edit/ rcs.Update: (với DAO) để chuyển vào chế độ sửa bản ghi, kết thúc việc chỉnh sửa thì dùng rcs.Update.
Với ADODB chỉ cần dùng lệnh rcs.Update mà không cần đưa vào chế độ sửa
rcs.Fields(“Tên trường”): Trả về hoặc gán giá trị cho 1 trường trên một bản ghi hiện tại

2.3.Bước 3: Kết thúc làm việc với CSDL
Một nguyên tắc bắt buộc phải tuân thủ là: Khi kết thúc làm việc với các đối tượng CSDL, phải đóng nó lại để giải phóng bộ nhớ và bỏ khóa CSDL. Đối với cả 2 loại DAO và ADODB, cách chung để thực hiện việc này là:
Dbs.Close – để đóng Cơ sở dữ liệu
Rcs.Close – để đóng kết nối với bảng.
Thứ tự thực hiện là Đóng bảng trước khi đóng CSDL. Với trường hợp kết nối muộn thì cần thêm phần giải phóng biến nữa như sau:
Set dbs=nothing và set rcs=nothing.

3.Ngôn ngữ SQL
Phần trên ta vừa trao đổi cách khởi động và thao tác thông thường với Cơ sở dữ liệu. Bây giờ hãy chuyển qua phần sức mạnh chính của SQL.
Các lệnh trong SQL được bắt đầu với bất cứ từ khóa nào trong SQL như SELECT, INSERT, UPDATE, DELETE, ALTER, DROP, … và lệnh kết thúc với một dấu chấm phảy (winking. Ví dụ về một lệnh SQL:
SELECT "ten_cot" FROM "ten_bang"; 
Tại sao dấu chấm phẩy được sử dụng sau các lệnh trong SQL. Đó là bởi vì dấu này được sử dụng để phân biệt riêng rẽ giữa các lệnh trong SQL. Đây là chuẩn mực để phân biệt các lệnh SQL khi mà có nhiều hơn một lệnh cùng được sử dụng trong một lời gọi.
Tôi xin phép chỉ viết những SQL đơn giản để mọi người tiện theo dõi.

3.1.Truy vấn lựa chọn SELECT
Mục đích: Lấy những thôn tin thỏa mãn điều kiện nào đó.
Cú pháp:
SELECT [tên trường 1], [tên trường 2] FROM [Tên bảng] WHERE [Tên trường 1] = 1 ORDER BY [Tên trường 1]
Với lệnh này ta sẽ nhận được đối tượng RecordSet bao gồm 2 trường trong đó có tất cả các bản ghi thỏa mãn Tên trường 1 = 1 và được sắp xếp theo tên trường 1 theo thứ tự Nhỏ đến lớn (muốn từ lớn đến nhỏ ta thêm từ khóa DESC sau Tên trường 1 ở mục Order by.
Ví dụ:
Set rcs = dbs.OpenRecordSet (“Select * FROM [tblCaption] WHERE [fldName] = ‘Label’;”
Ta sẽ thu được bảng rcs bao gồm các bản ghi có trường fldName có giá trị là Label. Lưu ý, khi kiểu trường là dạng ký tự ta cần có thêm các dấu nháy vào điều kiện.

3.1.1.Mệnh đề DISTINCT trong SQL
Mục đích: Lấy danh sách các đối tượng không trùng nhau trên 1 trường
Cú pháp: SELECT DISTINCT cot1 FROM   ten_bang;

3.1.2.Mệnh đề WHERE trong SQL
Mục đích: Lấy danh sách các đối tượng thỏa mãn điều kiện
Cú pháp: SELECT cot1, cot2....cotN FROM  ten_bang WHERE  DIEU_KIEN;

3.1.3.Mệnh đề AND/OR trong SQL
Mục đích: Xác lập điều kiện kiểm tra cho câu lệnh truy vấn
Cú pháp:       SELECT cot1, cot2....cotN FROM  ten_bang
WHERE  DIEU_KIEN_1 {AND|OR} DIEU_KIEN_2;

3.1.4.Mệnh đề IN trong SQL
Mục đích: Xác lập giá trị kiểm tra của điều kiện WHERE cho câu lệnh truy vấn
Cú pháp:       SELECT cot1, cot2....cotN FROM   ten_bang
WHERE  ten_cot IN (gtri-1, gtri-2,...gtri-N);
... Bài sẽ viết tiếp.


File đính kèm
.zip   SQL.zip (Kích cỡ: 39.83 KB / Tải về: 44)
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Che_Guevara , jason , ongke0711 , Minh Tiên
#3
Xin đóng góp 1 bài:


Link: [Hàm] Demo Ứng dụng: Tự chuyển code SQL trong Query sang Code VBA để sử dụng


Hình minh họa
[Hình: sqltovba.png]

Hy vọng nó hữu ích cho người mới bắt đầu.
Chữ ký của maidinhdan * Để được hỗ trợ tốt nhất, nhấn vào link dưới đây để xem.
1. [Hướng dẫn] Kiểu file gửi lên để được giúp đỡ
2. [Hướng dẫn] Nội quy diễn đàn
3. [Hướng dẫn] Cách Đưa file và hình vào diễn đàn
4.[Hướng dẫn] Để xây dựng một ứng dụng hoàn hảo và lời cảm tạ
5. Cần tìm Demo hay ứng dụng sử dụng thanh tìm kiếm phía trên cùng, bên phải của diễn đàn.
* Nếu muốn cảm ơn, hãy nhấn nút thank, không cần viết thêm bài nào nửa.



ღღღღღTài sản của maidinhdan (View All Items) ღღღღღ
Reply
Những người đã cảm ơn paulsteigel , jason , Che_Guevara , nam8384 , hungle2006 , ledangvan , Minh Tiên
#4
Bài viết rất hay, cảm ơn hai bác Paulsteigel và Maidinhdan, chúc hai bác khoẻ và đóng góp nhiều cho diễn đàn
Chữ ký của hungle2006 hungle2006,gia nhập Thủ Thuật Access từ 10-10 -15.
Reply
Những người đã cảm ơn
#5
Cảm ơn  paulsteigel ! Bài viết rất hay.
Bạn cho mình hỏi: Ưu và khuyết điểm của 2 kiểu kết nối sớm và muộn ? Khi nào thì nên dùng kiểu kết nối nào ?
Thanks !
Chữ ký của Minh Tiên -----------------------------------------------
Đường tuy ngắn, không đi không đến
Việc tuy nhỏ, không làm không nên.
                                           Tuân Tử
-----------------------------------------------
Reply
Những người đã cảm ơn
#6
(08-05-16, 11:14 AM)Minh Tiên Đã viết: ....

Theo đúng khái niệm thì Binding ở đây nên dịch là liên kết/ tham chiếu nhưng tôi dịch một cách nôm na để dễ tưởng tượng – đó là Kết nối.

1. Vài nét về Kết nối Sớm và Muộn (Early binding and Late Binding)

1.1. Kết nối muộn – Late bind
Binding trong lập trình là công cụ để tự động hóa/ điều khiển các đối tượng ngoài (OLE). Ví dụ người ta hay kết nối Word/ Excel từ Access hoặc ngược lại ...vv để điều khiển các ứng dụng ngoài đó.
Để thực hiện việc kết nối ngoài như vậy, các ứng dụng cần kết nối phải có các giao diện/ thư viện cho phép kết nối và phải được đăng ký với Hệ điều hành.
Có 2 cách để thực hiện việc kết nối này đó là:
Kết nối muộn (Late binding) bằng việc sử dụng từ khóa CreateObject để tạo ra phiên làm việc của ứng dụng cần kết nối theo đó bạn có thể điều khiển được nó. Ví dụ ta có thể tạo ra phiên làm việc mới của Excel bằng cách này với nhóm lệnh sau

Mã:
Dim oXL As Object
Set oXL = CreateObject("Excel.Application")
Ngoài ra, để điều khiển phiên làm việc của Excel đang chạy (Excel đã được khởi động), ta có thể dùng từ khóa GetObject (bất kể chúng ta đang dùng chế độ kết nối sớm hay muộn):

Mã:
Dim oXL As Object
Set oXL = GetObject(, "Excel.Application")

1.2. Kết nối sớm – Early bind
Để sử dụng Kết nối sớm (early binding), đầu tiên, chúng ta cần khởi tạo tham chiếu (reference) thư viện ứng dụng cần kết nối và điều khiển với chương trình của bạn. Có thể làm việc này đơn giản bằng cách chọn Tools/ References trong màn hình soạn Code VBA của bất kỳ ứng dụng Office nào (chẳng hạn chọn “Microsoft Excel 12.0 Object Library”). Sau đó để khởi tạo phiên làm việc mới với Excel, bạn chỉ cần thực hiện đoạn lệnh sau:

Mã:
Dim oXL As Excel.Application
Set oXL = New Excel.Application
Lưu ý: Với cả 2 cách, điều đầu tiên nên kiểm tra xem có phiên làm việc hiện thời nào của Excel đang chạy không, nếu có thì hãy kết nối với nó trước để tận dụng luôn, nếu không có mới thực hiện tạo Kết nối mới. Điều này tránh việc tạo ra quá nhiều phiên làm việc trong quá trình chạy chương trình, gây ảnh hưởng hoặc lỗi hệ thống. Hãy xem đoạn mã sau đây dùng để tạo kết nối với Word nhé...

Mã:
Function CreateWordDocument(retApp As Object) As Object
   'Muc dich: Co gang thiet lap ket noi voi mot phien lam viec cua Word neu duoc. Neu khong thi tao moi
   Dim wrdApp As Object
   
   'Co gang tao ket noi
   On Error Resume Next
   Set wrdApp = GetObject(, "Word.Application")
   If Err.Number <> 0 Then
       'Khong tao duoc ketnoi
       Err.Clear
       Set wrdApp = CreateObject("Word.Application")
       wrdApp.Visible = True
   End If
   ' Doan code chinh...
   Set retApp = wrdApp
   Set CreateWordDocument = wrdApp.Documents.Add
End Function

2. Lợi ích của Kết nối sớm
• Mã chương trình của bạn sẽ chạy nhanh hơn tương đối đấy. Đó là do mã chương trình đã được dịch sang mã máy ngay từ đầu trong khi đó, với Kết nối muộn, mã liên quan đến ứng dụng bạn cần kết nối sẽ chỉ được dịch khi nó chạy đến đoạn mã đó;
• Do mã nguồn của bạn được dịch ngay từ đầu nên quá trình tìm lỗi, Debug sẽ dễ dàng hơn và trình dịch sẽ giúp bạn tìm lỗi chương trình mà bạn vô tỉnh quên xử lý trong quá trình thực hiện. Điều này không thể làm được khi bạn sử dụng Kết nối muộn;
• Bạn có toàn quyền sử dụng tính năng tự động hoàn tất mã (Intellisense – trong quá trình viết code, chỉ cần gõ dấu chấm của đối tượng thì các thuộc tính và phương thức của đối tượng đó sẽ tự động hiển thị và chèn vào; bạn nhấn F1 thì cũng sẽ nhận được trợ giúp của chính ứng dụng đó ngay);
• Ngoài ra, khi nhấn F2 trong màn hình soạn thảo Code, bạn cũng có thể đọc được toàn bộ các đối tượng, lớp, thuộc tính của ứng dụng cần kết nối;
• Việc sử dụng các hàm/ thư viện/ hằng số của ứng dụng cũng tiện lợi, bạn không phải định nghĩa/ khai báo lại chúng như khi dùng Kết nối muộn. Nếu bạn muốn sử dụng Word từ Excel bạn chỉ cần làm thế này:

Mã:
Dim objWord As Word.Application
Set objWord = New Word.Application
With objWord
  .Visible = True
  .Activate
  .WindowState = wdWindowStateMaximize
  .Documents.Open ("c:\temp\temp.doc")
End With
Ngoài ra, khi bạn nhập .WindowState =, bạn sẽ thấy danh sách các hằng số hiện ra để chọn và chỉ cần chọn “wdWindowStateMaximize” từ danh sách. Trong khi đó, nếu dùng chế độ kết nối muộn, bạn sẽ phải tự nhập vào .WindowState = 1. ..  và bạn cũng cần phải biết xem giá trị của hằng số “wdWindowStateMaximize” là gì từ đó mới nhập vào giá trị là 1.
Nói khác hơn, với Kết nối sớm, việc lập trình của bạn sẽ dễ hơn nhiều so với kết nối muộn.

3. Lợi ích của Kết nối muộn
Nhìn chung Kết nối muộn thường được người viết code có kinh nghiệm sử dụng do nó tránh được một số phiền toái:
• Mã chương trình của bạn sẽ không phụ thuộc vào phiên bản ứng dụng bạn muốn điều khiển trong hệ thống. Ví dụ, bạn đã chọn tham chiếu đến “Microsoft Excel 12.0 Object Library”, khi thực hiện Kết nối sớm, ứng dụng của bạn sẽ chạy nếu trên hệ thống có Excel 12. Trong một số trường hợp do sự khác biệt về bộ thư viện do các phiên bản của Office, chương trình của bạn sẽ không chạy được. Với kết nối muộn, tôi chỉ cần khởi tạo Excel thì hệ thống sẽ tự tìm kiếm phiên bản Excel đang cài ổn định nhất để khởi động.
• Kích thước chương trình của bạn sẽ nhỏ hơn nếu bạn tham chiếu đến nhiều ứng dụng và mất thêm thời gian để dịch;
• Một số môi trường lập trình còn không cho bạn tạo liên kết đến ứng dụng khác.

4. Kết luận
Thường tôi sử dụng mềm dẻo giữa 2 kiểu kết nối.
• Những gì ít thay đổi và phải dùng nhiều (DAO/ADODB) – tôi dùng Kết nối sớm;
• Những gì thay đổi phiên bản nhiều trong khi tôi chỉ cần những thao tác tối thiểu (Excel/ Word...vv)– tôi dùng Kết nối muộn.
Ví dụ mà tôi chia sẻ ở bài đầu là một cách nhìn.
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Che_Guevara , maidinhdan , Minh Tiên
#7
Sử dụng SQL thay cho việc tương tác trực tiếp với RecordSet
Vấn đề này thực sự chả có gì to tát nhưng nó sẽ là cách để chúng ta thoát ly khỏi một vài phiền toái và nhàm chán khi phải thực hiện việc cập nhập bản ghi đối với các Form dạng Unbound!
Ví dụ:
Bạn muốn cập nhập 2 trường số liệu là Tuổi và Ngày thăm của Khách có tên Nguyễn Văn A đối với cửa hàng sách.
Trong đó thông tin về chuyến thăm của khách được lưu vào bảng tblCustomerVisit với các trường như ID (Kiểu Autonumber), TenKhach (kiểu Text), Tuoi (Kiểu Number), NgayTham (Kiểu DateTime)
Sẽ có 2 cách làm
Cách 1: Dùng RecordSet
Mã:
Sub UpdateCustomer()
    ' Kiểm tra xem các dữ liệu có trống không
    If Nz(txtHovatenKhach, "") = "" Or Nz(txtNgayTham, 0) = 0 Or Nz(txtTuoiKhach, 0) = 0 Then GoTo ExitSub
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("Select * from tblCustomerVisit Where TenKhach='" & txtHovatenKhach & "';")
    If rs.EOF Then GoTo ExitSub
    With rs
        .Edit
        .Fields("Tuoi") = txtTuoiKhach
        .Fields("NgayTham") = txtNgayTham
        .Update
    End With
ExitSub:
    rs.Close
End Sub

Cách 2: Dùng SQL
Mã:
Private Sub UpdateCustomer_Click()
    'Kiểm tra xem các dữ liệu có trống không
    If Nz(txtHovatenKhach, "") = "" Or Nz(txtNgayTham, 0) = 0 Or Nz(txtTuoiKhach, 0) = 0 Then GoTo ExitSub
    Dim SqlTxt As String
    SqlTxt = "UPDATE tblCustomerVisit SET Tuoi= " & txtTuoiKhach & ", NgayTham=" & txtNgayTham & " " & _
        "WHERE TenKhach='" & txtHovatenKhach & "';"
    CurrentDb.Execute SqlTxt
ExitSub:
End Sub

Cách 2 sẽ làm cho bạn đỡ phải lo lắng với việc thao tác với các đối tượng RecordSet và chỉ cần quan tâm tới SQL mà thôi.
Với SQL ta có thể:
Thêm bản ghi với SELECT ... INTO
Xóa bản ghi với DELETE ... FROM
và còn nhiều điều nữa - chúng ta sẽ cùng nghiên cứu tiếp
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn maidinhdan , Che_Guevara , Minh Tiên
#8
(08-05-16, 02:16 PM)paulsteigel Đã viết: Làm thế nào để dùng SQL trong lập trình?

Anh Ngọc có rất nhiều bài viết hay.
Xin cảm ơn a và các các thành viên trong diển đàn đã đóng góp trí tuệ, tâm huyết để cho các thành viên mới như e học hỏi.
Chữ ký của Che_Guevara Hạnh phúc không phải là cảm giác tới đích mà là trên từng chặng đường đi!
Reply
Những người đã cảm ơn
#9
Bổ sung 1/ nhiều bản ghi vào bảng với SQL
Với DAO/ADODB chúng ta sẽ phải sử dụng phương thức AddNew và sau đó là Update.
Với SQL chúng ta cũng có thể làm như vậy với 2 cách sau đây:
1. INSERT INTO [Tên bảng] ([Danh sách trường cách nhau bằng dấu phảy] VALUES ([Danh sách giá trị theo kiểu phù hợp*])
Ghi chú: * [Danh sách giá trị theo kiểu phù hợp*] có nghĩa là:
+ Đối với trường Text, giá trị phải được đặt trong cặp dấu nháy đơn ''
+ Đối với trường ngày, giá trị phải được đặt trong cặp dấu ##

2. SELECT [Danh sách trường] INTO [Tên bảng mới] [IN 'Đường dẫn đến cơ sở dữ liệu'] FROM [Tên bảng hiện tại]
Lệnh này để lựa chọn danh sách trường để đẩy vào bảng mới (trong Cơ sở dữ liệu mới nếu có thêm từ khóa IN ..).
Nếu dùng lệnh này mà không đặc tả điều kiện WHERE thì nó sẽ thêm hàng loạt bản ghi (trái với trường hợp 1 chỉ thêm 1 bản ghi).
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Che_Guevara , maidinhdan , Minh Tiên
#10
Chào bạn Ngọc cùng các ACE Pro !
Tiên có đoạn code Update dữ liệu bằng ADODB như sau:

Mã:
Function fUpdateDSHH()

   Dim strMahang As String, sqlUp As String, rs As Recordset, rsUp As ADODB.Recordset
   Set rs = CurrentDb.OpenRecordset("strTableNameTam")
   If rs.RecordCount > 0 Then
       rs.MoveFirst
       Do Until rs.EOF
       strMahang = rs!Mahang
       sqlUp = "Select * from tblDanhsach_Hanghoa Where Mahang='" & strMahang & "'"
       Call OpenConnect
       Set rsUp = New ADODB.Recordset
       rsUp.Open sqlUp, mConn, adOpenKeyset, adLockOptimistic
               If rsUp.RecordCount > 0 Then
                   rsUp!Soluongton = rsUp!Soluongton + rs!Soluongnhap
                   rsUp!Dongianhap = rs!Dongianhap
                   rsUp!Dongiabanle = rs!Dongiabanle
                   rsUp!Dongiabansy = rs!Dongiabansy
                  ...
                   rsUp.Update
               Else
                   rsUp.AddNew
                   rsUp!Mahang = rs!Mahang
                   rsUp!Tenhang = rs!Tenhang
                   rsUp!Donvitinh = rs!Donvitinh
                   rsUp!Nhomhang = rs!Nhomhang
                   rsUp!Nganhhang = rs!Nganhhang
                   rsUp!Soluongton = rs!Soluongnhap
                   rsUp!Dongianhap = rs!Dongianhap
                   rsUp!Dongiabanle = rs!Dongiabanle
                   ...
                   rsUp.Update
               End If
       rs.MoveNext
       Loop
   End If
   rs.Close: rsUp.Close
   Call CloseConnect

End Function

Dùng để Update vào DSHH , chạy OK nhưng rất chậm. Bạn Ngọc cùng các Pro xem có cách nào cải tiến đoạn code để Update được nhanh hơn không ?
Cảm ơn nhiều !
Chữ ký của Minh Tiên -----------------------------------------------
Đường tuy ngắn, không đi không đến
Việc tuy nhỏ, không làm không nên.
                                           Tuân Tử
-----------------------------------------------
Reply
Những người đã cảm ơn


Có thể liên quan đến chủ đề
Chủ đề: Tác giả Trả lời: Xem: Bài mới nhất
  [Help] Xin giúp đỡ về sử dụng hàm Dlookup với nhiều điều kiện dangh5 1 74 30-11-16, 10:44 PM
Bài mới nhất: dangh5
  [Hỏi] Sự khác nhau của Like và "=" trong các hàm D toancvp 6 203 10-11-16, 12:01 AM
Bài mới nhất: toancvp
  Thay thế giá trị từ cột này sang cột khác trong 1 query trungminh 6 139 08-11-16, 03:24 PM
Bài mới nhất: ongke0711
  [Help] Gộp nhiều dòng có cùng điều kiện lên chung một dòng trong query tronghieu9792 4 181 03-11-16, 09:58 AM
Bài mới nhất: tronghieu9792
  [Hỏi] Cách lọc trong query trungdv007 10 355 11-10-16, 08:30 AM
Bài mới nhất: trungdv007

Chuyển nhanh:


User(s) browsing this thread: 1 Guest(s)
Diễn Đàn Thơ Văn Thi Ẩm Lâu|Nhà Hàng Sông Thơ