-
Làm thế nào để dùng SQL trong lập trình?
paulsteigel > 06-05-16, 12:27 PM
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====================== -
RE: Từ lập trình thông thường chuyển sang SQL
paulsteigel > 06-05-16, 12:31 PM
(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 DatabaseVới ADODB:Cách 1:Dim dbs as ADODB.ConnectionSet dbs = new ADODB.ConnectionCách 2:Dim dbs as New ADODB.Connection
· Bước 2: Kết nối CSDLVớ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 ObjectVới ADODB:Dim dbs As ObjectSet dbs = CreateObject("ADODB.Connection")· Bước 2: Kết nối CSDLVớ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 (. 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. -
RE: Làm thế nào để dùng SQL trong lập trình?
maidinhdan > 06-05-16, 03:04 PM
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
Hy vọng nó hữu ích cho người mới bắt đầu. -
RE: Làm thế nào để dùng SQL trong lập trình?
hungle2006 > 07-05-16, 10:08 AM
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 -
RE: Làm thế nào để dùng SQL trong lập trình?
Minh Tiên > 08-05-16, 11:14 AM
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 ! -
RE: Làm thế nào để dùng SQL trong lập trình?
paulsteigel > 08-05-16, 12:06 PM
(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
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 = CreateObject("Excel.Application")
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:
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ã:Dim oXL As Excel.Application
Set oXL = New Excel.Application
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:
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.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
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. -
RE: Làm thế nào để dùng SQL trong lập trình?
paulsteigel > 08-05-16, 02:16 PM
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 -
RE: Làm thế nào để dùng SQL trong lập trình?
Che_Guevara > 08-05-16, 09:58 PM
-
RE: Làm thế nào để dùng SQL trong lập trình?
paulsteigel > 09-05-16, 02:35 PM
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). -
RE: Làm thế nào để dùng SQL trong lập trình?
Minh Tiên > 10-05-16, 09:30 AM
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 !