1. tao command
Bạn có thể dùng phần tử “Command Button” trong cửa sổ Toolbox để tạo nút lệnh. Ngay
sau khi bạn vẽ nút lệnh vào form xong, cửa sổ “Command Button Wizard” sẽ hiển thị
lên, bạn chọn mục “Miscellaneous” trong danh sách “Categories” rồi nhấn nút Cancel để
hoàn thành việc tạo nút lệnh. Sau đó, bạn nhấn phải chuột trên nút lệnh vừa vẽ để hiển thị
menu pop-up kèm theo; bạn chọn mục “Build Events”, chọn mục “Code Builder” rồi
nhấn button OK để hoàn thành việc tạo thủ tục xử lý sự kiện Click chuột trên nút lệnh
tương ứng. Bạn có thể viết code VBA vào thân của thủ tục này để giải quyết chức năng
mà bạn muốn.

Để mở file Word, cách tốt nhất là kích hoạt ứng dụng Word rồi nhờ nó mở file Word để
người dùng xem/hiệu chỉnh nội dung. Tương tự, để mở file Excel, cách tốt nhất là kích
hoạt ứng dụng Excel rồi nhờ nó mở file Excel để người dùng xem/hiệu chỉnh nội dung.
Để kích hoạt ứng dụng và yêu cầu nó mở file dữ liệu kèm theo, bạn có thể gọi hàm API
Windows tên là WinExec(). Sau đây là đoạn code VBA mẫu miêu tả thủ tục xử lý nút
lệnh, nó kích hoạt Word (Excel) và yêu cầu ứng dụng này mở file dữ liệu kèm theo:

‘khai báo hàm API cần gọi
Private Declare Function WinExec Lib “kernel32” (ByVal lpCmdLine As String, ByVal
nCmdShow As Long) As Long
‘định nghĩa hằng cần dùng
Const SW_SHOWNORMAL = 1

‘thủ tục đáp ứng Click chuột trên button chạy Word
Private Sub btnWord_Click()
WinExec “””c:Program FilesMicrosoft OfficeOffice10winword.exe””
c:YourDatayourfile.doc”, SW_SHOWNORMAL
End Sub
‘thù tục đáp ứng Click chuột trên button chạy Excel
Private Sub btnExcel_Click()
WinExec “””c:Program FilesMicrosoft OfficeOffice10excel.exe””
c:YourDatayourfile.xls”, SW_SHOWNORMAL
End Sub

Lưu ý chuỗi miêu tả đường dẫn của file khả thi cần chạy được đặt trong cặp nháy kép nếu
đường dẫn có chứa các ký tự trống. Khi ứng dụng đã được kích hoạt, nó sẽ chạy song
song và độc lập với ứng dụng kích hoạt nó.]




PhamQuanNet
   •   Trang chủHome page
   •   Hình ảnhPhotos
   •   Liên hệContact us
•   Giới thiệuAbout us

19. 12 .2008

Cách tạo nút đơn giản từ macro trong Access




Macro là những hành động được ta tạo ra, được giao một nhiệm vụ ghi lại những hành
động ta làm, ví dụ như ta đặt font chữ font chữ gì cỡ bao nhiêu…ghi lại những hành động
đó ta sẽ sử dụng sau, ta sẽ không phải thực hiện nó lần nữa mà sẽ dùng chính những hành
động trước đó ta làm đó gán cho macro thực hiện nó, trong Access cũng gần như vậy, gán
cho hình ảnh một lệnh đơn giản như mở một form khác, tạo các nút như First, Previous,
Next, Last, New, Delete, Close , Exit… Hôm nay mình dành chút thời gian viết bài cho
các bạn, về chức năng cơ bản về Macro trong access để thực hiện một trong những lệnh
cơ bản nhất trong Project Q1 của các bạn nhé !
Tạo một nút Next cơ bản bằng cô cụ Rectangle và Label.
Hành động khi nhấn vào đối tượng đều được nằm trong thẻ Event, hãy chỉ vào đối tượng
đó và chọn On Click > Khi chỉ chuột vào đố, nó hiện lên dấu 3 chấm nhấn vào đó




Cửa sổ Choose Builder hiện ra có 3 lựa chọn: Ta hãy chọn Macro Builder nhé !(Chúng ta
đang đi tạo macro cho nó mà hì hì)




Cửa sổ Macro hiện ra với bảng Save as hiện lên bắt đặt tên cho Macro sắp được đặt ra: gõ
Next nhé !




Các bạn đang tạo macro rồi đấy 1, nhấn vào khung action chọn: GotoRecord;
Bảng Action Argument với 4 ô hiện ra, lựa chọn khung Record là next để gán cho nút
lệnh là next.
và tắt bảng macro đi, bây giờ khung label đã được gán với lệnh là Next.




Tương tự như vậy tạo các nút khác rồi chọn các bước tương tự như trên, những nút lệnh
trên chờ các bạn mò tới chúng đấy hì hì.
Khi không muốn hiện thị những thành phần của form, làm cho tập trung vào giao diện
chính của form,ta có thể loại bỏ những thành phần như sau:

Record Selectors Yes > NO
Navigation Buttons Yes > NO
Dividing Lines Yes > NO

Hiển thị giao diện không có nút của windown, và access tạo cho một cảm giác gì đó thật
thoải mái trong cách làm việc với chúng. Lên ta có thể loại bỏ nút Close của chương
trình làm ra bằng cách chọn Border Style: Sizable > None
Trên đây là những cách hiểu và làm việc với Macro trong lúc làm project này. Còn rất
nhiều điều mình muốn chúng hoạt động nhưng do khả năng hạn chế, chưa thực hiện
những điều mong muốn, Chúng ta hãy cố gắng lên nhé !


Tin học 365
Recordset trong Access Data
Project
Thứ tư, 16 Tháng 1 2008 09:39
1. Chương trình phải là một ADP (Access Data Project), không phải là MDB.

2. Dự án có thể tiếp tục kết nối sang cơ sở dữ liệu ‘config’ của SQL Server.

3. Tất cả dữ liệu phải được lưu trữ trong các cơ sở dữ liệu ‘client’ SQL Server.

4. Các form phải kết nối tới cơ sở dữ liệu client chính xác trong thời gian chạy.

Bạn có thực hiện điều này? Tất cả cơ sở dữ liệu (CSDL) được đặt trên một SQL Server
đơn, nhưng ứng dụng có thể cần lấy dữ liệu từ bất kỳ một nguồn trong số đó. Ở một số
trường hợp, người dùng yêu cầu trích lấy dữ liệu từ một CSDL cụ thể. Họ có thể khởi phát
hoạt động sử dụng CSDL riêng và ứng dụng phải được trỏ động tới nơi lưu trữ dữ liệu
chính xác.

Ý nghĩ đầu tiên của tôi là phải thay đổi thuộc tính kết nối của ứng dụng ADP mỗi khi
người dùng chọn một CSDL khác nhau. Nhưng điều này không đơn giản mà cũng chẳng
dễ dàng gì. Thay đổi kết nối trong thời gian chạy cũng giống như bắt con ngựa đua phải
quay ngược lại giữa đường đua. Khi một thuộc tính kết nối của ADP bị đóng, tất cả form
đều bị huỷ.

Giải pháp cuối cùng rất dễ chịu và có thể dùng lại được. Trong một nutsell, nó gồm những
phần sau:

• Kết nối ADP được gắn với CSDL config.
• CSDL config quản lý đăng nhập người dùng.
• Config bao gồm một danh sách CSDL client.
• Nhiệm vụ cho tất cả client nằm trong CSDL Config.
• ADP có hai thủ tục đơn giản hoá chuyển đổi.
• Thủ tục con: LoadDbsConnectString(ClientID).
• Hàm: GetRecordset(SQL) As Recordset.
• Dữ liệu Form và Control được load qua thuộc tính Recordset.
• Thuộc tính Form.RecordSource phải để trống.
• Thuộc tính Form.RecordSet phải được thiết lập ở mã VBA.
• Phải dùng toán tử Set.
• Bảng, bảng ảo (view) hoặc thủ tục lưu trữ có thể được sử dụng.

Ví dụ bên dưới (hình minh hoạ) là frmAddress ở mô hình thiết kế. Form này sẽ đòi hỏi
thiết lập bốn recordset: một cho dữ liệu của form và ba cho các hộp combo box. Chú ý là
recordset cho một trong ba hộp đó, cboStateCode sẽ phụ thuộc vào giá trị được chọn trong
tuỳ chọn country (đất nước), cboCountryID. Chúng ta sẽ xem có thể load form này với dữ
liệu như thế nào.

Chú ý: Hiện nay không có mã nguồn để download. Bởi để làm việc với các kết nối đòi hỏi
phải có lượng rất lớn mã nguồn. Do người đọc thường có máy chủ và CSDL riêng nên
điều này trở thành một vấn đề không đơn giản để triển khai.

Thiết lập kết nối ADP

Như đã đề cập tới ở trên, bước đầu tiên là thiết lập toàn diện kết nối cho ADP. Trong
trường hợp của chúng ta, đây là thiết lập cho CSDL Config chứa thông tin về các database
client khác nhau mà ứng dụng có thể trỏ tới.

Thuộc tính Connection của ADP có thể được thiết lập dễ dàng trong thời gian thiết kế mà
không cần phải chỉnh sửa bởi người dùng. Đơn giản chỉ cần chọn Connection từ menu
File và điền đầy đủ giá trị yêu cầu trong hộp thoại.

Hộp thoại này có một nút "Test Connection" (kiểm tra kết nối), nhưng nó là một placebo
(hộp để giữ chỗ). Bạn chỉ có thể chọn một CSDL nếu nhập một server hợp lệ. Nếu bạn có
cả tên server và database hợp lệ, sẽ chẳng có cái gì để phải kiểm tra cả. Nếu muốn yên
tâm hơn, kích vào nút Test Connection để kiểm tra lại trước khi đóng hộp thoại.

Tạo các thủ tục

Theo các yêu cầu ở trên, nguồn cho client data (dữ liệu cho máy khách) phải nằm ở dạng
JIT (just in time, tức tạm thời). Những nguồn này có thể là khi người dùng lựa chọn tìm
kiếm một CSDL cụ thể hoặc là kết quả sau khi thực hiện một nhiệm vụ gắn với một cơ sở
dữ liệu client cụ thể. Nhưng kết luận cuối cùng thì, bạn sẽ không biết CSDL nào được trỏ
tới trước khi form được mở.

Để đáp ứng yêu cầu này, chúng tôi tạo một giá trị xâu tổng thể (g_ClientCnn), chia nhỏ
xâu kết nối đầy đủ vào CSDL client được yêu cầu. Do đó, khi một yêu cầu dữ liệu được
thực hiện, chúng tôi sẽ xác định ClientID phù hợp và đưa nó vào thủ tục con thiết lập xâu
kết nối. (Xem đoạn mã bên dưới để hiểu chi tiết).

' Client connect string is saved in this public variable.
Public g_ClientCnn As String
Public Sub LoadDbsConnectString(ByVal lClientID As Long)
On Error GoTo Err_Handler
Dim rstTemp As New ADODB.Recordset
Dim strSQL As String
Dim strDatabase As String
Dim strProjCnn As String
' You must hard-code the name of the config database. It will
' be used below to simplify the creation of the new connect string.
Const strProjDBS As String = "RecreationConfigDB"
' The config database must include a table to manage client
' database names based on an identifier, such as ClientID.
strSQL = "SELECT [DatabaseName] FROM tblClient " & _
"WHERE [ClientID]=" & lClientID
rstTemp.Open strSQL, CurrentProject.Connection
' If the client record isn't found, throw an error. Otherwise,
' use the database name to update the connection string variable.
If rstTemp.BOF And rstTemp.EOF Then
MsgBox "Couldn't locate the database.", vbCritical, "ERROR"
Else
' The Replace function simplifies the connection string edit.
' We know that the format of CurrentProject.Connection is
' correct. Simply replace the database name (assuming the
' user's login has permission to both databases.)
strDatabase = rstTemp!DatabaseName
strProjCnn = CurrentProject.Connection
g_ClientCnn = Replace(strProjCnn, strProjDBS, strDatabase)
End If
Exit_Here:
Set rstTemp = Nothing
Exit Function
Err_Handler:
Resume Next
End Sub

Ngoài ra còn cần một thủ tục con để thiết lập xâu kết nối, với một hoặc nhiều hàm tải dữ
liệu vào recordset. Bên dưới là một trong các hàm trả ra recordset ADO. Tôi sử dụng một
số thực thi khác cho thủ tục lưu trữ và chạy các lệnh INSERT, UPDATE DELETE. Tuy
nhiên, để thực hiện nhiệm vụ tiếp theo, chúng ta cần trả lại một recordset ADO, thực hiện
như sau:

Public Function GetRecordset(ByVal sSQL As String) As ADODB.Recordset
  On Error GoTo Err_Handler

  Dim rstTemp As New ADODB.Recordset
  Dim cnnTemp As New ADODB.Connection

  ' First open a temporary connection, and then load the recordset.
  cnnTemp.Open g_ClientCnn
  rstTemp.Open sSQL, cnnTemp, adOpenDynamic, adLockOptimistic
  ' This doesn't include any error handling
  ' You will have to add that to meet your needs.
  Set GetRecordset = rstTemp
Exit_Here:
  Set rstTemp = Nothing
  Set cnnTemp = Nothing
  Exit Function
Err_Handler:
  Resume Exit_Here
End Function
Đặt tất cả lại với nhau

Bây giờ chúng ta đã có tất cả các thành phần (một kết nối dự án, một form và bốn thủ
tục). Vấn đề chỉ còn là làm sao ghép chúng lại với nhau trong sự kiện Form_Open(). Hãy
chắc chắn rằng form của bạn không có lệnh SELECT trong thuộc tính RecordSource, vì
nó sẽ cạnh tranh với mã nguồn chúng ta sẽ chạy. Với mục đích đó, form này sẽ không có
nguồn record khi thiết kế. Thực tế, nó không thể trỏ tới bất kỳ bảng nào vì các bảng client
chúng ta tìm kiếm thậm chí không nằm trong CSDL Config, CSDL hiện ADP đang được
kết nối. Dataset sẽ được gán tự động vào form và các điều khiển của nó nằm trong mã
sau:

Private Sub Form_Open(Cancel As Integer)
  On Error GoTo Err_Handler
  Dim strSQL As String
  Dim lngEmployeeID As Long
  Dim lngCountryID As Long

  ' Call a 'Property Get' function to grab EmployeeID
  ' This will be used to filter the recordset. (You will need to adapt
  ' this part of the code to match your SQL requirements.)
  lngEmployeeID = GetEmployeeID()
' Identify SQL to be passed, a stored proc in this case, and
  ' remember to use the SET command when assigning the recordset.
  strSQL = "spc_uclAddress @EmployeeID=" & EmployeeID
  Set Me.Recordset = GetRecordset(strSQL)

  ' Load record sources for all combo boxes
  strSQL = "spc_ddlAddressType"
  Set Me!cboAddressTypeID.Recordset = GetRecordset(strSQL, client)
  strSQL = "spc_ddlCountry"
  Set Me!cboCountryID.Recordset = GetRecordset(strSQL, client)

  ' The list of states depends upon the country. This param
  ' is passed to the stored proc. (our default is 1 for USA)
  lngCountryID = Nz(Me.Recordset!CountryID, 1)
  strSQL = "spc_ddlState @CountryID=" & lngCountryID
  Set Me!cboStateProvince.Recordset = GetRecordset(strSQL, client)

Exit_Here:
  Exit Sub
Err_Handler:
  Resume Next
End Sub

Nhiều năm nay tôi biết rằng, bạn có thể đưa một dataset vào form hay control, nhưng
chưa bao giờ hiểu tại sao lại như thế. Khi tiếp cận với phương thức này, đột nhiên tôi hiểu
ra lý do. Nó cũng hữu ích một cách đặc biệt khi bạn muốn sử dụng SQL Server để lưu trữ
các thủ tục trong Access Data Project. Chương trình này chắc chắn cũng hoạt động được
cho MDB mặc dù chưa có một kiểmt tra chính thức nào. Có một số quan điểm phản ứng
mạnh về vấn đề này, phản đối ADP. Nhưng tôi phải nói rằng, với các phương thức đã
được mô tả ở trên, việc sử dụng ADO recordset thực sự trở nên đơn giản, đặc biệt là khi
tải dữ liệu vào form và control.

access

  • 1.
    1. tao command Bạncó thể dùng phần tử “Command Button” trong cửa sổ Toolbox để tạo nút lệnh. Ngay sau khi bạn vẽ nút lệnh vào form xong, cửa sổ “Command Button Wizard” sẽ hiển thị lên, bạn chọn mục “Miscellaneous” trong danh sách “Categories” rồi nhấn nút Cancel để hoàn thành việc tạo nút lệnh. Sau đó, bạn nhấn phải chuột trên nút lệnh vừa vẽ để hiển thị menu pop-up kèm theo; bạn chọn mục “Build Events”, chọn mục “Code Builder” rồi nhấn button OK để hoàn thành việc tạo thủ tục xử lý sự kiện Click chuột trên nút lệnh tương ứng. Bạn có thể viết code VBA vào thân của thủ tục này để giải quyết chức năng mà bạn muốn. Để mở file Word, cách tốt nhất là kích hoạt ứng dụng Word rồi nhờ nó mở file Word để người dùng xem/hiệu chỉnh nội dung. Tương tự, để mở file Excel, cách tốt nhất là kích hoạt ứng dụng Excel rồi nhờ nó mở file Excel để người dùng xem/hiệu chỉnh nội dung. Để kích hoạt ứng dụng và yêu cầu nó mở file dữ liệu kèm theo, bạn có thể gọi hàm API Windows tên là WinExec(). Sau đây là đoạn code VBA mẫu miêu tả thủ tục xử lý nút lệnh, nó kích hoạt Word (Excel) và yêu cầu ứng dụng này mở file dữ liệu kèm theo: ‘khai báo hàm API cần gọi Private Declare Function WinExec Lib “kernel32” (ByVal lpCmdLine As String, ByVal nCmdShow As Long) As Long ‘định nghĩa hằng cần dùng Const SW_SHOWNORMAL = 1 ‘thủ tục đáp ứng Click chuột trên button chạy Word Private Sub btnWord_Click() WinExec “””c:Program FilesMicrosoft OfficeOffice10winword.exe”” c:YourDatayourfile.doc”, SW_SHOWNORMAL End Sub ‘thù tục đáp ứng Click chuột trên button chạy Excel Private Sub btnExcel_Click() WinExec “””c:Program FilesMicrosoft OfficeOffice10excel.exe”” c:YourDatayourfile.xls”, SW_SHOWNORMAL End Sub Lưu ý chuỗi miêu tả đường dẫn của file khả thi cần chạy được đặt trong cặp nháy kép nếu đường dẫn có chứa các ký tự trống. Khi ứng dụng đã được kích hoạt, nó sẽ chạy song song và độc lập với ứng dụng kích hoạt nó.] PhamQuanNet • Trang chủHome page • Hình ảnhPhotos • Liên hệContact us
  • 2.
    Giới thiệuAbout us 19. 12 .2008 Cách tạo nút đơn giản từ macro trong Access Macro là những hành động được ta tạo ra, được giao một nhiệm vụ ghi lại những hành động ta làm, ví dụ như ta đặt font chữ font chữ gì cỡ bao nhiêu…ghi lại những hành động đó ta sẽ sử dụng sau, ta sẽ không phải thực hiện nó lần nữa mà sẽ dùng chính những hành động trước đó ta làm đó gán cho macro thực hiện nó, trong Access cũng gần như vậy, gán cho hình ảnh một lệnh đơn giản như mở một form khác, tạo các nút như First, Previous, Next, Last, New, Delete, Close , Exit… Hôm nay mình dành chút thời gian viết bài cho các bạn, về chức năng cơ bản về Macro trong access để thực hiện một trong những lệnh cơ bản nhất trong Project Q1 của các bạn nhé ! Tạo một nút Next cơ bản bằng cô cụ Rectangle và Label.
  • 3.
    Hành động khinhấn vào đối tượng đều được nằm trong thẻ Event, hãy chỉ vào đối tượng đó và chọn On Click > Khi chỉ chuột vào đố, nó hiện lên dấu 3 chấm nhấn vào đó Cửa sổ Choose Builder hiện ra có 3 lựa chọn: Ta hãy chọn Macro Builder nhé !(Chúng ta đang đi tạo macro cho nó mà hì hì) Cửa sổ Macro hiện ra với bảng Save as hiện lên bắt đặt tên cho Macro sắp được đặt ra: gõ Next nhé ! Các bạn đang tạo macro rồi đấy 1, nhấn vào khung action chọn: GotoRecord; Bảng Action Argument với 4 ô hiện ra, lựa chọn khung Record là next để gán cho nút lệnh là next.
  • 4.
    và tắt bảngmacro đi, bây giờ khung label đã được gán với lệnh là Next. Tương tự như vậy tạo các nút khác rồi chọn các bước tương tự như trên, những nút lệnh trên chờ các bạn mò tới chúng đấy hì hì. Khi không muốn hiện thị những thành phần của form, làm cho tập trung vào giao diện chính của form,ta có thể loại bỏ những thành phần như sau: Record Selectors Yes > NO Navigation Buttons Yes > NO Dividing Lines Yes > NO Hiển thị giao diện không có nút của windown, và access tạo cho một cảm giác gì đó thật thoải mái trong cách làm việc với chúng. Lên ta có thể loại bỏ nút Close của chương trình làm ra bằng cách chọn Border Style: Sizable > None
  • 5.
    Trên đây lànhững cách hiểu và làm việc với Macro trong lúc làm project này. Còn rất nhiều điều mình muốn chúng hoạt động nhưng do khả năng hạn chế, chưa thực hiện những điều mong muốn, Chúng ta hãy cố gắng lên nhé ! Tin học 365 Recordset trong Access Data Project Thứ tư, 16 Tháng 1 2008 09:39 1. Chương trình phải là một ADP (Access Data Project), không phải là MDB. 2. Dự án có thể tiếp tục kết nối sang cơ sở dữ liệu ‘config’ của SQL Server. 3. Tất cả dữ liệu phải được lưu trữ trong các cơ sở dữ liệu ‘client’ SQL Server. 4. Các form phải kết nối tới cơ sở dữ liệu client chính xác trong thời gian chạy. Bạn có thực hiện điều này? Tất cả cơ sở dữ liệu (CSDL) được đặt trên một SQL Server đơn, nhưng ứng dụng có thể cần lấy dữ liệu từ bất kỳ một nguồn trong số đó. Ở một số trường hợp, người dùng yêu cầu trích lấy dữ liệu từ một CSDL cụ thể. Họ có thể khởi phát hoạt động sử dụng CSDL riêng và ứng dụng phải được trỏ động tới nơi lưu trữ dữ liệu chính xác. Ý nghĩ đầu tiên của tôi là phải thay đổi thuộc tính kết nối của ứng dụng ADP mỗi khi người dùng chọn một CSDL khác nhau. Nhưng điều này không đơn giản mà cũng chẳng dễ dàng gì. Thay đổi kết nối trong thời gian chạy cũng giống như bắt con ngựa đua phải quay ngược lại giữa đường đua. Khi một thuộc tính kết nối của ADP bị đóng, tất cả form đều bị huỷ. Giải pháp cuối cùng rất dễ chịu và có thể dùng lại được. Trong một nutsell, nó gồm những
  • 6.
    phần sau: • Kếtnối ADP được gắn với CSDL config. • CSDL config quản lý đăng nhập người dùng. • Config bao gồm một danh sách CSDL client. • Nhiệm vụ cho tất cả client nằm trong CSDL Config. • ADP có hai thủ tục đơn giản hoá chuyển đổi. • Thủ tục con: LoadDbsConnectString(ClientID). • Hàm: GetRecordset(SQL) As Recordset. • Dữ liệu Form và Control được load qua thuộc tính Recordset. • Thuộc tính Form.RecordSource phải để trống. • Thuộc tính Form.RecordSet phải được thiết lập ở mã VBA. • Phải dùng toán tử Set. • Bảng, bảng ảo (view) hoặc thủ tục lưu trữ có thể được sử dụng. Ví dụ bên dưới (hình minh hoạ) là frmAddress ở mô hình thiết kế. Form này sẽ đòi hỏi thiết lập bốn recordset: một cho dữ liệu của form và ba cho các hộp combo box. Chú ý là recordset cho một trong ba hộp đó, cboStateCode sẽ phụ thuộc vào giá trị được chọn trong tuỳ chọn country (đất nước), cboCountryID. Chúng ta sẽ xem có thể load form này với dữ liệu như thế nào. Chú ý: Hiện nay không có mã nguồn để download. Bởi để làm việc với các kết nối đòi hỏi phải có lượng rất lớn mã nguồn. Do người đọc thường có máy chủ và CSDL riêng nên điều này trở thành một vấn đề không đơn giản để triển khai. Thiết lập kết nối ADP Như đã đề cập tới ở trên, bước đầu tiên là thiết lập toàn diện kết nối cho ADP. Trong trường hợp của chúng ta, đây là thiết lập cho CSDL Config chứa thông tin về các database client khác nhau mà ứng dụng có thể trỏ tới. Thuộc tính Connection của ADP có thể được thiết lập dễ dàng trong thời gian thiết kế mà không cần phải chỉnh sửa bởi người dùng. Đơn giản chỉ cần chọn Connection từ menu File và điền đầy đủ giá trị yêu cầu trong hộp thoại. Hộp thoại này có một nút "Test Connection" (kiểm tra kết nối), nhưng nó là một placebo (hộp để giữ chỗ). Bạn chỉ có thể chọn một CSDL nếu nhập một server hợp lệ. Nếu bạn có cả tên server và database hợp lệ, sẽ chẳng có cái gì để phải kiểm tra cả. Nếu muốn yên tâm hơn, kích vào nút Test Connection để kiểm tra lại trước khi đóng hộp thoại. Tạo các thủ tục Theo các yêu cầu ở trên, nguồn cho client data (dữ liệu cho máy khách) phải nằm ở dạng JIT (just in time, tức tạm thời). Những nguồn này có thể là khi người dùng lựa chọn tìm kiếm một CSDL cụ thể hoặc là kết quả sau khi thực hiện một nhiệm vụ gắn với một cơ sở
  • 7.
    dữ liệu clientcụ thể. Nhưng kết luận cuối cùng thì, bạn sẽ không biết CSDL nào được trỏ tới trước khi form được mở. Để đáp ứng yêu cầu này, chúng tôi tạo một giá trị xâu tổng thể (g_ClientCnn), chia nhỏ xâu kết nối đầy đủ vào CSDL client được yêu cầu. Do đó, khi một yêu cầu dữ liệu được thực hiện, chúng tôi sẽ xác định ClientID phù hợp và đưa nó vào thủ tục con thiết lập xâu kết nối. (Xem đoạn mã bên dưới để hiểu chi tiết). ' Client connect string is saved in this public variable. Public g_ClientCnn As String Public Sub LoadDbsConnectString(ByVal lClientID As Long) On Error GoTo Err_Handler Dim rstTemp As New ADODB.Recordset Dim strSQL As String Dim strDatabase As String Dim strProjCnn As String ' You must hard-code the name of the config database. It will ' be used below to simplify the creation of the new connect string. Const strProjDBS As String = "RecreationConfigDB" ' The config database must include a table to manage client ' database names based on an identifier, such as ClientID. strSQL = "SELECT [DatabaseName] FROM tblClient " & _ "WHERE [ClientID]=" & lClientID rstTemp.Open strSQL, CurrentProject.Connection ' If the client record isn't found, throw an error. Otherwise, ' use the database name to update the connection string variable. If rstTemp.BOF And rstTemp.EOF Then MsgBox "Couldn't locate the database.", vbCritical, "ERROR" Else ' The Replace function simplifies the connection string edit. ' We know that the format of CurrentProject.Connection is ' correct. Simply replace the database name (assuming the ' user's login has permission to both databases.) strDatabase = rstTemp!DatabaseName strProjCnn = CurrentProject.Connection g_ClientCnn = Replace(strProjCnn, strProjDBS, strDatabase) End If Exit_Here: Set rstTemp = Nothing Exit Function Err_Handler: Resume Next End Sub Ngoài ra còn cần một thủ tục con để thiết lập xâu kết nối, với một hoặc nhiều hàm tải dữ
  • 8.
    liệu vào recordset.Bên dưới là một trong các hàm trả ra recordset ADO. Tôi sử dụng một số thực thi khác cho thủ tục lưu trữ và chạy các lệnh INSERT, UPDATE DELETE. Tuy nhiên, để thực hiện nhiệm vụ tiếp theo, chúng ta cần trả lại một recordset ADO, thực hiện như sau: Public Function GetRecordset(ByVal sSQL As String) As ADODB.Recordset On Error GoTo Err_Handler Dim rstTemp As New ADODB.Recordset Dim cnnTemp As New ADODB.Connection ' First open a temporary connection, and then load the recordset. cnnTemp.Open g_ClientCnn rstTemp.Open sSQL, cnnTemp, adOpenDynamic, adLockOptimistic ' This doesn't include any error handling ' You will have to add that to meet your needs. Set GetRecordset = rstTemp Exit_Here: Set rstTemp = Nothing Set cnnTemp = Nothing Exit Function Err_Handler: Resume Exit_Here End Function Đặt tất cả lại với nhau Bây giờ chúng ta đã có tất cả các thành phần (một kết nối dự án, một form và bốn thủ tục). Vấn đề chỉ còn là làm sao ghép chúng lại với nhau trong sự kiện Form_Open(). Hãy chắc chắn rằng form của bạn không có lệnh SELECT trong thuộc tính RecordSource, vì nó sẽ cạnh tranh với mã nguồn chúng ta sẽ chạy. Với mục đích đó, form này sẽ không có nguồn record khi thiết kế. Thực tế, nó không thể trỏ tới bất kỳ bảng nào vì các bảng client chúng ta tìm kiếm thậm chí không nằm trong CSDL Config, CSDL hiện ADP đang được kết nối. Dataset sẽ được gán tự động vào form và các điều khiển của nó nằm trong mã sau: Private Sub Form_Open(Cancel As Integer) On Error GoTo Err_Handler Dim strSQL As String Dim lngEmployeeID As Long Dim lngCountryID As Long ' Call a 'Property Get' function to grab EmployeeID ' This will be used to filter the recordset. (You will need to adapt ' this part of the code to match your SQL requirements.) lngEmployeeID = GetEmployeeID()
  • 9.
    ' Identify SQLto be passed, a stored proc in this case, and ' remember to use the SET command when assigning the recordset. strSQL = "spc_uclAddress @EmployeeID=" & EmployeeID Set Me.Recordset = GetRecordset(strSQL) ' Load record sources for all combo boxes strSQL = "spc_ddlAddressType" Set Me!cboAddressTypeID.Recordset = GetRecordset(strSQL, client) strSQL = "spc_ddlCountry" Set Me!cboCountryID.Recordset = GetRecordset(strSQL, client) ' The list of states depends upon the country. This param ' is passed to the stored proc. (our default is 1 for USA) lngCountryID = Nz(Me.Recordset!CountryID, 1) strSQL = "spc_ddlState @CountryID=" & lngCountryID Set Me!cboStateProvince.Recordset = GetRecordset(strSQL, client) Exit_Here: Exit Sub Err_Handler: Resume Next End Sub Nhiều năm nay tôi biết rằng, bạn có thể đưa một dataset vào form hay control, nhưng chưa bao giờ hiểu tại sao lại như thế. Khi tiếp cận với phương thức này, đột nhiên tôi hiểu ra lý do. Nó cũng hữu ích một cách đặc biệt khi bạn muốn sử dụng SQL Server để lưu trữ các thủ tục trong Access Data Project. Chương trình này chắc chắn cũng hoạt động được cho MDB mặc dù chưa có một kiểmt tra chính thức nào. Có một số quan điểm phản ứng mạnh về vấn đề này, phản đối ADP. Nhưng tôi phải nói rằng, với các phương thức đã được mô tả ở trên, việc sử dụng ADO recordset thực sự trở nên đơn giản, đặc biệt là khi tải dữ liệu vào form và control.