Thủ thuật access 1

450 views
Skip to first unread message

quang quac

unread,
May 29, 2010, 1:51:03 AM5/29/10
to sptink44
Sau khi tìm kiếm khá lâu và tổng hợp các kiến thức trên mạng, tớ đã
lọc ra được rất nhiều thủ thuật hay về access (cụ thể là phần macro và
VBA). Do quá dài nên tớ chia nó ra làm 4 phần và post lên group từng
phần cho các bạn. Các bạn lên đọc và tham khảo thêm nhá, có gì ko rõ
thì cứ pmm tớ (mà hỏi câu dễ thôi nhá, câu khó tớ cũng không biết trả
lời đâu)

------------------------------------------------------------------------------------------------------------------------------------------

Phần 1:
Thủ thuật chỉnh hay nên đọc

Option Group thông minh (Access 97/95/2.0)
Thông thưòng khi bạn nhóm các nút Option vào trong một Option group,
thì mỗi nút Option này sẽ không nhận được sự kiện nhấn đúp vào một nút
Option nào đóã. Điều này gây khó chịu cho người dùng có thói quen nhấn
kép chuột vào Option được chọn để đồng thời xác nhận lưạ chọn Option
và đóng lại Dialog box, (thông thường thì trong Dialog box kiểu chọn
lựa một trong nhiều Option, ta phải chọn bấm nút Option, rồi bấm tiếp
nút OK).
Chúng ta lợi dụng sự kiện DblClick của đối tượng Option group để giải
quyết vấn đề trên. Khi ấy sự kiện DblClick lên một nút Option bất kỳ
trong Option group sẽ kích nút OK (hoặc nút lệnh tương ứng với nút
Option ấy), và sau đây là đoạn mã minh họa:
Sub grpOpt_DblClick (Cancel As Integer)
? Fire the OK Command Button
Call cmdOK_Click
End Sub
Đoạn mã trong nút lệnh OK như sau:
Sub cmdOK_Click ()
If grpOpt.Value = 1 Then
<More code here>
<Ca?c ma~ u+?ng vo+?i nu?t Option 1>
Else
<More code here>
<Ca?c ma~ u+?ng vo+?i nu?t Option kha?c>
End If
End Sub
Giữ cho các tiến trình DOS tiếp tục bị che
(Access 97/95 - Visual Basic (32-bit)
Trong khi làm việc, có nhiều khi chúng ta cần thực thi một lệnh Dos
nào đó hay phải gọi đến Shell Command từ trong ứng dụng của mình. Để
không bị gián đoạn điều khiển màn hình hiện hành của chương trình đang
chạy, bạn muốn ngăn không cho hệ điều hành trao "điều khiển" từ tiến
trình đang thi hành này cho một tiến trình Dos hay Windows khác đang
được thực thi trong chế độ nền.
Đoạn mã sau có thể giúp bạn giữ cho tiến trình đang thực thi tiếp tục
chạy ở chế độ foreground và buộc các tiến trình Dos hay Windows được
gọi đến vẫn chạy ở chế độ background:
Declare Function SetFocus Lib "user32" _
(ByVal hWnd As Long) As Long
Declare Function GetTopWindow Lib_ "user32" (ByVal hWnd As Long) As
Long
Sub Main()
On Error Resume Next
Dim Ret As Variant
Dim lngAct As Long
Dim lngRet As Long
lngAct = GetTopWindow
Ret = Shell(Command, vbMinimizedNoFocus)
lngRet = SetFocus(lngAct)
End Sub
Giải pháp cho một Combo box có quá nhiều mục chọn
(Access 97/95/2.0)
Thật là khó nhọc khi muốn chọn một mục trong Combo box có hàng trăm
dòng, nhất là trong trưòng hợp bạn thuộc loại "bốn mắt". Nhằm giải
quyết vấn đề này, tại sao chúng ta không "chia để trị" bằng cách tạo
ra nhiều Combo box nhỏ hơn, mà mỗi Combo box này chỉ chứa một phần dữ
liệu của Combo box ban đầu để bạn làm việc thoải mái hơn.
Sau đây là đoạn mã tạo ra sự phân phối dữ liệu giữa các Combo box.
Đây là dòng lệnh SQL trong RowSource của Combo box nguyên thủy:
SELECT DISTINCTROW [tblUnits].[ID], _[tblUnits].[UnitName] FROM
[tblUnits] ;
Trong Combo box con thứ nhất ta thay RowSource của nó như sau:
SELECT DISTINCTROW [tblUnits].[ID], _[tblUnits].[UnitName] FROM
[tblUnits] _WHERE [UnitName] BETWEEN "A" AND "D";
Dòng lệnh SQL này chỉ cho phép các dòng có UnitName từ A đến D xuất
hiện trong Combo box thứ nhất. Thực hiện tương tư với các Combo box
còn lạiẩ. Lúc đó sẽ không còn Combo box "voi" nửa mà bạn sẽ có một số
Combo box con dễ quản lý hơn.
Duyệt String
(VBA - Visual Basic 5.0/4.0 - Access 97/95/2.0 - Excel)
Rất nhiều khi chúng ta cần trích một String ra nhiều phần nhỏ, ví dụ
như tríãch String ngày tháng thành những trường riêng biệt: ngày,
tháng, năm.
Chúng ta giải quyết vấn đề này bằng một hàm có ba thông số: thông số
thứ nhất là String cần duyệt, thông số thứ hai là thứ tự của phần muốn
trích ra (String con), thông số thứ ba là ký tự phân cách đưọc dùng
trong String. Ví dụ:
? FieldSplit("3/14/97",2,"/")
14
? FieldSplit("2-3-96",3,"-")
96
? FieldSplit("124.1244.123434.",1,".")
124
Và đây là mã nguồn của hàm FieldSplit:
Function FieldSplit(FullString As_
Variant, FieldNum As Integer,_
SplitChar As String) As Variant
Dim MyArray As Variant
Dim j As Integer, k As Integer
Dim x As Integer, z As Integer
Dim TempString As String
?Count the fields within FullString
z = 1
For k = 1 To Len(FullString) - 1
If Mid$(FullString, k, 1) = SplitChar _
Then
z = z + 1
End If
Next k
?Check if user requested a field number
?greater than fields in FullString
If FieldNum > z Then
FieldSplit = Null
Exit Function
End If
?Set array to the correct number of fields
ReDim MyArray(z)
TempString = ""
j = 0
For x = 1 To Len(FullString)
If Mid$(FullString, x, 1) = SplitChar _
Then
MyArray(j) = TempString
TempString = ""
j = j + 1
End If
If Mid$(FullString, x, 1) <>_
SplitChar Then
TempString = TempString & _
Mid$(FullString, x, 1)
End If
Next x
MyArray(j) = TempString
FieldSplit = MyArray(FieldNum - 1)
End Function
Một khi bạn đã sáng tạo cho mình đưọc một hàm như vậy, bạn có thể giữ
cho mình hay "ban phát" cho bạn bè; nó dùng được trong cả Excel,
Access và Visual Basic.
Hữu Hoan
Theo Advisor VB
Lập trình bảo mật cơ sở dữ liệu Access5/3/2004 12:20:00 AM
Hầu như ai mần một ứng dụng Microsoft Access cũng xài một trong những
(hoặc tất cả) cách sau để bảo vệ cơ sở dữ liệu (CSDL), hòng khóa tay,
khóa chân những nhân viên tò mò, thích quậy:
1. Bảo vệ mã lệnh VBA (Visual Basic for Application) bằng cách chọn
mục Properties trên trình đơn Tools của cửa sổ soạn thảo Microsoft
Visual Basic rồi chọn trang Protection trên hộp thoại Project
Properties. Cuối cùng, chọn Lock project for viewing, kèm theo là mật
khẩu bảo vệ. Với cách này, cấu trúc và dữ liệu các bảng (table) vẫn có
thể được xem và sửa đổi.
2. Dùng chức năng Make MDE file để ngăn không cho sửa đổi mã lệnh,
thiết kế biểu mẫu (form) và thiết kế báo biểu (report). Với cách này,
cấu trúc và dữ liệu các bảng (table) vẫn có thể được lấy đi để chuyển
vào tập tin .MDB khác mà xem và sửa đổi.
3. Dùng chức năng Encrypt / Decrypt database… để mã hóa CSDL, ngăn
không cho các chương trình tiện ích hay xử lý văn bản giải mã nhưng
vẫn có thể dùng Access để mở.
4. Dùng chức năng Set database password để quy định mật khẩu cho CSDL.
Cách này hơi phiền nếu có một bảng trong CSDL khác liên kết (link) với
nó. Nếu quên mật khẩu thì … khóc luôn chứ sao!
5. Thiết kế một biểu mẫu khởi động, trong đó yêu cầu cho biết tên và
mật khẩu, dùng hộp thoại Startup (từ danh sách Display Form/Page) để
quy định phải mở biểu mẫu này trước tiên mỗi lần mở CSDL. Nhờ cách
này, ta có thể giấu luôn cửa sổ Database, nơi có thể xem và chọn các
thành phần của CSDL để sửa chữa.
Trong những cách trên, cách thứ 5 vẫn có thể bị vượt qua bằng cách
nhấn và giữ phím Shift trong lúc mở CSDL. Để khắc phục, ta có thể dùng
Visual Basic gán trị False cho thuộc tính AllowBypassKey để vô hiệu
hóa phím Shift khi mở CSDL.
Giả sử bạn có một CSDL tên dbLock.MDB. Mỗi lần người ta mở nó, bạn
muốn biểu mẫu frmKhoiDong luôn được hiển thị trước tiên bằng cách xác
định Display Form/Page là frmKhoiDong. Để thay đổi thuộc tính
AllowBypassKey, bắt buộc phải mở CSDL, gán trị mới cho thuộc tính này,
đóng CSDL lại thì lần mở sau mới có ép-phê. Bạn nhớ, cần khóa làm sao
để người ta không mở được mà mình mở được, nghĩa là ta phải có chìa
khóa để mở. Chìa ở đây chính là một biểu mẫu khác, chẳng hạn có tên là
frmChiaKhoa.
Khi đã thay đổi thuộc tính AllowBypassKey được rồi, chắc chắn biểu mẫu
frmKhoiDong được hiển thị khi mở CSDL. Cho nên ta đặt chìa khóa thông
qua biểu mẫu này bằng cách vẽ một ô điều khiển nào đấy (miễn sao nó có
thủ tục xử lý tình huống Click là được), chẳng hạn nhãn lblChiaKhoa,
rồi đặt thuộc tính Visible là No và thêm dòng lệnh DoCmd.OpenForm
“frmChiaKhoa” vào thủ tục xử lý tình huống Click. Bạn phải nhớ vị trí
nhãn lblChiaKhoa để lôi chìa khóa ra nhé. Như vậy, vấn đề còn lại nằm
ở biểu mẫu frmChiaKhoa.
Bạn mở cửa sổ soạn thảo Microsoft Visual Basic, chọn mục References…
để bảo đảm Microsoft DAO xx.xx Object Library (trong đó, phiên bản
xx.xx có thể là: 2.5 hoặc 3.51 hoặc 3.6 tùy theo phiên bản Access, dĩ
nhiên nên chọn phiên bản mới nhất) đã được chọn trong danh sách
Available References.

Hình 1: Biểu mẫu cần thiết kế
Hình 1 là biểu mẫu frmChiaKhoa cần thiết kế, bao gồm một ô văn bản
txtPassword để nhận mật khẩu mà người cần mở khóa phải gõ vào, một nút
lệnh cmdLock thực hiện việc khóa CSDL và một nút lệnh cmdUnlock thực
hiện việc mở khóa CSDL. Xong, bạn gõ các thủ tục xử lý như đoạn mã 1.
Trước khi quậy chuyện này trên một CSDL, bạn nên sao chép phòng hờ
CSDL để tránh sự cố khóa được rồi nhưng không mở được (do bạn gõ nhầm
các dòng lệnh).
Đoạn mã 1
'Hàm ChangeProperty thay đổi các thuộc tính của CSDL
Function ChangeProperty(strPropName, varPropType, varPropValue)
Dim dbs As Database, prp As Property
Const conPropNotFoundError = 3270
Set dbs = CurrentDb
On Error GoTo Change_XuLyLoi
dbs.Properties(strPropName) = varPropValue
ChangeProperty = True
Change_KetThuc:
Exit Function
Change_XuLyLoi:
'Thuộc tính không thấy
If Err = conPropNotFoundError Then
Set prp = dbs.CreateProperty(strPropName, _
varPropType, varPropValue)
dbs.Properties.Append prp
Resume Next
Else
'Không biết lỗi gì
ChangeProperty = False
Resume Change_KetThuc
End If
End Function
'Xử lý tình huống chọn nút [Khóa database]
Private Sub cmdLock_Click()
‘Biểu mẫu này được nạp trước
ChangeProperty "StartupForm", dbText, "frmKhoiDong"
ChangeProperty "StartupShowDBWindow", dbBoolean, False
ChangeProperty "StartupShowStatusBar", dbBoolean, False
ChangeProperty "AllowBuiltinToolbars", dbBoolean, False
ChangeProperty "AllowFullMenus", dbBoolean, False
ChangeProperty "AllowBreakIntoCode", dbBoolean, False
ChangeProperty "AllowSpecialKeys", dbBoolean, False

‘Không cho xài phím Shift để bỏ qua biểu mẫu frmKhoiDong
ChangeProperty "AllowBypassKey", dbBoolean, False

MsgBox "Cơ sở dữ liệu đã được khóa! Đóng cơ sở dữ liệu, _
rồi mở lại mới có ép-phê.", vbOKOnly, "eChip Security"
cmdExit.SetFocus
cmdUnlock.Visible = True
cmdLock.Visible = False
End Sub
'Xử lý tình huống chọn nút [Mở database]
Private Sub cmdUnlock_Click()
‘Không cần biểu mẫu khởi động nữa
ChangeProperty "StartupForm", dbText, ""
ChangeProperty "StartupShowDBWindow", dbBoolean, True
ChangeProperty "StartupShowStatusBar", dbBoolean, True
ChangeProperty "AllowBuiltinToolbars", dbBoolean, True
ChangeProperty "AllowFullMenus", dbBoolean, True
ChangeProperty "AllowBreakIntoCode", dbBoolean, True
ChangeProperty "AllowSpecialKeys", dbBoolean, True
ChangeProperty "AllowBypassKey", dbBoolean, True
MsgBox "Cơ sở dữ liệu đã được mở khóa ! _
Đóng cơ sở dữ liệu, rồi mở lại mới có ép-phê.", _
vbOKOnly, "eChip Security"
cmdExit.SetFocus
txtPassword = ""
cmdLock.Visible = True
cmdUnlock.Visible = False
txtPassword.Visible = False
End Sub
'Xử lý tình huống khi mở biểu mẫu
Private Sub Form_Open(Cancel As Integer)
Dim dbs As Database
Set dbs = CurrentDb
On Error GoTo KhongCoThuocTinh_Err
If dbs.Properties("AllowBypassKey") Then
cmdLock.Visible = True
txtPassword.Visible = False
Else
cmdLock.Visible = False
txtPassword.Visible = True
End If
Exit Sub
KhongCoThuocTinh_Err:
cmdLock.Visible = True
txtPassword.Visible = False
End Sub
'Khi người ta gõ mật khẩu và nhấn phím Enter
Private Sub txtPassword_LostFocus()
If txtPassword = "echip" Then
cmdUnlock.Visible = True
End If
End Sub


4. Hỏi: Các Huynh chỉ dùm trong Access khi chọn 1 mục trong Combo box
VD: MANV nào đó thì ở TextBox kế bên hiển thị ngay tên nhân viên theo
MANV đó.

Mình cho vd nhé: Giả sử bạn có bảng nhân viên(MaNV;TenNV) bây giờ tại
Form: Frmnhanvien bạn có 1 combobox(tên là Cboma) để gõ mã nhân viên
và 1 Textbox(tên là txttenNV) để hiển thị tên nhân viên ứng với mã NV
đã chọn. VD khi gõ vào combobox mã nhân viên NV01 thì textbox sẽ hiển
thị là Nguyễn Văn A; khi gõ vào nhân viên NV02 thì textbox hiển thị là
Nguyễn văn B...
Muốn vậy tại textbox trên Form frmnhanvien: chọn Text txttenNV gõ vào
công thức:
=Dlookup("tenNV","nhanvien","nhanvien!maNV=[Forms]![frmNhanvien]!
[Cboma]")
thì bạn sẽ có được kết quả ngay nhưng nhớ đặt thuộc tính Looked= Yes
cho Textbox txttenNV (Mục đích là textbox này chỉ để hiển thị kết quả,
không cho sửa đổi)


Ví dụ bạn có Table la NhanVien gồm hai trường MaNV, TenNV
Bạn tạo Form có 1 Combo la CmbMaNV; 1 Text Box là txtTenNV
Source của CmbMaNV là table NhanVien trên.
Đoạn code như sau:
Private Sub cmbMaNV Click()
Me.txtTenNV.Value = Me.cmbMaNV.Column(1)
End Sub
Mình đã làm rồi, rất là OK bạn ah, bạn có thể sử dung

5. Mình có một chương trình Access tự viết nhỏ, mình muốn
chương trình tính được số ngày sử dụng hoặc số lần đã mở
chương trình nhưng không phụ thuộc vào ngày của hệ thống
bạn tạo 1 table, tạo field có tên là userTime, kiểu number
Khi user mở starup form, ở sự kiện open của form, bạn viết 1
đoạn code mở table trên và edit thêm sự kiện như sau:
Private Sub Form_Open(Cancel As Integer)
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("T2")
With rs
.MoveFirst
.Edit
!UserTime = !UserTime + 1
.Update
End With
rs.Close
End Sub

6. Bạn nào có biết cách phân quyền sử dụng trong Access không chỉ cho
mình với. Có nghĩa là với chương trình mình tạo ra thì chỉ có mình mới
có thể sửa source code được, có thể sửa design... được thôi, người sử
dụng chỉ được quyền sử dụng và không có quyền truy cập vào source code
cũng như table... để sửa chương trình. Ở bên mình mọi người cũng có
kiến thức về Access nên biết là cứ bấm F11 là vào được data của chương
trình.

Đáp

Bạn phải làm 2 việc :

1) Vào Tools --> Startup : bỏ chọn tất cả các check box trên biểu mẫu
này. (không cho users sử dụng các phím tắt)

Còn muốn triệt để hơn, không cho xem code thì .mdb --> .mde


2) Disable phím SHIFT

Nguyên lý : trong database có 1 thuộc tính (property) gọi là :
AllowBypassKey. Thuộc tính này cho phép bạn enable/disable phím SHIFT.

+ Nếu AllowBypassKey = False --> disable phím SHIFT

+ Nếu AllowBypassKey = True --> enable phím SHIFT

Cách làm : bạn tạo 1 Form (tạm gọi : F_ShiftKey) có 2 nút lịnh : 1 để
enable và 1 disable phím SHIFT. Đưa 2 private sub dưới đây
vào..........

Private Sub DisableSHIFTButton_Click()
On Error GoTo ErrHandler

Dim db As Database
Dim ThuocTinh As Property

Set db = CurrentDb
db.Properties("AllowBypassKey") = False
Set db = Nothing

Egress:
On Error Resume Next
Set db = Nothing
Set ThuocTinh = Nothing
Exit Sub

ErrHandler:
MsgBox Err.Number
If Err.Number = 3270 Then ' Property not found.
Set ThuocTinh = db.CreateProperty("AllowBypassKey", dbBoolean, False)
db.Properties.Append ThuocTinh
Resume Next
Else
MsgBox Err.Description
Resume Egress
End If
End Sub

=================================================

Private Sub EnableSHIFTButton_Click()

On Error GoTo ErrHandler

Dim db As Database
Dim ThuocTinh As Property

Set db = CurrentDb
db.Properties("AllowBypassKey") = True
Set db = Nothing

Egress:
On Error Resume Next
Set db = Nothing
Set ThuocTinh = Nothing
Exit Sub

ErrHandler:
MsgBox Err.Number
If Err.Number = 3270 Then ' Property not found.
Set ThuocTinh = db.CreateProperty("AllowBypassKey", dbBoolean, True)
db.Properties.Append ThuocTinh
Resume Next
Else
MsgBox Err.Description
Resume Egress
End If
End Sub

++++++++++++++++++++++++++++++++++++++++++++++++++

OK chưa bạn ? .............................................. Chưa
đâu !


Bây giờ đặt F_ShiftKey ở đâu trong chương trình để không ai được quyền
mở ngoại trừ Admin ? Có nhiều cách : cách đơn giản nhất là đặt ….ở đâu
cũng được với 1 điều kiện : để mở F_ShiftKey cần phải biết password.

Ở sự kiện Form_Open, bạn yêu cầu nhập đúng password : Lambada mới cho
mở form này.


Private Sub Form_Open(Cancel As Integer)

Dim Message, Title, MyValue

Message = "Ban vui long cho biet mat khau :" ' Set prompt.

Title = "Kiem tra" ' Set title.

MyValue = InputBox(Message, Title)

If MyValue <> "Lambada" Then

DoCmd.Close

End If

End Sub

7. Không phải mọi thứ Access đều có thể giúp được bạn, đôi khi phải
vận dụng linh hoạt với Excel.
Câu lệnh Export một đối tượng Access ra Excel

DoCmd.OutputTo Kiểu đối tượng, "tên đối tượng",
"MicrosoftExcelBiff8(*.xls)", "", True, "", 0

Ví dụ bạn đẩy một query tên là DThutheothang ra excel:

DoCmd.OutputTo acQuery, "DThutheothang", "MicrosoftExcelBiff8(*.xls)",
"", True, "", 0

8. Xuống dòng trong Msgbox
Access 97 trở về trước khi xuống dòng dùng ký tự @. Access gần đây
dùng vbCrLf để xuống dòng. Việc chủ động xuống dòng trong Msgbox giúp
hiển thị thông báo rõ ràng hơn.

MsgBox "1. Hello!" & vbCrLf & "2. Xin chào các bạn!" & vbCrLf & "3.
Seeuagain!", vbInformation, "Message"

9. Hiện duy nhất một cửa sổ khi mở nhiều form

Các bạn giúp mình với, làm sao khi mở một From VD From này la From
Main, trong From Main này có các Nút lệnh để mở các From khác. Thì làm
sao khi mở một From khác thì trên Takbar không xuất hiện From này mà
vẩn còn From Main hiện diện trên Taskbar. Vì nếu tôi mở nhiều Fron
trên một chương trình thì Taskbar sẻ đầy.

Bạn chỉ cần vào Tools/options

Bỏ dấu check ở mục Windows on Taskbar. khi đó trên Task bar chỉ còn
duy nhất 1 màn hình Access thôi, bạn thư nhé.
----------------------
sanyovietnam in MaNguon


Bổ sung :
Vì Access luôn chọn Check box Windows on Taskbar = True (default) nên
nếu đem file mdb của bạn sang máy khác thì sẽ gặp lại trường hợp nhiều
cửa sổ trên taskbar.
Cách tổng quát hơn :
Khi mở form Startup bạn thêm dòng lệnh :

Private Sub Form_Open(Cancel As Integer)
Application.SetOption "ShowWindowsInTaskbar", False
End Sub

3. Trong các câu lệnh iif, Dsum, ... trong phần điều kiện. ví dụ như
thế này:
=Dsum("DiemThi","DSTS","SoBD = txtSoBD") (1)

=Dsum("DiemThi","DSTS"," ' " & SoBD = txtSoBD & " ' ") (2)

thì mình thấy cái nào nó cũng chạy được, nhưng mình muốn biết khi nào
thì dùng câu lệnh nào và tốt nhất thì nên dùng câu lệnh nào ( 1 hay
2 )

Xin chào các Bạn,
Xin trao đổi với các Bạn 1 cách export Report đang mở trong Access
sang Excel như sau:

1. Viết 1 hàm dùng chung có nội dung:
Function ExPortActRpt2Excel()
'
Dim Tentailieu As String, GetAppDir as string
GetAppDir = Left(CurrentDb.Name, Len(CurrentDb.Name) - Len(Dir$
(CurrentDb.Name)))
Tentailieu = Screen.ActiveReport.Name
DoCmd.OutputTo acOutputReport, Tentailieu, acFormatXLS, GetAppDir &
Tentailieu & ".XLS"
MsgBox "Da xuat Bao bieu hien hanh thanh File " & GetAppDir &
Tentailieu & ".XLS"

End Function

2. sau đó tạo 1 Macro Autokeys như sau:
Macro Name: ^{F12}
Action: RunCode
Comment: Export Report dang mo sang Excel
Function Name: ExportActRpt2Excel()

Bằng cách tạo Macro này ta đã tạo 1 phím tắt Ctrl+F12
Từ sau đấy, khi 1 Report đã được mở trên màn hình ở chế độ Preview ta
chỉ cần dùng phím tắt này sẽ Export được Report sang Excel.

Lê Hồng Đức

10 Các hàm chuẩn mới

Một loạt hàm mới được bổ sung so với Access 97, dùng để xử lý xâu ký
tự: Replace(), InstrRev(), StrReverse(), Split(), Join() và Filter().

Hàm Replace() dùng để thay xâu con của xâu nào đó bằng xâu con mới:

?Replace ("a1a2a3a4a5", "a", "b")

b1b2b3b4b5

?Replace ("a1a2a3a4a5", "a", "b", 3)

b2b3b4b5

?Replace ("a1a2a3a4a5", "a", "b", 3, 2)

b2b3a4a5

Trong 2 ví dụ cuối, số 3 ở tham số thứ tư dùng chỉ vị trí từ đó bắt
đầu cần thay thế (và kết quả cũng từ đó luôn). Tham số thứ 5 trong ví
dụ cuối cùng để đặc tả số lần phải thay (xâu con có thể hiện diện
nhiều lần).

Hàm StrReverse() trả về chuỗi ký tự đảo ngược (không rõ thực tế ứng
dụng CSDL có cần đến hàm này không?).

?StrReverse ("abcdef")

fedcba

Hàm InstrRev() có cơ chế làm việc như Instr() nhưng tìm kiếm ngược từ
ký tự cuối đến ký tự đầu (hàm này thì thật sự cần thiết):

?InstrRv ("C:\MyPath\MyFile.ext", "\")


Các hàm Split(), Join() và Filter() cũng rất hữu ích. Split() chuyển
đổi xâu ký tự có chia tách (bởi một ký tự nào đó, ví dụ dấu chấm phẩy)
thành mảng các giá trị. Join() thực hiện thao tác ngược lại, từ mảng
trở về xâu ký tự có chia tách. Filter() trích từ mảng các dòng thỏa
mãn điều kiện nào đó.

? Filter(Split(CurrentProject.Connection, ","), _

"Data Source = ") (0)

Data Source=D:\Temp\db1.mdb

Thêm một bước nữa thì nhận được trị của Data Source.

? Split (Filter(Split(CurrentProject .Connection, ";"), _

"Data Source = ") (0) ,"=") (1)

D:\Temp\db1.mdb

Nếu đã quen thuộc với ngôn ngữ Lisp, chắc bạn rất hài lòng với bộ hàm
trên và tự hỏi: tại sao đến bây giờ VBA mới có được khả năng phân tích
xâu ký tự như vậy?

11. Ví dụ sau đây dùng để bẫy một số lỗi cơ bản:
Private Sub Form_Error (DataErr As Integer, Response As Integer)
Response = acDataErrContinue ‘ tắt thông báo của Access
Select Case DataErr
Case 3022
MsgBox “Trùng khóa chính.”
Case 3058
MsgBox “Khóa chính để trống.”
Case 3314
MsgBox “Có ít nhất một field chưa nhập theo yêu cầu bắt buộc.”
Case Else
MsgBox “Có lỗi xảy ra.” & Chr(13) & “Chỉ số lỗi: “ & DataErr & Chr(13)
& _
“Nội dung lỗi: “ & Err.Description
End Select
End Sub

12. Khi bạn sử dụng VBA và cho thi hành một ứng dụng nào đó, bạn sẽ
thấy một thông báo lỗi nhưng bạn không biết lỗi đó là lỗi gì. Bạn chỉ
cần thêm dòng lệnh sau :
Code:
msgbox Err.Description & vbCrLf & Err.number
Hộp thoại sẽ hiển thị và cho bạn biết lỗi xảy ra và số của lỗi đó.

13. Nội dung dưới đây do post lộn chỗ, do đó tôi xin post lại như là
một new thread:

Thể theo lời của bạn Simon, tôi sẽ mở đầu bằng một bài về việc viết
code trong Access, trước tiên là khái niệm.

Access ngoài chức năng là quản trị CSDL, nó còn có thể cho phép người
dùng xây dựng một ứng dụng. Đde63 xây dựng một ứng dụng, điều nhất
thiết là phải lập trình (coding).

Access sử dụng ngôn ngữ Visual Basic được Microsoft support cho các
phần mềm trong Microcost Office: Word, Excel, Access, PowerPoint, ...
và được gọi là VBA - Visual Basic for Applications.

Nếu bạn nào đã biết ngôn ngữ VB thì VBA không là gì cả. Tuy nhiên nó
có một số khác biệt nho nhỏ do đã được hỗ trợ thêm một số thư viện
thích hợp.

Lập trình trong Access còn được gọi là lập trình điều khiển sự kiện
(event-driven programming). Về hình thức nó tương tự như lập trình
hướng đối tượng nhưng đơn giản hơn nhiều.

Lập trình điều khiển sự kiện là việc lập trình sao cho khi có một sự
kiện, một hành vi tác động lên một đối tượng thì sẽ thực thi một hay
nhiều tác vụ nào đó tương ứng.

Chúng ta có thể lập trình sự kiện trên các Form, Report và những đối
tượng trong chúng.

Tuy nhiên muốn lập trình sự kiện một cách "pro", chúng ta phải nắm
vững ý nghĩa của các sự kiện và diễn biến của sự kiện.

Ví dụ: Một người muốn kiểm tra dữ liệu nhập vào textbox số lượng
(soluong), số lượng nhập vào không được phép để trống và phải dương.
Ở đây người dùng sẽ yêu cầu một trong hai tình huống:
- Hoặc là kiểm tra khi dấu chèn (insertion I-beam) rời khỏi textbox
soluong.
- Hoặc là kiểm tra khi chuẩn bị chuyển sang một record khác.

Khi dấu chèn rời khỏi textbox soluong, hàng loại các sự kiện sau sẽ
xảy ra (có giản lược, chỉ giữ các sự kiện chính): BeforeUpdate,
AfterUpdate, Exit, LostFocus.

- BeforeUpdate là sự kiện xảy ra trước khi dữ liệu trong textbox
soluong được lưu lại trong recordset (nhưng chưa lưu vào table). Sự
kiện này chỉ xảy ra khi người sử dụng có gõ (entry) bất cứ gì vào
textbox kể cả xóa trắng nội dung.
- AfterUpdate là sự kiện xảy ra sau khi dữ liệu trong textbox soluong
được lưu lại trong recordset (nhưng chưa lưu vào table).
- Exit: sự kiện xảy ra trước khi dấu chèn rời khỏi textbox.
- LostFocus: sự kiện xảy ra khi dấu chèn thực sự ra khỏi textbox.

Trong các thủ tục sự kiện tương ứng BeforeUpdate và Exit của textbox
soluong, chúng ta đều có thể kiểm tra được dữ liệu nhập vào của người
dùng, nhưng có hơi khác một tý về cách hành xử.

Private Sub soluong_BeforeUpdate (Cancel As Integer)
If IsNull(soluong) Or soluong <= 0 Then
MsgBox "So luong khong hop le."
Cancel = True
End If
End Sub
Private Sub soluong_Exit (Cancel As Integer)
If IsNull(soluong) Or soluong <= 0 Then
MsgBox "So luong khong hop le."
Cancel = True
End If
End Sub

Thoạt nhìn, cả hai hầu như không có gì khác nhau, nhưng nó sẽ có một
số điểm khác biệt:
Nếu ở textbox soluong, người sử dụng không nhập gì (trước đó soluong
đang để trống) thì khi người sử dụng ENTER để đi qua, thủ tục
BeforeUpdate không thi hành mà thủ tục Exit thi hành. Khi thi hành,
chúng hiện thông báo, sau đó giữ dấu chèn ở lại trong textbox soluong.
Nếu sử dụng thủ tục beforeUpdate, để rời khỏi soluong, người sử dụng
có thể nhấn phím ESC để lấy lại giá trị cũ của soluong, và từ đó có
thể rời khỏi nó. Trong khi đó, nếu sử dụng thủ tục Exit thì sẽ gần như
là bị loop, không ra được textbox soluong.

Thường thì biện pháp tốt nhất là kiểm tra trước khi record lưu vào
table. Trong trường hợp này sẽ sử dụng thủ tục sự kiện BeforeUpdate
của Form.

Private Sub Form_BeforeUpdate (Cancel As Integer)
If IsNull(soluong) Or soluong <= 0 Then
MsgBox "So luong khong hop le."
Cancel = True
End If
End Sub

Trong thủ tục này của form, chúng ta có thể kiểm tra toàn bộ những
ràng buộc mà chúng ta cần.

Trên là một số khái niệm ban đầu, trong thời gian tới, tôi sẽ sắp xếp
thời gian post một số kinh nghiệm về lập trình trong Access để các bạn
tham khảo.


14. Thủ Thuật:
Chỉ cho phép người dùng gõ số vào TextBox
Giới Thiệu:
Đoạn code này để khống chế nhập số cho TextBox. Nó chỉ cho phép nhập
ký tự số, dấu âm (-) và dấu thập phân (.) trong KeyPress Event.
Ví Dụ:
Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim Tmp As String
Tmp = Text1.Text
Select Case Chr$(KeyAscii)
Case "0" To "9", Chr$(8)
Case "-"
If InStr(1, Tmp, "-") = 0 Then
If Text1.SelStart > 0 Then
KeyAscii = 0
End If
Else
KeyAscii = 0
End If
Case "."
If InStr(1, Tmp, ".") > 0 Then
KeyAscii = 0
End If
Case Else
KeyAscii = 0
End Select
End Sub


15. Thủ Thuật:
Không cho người dùng gõ số vào TextBox
Giới Thiệu:
Khống chế không cho người dùng gõ số vào TextBox.
Ví Dụ:
Private Sub Text1_KeyPress(KeyAscii As Integer)
If InStr("1234567890" + Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then
KeyAscii = 0
Beep
End If
End Sub
16. Thủ Thuật:
Nén cơ sở dữ liệu Access
Giới Thiệu:
Có lẽ bạn rất bực mình khi cơ sở dữ liệu cứ tăng kích thước ngay cả
khi bạn xóa record. Bạn có thể giải quyết vấn đề này bằng cách nén
CSDL lại mỗi khi đóng ứng dụng.
Ví Dụ:
Vào Project / References và chọn Microsoft Access 10.0 Object Library.

Thêm đoạn code sau vào Form:

Private Sub Form_Unload(Cancel As Integer)

'Nén CSDL tên MyData.mdb và tạo 1 CSDL mới tên DB2.mdb
DBEngine.CompactDatabase App.Path & "MyData.mdb", App.Path & "DB2.mdb"

'Xóa MyData.mdb
Kill "MyData.mdb"

'Đổi tên DB2.mdb thành MyData.mdb
Dim OldName
Dim NewName

OldName = "DB2.mdb": NewName = "MyData.mdb"

Name OldName As NewName

End Sub

17. Thủ Thuật:
Làm cho chương trình có giao diện XP
Giới Thiệu:
Làm cho chương trình của bạn có giao diện XP.
Ví Dụ:
Thêm đoạn code này vào Form chính:
Private Declare Sub InitCommonControls Lib "comctl32" ()
Private Sub Form_Initialize()
InitCommonControls
End Sub

Bạn copy đoạn code sau vô chương trình soạn thảo NotePad:


18. Giải pháp cho một Combo box có quá nhiều mục chọn
(Access 97/95/2.0)
Thật là khó nhọc khi muốn chọn một mục trong Combo box có hàng trăm
dòng, nhất là trong trưòng hợp bạn thuộc loại "bốn mắt". Nhằm giải
quyết vấn đề này, tại sao chúng ta không "chia để trị" bằng cách tạo
ra nhiều Combo box nhỏ hơn, mà mỗi Combo box này chỉ chứa một phần dữ
liệu của Combo box ban đầu để bạn làm việc thoải mái hơn.
Sau đây là đoạn mã tạo ra sự phân phối dữ liệu giữa các Combo box.
Đây là dòng lệnh SQL trong RowSource của Combo box nguyên thủy:
SELECT DISTINCTROW [tblUnits].[ID], _
[tblUnits].[UnitName] FROM [tblUnits] ;
Trong Combo box con thứ nhất ta thay RowSource của nó như sau:
SELECT DISTINCTROW [tblUnits].[ID], _
[tblUnits].[UnitName] FROM [tblUnits] _
WHERE [UnitName] BETWEEN "A" AND "D";
Dòng lệnh SQL này chỉ cho phép các dòng có UnitName từ A đến D xuất
hiện trong Combo box thứ nhất. Thực hiện tương tư với các Combo box
còn lạiẩ. Lúc đó sẽ không còn Combo box "voi" nửa mà bạn sẽ có một số
Combo box con dễ quản lý hơn.
19. Duyệt String
(VBA - Visual Basic 5.0/4.0 - Access 97/95/2.0 - Excel)
Rất nhiều khi chúng ta cần trích một String ra nhiều phần nhỏ, ví dụ
như tríãch String ngày tháng thành những trường riêng biệt: ngày,
tháng, năm.
Chúng ta giải quyết vấn đề này bằng một hàm có ba thông số: thông số
thứ nhất là String cần duyệt, thông số thứ hai là thứ tự của phần muốn
trích ra (String con), thông số thứ ba là ký tự phân cách đưọc dùng
trong String. Ví dụ:
? FieldSplit("3/14/97",2,"/")
14
? FieldSplit("2-3-96",3,"-")
96
? FieldSplit("124.1244.123434.",1,".")
124
Và đây là mã nguồn của hàm FieldSplit:
Function FieldSplit(FullString As_
Variant, FieldNum As Integer,_
SplitChar As String) As Variant
Dim MyArray As Variant
Dim j As Integer, k As Integer
Dim x As Integer, z As Integer
Dim TempString As String
?Count the fields within FullString
z = 1
For k = 1 To Len(FullString) - 1
If Mid$(FullString, k, 1) = SplitChar _
Then
z = z + 1
End If
Next k
?Check if user requested a field number
?greater than fields in FullString
If FieldNum > z Then
FieldSplit = Null
Exit Function
End If
?Set array to the correct number of fields
ReDim MyArray(z)
TempString = ""
j = 0
For x = 1 To Len(FullString)
If Mid$(FullString, x, 1) = SplitChar _
Then
MyArray(j) = TempString
TempString = ""
j = j + 1
End If
If Mid$(FullString, x, 1) <>_
SplitChar Then
TempString = TempString & _
Mid$(FullString, x, 1)
End If
Next x
MyArray(j) = TempString
FieldSplit = MyArray(FieldNum - 1)
End Function
Một khi bạn đã sáng tạo cho mình đưọc một hàm như vậy, bạn có thể giữ
cho mình hay "ban phát" cho bạn bè; nó dùng được trong cả Excel,
Access và Visual Basic. Option Group thông minh (Access 97/95/2.0)
Thông thưòng khi bạn nhóm các nút Option vào trong một Option group,
thì mỗi nút Option này sẽ không nhận được sự kiện nhấn đúp vào một nút
Option nào đóã. Điều này gây khó chịu cho người dùng có thói quen nhấn
kép chuột vào Option được chọn để đồng thời xác nhận lưạ chọn Option
và đóng lại Dialog box, (thông thường thì trong Dialog box kiểu chọn
lựa một trong nhiều Option, ta phải chọn bấm nút Option, rồi bấm tiếp
nút OK). Chúng ta lợi dụng sự kiện DblClick của đối tượng Option group
để giải quyết vấn đề trên. Khi ấy sự kiện DblClick lên một nút Option
bất kỳ trong Option group sẽ kích nút OK (hoặc nút lệnh tương ứng với
nút Option ấy), và sau đây là đoạn mã minh họa: Sub grpOpt_DblClick
(Cancel As Integer) ? Fire the OK Command Button Call cmdOK_Click End
Sub Đoạn mã trong nút lệnh OK như sau: Sub cmdOK_Click () If
grpOpt.Value = 1 Then <More code here> <Ca?c ma~ u+?ng vo+?i nu?t
Option 1> Else <More code here> <Ca?c ma~ u+?ng vo+?i nu?t Option kha?
c> End If End Sub Giữ cho các tiến trình DOS tiếp tục bị che (Access
97/95 - Visual Basic (32-bit) Trong khi làm việc, có nhiều khi chúng
ta cần thực thi một lệnh Dos nào đó hay phải gọi đến Shell Command từ
trong ứng dụng của mình. Để không bị gián đoạn điều khiển màn hình
hiện hành của chương trình đang chạy, bạn muốn ngăn không cho hệ điều
hành trao "điều khiển" từ tiến trình đang thi hành này cho một tiến
trình Dos hay Windows khác đang được thực thi trong chế độ nền. Đoạn
mã sau có thể giúp bạn giữ cho tiến trình đang thực thi tiếp tục chạy
ở chế độ foreground và buộc các tiến trình Dos hay Windows được gọi
đến vẫn chạy ở chế độ background: Declare Function SetFocus Lib
"user32" _ (ByVal hWnd As Long) As Long Declare Function GetTopWindow
Lib_ "user32" (ByVal hWnd As Long) As Long Sub Main() On Error Resume
Next Dim Ret As Variant Dim lngAct As Long Dim lngRet As Long lngAct =
GetTopWindow Ret = Shell(Command, vbMinimizedNoFocus) lngRet =
SetFocus(lngAct) End Sub Giải pháp cho một Combo box có quá nhiều mục
chọn (Access 97/95/2.0) Thật là khó nhọc khi muốn chọn một mục trong
Combo box có hàng trăm dòng, nhất là trong trưòng hợp bạn thuộc loại
"bốn mắt". Nhằm giải quyết vấn đề này, tại sao chúng ta không "chia để
trị" bằng cách tạo ra nhiều Combo box nhỏ hơn, mà mỗi Combo box này
chỉ chứa một phần dữ liệu của Combo box ban đầu để bạn làm việc thoải
mái hơn. Sau đây là đoạn mã tạo ra sự phân phối dữ liệu giữa các Combo
box. Đây là dòng lệnh SQL trong RowSource của Combo box nguyên thủy:
SELECT DISTINCTROW [tblUnits].[ID], _[tblUnits].[UnitName] FROM
[tblUnits] ; Trong Combo box con thứ nhất ta thay RowSource của nó như
sau: SELECT DISTINCTROW [tblUnits].[ID], _[tblUnits].[UnitName] FROM
[tblUnits] _WHERE [UnitName] BETWEEN "A" AND "D"; Dòng lệnh SQL này
chỉ cho phép các dòng có UnitName từ A đến D xuất hiện trong Combo box
thứ nhất. Thực hiện tương tư với các Combo box còn lạiẩ. Lúc đó sẽ
không còn Combo box "voi" nửa mà bạn sẽ có một số Combo box con dễ
quản lý hơn. Duyệt String (VBA - Visual Basic 5.0/4.0 - Access
97/95/2.0 - Excel) Rất nhiều khi chúng ta cần trích một String ra
nhiều phần nhỏ, ví dụ như tríãch String ngày tháng thành những trường
riêng biệt: ngày, tháng, năm. Chúng ta giải quyết vấn đề này bằng một
hàm có ba thông số: thông số thứ nhất là String cần duyệt, thông số
thứ hai là thứ tự của phần muốn trích ra (String con), thông số thứ ba
là ký tự phân cách đưọc dùng trong String. Ví dụ: ?
FieldSplit("3/14/97",2,"/") 14 ? FieldSplit("2-3-96",3,"-") 96 ?
FieldSplit("124.1244.123434.",1,".") 124 Và đây là mã nguồn của hàm
FieldSplit: Function FieldSplit(FullString As_ Variant, FieldNum As
Integer,_ SplitChar As String) As Variant Dim MyArray As Variant Dim j
As Integer, k As Integer Dim x As Integer, z As Integer Dim TempString
As String ?Count the fields within FullString z = 1 For k = 1 To
Len(FullString) - 1 If Mid$(FullString, k, 1) = SplitChar _ Then z = z
+ 1 End If Next k ?Check if user requested a field number ?greater
than fields in FullString If FieldNum > z Then FieldSplit = Null Exit
Function End If ?Set array to the correct number of fields ReDim
MyArray(z) TempString = "" j = 0 For x = 1 To Len(FullString) If Mid$
(FullString, x, 1) = SplitChar _ Then MyArray(j) = TempString
TempString = "" j = j + 1 End If If Mid$(FullString, x, 1) <>_
SplitChar Then TempString = TempString & _ Mid$(FullString, x, 1) End
If Next x MyArray(j) = TempString FieldSplit = MyArray(FieldNum - 1)
End Function Một khi bạn đã sáng tạo cho mình đưọc một hàm như vậy,
bạn có thể giữ cho mình hay "ban phát" cho bạn bè; nó dùng được trong
cả Excel, Access và Visual Basic. Hữu Hoan Theo Advisor VB Lập trình
bảo mật cơ sở dữ liệu Access5/3/2004 12:20:00 AM Hầu như ai mần một
ứng dụng Microsoft Access cũng xài một trong những (hoặc tất cả) cách
sau để bảo vệ cơ sở dữ liệu (CSDL), hòng khóa tay, khóa chân những
nhân viên tò mò, thích quậy: 1. Bảo vệ mã lệnh VBA (Visual Basic for
Application) bằng cách chọn mục Properties trên trình đơn Tools của
cửa sổ soạn thảo Microsoft Visual Basic rồi chọn trang Protection trên
hộp thoại Project Properties. Cuối cùng, chọn Lock project for
viewing, kèm theo là mật khẩu bảo vệ. Với cách này, cấu trúc và dữ
liệu các bảng (table) vẫn có thể được xem và sửa đổi. 2. Dùng chức
năng Make MDE file để ngăn không cho sửa đổi mã lệnh, thiết kế biểu
mẫu (form) và thiết kế báo biểu (report). Với cách này, cấu trúc và dữ
liệu các bảng (table) vẫn có thể được lấy đi để chuyển vào tập
tin .MDB khác mà xem và sửa đổi. 3. Dùng chức năng Encrypt / Decrypt
database… để mã hóa CSDL, ngăn không cho các chương trình tiện ích hay
xử lý văn bản giải mã nhưng vẫn có thể dùng Access để mở. 4. Dùng chức
năng Set database password để quy định mật khẩu cho CSDL. Cách này hơi
phiền nếu có một bảng trong CSDL khác liên kết (link) với nó. Nếu quên
mật khẩu thì … khóc luôn chứ sao! 5. Thiết kế một biểu mẫu khởi động,
trong đó yêu cầu cho biết tên và mật khẩu, dùng hộp thoại Startup (từ
danh sách Display Form/Page) để quy định phải mở biểu mẫu này trước
tiên mỗi lần mở CSDL. Nhờ cách này, ta có thể giấu luôn cửa sổ
Database, nơi có thể xem và chọn các thành phần của CSDL để sửa chữa.
Trong những cách trên, cách thứ 5 vẫn có thể bị vượt qua bằng cách
nhấn và giữ phím Shift trong lúc mở CSDL. Để khắc phục, ta có thể dùng
Visual Basic gán trị False cho thuộc tính AllowBypassKey để vô hiệu
hóa phím Shift khi mở CSDL. Giả sử bạn có một CSDL tên dbLock.MDB. Mỗi
lần người ta mở nó, bạn muốn biểu mẫu frmKhoiDong luôn được hiển thị
trước tiên bằng cách xác định Display Form/Page là frmKhoiDong. Để
thay đổi thuộc tính AllowBypassKey, bắt buộc phải mở CSDL, gán trị mới
cho thuộc tính này, đóng CSDL lại thì lần mở sau mới có ép-phê. Bạn
nhớ, cần khóa làm sao để người ta không mở được mà mình mở được, nghĩa
là ta phải có chìa khóa để mở. Chìa ở đây chính là một biểu mẫu khác,
chẳng hạn có tên là frmChiaKhoa. Khi đã thay đổi thuộc tính
AllowBypassKey được rồi, chắc chắn biểu mẫu frmKhoiDong được hiển thị
khi mở CSDL. Cho nên ta đặt chìa khóa thông qua biểu mẫu này bằng cách
vẽ một ô điều khiển nào đấy (miễn sao nó có thủ tục xử lý tình huống
Click là được), chẳng hạn nhãn lblChiaKhoa, rồi đặt thuộc tính Visible
là No và thêm dòng lệnh DoCmd.OpenForm “frmChiaKhoa” vào thủ tục xử lý
tình huống Click. Bạn phải nhớ vị trí nhãn lblChiaKhoa để lôi chìa
khóa ra nhé. Như vậy, vấn đề còn lại nằm ở biểu mẫu frmChiaKhoa. Bạn
mở cửa sổ soạn thảo Microsoft Visual Basic, chọn mục References… để
bảo đảm Microsoft DAO xx.xx Object Library (trong đó, phiên bản xx.xx
có thể là: 2.5 hoặc 3.51 hoặc 3.6 tùy theo phiên bản Access, dĩ nhiên
nên chọn phiên bản mới nhất) đã được chọn trong danh sách Available
References. Hình 1: Biểu mẫu cần thiết kế Hình 1 là biểu mẫu
frmChiaKhoa cần thiết kế, bao gồm một ô văn bản txtPassword để nhận
mật khẩu mà người cần mở khóa phải gõ vào, một nút lệnh cmdLock thực
hiện việc khóa CSDL và một nút lệnh cmdUnlock thực hiện việc mở khóa
CSDL. Xong, bạn gõ các thủ tục xử lý như đoạn mã 1. Trước khi quậy
chuyện này trên một CSDL, bạn nên sao chép phòng hờ CSDL để tránh sự
cố khóa được rồi nhưng không mở được (do bạn gõ nhầm các dòng lệnh).
Đoạn mã 1 'Hàm ChangeProperty thay đổi các thuộc tính của CSDL
Function ChangeProperty(strPropName, varPropType, varPropValue) Dim
dbs As Database, prp As Property Const conPropNotFoundError = 3270 Set
dbs = CurrentDb On Error GoTo Change_XuLyLoi
dbs.Properties(strPropName) = varPropValue ChangeProperty = True
Change_KetThuc: Exit Function Change_XuLyLoi: 'Thuộc tính không thấy
If Err = conPropNotFoundError Then Set prp =
dbs.CreateProperty(strPropName, _ varPropType, varPropValue)
dbs.Properties.Append prp Resume Next Else 'Không biết lỗi gì
ChangeProperty = False Resume Change_KetThuc End If End Function 'Xử
lý tình huống chọn nút [Khóa database] Private Sub cmdLock_Click()
‘Biểu mẫu này được nạp trước ChangeProperty "StartupForm", dbText,
"frmKhoiDong" ChangeProperty "StartupShowDBWindow", dbBoolean, False
ChangeProperty "StartupShowStatusBar", dbBoolean, False ChangeProperty
"AllowBuiltinToolbars", dbBoolean, False ChangeProperty
"AllowFullMenus", dbBoolean, False ChangeProperty
"AllowBreakIntoCode", dbBoolean, False ChangeProperty
"AllowSpecialKeys", dbBoolean, False ‘Không cho xài phím Shift để bỏ
qua biểu mẫu frmKhoiDong ChangeProperty "AllowBypassKey", dbBoolean,
False MsgBox "Cơ sở dữ liệu đã được khóa! Đóng cơ sở dữ liệu, _ rồi mở
lại mới có ép-phê.", vbOKOnly, "eChip Security" cmdExit.SetFocus
cmdUnlock.Visible = True cmdLock.Visible = False End Sub 'Xử lý tình
huống chọn nút [Mở database] Private Sub cmdUnlock_Click() ‘Không cần
biểu mẫu khởi động nữa ChangeProperty "StartupForm", dbText, ""
ChangeProperty "StartupShowDBWindow", dbBoolean, True ChangeProperty
"StartupShowStatusBar", dbBoolean, True ChangeProperty
"AllowBuiltinToolbars", dbBoolean, True ChangeProperty
"AllowFullMenus", dbBoolean, True ChangeProperty "AllowBreakIntoCode",
dbBoolean, True ChangeProperty "AllowSpecialKeys", dbBoolean, True
ChangeProperty "AllowBypassKey", dbBoolean, True MsgBox "Cơ sở dữ liệu
đã được mở khóa ! _ Đóng cơ sở dữ liệu, rồi mở lại mới có ép-phê.", _
vbOKOnly, "eChip Security" cmdExit.SetFocus txtPassword = ""
cmdLock.Visible = True cmdUnlock.Visible = False txtPassword.Visible =
False End Sub 'Xử lý tình huống khi mở biểu mẫu Private Sub
Form_Open(Cancel As Integer) Dim dbs As Database Set dbs = CurrentDb
On Error GoTo KhongCoThuocTinh_Err If dbs.Properties("AllowBypassKey")
Then cmdLock.Visible = True txtPassword.Visible = False Else
cmdLock.Visible = False txtPassword.Visible = True End If Exit Sub
KhongCoThuocTinh_Err: cmdLock.Visible = True txtPassword.Visible =
False End Sub 'Khi người ta gõ mật khẩu và nhấn phím Enter Private Sub
txtPassword_LostFocus() If txtPassword = "echip" Then
cmdUnlock.Visible = True End If End Sub 4. Hỏi: Các Huynh chỉ dùm
trong Access khi chọn 1 mục trong Combo box VD: MANV nào đó thì ở
TextBox kế bên hiển thị ngay tên nhân viên theo MANV đó. Mình cho vd
nhé: Giả sử bạn có bảng nhân viên(MaNV;TenNV) bây giờ tại Form:
Frmnhanvien bạn có 1 combobox(tên là Cboma) để gõ mã nhân viên và 1
Textbox(tên là txttenNV) để hiển thị tên nhân viên ứng với mã NV đã
chọn. VD khi gõ vào combobox mã nhân viên NV01 thì textbox sẽ hiển thị
là Nguyễn Văn A; khi gõ vào nhân viên NV02 thì textbox hiển thị là
Nguyễn văn B... Muốn vậy tại textbox trên Form frmnhanvien: chọn Text
txttenNV gõ vào công thức: =Dlookup("tenNV","nhanvien","nhanvien!
maNV=[Forms]![frmNhanvien]![Cboma]") thì bạn sẽ có được kết quả ngay
nhưng nhớ đặt thuộc tính Looked= Yes cho Textbox txttenNV (Mục đích là
textbox này chỉ để hiển thị kết quả, không cho sửa đổi) Ví dụ bạn có
Table la NhanVien gồm hai trường MaNV, TenNV Bạn tạo Form có 1 Combo
la CmbMaNV; 1 Text Box là txtTenNV Source của CmbMaNV là table
NhanVien trên. Đoạn code như sau: Private Sub cmbMaNV Click()
Me.txtTenNV.Value = Me.cmbMaNV.Column(1) End Sub Mình đã làm rồi, rất
là OK bạn ah, bạn có thể sử dung 5. Mình có một chương trình
Access tự viết nhỏ, mình muốn chương trình tính được số ngày
sử dụng hoặc số lần đã mở chương trình nhưng không phụ thuộc
vào ngày của hệ thống bạn tạo 1 table, tạo field có tên là
userTime, kiểu number Khi user mở starup form, ở sự kiện open
của form, bạn viết 1 đoạn code mở table trên và edit thêm sự
kiện như sau: Private Sub Form_Open(Cancel As Integer) Dim rs As
DAO.Recordset Set rs = CurrentDb.OpenRecordset("T2") With
rs .MoveFirst .Edit !UserTime = !UserTime + 1 .Update End With
rs.Close End Sub 6. Bạn nào có biết cách phân quyền sử dụng trong
Access không chỉ cho mình với. Có nghĩa là với chương trình mình tạo
ra thì chỉ có mình mới có thể sửa source code được, có thể sửa
design... được thôi, người sử dụng chỉ được quyền sử dụng và không có
quyền truy cập vào source code cũng như table... để sửa chương trình.
Ở bên mình mọi người cũng có kiến thức về Access nên biết là cứ bấm
F11 là vào được data của chương trình. Đáp Bạn phải làm 2 việc : 1)
Vào Tools --> Startup : bỏ chọn tất cả các check box trên biểu mẫu
này. (không cho users sử dụng các phím tắt) Còn muốn triệt để hơn,
không cho xem code thì .mdb --> .mde 2) Disable phím SHIFT Nguyên lý :
trong database có 1 thuộc tính (property) gọi là : AllowBypassKey.
Thuộc tính này cho phép bạn enable/disable phím SHIFT. + Nếu
AllowBypassKey = False --> disable phím SHIFT + Nếu AllowBypassKey =
True --> enable phím SHIFT Cách làm : bạn tạo 1 Form (tạm gọi :
F_ShiftKey) có 2 nút lịnh : 1 để enable và 1 disable phím SHIFT. Đưa 2
private sub dưới đây vào.......... Private Sub
DisableSHIFTButton_Click() On Error GoTo ErrHandler Dim db As Database
Dim ThuocTinh As Property Set db = CurrentDb
db.Properties("AllowBypassKey") = False Set db = Nothing Egress: On
Error Resume Next Set db = Nothing Set ThuocTinh = Nothing Exit Sub
ErrHandler: MsgBox Err.Number If Err.Number = 3270 Then ' Property not
found. Set ThuocTinh = db.CreateProperty("AllowBypassKey", dbBoolean,
False) db.Properties.Append ThuocTinh Resume Next Else MsgBox
Err.Description Resume Egress End If End Sub
================================================= Private Sub
EnableSHIFTButton_Click() On Error GoTo ErrHandler Dim db As Database
Dim ThuocTinh As Property Set db = CurrentDb
db.Properties("AllowBypassKey") = True Set db = Nothing Egress: On
Error Resume Next Set db = Nothing Set ThuocTinh = Nothing Exit Sub
ErrHandler: MsgBox Err.Number If Err.Number = 3270 Then ' Property not
found. Set ThuocTinh = db.CreateProperty("AllowBypassKey", dbBoolean,
True) db.Properties.Append ThuocTinh Resume Next Else MsgBox
Err.Description Resume Egress End If End Sub ++++++++++++++++++++++++++
++++++++++++++++++++++++ OK chưa
bạn ? .............................................. Chưa đâu ! Bây
giờ đặt F_ShiftKey ở đâu trong chương trình để không ai được quyền mở
ngoại trừ Admin ? Có nhiều cách : cách đơn giản nhất là đặt ….ở đâu
cũng được với 1 điều kiện : để mở F_ShiftKey cần phải biết password. Ở
sự kiện Form_Open, bạn yêu cầu nhập đúng password : Lambada mới cho mở
form này. Private Sub Form_Open(Cancel As Integer) Dim Message, Title,
MyValue Message = "Ban vui long cho biet mat khau :" ' Set prompt.
Title = "Kiem tra" ' Set title. MyValue = InputBox(Message, Title) If
MyValue <> "Lambada" Then DoCmd.Close End If End Sub 7. Không phải mọi
thứ Access đều có thể giúp được bạn, đôi khi phải vận dụng linh hoạt
với Excel. Câu lệnh Export một đối tượng Access ra Excel
DoCmd.OutputTo Kiểu đối tượng, "tên đối tượng",
"MicrosoftExcelBiff8(*.xls)", "", True, "", 0 Ví dụ bạn đẩy một query
tên là DThutheothang ra excel: DoCmd.OutputTo acQuery,
"DThutheothang", "MicrosoftExcelBiff8(*.xls)", "", True, "", 0 8.
Xuống dòng trong Msgbox Access 97 trở về trước khi xuống dòng dùng ký
tự @. Access gần đây dùng vbCrLf để xuống dòng. Việc chủ động xuống
dòng trong Msgbox giúp hiển thị thông báo rõ ràng hơn. MsgBox "1.
Hello!" & vbCrLf & "2. Xin chào các bạn!" & vbCrLf & "3. Seeuagain!",
vbInformation, "Message" 9. Hiện duy nhất một cửa sổ khi mở nhiều form
Các bạn giúp mình với, làm sao khi mở một From VD From này la From
Main, trong From Main này có các Nút lệnh để mở các From khác. Thì làm
sao khi mở một From khác thì trên Takbar không xuất hiện From này mà
vẩn còn From Main hiện diện trên Taskbar. Vì nếu tôi mở nhiều Fron
trên một chương trình thì Taskbar sẻ đầy. Bạn chỉ cần vào Tools/
options Bỏ dấu check ở mục Windows on Taskbar. khi đó trên Task bar
chỉ còn duy nhất 1 màn hình Access thôi, bạn thư nhé.
---------------------- sanyovietnam in MaNguon Bổ sung : Vì Access
luôn chọn Check box Windows on Taskbar = True (default) nên nếu đem
file mdb của bạn sang máy khác thì sẽ gặp lại trường hợp nhiều cửa sổ
trên taskbar. Cách tổng quát hơn : Khi mở form Startup bạn thêm dòng
lệnh : Private Sub Form_Open(Cancel As Integer) Application.SetOption
"ShowWindowsInTaskbar", False End Sub 3. Trong các câu lệnh iif,
Dsum, ... trong phần điều kiện. ví dụ như thế này:
=Dsum("DiemThi","DSTS","SoBD = txtSoBD") (1) và
=Dsum("DiemThi","DSTS"," ' " & SoBD = txtSoBD & " ' ") (2) thì mình
thấy cái nào nó cũng chạy được, nhưng mình muốn biết khi nào thì dùng
câu lệnh nào và tốt nhất thì nên dùng câu lệnh nào ( 1 hay 2 ) Xin
chào các Bạn, Xin trao đổi với các Bạn 1 cách export Report đang mở
trong Access sang Excel như sau: 1. Viết 1 hàm dùng chung có nội dung:
Function ExPortActRpt2Excel() ' Dim Tentailieu As String, GetAppDir as
string GetAppDir = Left(CurrentDb.Name, Len(CurrentDb.Name) - Len(Dir$
(CurrentDb.Name))) Tentailieu = Screen.ActiveReport.Name
DoCmd.OutputTo acOutputReport, Tentailieu, acFormatXLS, GetAppDir &
Tentailieu & ".XLS" MsgBox "Da xuat Bao bieu hien hanh thanh File " &
GetAppDir & Tentailieu & ".XLS" End Function 2. sau đó tạo 1 Macro
Autokeys như sau: Macro Name: ^{F12} Action: RunCode Comment: Export
Report dang mo sang Excel Function Name: ExportActRpt2Excel() Bằng
cách tạo Macro này ta đã tạo 1 phím tắt Ctrl+F12 Từ sau đấy, khi 1
Report đã được mở trên màn hình ở chế độ Preview ta chỉ cần dùng phím
tắt này sẽ Export được Report sang Excel. Lê Hồng Đức 10 Các hàm chuẩn
mới Một loạt hàm mới được bổ sung so với Access 97, dùng để xử lý xâu
ký tự: Replace(), InstrRev(), StrReverse(), Split(), Join() và
Filter(). Hàm Replace() dùng để thay xâu con của xâu nào đó bằng xâu
con mới: ?Replace ("a1a2a3a4a5", "a", "b") b1b2b3b4b5 ?Replace
("a1a2a3a4a5", "a", "b", 3) b2b3b4b5 ?Replace ("a1a2a3a4a5", "a", "b",
3, 2) b2b3a4a5 Trong 2 ví dụ cuối, số 3 ở tham số thứ tư dùng chỉ vị
trí từ đó bắt đầu cần thay thế (và kết quả cũng từ đó luôn). Tham số
thứ 5 trong ví dụ cuối cùng để đặc tả số lần phải thay (xâu con có thể
hiện diện nhiều lần). Hàm StrReverse() trả về chuỗi ký tự đảo ngược
(không rõ thực tế ứng dụng CSDL có cần đến hàm này không?). ?
StrReverse ("abcdef") fedcba Hàm InstrRev() có cơ chế làm việc như
Instr() nhưng tìm kiếm ngược từ ký tự cuối đến ký tự đầu (hàm này thì
thật sự cần thiết): ?InstrRv ("C:\MyPath\MyFile.ext", "\") Các hàm
Split(), Join() và Filter() cũng rất hữu ích. Split() chuyển đổi xâu
ký tự có chia tách (bởi một ký tự nào đó, ví dụ dấu chấm phẩy) thành
mảng các giá trị. Join() thực hiện thao tác ngược lại, từ mảng trở về
xâu ký tự có chia tách. Filter() trích từ mảng các dòng thỏa mãn điều
kiện nào đó. ? Filter(Split(CurrentProject.Connection, ","), _ "Data
Source = ") (0) Data Source=D:\Temp\db1.mdb Thêm một bước nữa thì nhận
được trị của Data Source. ? Split
(Filter(Split(CurrentProject .Connection, ";"), _ "Data Source = ")
(0) ,"=") (1) D:\Temp\db1.mdb Nếu đã quen thuộc với ngôn ngữ Lisp,
chắc bạn rất hài lòng với bộ hàm trên và tự hỏi: tại sao đến bây giờ
VBA mới có được khả năng phân tích xâu ký tự như vậy? 11. Ví dụ sau
đây dùng để bẫy một số lỗi cơ bản: Private Sub Form_Error (DataErr As
Integer, Response As Integer) Response = acDataErrContinue ‘ tắt thông
báo của Access Select Case DataErr Case 3022 MsgBox “Trùng khóa
chính.” Case 3058 MsgBox “Khóa chính để trống.” Case 3314 MsgBox “Có
ít nhất một field chưa nhập theo yêu cầu bắt buộc.” Case Else MsgBox
“Có lỗi xảy ra.” & Chr(13) & “Chỉ số lỗi: “ & DataErr & Chr(13) & _
“Nội dung lỗi: “ & Err.Description End Select End Sub 12. Khi bạn sử
dụng VBA và cho thi hành một ứng dụng nào đó, bạn sẽ thấy một thông
báo lỗi nhưng bạn không biết lỗi đó là lỗi gì. Bạn chỉ cần thêm dòng
lệnh sau : Code: msgbox Err.Description & vbCrLf & Err.number Hộp
thoại sẽ hiển thị và cho bạn biết lỗi xảy ra và số của lỗi đó. 13. Nội
dung dưới đây do post lộn chỗ, do đó tôi xin post lại như là một new
thread: Thể theo lời của bạn Simon, tôi sẽ mở đầu bằng một bài về việc
viết code trong Access, trước tiên là khái niệm. Access ngoài chức
năng là quản trị CSDL, nó còn có thể cho phép người dùng xây dựng một
ứng dụng. Đde63 xây dựng một ứng dụng, điều nhất thiết là phải lập
trình (coding). Access sử dụng ngôn ngữ Visual Basic được Microsoft
support cho các phần mềm trong Microcost Office: Word, Excel, Access,
PowerPoint, ... và được gọi là VBA - Visual Basic for Applications.
Nếu bạn nào đã biết ngôn ngữ VB thì VBA không là gì cả. Tuy nhiên nó
có một số khác biệt nho nhỏ do đã được hỗ trợ thêm một số thư viện
thích hợp. Lập trình trong Access còn được gọi là lập trình điều khiển
sự kiện (event-driven programming). Về hình thức nó tương tự như lập
trình hướng đối tượng nhưng đơn giản hơn nhiều. Lập trình điều khiển
sự kiện là việc lập trình sao cho khi có một sự kiện, một hành vi tác
động lên một đối tượng thì sẽ thực thi một hay nhiều tác vụ nào đó
tương ứng. Chúng ta có thể lập trình sự kiện trên các Form, Report và
những đối tượng trong chúng. Tuy nhiên muốn lập trình sự kiện một cách
"pro", chúng ta phải nắm vững ý nghĩa của các sự kiện và diễn biến của
sự kiện. Ví dụ: Một người muốn kiểm tra dữ liệu nhập vào textbox số
lượng (soluong), số lượng nhập vào không được phép để trống và phải
dương. Ở đây người dùng sẽ yêu cầu một trong hai tình huống: - Hoặc là
kiểm tra khi dấu chèn (insertion I-beam) rời khỏi textbox soluong. -
Hoặc là kiểm tra khi chuẩn bị chuyển sang một record khác. Khi dấu
chèn rời khỏi textbox soluong, hàng loại các sự kiện sau sẽ xảy ra (có
giản lược, chỉ giữ các sự kiện chính): BeforeUpdate, AfterUpdate,
Exit, LostFocus. - BeforeUpdate là sự kiện xảy ra trước khi dữ liệu
trong textbox soluong được lưu lại trong recordset (nhưng chưa lưu vào
table). Sự kiện này chỉ xảy ra khi người sử dụng có gõ (entry) bất cứ
gì vào textbox kể cả xóa trắng nội dung. - AfterUpdate là sự kiện xảy
ra sau khi dữ liệu trong textbox soluong được lưu lại trong recordset
(nhưng chưa lưu vào table). - Exit: sự kiện xảy ra trước khi dấu chèn
rời khỏi textbox. - LostFocus: sự kiện xảy ra khi dấu chèn thực sự ra
khỏi textbox. Trong các thủ tục sự kiện tương ứng BeforeUpdate và Exit
của textbox soluong, chúng ta đều có thể kiểm tra được dữ liệu nhập
vào của người dùng, nhưng có hơi khác một tý về cách hành xử. Private
Sub soluong_BeforeUpdate (Cancel As Integer) If IsNull(soluong) Or
soluong <= 0 Then MsgBox "So luong khong hop le." Cancel = True End If
End Sub Private Sub soluong_Exit (Cancel As Integer) If
IsNull(soluong) Or soluong <= 0 Then MsgBox "So luong khong hop le."
Cancel = True End If End Sub Thoạt nhìn, cả hai hầu như không có gì
khác nhau, nhưng nó sẽ có một số điểm khác biệt: Nếu ở textbox
soluong, người sử dụng không nhập gì (trước đó soluong đang để trống)
thì khi người sử dụng ENTER để đi qua, thủ tục BeforeUpdate không thi
hành mà thủ tục Exit thi hành. Khi thi hành, chúng hiện thông báo, sau
đó giữ dấu chèn ở lại trong textbox soluong. Nếu sử dụng thủ tục
beforeUpdate, để rời khỏi soluong, người sử dụng có thể nhấn phím ESC
để lấy lại giá trị cũ của soluong, và từ đó có thể rời khỏi nó. Trong
khi đó, nếu sử dụng thủ tục Exit thì sẽ gần như là bị loop, không ra
được textbox soluong. Thường thì biện pháp tốt nhất là kiểm tra trước
khi record lưu vào table. Trong trường hợp này sẽ sử dụng thủ tục sự
kiện BeforeUpdate của Form. Private Sub Form_BeforeUpdate (Cancel As
Integer) If IsNull(soluong) Or soluong <= 0 Then MsgBox "So luong
khong hop le." Cancel = True End If End Sub Trong thủ tục này của
form, chúng ta có thể kiểm tra toàn bộ những ràng buộc mà chúng ta
cần. Trên là một số khái niệm ban đầu, trong thời gian tới, tôi sẽ sắp
xếp thời gian post một số kinh nghiệm về lập trình trong Access để các
bạn tham khảo. 14. Thủ Thuật: Chỉ cho phép người dùng gõ số vào
TextBox Giới Thiệu: Đoạn code này để khống chế nhập số cho TextBox. Nó
chỉ cho phép nhập ký tự số, dấu âm (-) và dấu thập phân (.) trong
KeyPress Event. Ví Dụ: Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim Tmp As String Tmp = Text1.Text Select Case Chr$(KeyAscii) Case "0"
To "9", Chr$(8) Case "-" If InStr(1, Tmp, "-") = 0 Then If
Text1.SelStart > 0 Then KeyAscii = 0 End If Else KeyAscii = 0 End If
Case "." If InStr(1, Tmp, ".") > 0 Then KeyAscii = 0 End If Case Else
KeyAscii = 0 End Select End Sub 15. Thủ Thuật: Không cho người dùng gõ
số vào TextBox Giới Thiệu: Khống chế không cho người dùng gõ số vào
TextBox. Ví Dụ: Private Sub Text1_KeyPress(KeyAscii As Integer) If
InStr("1234567890" + Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then
KeyAscii = 0 Beep End If End Sub 16. Thủ Thuật: Nén cơ sở dữ liệu
Access Giới Thiệu: Có lẽ bạn rất bực mình khi cơ sở dữ liệu cứ tăng
kích thước ngay cả khi bạn xóa record. Bạn có thể giải quyết vấn đề
này bằng cách nén CSDL lại mỗi khi đóng ứng dụng

Reply all
Reply to author
Forward
0 new messages