PDA

View Full Version : Access và những câu hỏi thường gặp



wll
08-06-10, 08:16 AM
Xin phép Admin mở riêng cho mình chuyên mục này, với một ít kiến thức về Access, đã từ lâu mình ấp ủ sẽ cho ra đời một cuốn cẩm nang dành riêng cho những người yêu thích Access, nhưng công viện bề bộn nên dự án ấp ủ nhưng vẫn chưa thực hiện được. Với những thủ thuật hay và những câu hỏi về Access là thành quả của mình sau khi nghiên cứu Access và sưu tầm được từ cộng đồng mạng.
================================================== ========




Hỏi: Tôi tạo form nhập liệu, và muốn bắt lỗi khi người dùng nhập sai nhưng muốn đóng form thì hiện ra thông báo : ” Có dữ liệu bị lỗi, Bạn có muốn đóng không?” Vậy tôi phải bắt lỗi thế nào?


Đáp:

Để bắt được lỗi này, bạn phải kết hợp hai sự kiện Form_Error và Form_UnLoad.

Bạn nên tạo một biến dùng chung cho module (nghĩa là khai báo ở vùng Declaration của Form Module), ví dụ Dim hasError As Boolean chẳng hạn

Cái sự kiện bạn bắt bao gồm 2 cái:

1. là Form_Unload: sự kiện này xảy ra trước Close. Do vậy nếu Cancel=True ở đây đồng nghĩa với việc hủy Close.

Private Sub Form_Unload(Cancel As Integer)
If hasError Then
If MsgBox(“Có dữ liệu bị lỗi, Bạn có muốn đóng không?”, vbYesNo) = vbNo Then
Cancel = True
Else
DoCmd.RunCommand acCmdUndo
End If
End If
End Sub

2. là Form_Error

Private Sub Form_Error(DataErr As Integer, Response As Integer)
Respponse = acDataErrContinue
hasError = True
Select Case DataErr
Case 2169
MsgBox “Co loi khi luu du lieu.”
Case Else
MsgBox “Err No.” & DataErr & vbCrLf & “Err Mess: ” & Error(DataErr)
End Select
End Sub

wll
08-06-10, 08:18 AM
Cách lấy (copy)database tại một máy trên mạng Lan



Hỏi:
Mong được sự giúp đỡ của các cao thủ lập trình Access :
_ Đến 1 ngày nhất định trong tháng phải copy database Access từ một máy tính trên mạng Lan; tên máy tính là computerA và địa chỉ IP tĩnh 192.168.1.30, máy tính A share thư mục với tên “Baocao” và tên file cần lấy là “Nhaplieu.mdb”.
( tức là \\computerA\Baocao\nhaplieu.mdb hoặc \\192.168.1.30\Baocao\nhaplieu.mdb )
+ Mình muốn tạo một button khi click vào sẽ tự động lấy file ấy về và để tại máy tính mình tại thư mục gốc ổ D.

Đáp:

Trong sự kiện Click, bạn cho dòng lệnh sau vào
Dim RCopy as String
Rcopy= “Copy \\computerA\Baocao\nhaplieu.mdb D:\nhaplieu.mdb”
Shell RCopy,vbHide

Hoặc:
Call FileCopy(“\\computerA\Baocao\nhaplieu.mdb”, “D:\nhaplieu.mdb”)

wll
08-06-10, 08:19 AM
Map Network Drive
Hỏi: Mình có làm 1 chương trình file Data để trên mạng LAN, do đó nếu người dùng không map ổ mạng thì sẽ không thể chạy chương trình được. Các bác cho em hỏi có đoạn code nào gọi cửa sổ Map network Drive lên được không?
Đáp:
Điều kiện là thư mục của bạn phải được share trước.
Sub MapNetwork(D As String, s As String, UserName As String, Password As String)
‘d : diver
‘s: Map Address
Dim p As String
p = “net use ” & D & “: \\” & s
Shell p, vbHide
MsgBox “Map ” & D & ” successful”
End Sub
Bây giờ, giả sử dữ liệu mình nằm trên server trong thư mục DuLieu. UserName Mình là Noname. Pass Của mình là khpt. Mình muốn gán ổ đĩa G làm ổ mạng. mình sẽ gọi Thủ tục map network Drive như sau:
MapNetwork “G”, “server\dulieu”, “Noname”, “khpt”

wll
08-06-10, 08:22 AM
Combo Box
Hỏi : Tôi có 1 combo box (cboMaHang), tôi muốn khi con chuột hoặc con trỏ nhảy đến cboMahang thì hộp danh sách tự động thả xuống, phải làm sao ?

Đáp : có nhiều cách, cách đơn giản nhất là tận dụng method sãn có của combo box : Dropdown.
Cách dùng:
Private Sub cboMahang_GotFocus()
cboMahang.Dropdown
End Sub

wll
08-06-10, 08:22 AM
Hỏi : Tôi có 1 combo box (cboMaHang), tôi muốn khi người dùng đánh mã hàng không có trong hộp danh sách thì hiện lên thông báo lỗi, phải làm sao ?

Đáp : dùng sự kiện NotInList của combo box

Private Sub cboMaHang_NotInList(NewData As String, Response As Integer)
Response = acDataErrContinue
MsgBox "Ma hang nay khong co.", , "Bao loi !"
End Sub

Bổ sung : Mở properties của cboMaHang --> Tab Data --> Limit To List : Yes

wll
08-06-10, 08:23 AM
Hỏi :
Tôi có 1 query có 3 trường MaHang, Nam2006, Nam2007. trong đó dữ liệu của Nam2006, Nam2007 là doanh thu của từng mặt hàng trong Field MaHang.
Tôi muốn tạo thêm 1 field so sánh doanh thu của Nam2007 với Nam2006 của từng MaHang. Field này yêu cầu có dạng %, ví dụ : 1,05%. Tôi phải làm sao ?

Đáp :
Field mới sẽ có công thức : =Round( (Nam2007/Nam2006)*100,2) & "%"

wll
08-06-10, 08:24 AM
Hỏi : Function rất hay dùng để Compact Database :
Public Sub CompactDB()
CommandBars("Menu Bar"). _
Controls("Tools"). _
Controls("Database utilities"). _
Controls("Compact and repair database..."). _
accDoDefaultAction
End Sub
Tuy nhiên tôi rất lười biếng và lại hay quên. Nên tôi muốn chương trình tự động mỗi tháng 1 lần Compact and repair Database giúp tôi. Tôi phải làm sao ?

Đáp :
Ý tưởng : Bạn tạo 1 table (T_Compact) chỉ có 1 field text (NamThang). Dữ liệu của field này có dạng : 200704 (tháng 04/2007). Khi mở chương trình bạn viêt code kiểm tra tháng hiện hành có trong T_compact hay không :
*****Nếu có thì không chạy Function CompactDB ở trên
*****Nếu không có thì chạy Function trên và thêm 1 record tháng hiện hành vào T_Compact.

wll
08-06-10, 08:25 AM
Hỏi : Tôi đã hoàn tất chương trình bán hàng trên Access, đã viết xong File hướng dẫn sử dụng (HuongDan.chm). Nhưng tôi không biết làm sao để kết nối file HuongDan.chm với chương trình ?

Đáp :

Bạn phải dùng đến hàm API.

Tạo 1 module
Khai báo hàm API

Code:
Option Compare Database

Private Declare Function HtmlHelp Lib "HHCtrl.ocx" Alias "HtmlHelpA" _
(ByVal hwndCaller As Long, _
ByVal pszFile As String, _
ByVal uCommand As Long, _
dwData As Any) As Long
Const HH_DISPLAY_TOPIC = &H0
Const HH_HELP_CONTEXT = &HF
tạo Function

Code:
Public Function GoiHelp()

Dim strPath As String
strPath = Application.CurrentProject.Path
strPath = strPath & "\huongdan.chm"

Call HtmlHelp(0, strPath, HH_DISPLAY_TOPIC, ByVal "Gioithieu.htm")

End Function
Trong đó Gioithieu.htm là trang mặc định (default) của File HuongDan.chm.
Như vậy từ chương trình (Command button hoặc Custom Menu) bạn chỉ cần gọi function GoiHelp là xong.

Lưu ý : file HuongDan.chm nằm cùng thư mục với file .mdb, .mde.

wll
08-06-10, 08:26 AM
Hỏi:
Báo cáo của chương trình in ra dựa trên 1 table (query). Thỉnh thoảng trên table không có dữ liệu phát sinh nhưng báo cáo vẫn được in ra ( dựa trên câu lịnh : docmd.OpenReport ...... ), trong không đuọc đẹp lắm : có header, footer nhưng dữ liệu lại trống không vì không có dữ liệu.

Tôi muốn khi table nguồn không có dữ liệu thì báo cáo sẽ không được in và hiện lên câu thông báo : không có dữ liệu phát sinh ! Tôi phải làm sao ?

Đáp:
Bạn có thể viết code kiểm tra nếu table nguồn có record = 0 thì hiện lên thông báo không có dữ liệu phát sinh ! và không cho chạy dòng lệnh doCmd.OpenReport ....

Tuy nhiên có 1 cách đơn giản hơn : sử dụng sự kiện On No Data của report.
Code:
Private Sub Report_NoData(Cancel As Integer)
MsgBox "Khong co du lieu phat sinh.", , "Thong bao !"
Cancel = True
End Sub

wll
08-06-10, 08:26 AM
Hỏi:
Tôi có 1 Form. Tôi muốn khi người dùng mở Form này thì thanh tiêu đề của Form (Form caption) nhấp nháy dòng chữ : Dữ liệu đã bị khóa ! Tôi phải làm sao ?

Đáp:
Bạn dùng 2 sự kiện của Form: Open và Timer

Code:
Private Sub Form_Open(Cancel As Integer)
Me.Caption = "Dữ liệu đã bị khóa !"
Me.TimerInterval = 600
End Sub
Code:
Private Sub Form_Timer()
If Me.Caption = Space(1) Then
Me.Caption = "Dữ liệu đã bị khóa !"
Else
Me.Caption = Space(1)
End If
End Sub

wll
08-06-10, 08:27 AM
Hỏi:
Tôi có CT Quản lý nhân sự trên Access, muốn bán cho nhiều công ty. Trong CT có 1 Form hiển thị thông tin về công ty (TenCongTy, DiaChi, Tel, Fax,...).
Tôi muốn khi người dùng nhập thông tin về công ty trên Form này thì thanh tiêu đề của Access sẽ hiển thị tên công ty đó trong suốt quá trình sử dụng. Tôi phải làm sao ?
Đáp:

1) Bạn tạo 1 public Function

Code:
Public Function AddAppProperty(strName As String, varType As Variant, varValue As Variant)
As Integer

Dim dbs As Object, prp As Variant
Const conPropNotFoundError = 3270

Set dbs = CurrentDb()
On Error GoTo AddProp_Err
dbs.Properties(strName) = varValue
AddAppProperty = True

AddProp_Bye:
Exit Function

AddProp_Err:
If Err = conPropNotFoundError Then
Set prp = dbs.CreateProperty(strName, varType, varValue)
dbs.Properties.Append prp
Resume
Else
AddAppProperty = False
Resume AddProp_Bye
End If

End Function
2) Ở sụ kiện Close của Form thông tin công ty :

Code:
Private Sub Form_Close()

Dim Tieude As String
Dim intX As Integer

Const DB_Text As Long = 10
Tieude = "Chuong trinh quan ly nhan su"

If IsNull(TenCongTy) Then ' TenCongTy là tên của TextBox trên Form
intX = AddAppProperty("AppTitle", DB_Text, Tieude)
Else
intX = AddAppProperty("AppTitle", DB_Text, Tieude & " - " & TenCongTy)
End If
Application.RefreshTitleBar

End Sub

wll
08-06-10, 08:28 AM
Hỏi:
Tôi có 1 report có 3 cột : Stt, MatHang, DoanhThu
Tôi dễ dàng tính tổng doanh thu của tất cả các mặt hàng bằng cách tạo 1 textbox (TongDoanhThu) ở Report Footer = Sum(DoanhThu). Tuy nhiên sếp tôi yêu cầu thêm : trên từng trang của báo cáo phải có tính tổng doanh thu của các mặt hàng trên trang đó. Access không hổ trợ trực tiếp cách tính tổng trên từng trang, tôi phải làm sao ?
Đáp:
Bạn phải viết code hoặc dùng Macro để tỉnh tổng trang. Tôi sẽ hướng dẫn bạn cách viết code

- Ở Page Footer bạn tạo 1 textbox : TongTrang
- Nhập 2 sub sau :

Code:
Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
TongTrang = TongTrang + DoanhThu
End Sub
Code:
Private Sub PageHeaderSection_Print(Cancel As Integer, PrintCount As Integer)
TongTrang = 0
' Reset TongTrang = 0 khi qua trang mới
End Sub
Lưu ý: Để dùng Macro bạn xem thêm File NorthWind.mdb ( chương trình mẫu của Access), Report Sales Totals by Amount

wll
08-06-10, 08:30 AM
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.

wll
08-06-10, 08:32 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.

Có một 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

Mã:
'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

wll
08-06-10, 08:32 AM
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:
Mã:
Private Sub cmbMaNV Click()
Me.txtTenNV.Value = Me.cmbMaNV.Column(1)
End Sub

wll
08-06-10, 08:35 AM
Câu 1
Hỏi : Tôi có 1 combo box (cboMaHang), tôi muốn khi con chuột hoặc con trỏ nhảy đến cboMahang thì hộp danh sách tự động thả xuống, phải làm sao ?

Đáp : có nhiều cách, cách đơn giản nhất là tận dụng method sãn có của combo box : Dropdown.
Cách dùng:
Private Sub cboMahang_GotFocus()
cboMahang.Dropdown
End Sub

Câu 2
Hỏi : Tôi có 1 combo box (cboMaHang), tôi muốn khi người dùng đánh mã hàng không có trong hộp danh sách thì hiện lên thông báo lỗi, phải làm sao ?

Đáp : dùng sự kiện NotInList của combo box

Private Sub cboMaHang_NotInList(NewData As String, Response As Integer)
Response = acDataErrContinue
MsgBox "Ma hang nay khong co.", , "Bao loi !"
End Sub

- Mở properties của cboMaHang --> Tab Data --> Limit To List : Yes

wll
08-06-10, 08:36 AM
Câu 3:
Hỏi : Tôi có 1 combo box (cboMaHang), Số mã hàng trong table lên đến 2000 record. khi tôi mở Form, mở cboMahang, kéo thanh trượt của hộp danh sách để tìm mã hàng thì thấy từng record hiện lên rất chậm (nếu số mã hàng chỉ có 15 - 20 record thì rất nhanh). Có cach gì đơn giản và nhanh khi duyệt qua từng record trong hộp danh sách của combo box hay không ?

Đáp:
Giải thích : Khi bắt đầu kéo thanh trượt của hộp danh sách, bộ nhớ của máy tính mới bắt đầu tải các record từ table vào bộ nhớ để hiện lên trên form. Nếu số recod càng nhiều thì thời gian tải sẽ càng lâu.

Để khắc phục tình trạng này, ta sẽ cho chương trình tải tất cả các record vào bộ nhớ ngay khi mở Form. Nhờ đó, khi nhảy đến combo box, hộp danh sach sẽ hiện các danh sách rất nhanh vì đã có sẵn các record trong bộ nhớ máy tính.

Cách làm :

Ở sự kiện Form_Load

Private Sub Form_Load()
Dim lngCount As Variant
lngCount = cboMaHang.ListCount
End Sub

wll
08-06-10, 08:37 AM
Câu 4:
Hỏi : Tôi đã hoàn tất chương trình bán hàng trên Access, đã viết xong File hướng dẫn sử dụng (HuongDan.chm). Nhưng tôi không biết làm sao để kết nối file HuongDan.chm với chương trình ?

Đáp :
Bạn phải dùng đến hàm API.

Tạo 1 module
Khai báo hàm API

Option Compare Database

Private Declare Function HtmlHelp Lib "HHCtrl.ocx" Alias "HtmlHelpA" _
(ByVal hwndCaller As Long, _
ByVal pszFile As String, _
ByVal uCommand As Long, _
dwData As Any) As Long
Const HH_DISPLAY_TOPIC = &H0
Const HH_HELP_CONTEXT = &HF
Public Function GoiHelp()

Dim strPath As String
strPath = Application.CurrentProject.Path
strPath = strPath & "\huongdan.chm"

Call HtmlHelp(0, strPath, HH_DISPLAY_TOPIC, ByVal "Gioithieu.htm")
End Function
Trong đó Gioithieu.htm là trang mặc định (default) của File HuongDan.chm.
Như vậy từ chương trình (Command button hoặc Custom Menu) bạn chỉ cần gọi function GoiHelp là xong.

Lưu ý : file HuongDan.chm nằm cùng thư mục với file .mdb, .mde.

wll
08-06-10, 08:37 AM
Câu 6:
Hỏi : Trong chương trình mydb.mdb của tôi, mỗi khi tôi nhấn phím F1 thì đều hiện lên hướng dẫn của MS Access, rất bực mình. Tôi muốn thay hướng dẫn của MS Access bằng File help của tôi (huongdan.chm) khi nhấn F1, phải làm sao ?
Đáp :
Bạn Tạo macro Autokeys :

Macro Name : {F1}
Action : RunCode
Function Name : GoiHelp()
(xem thêm câu hỏi đáp số 4 để tạo Function GoiHelp())
Lưu ý: Bạn có thể dùng Macro AutoKeys để tạo Phím tắt (Short cut) cho các ứng dụng trong CT của mình.
Ví dụ : bạn muốn tạo phím tắt để mở Form_NhapXuat là F2, trong AutoKeys bạn thêm :
Macro Name : {F2}
Action : OpenForm
Form Name : Form_NhapXuat

wll
08-06-10, 08:38 AM
Câu 7:

Hỏi: Làm thế nào để mở một file Word trong trong Access?

Đáp: Để mở một file Word trong Access bạn có thể làm như sau (vd khi bạn nhấn chuột vào Command1 của 1 form nào đó):‘ Khai báo hàm API cần dùng

Private Declare Function WinExec Lib “kernel32” (ByVal lpCmdLine As String, ByVal nCmdShow As Long) As Long

Option Compare Database

Option Explicit
‘ Hàm phục vụ nhấn chuột
Private Sub Command1_Click()
‘ Chạy Word và mở file c:\data\rose.doc
WinExec “””C:\Program Files\Microsoft Office\Office\WINWORD.EXE”” c:\data\rose.doc”, 8
End Sub

Từ đây bạn có thể sử dụng đoạn mã trên để chạy các ứng dụng khác tương tự bằng cách thay các thông số.

wll
08-06-10, 08:38 AM
Câu 8:

Hỏi:

File Access của tôi ngày càng phình to ra, có khi lên đến 100 MB. Tôi biết trong Main Menu của Access có lịnh Compact and Repair Database. Nhưng trong chuơng trình của tôi Main Menu của Access đã được giấu đi, thay bằng My Custom Menu Bar, tôi phải làm sao để sử dụng lịnh này ?

Đáp:

Bạn tạo Public Function

Public Sub CompactDB()
CommandBars("Menu Bar"). _
Controls("Tools"). _
Controls("Database utilities"). _
Controls("Compact and repair database..."). _
accDoDefaultAction
End Sub

Từ 1 Command Button hoặc Menu Command bạn gọi CompactDB() là xong.

wll
08-06-10, 08:38 AM
Câu 9:

Hỏi: Tôi có thể mở bất kỳ mẫu biểu nào trong CSDL bằng cách chọn tên mẫu biểu từ combo box (list box) trong mẫu biểu khác không.

Trả lời:

Tạo một combo box từ mẫu biểu nào mà bạn muốn chọn để mở mẫu biểu đầu tiên. Combo box được thiết lập các thuộc tính sau:

Name: List of forms

Data: Value list (để cài đặt thuộc tính Row Suorce type)

Event: [On Enter]

' Đoạn mã xử lý như sau:

Private Sub Listofforms_enter()

Dim MyDb as Database

Dim MyContainer as Container

Dim I as integer

Dim list as string

Set MyDb = DBEngine.Workspace(0).Database(0)

Set My Container = MyDb.Containers("Forms")

List = " "

For I=0 to MyContainer.Documents.count - 1

List = List & MyContainer.Documents(I).name & ";"

Next I

me![List of Forms].Row Suorce = Left(List, Len(list)-1)

End sub

' Nhập tiếp thuộc tính After Update của Combo box

Private Sub ListofForms_AfterUpdate()

Docmd.OpenForm me![ListofForms)

End Sub

wll
08-06-10, 08:39 AM
Câu 10:

Hỏi: Tôi làm chương trình qlý SV, vô ý lúc nhập tên toàn nhập chữ thường, tôi muốn tạo một hàm có thể in hoa tất cả mẫu tự đầu của từng từ trong trường văn bản thì phải làm như thế nào?

Trả lời: Hàm của bạn làm như sau:

Function Inhoachucaidau (Word as Variant) as String

Dim temp as string, C as string, OldC as String, X as integer

If IsNull(Word) then

Exit Function

Else

temp = CStr(LCase(Word)

OldC = " "

For X = 1 to Len(temp)

C= Mid(temp, X, 1)

If C >= "a" and C <= "z" and (OldC < "a" or OldC > "z") then

Mid(temp, X, 1) = UCase(C)

End If

OldC = C

Next X

Inhoachucaidau = temp

End If

End Function

Lúc các bạn sử dụng thì thay đổi trường Control Suorce thành

= Inhoachucaidau([text field_của bạn])

wll
08-06-10, 08:39 AM
Câu 11

Hỏi:

Trong câu hỏi đáp số 8 tôi đã biết cách sử dụng lịnh Compact and Repair Database trong chương trình (gọi sub CompactDB()).Tuy nhiên khách hàng của tôi yêu cầu cao hơn : làm sao để chương trình mỗi tháng 1 lần tự động Compact and Repair Database. Đau đầu quá, tôi phải làm sao ?

Đáp:

Ý tưởng : Bạn tạo 1 table (T_Compact) chỉ có 1 field text (NamThang). Dữ liệu của field này có dạng : 200704 (tháng 04/2007). Khi mở chương trình bạn viêt code kiểm tra tháng hiện hành có trong T_compact hay không :
*****Nếu có thì không chạy Sub CompactDB ở câu 8
*****Nếu không có thì chạy Sub trên và thêm 1 record tháng hiện hành vào T_Compact.

Cách làm :

1) Tạo 1 table (T_Compact) chỉ có 1 field text (NamThang)

2) Tạo Form (F_Compact) chỉ có 1 label, caption : Đang tự động "dọn dẹp" chương trình định kỳ hàng tháng, bạn vui lòng chờ trong giây lát ....
Dung nhan mùa hạ của F_Compact :
************************************************** *******

* Đang tự động "dọn dẹp" chương trình định kỳ hàng tháng, *

* bạn vui lòng chờ trong giây lát .... *

************************************************** *******

Lưu ý: Form này không có tiêu đề (titlebar) chắc bạn cũng biết nó để làm gì rôi !

Mở Properties của F_Compact :
****** Timer Interval : 4000
****** On Timer :
Private Sub Form_Timer()
Call CompactDB
End Sub

3) Mở cửa sổ viết code của Form Startup, chèn thêm 1 sub :
Private Sub DonDep()
Dim ChuoiNgay As String, TimKiem As Variant
Dim KyNay As Variant

KyNay = Year(Date) & Right("0" & Month(Date), 2)
ChuoiNgay = "NamThang = '" & KyNay & "'"
TimKiem = DLookup("Namthang", "T_Compact", ChuoiNgay)

If IsNull(TimKiem) Then
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO T_Compact(NamThang) VALUES(" & KyNay & ")"
DoCmd.SetWarnings True
DoCmd.OpenForm "F_Compact"
End If
End Sub
4) Ở sự kiện open hoặc close của Form Startup, bạn cho chạy sub DonDep

5) Tạo 1 module , đưa Public Sub Compact() trong câu 8 vào.

wll
08-06-10, 08:40 AM
Hoi: Trong table Hocsinh của tôi có trường hoten bây giờ tôi muốn xắp xếp các tên theo thứ tự tăng dần, nếu cùng tên thì xắp xếp theo họ, vậy tôi phải làm thế nào?

Trả lời: Dùng hàm sau để tách tên, sau đó có thể áp dụng gọi hàm này trong query cũng được

Function GetTen(hoten As String) As String
Dim pos As Integer
pos = 1
If InStr(pos, Trim(hoten), " ") = 0 Then
GetTen = hoten
Exit Function
End If
While InStr(pos + 1, Trim(hoten), " ") > 0

pos = InStr(pos + 1, Trim(hoten), " ")
Wend

GetTen = Mid(hoten, pos)
End Function

wll
08-06-10, 08:40 AM
Câu 13

Hỏi:
Báo cáo của chương trình in ra dựa trên 1 table (query). Thỉnh thoảng trên table không có dữ liệu phát sinh nhưng báo cáo vẫn được in ra ( dựa trên câu lịnh : docmd.OpenReport ...... ), trong không đuọc đẹp lắm : có header, footer nhưng dữ liệu lại trống không vì không có dữ liệu.

Tôi muốn khi table nguồn không có dữ liệu thì báo cáo sẽ không được in và hiện lên câu thông báo : không có dữ liệu phát sinh ! Tôi phải làm sao ?

Đáp:
Bạn có thể viết code kiểm tra nếu table nguồn có record = 0 thì hiện lên thông báo không có dữ liệu phát sinh ! và không cho chạy dòng lệnh doCmd.OpenReport ....

Tuy nhiên có 1 cách đơn giản hơn : sử dụng sự kiện On No Data của report.

Private Sub Report_NoData(Cancel As Integer)
MsgBox "Khong co du lieu phat sinh.", , "Thong bao !"
Cancel = True
End Sub

wll
08-06-10, 08:41 AM
Câu 14:

Hỏi: Tôi muốn làm một trường thông báo những thông tin mới nhất nhưng không biết giải thuật làm sao cho chữ chạy trên màn hình?

Đáp: Ý tưởng đặt ra là bạn phải sử dụng một label với sự kiện On Timer của Form

Name: label; Caption: muốn chạy chữ gì ở đây cũng được

Code:

Private Sub Form_Timer()
me.TimerInterval = 400

Dim x, y As String
x = Left(label.Caption, 1)
y = Right(label.Caption, Len(label.Caption) - 1)
label.Caption = y + x
End Sub

Note:

Giá trị TimerInterval có thể thay đổi tùy thuộc vào tốc độ mà các bạn muốn. Với giải thuật đơn giản trên các bạn cũng có thể làm cho Caption của Form hiện hành chạy bằng cách thay label.Caption bằng me.Caption

wll
08-06-10, 08:41 AM
Câu 15

Hỏi:
Bạn PhiLongXPCT đã hướng dẫn cách tạo dòng chữ chạy trên form hoặc trên thanh tiêu đề của form.. Bây giờ tôi muốn tạo dòng chữ nhấp nháy trên thanh tiêu đề của Form (Form caption) : Dữ liệu đã bị khóa ! Tôi phải làm sao ?

Đáp:
Bạn dùng 2 sự kiện của Form: Open và Timer

Private Sub Form_Open(Cancel As Integer)
Me.Caption = "Dữ liệu đã bị khóa !"
Me.TimerInterval = 600
End Sub

Private Sub Form_Timer()
If Me.Caption = Space(1) Then
Me.Caption = "Dữ liệu đã bị khóa !"
Else
Me.Caption = Space(1)
End If
End Sub

wll
08-06-10, 08:41 AM
Câu 16

Hỏi:
Tôi có CT Quản lý nhân sự trên Access, muốn bán cho nhiều công ty. Khi mua CT về, Công ty đó sẽ nhập thông tin công ty (TenCongTy, DiaChi, Tel, Fax,...).trên 1 Form trong CT.
Để giao diện CT mang tính "pro" (chuyên nghiệp) hơn, tôi muốn khi người dùng nhập thông tin về công ty trên Form này thì thanh tiêu đề của Access sẽ hiển thị tên công ty đó trong suốt quá trình sử dụng. Tôi phải làm sao ?
Đáp:

1) Bạn tạo 1 public Function

Public Function AddAppProperty(strName As String, varType As Variant, varValue As Variant)
As Integer

Dim dbs As Object, prp As Variant
Const conPropNotFoundError = 3270

Set dbs = CurrentDb()
On Error GoTo AddProp_Err
dbs.Properties(strName) = varValue
AddAppProperty = True

AddProp_Bye:
Exit Function

AddProp_Err:
If Err = conPropNotFoundError Then
Set prp = dbs.CreateProperty(strName, varType, varValue)
dbs.Properties.Append prp
Resume
Else
AddAppProperty = False
Resume AddProp_Bye
End If

End Function

2) Ở sụ kiện Close của Form thông tin công ty :

Private Sub Form_Close()

Dim Tieude As String
Dim intX As Integer

Const DB_Text As Long = 10
Tieude = "Chuong trinh quan ly nhan su"

If IsNull(TenCongTy) Then ' TenCongTy là tên của TextBox trên Form
intX = AddAppProperty("AppTitle", DB_Text, Tieude)
Else
intX = AddAppProperty("AppTitle", DB_Text, Tieude & " - " & TenCongTy)
End If
Application.RefreshTitleBar

End Sub

wll
08-06-10, 08:42 AM
Câu 16:

Hỏi:Tôi viết một chương trình trên Access 2003. Tôi muốn khi người dùng Click vào một nút để hiển thị Form trong chế độ Pivot Table View (tính năng này không có trong Ver 97,2000) thì hiện ra một cảnh báo, xin hướng dẫn

Trả lời

Chép đoạn mã sau vào thủ tục Click

If Syscmd(acSyscmdAccessVer)<=9 then

msgbox "Form này yêu cầu từ Access phiên bản 2002 trở lên.",vbOkonly,"Thong bao"

exit sub

else

'Thực hiện lệnh mở Form

end if

wll
08-06-10, 08:42 AM
Câu 17

Hỏi: Tôi có một table: tblBanhang gồm các trường :Ngayban,mahang,soluong,dongia. Bây giờ tôi muốn dựa vào trường ngày bán tôi muốn thống kê doanh số bán hàng theo từng tháng. Nhưng khi tôi dùng hàm Month(ngayban) rồi Group by nhưng kết quả trả về không như ý muốn vì nó bao gồm tháng của tất cả các năm. Vây tôi phải làm sao.

Trả lời:

Đúng vậy, ta không thể dùng hàm Month trong trường hợp này. Rất may Access cung cấp cho ta hàm DateSerial. cú pháp như sau:

DateSerial(Year,month,date) (*)

Áp dụng cho câu hỏi trên: DateSerial(Year(Ngayban),month(ngayban),1) Khi sử dụng thì tất cả các ngày trong tháng 04/2007 đều được nhóm thành ngày 01/04/2007. Tất cả các ngày trong tháng 05/2007 được nhóm thành 01/05/2007.

wll
08-06-10, 08:42 AM
Câu 18

Hỏi:
Tôi có 1 report có 3 cột : Stt, MatHang, DoanhThu
Tôi dễ dàng tính tổng doanh thu của tất cả các mặt hàng bằng cách tạo 1 textbox (TongDoanhThu) ở Report Footer = Sum(DoanhThu). Tuy nhiên sếp tôi yêu cầu thêm : trên từng trang của báo cáo phải có tính tổng doanh thu của các mặt hàng trên trang đó. Access không hổ trợ trực tiếp cách tính tổng trên từng trang, tôi phải làm sao ?
Đáp:
Bạn phải viết code hoặc dùng Macro để tỉnh tổng trang. Tôi sẽ hướng dẫn bạn cách viết code

- Ở Page Footer bạn tạo 1 textbox : TongTrang
- Nhập 2 sub sau :

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
TongTrang = TongTrang + DoanhThu
End Sub

Private Sub PageHeaderSection_Print(Cancel As Integer, PrintCount As Integer)
TongTrang = 0
' Reset TongTrang = 0 khi qua trang mới
End Sub

Lưu ý: Để dùng Macro bạn xem thêm File NorthWind.mdb ( chương trình mẫu của Access), Report Sales Totals by Amount

wll
08-06-10, 08:43 AM
Câu 19
Hỏi:
Trên Form có textbox :
SoLuong - kiểu dữ liệu : Number
Khi tôi đánh nhầm kiểu dữ liệu vào textbox trên (ví dụ : tôi đánh nhầm abc thay vì phải đánh số 12300) Access báo lỗi :

“The value you entered isn’t valid for this field.
For example, you may have entered text in ......”
Tôi muốn thay câu báo lỗi trên bằng câu báo lỗi tiếng Việt : "Bạn kiểm tra lại dữ liệu nhập", phải làm sao ?

Đáp:
Có nhiều cách nhưng cách sau đây là tổng quát nhất.

1) Đầu tiên bạn download file AccessAndJetErrors.zip từ :
http://www.access-programmers.co.uk/...1&d=1055362440
Giải nén và mở file AccessAndJetErrors.mdb, mở table tAccessAndJetErrors bạn sẽ thấy table này có 2 Field : ErrorCode và ErrorString. Table này liệt kê hầu hết các lỗi của Access, Ví dụ : bạn tìm trong table này record có ErrorCode là 2113 sẽ thấy ErrorString chính là câu báo lỗi trên.

2)Như vậy ta đã biết câu báo lỗi trên có errorcode là 2113, bây giờ ta tạo thủ tục trên form :

Private Sub Form_Error(DataErr As Integer, Response As Integer)

Const SaiDuLieu = 2113
Const Rong = 2107 ' khai báo hằng này có tính chất minh họa cho select case
Const TaoLao = 1670 ' khai báo hằng này có tính chất minh họa cho select case
Dim strMsg As String

Select Case DataErr
Case SaiDuLieu
Response = acDataErrContinue
strMsg = "Bạn kiểm tra lại dữ liệu nhập. "
MsgBox strMsg, , "Báo lỗi !"
Case Rong
Response = acDataErrContinue
strMsg = "Bạn không được để trống số lượng, đơn giá"
MsgBox strMsg, , "Báo lỗi !"
Case else
Response = acDataErrContinue
strMsg = "Có một lỗi phát sinh "
MsgBox strMsg, , "Báo lỗi !"
End Select

End Sub
Vậy là xong !

Bạn lưu ý: bằng cách này bạn có thể thay thế hầu hết các câu báo lỗi tiếng Anh trên Forrm bằng tiếng Việt ngon lành. Khi thiết kế Form, Bạn nhập tầm bậy tầm bạ trên Form để tìm tất cả các câu báo lỗi bằng tiếng Anh, mở Table AccessAndJetErrors tìm ErrorCode của các câu báo lỗi đó và đưa vào trong thủ tục Form_Error.

wll
08-06-10, 08:43 AM
Câu 20:

Hỏi: Tôi muốn viết một hàm để liên kết tới CSDL là Foxpro,dBase,hoặc Access...Xin hướng dẫn

Trả lời:

Function ConnectSource(DBF As String, Tenbang As String)
Dim db As Database, tb As TableDef
Set db = CurrentDb
On Error Resume Next
DoCmd.RunSQL ("drop table " + Tenbang)
On Error GoTo 0
Set tb = db.CreateTableDef(Tenbang)
tb.Connect = ("FoxPro 2.6;Database=path")
tb.SourceTableName = DBF
db.TableDefs.Append tb
Set db = Nothing
End Function

Tương tự, nếu muốn nối tới dbase,bạn thay Foxpro bằng Dbase..

- Nếu muốn link tới một File Access có mật khẩu bạn thay dòng in đậm như sau:

tb.Connect = (";pwd=******;Database=path")

wll
08-06-10, 08:44 AM
Hỏi: Tôi có một table People trong đó có một cột full name. Trong Form tôi muốn tạo một lệnh sao cho hiện lên thông báo tất cả tên có trong cột đó, tôi phải làm như thế nào?
Đáp: Thủ tục in nội dung của một column trong table mà bạn cần ra một thông báo như sau:
Private Sub cmdFullNames_Click()
Dim rstPeople As ADODB.Recordset
Dim fldFullName As Field
Dim strFullName As String
Set rstPeople = New ADODB.Recordset
rstPeople.Open "People", CurrentProject.Connection, _
adOpenStatic, adLockOptimistic
strFullName = " =-= Full Names =-=" & vbCrLf
With rstPeople
While Not .EOF
For Each fldFullName In .Fields
If fldFullName.Name = "FullName" Then
strFullName = strFullName & fldFullName.Value & vbCrLf
End If
Next
.MoveNext
Wend
End With
MsgBox strFullName
rstPeople.Close
Set rstPeople = Nothing
End Sub

wll
08-06-10, 08:44 AM
Câu 23
Hỏi :
Các command button trong chuơng trình của tôi không đẹp lắm (H.1):

Tôi thấy trên 1 số máy khác có các command button trong đẹp hơn mà chẳng cần thêm 1 dòng code nào cả (H.2):


Tôi phải làm sao để có được các button như H.2 ?
Đáp :
Bạn mở Tools --> Options --> Tab Forms/Reports --> đánh dấu chọn check box Use Windows Themed Controls On Forms

Hoặc tổng quát hơn : Ở sự kiện open của Form Startup bạn thêm dòng lệnh :

Private Sub Form_Open(Cancel As Integer)
Application.SetOption "Themed Form Controls", True
End Sub

wll
08-06-10, 08:45 AM
Câu 24:

Hỏi:

Tôi đã xây dựng xong CT nhân sự (C:\QLNS.mdb). Tôi tạo 1 custom menu bar, giấu đi Main menu của Access, tạo form startup, disable phím Shift để không ai có thể mở được cửa sổ database. Sau một thời gian CT bị lỗi nhưng hỡi ơi tôi lại quên viết code enable phím Shift nên không tài nào mở của sổ database, mở cửa sổ viết code để sửa lại CT. Tôi phải làm sao đây ?

Đáp:

Rất đơn giản, bạn tạo 1 file .mdb mới , viết code để can thiệp vào file QLNS.mdb, enable phím Shift.

Cách làm:

Trong file .mdb mới, bạn tạo 1 form, tạo 1 command button và :

Private Sub EnableSHIFTButton_Click()

On Error GoTo ErrHandler

Dim db As Database
Dim ThuocTinh As Property

Set db = OpenDatabase("C:\QLNS.mdb")
db.Properties("AllowBypassKey") = True
Set db = 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
End If
End Sub

wll
08-06-10, 08:45 AM
Câu 25: Tôi lỡ xóa một table dữ liệu trong access làm sao có thể phục hồi lại được?

Trả lời: Ý tưởng đặt ra là ta sẽ tìm lại table bi xóa trong những file ~templete (được tạo ra khi access dang chạy). Bạn tạo một command button phuchoi gọi lệnh UndeleteTable () như sau nhé:

Private sub phuchoi_click ()

Call UnDeleteTable ()

End sub

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

Option Compare Database

Function UnDeleteTable(Optional sName As String)

Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim sTable As String
Dim sSQL As String
Dim sMsg As String

If IsMissing(sName) Then sName = "Tablephuchoi"
If Len(sName) = 0 Then sName = "Tablephuhoi"

Set db = CurrentDb()

For Each tdf In db.TableDefs
If left(tdf.Name, 4) = "~tmp" Then
sTable = tdf.Name
sSQL = "SELECT [" & sTable & "].* INTO " & sName
sSQL = sSQL & " FROM [" & sTable & "];"

db.Execute sSQL

sMsg = "Da phuc hoi xong mot Tablle bi xoa voi ten " & sName
MsgBox sMsg, vbOKOnly, "Da phuc hoi xong"
GoTo Exit_Undelete
End If
Next

' Neu khong tim thay thi thong bao
MsgBox "Khong tim thay Table nao co the phuc hoi", vbOKOnly, "Xin loi!"

Exit_Undelete:
Set db = Nothing
Exit Function

Err_Undelete:
MsgBox err.Description
Resume Exit_Undelete

End Function

wll
08-06-10, 08:46 AM
Câu 26: Tôi muốn tạo một đường viền cho report giống như boder style của word khi in mà kô phải mất công kẻ bằng tay được ko?

Trả lời: Có hai cách để làm việc này.

Cách một: Chép đoạn mã sau vào report cần

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
'goi Drawline procedure
DrawLine
End Sub
-----------------------------------------------------------------------
Sub DrawLine()
Dim rpt As Report, lngColor As Long
Dim sngTop As Single, sngLeft As Single
Dim sngWidth As Single, sngHeight As Single
Set rpt = Reports!EmployeeReport
' thiet lap loai pixels.
rpt.ScaleMode = 3
' Top
sngTop = rpt.ScaleTop + 5
' Left
sngLeft = rpt.ScaleLeft + 5
' Width
sngWidth = rpt.ScaleWidth - 10
' Height
sngHeight = rpt.ScaleHeight - 10
' mau sac: Do
lngColor = RGB(255,0,0)
' Draw line as a box.
rpt.Line(sngTop, sngLeft) - (sngWidth, sngHeight), lngColor, B
End Sub
Cách 2: lại code

Private Sub Report_Page()
On Error Resume Next
Me.DrawWidth = 6 ' do rong duong line
Me.DrawStyle = 0 ' 0 den 6 => kieu duong mat dan
' Sử dụng công thức object.Line (x1, y1) - (x2,y2), color, [Box=B]
Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), vbred, B
End Sub

wll
08-06-10, 08:47 AM
Câu 27
Hỏi: Em có thấy ở chương trình FAST họ thiết kế nhập liệu rất hay , mà họ viết băng Visual fox không biết ở access mình có thể làm được như vậy không ? Nếu mà được thì thật tuyệt.

Khi vào chức năng nhập dữ liệu họ brow cho ta xem toàn bộ danh sách của dũ liệu sau đó gán các phím F5= Thêm mới, F4= Sửa, F8=Xóa, F7=Tìm kiếm, F9=In ấn
Nếu muốn thêm một bản ghi mới thì bấm phím F5, chương trình sẽ mở ra form nhập dữ liệu, khi ta nhập xong dữ liệu nếu bấm Save thì nó sẽ về danh sách và có luôn bản ghi mới nhập, việc sửa, xóa cũng thực hiện như vậy. Không biết trong access có làm được như vậy không nhỉ ?
Đáp:.
Cái này trong sự kiện keydown của form, bạn chặn các phím bằng case, nếu là phím nào thì cho thực thi đoạn code đó, cái đó cũng đơn giản thôi! Hoàn toàn có thể làn được

Ví dụ:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case "8"
MsgBox "Backspace Keyis " & KeyCode

Case "9"
MsgBox "Tap Key is " & KeyCode

Case "12"
MsgBox "Clear Key is " & KeyCode

Case "13"
MsgBox "Enter Key is " & KeyCode

Case "16"
MsgBox "Shift Key is " & KeyCode

Case "17"
MsgBox "Control Key is " & KeyCode

Case "27"
MsgBox "Esc Key is " & KeyCode

Case "32"
MsgBox "SpaceBar Key is " & KeyCode

Case "112"
MsgBox "F1 Key is " & KeyCode

Case "113"
MsgBox "F2 Key is " & KeyCode

Case "114"
MsgBox "F3 Key is " & KeyCode

Case "115"
MsgBox "F4 Key is " & KeyCode

Case "116"
MsgBox "F5 Key is " & KeyCode

Case "117"
MsgBox "F6 Key is " & KeyCode

Case "118"
MsgBox "F7 Key is " & KeyCode

Case "119"
MsgBox "F8 Key is " & KeyCode

Case "120"
MsgBox "F9 Key is " & KeyCode

Case "121"
MsgBox "F10 Key is " & KeyCode

Case "122"
MsgBox "F11 Key is " & KeyCode

Case "123"
MsgBox "F12 Key is " & KeyCode

Case Else
MsgBox "you is press " & KeyCode

End Select

End Sub

wll
08-06-10, 08:47 AM
Câu 28:

Hỏi: Nếu mình muốn biết được hiện máy nào (theo tên máy) đang sử dụng chương trinh Access của mình hoặc số lượng người hiện đang sử dụng chương trình của mình thì có làm được không?

Đáp:

1) Để hiển thị user và computer name log in vào chương trình bạn phải dùng ADO recordset (không dùng DAO) do vậy bạn nhớ tham chiếu đến thư viện ADO 2.x

2) Dùng 1 loại ADO recordset đặc biệt , có tên là Schema Information để lấy thông tin user và computer name log in đang sử dụng chương trình.

3) Cách làm như sau :
- Bạn tạo 1 Form (F_TrackUsers) có 1 listbox và 2 command button.
+ Listbox tên : lboConnections
Đây là unbound Listbox, lưu ý : Row Source Type : value list.
+ 1 command button tên : CmdRefresh
+ 1 command button tên : CmdClose

- Ở cửa sổ viết code, nhập các đoạn code sau :

Private Sub cmdClose_Click()
DoCmd.Close
End Sub

Private Sub cmdRefresh_Click()
ListConnections
End Sub

Private Sub Form_Load()
ListConnections
End Sub

Private Sub ListConnections()
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim strComputerName As String

Set cnn = CurrentProject.Connection
Set rst = cnn.OpenSchema(adSchemaProviderSpecific, , _
"{947bb102-5d43-11d1-bdbf-00c04fb92675}")
lboConnections.RowSource = vbNullString
lboConnections.AddItem "Computer Name;Login Name"

Do While Not rst.EOF
If rst("Connected") Then
strComputerName = rst("Computer_Name")
lboConnections.AddItem Left(strComputerName, _
InStr(strComputerName, vbNullChar) - 1) & ";" & rst("Login_Name")
End If
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set cnn = Nothing
End Sub

4) Nguyên lý : Khi bạn mở form F_TrackUsers, Sub ListConnections() sử dụng ADO record đăc biệt đã nói ở trên để lấy thông tin và hiển thị trong listbox lboConnections.

wll
08-06-10, 08:48 AM
phù, mệt quá - sao chưa thấy có cái huân chương nào nhỉ?

wll
08-06-10, 08:48 AM
Hỏi: Tôi đã lưu hình ảnh vào ổ đĩa G: ( G: là ổ đĩa mạng). Và có 1 cơ sở dữ liệu lưu đường dẫn theo dạng : tvhinh(mahang,txtpic). Bây giờ trong Report làm sao tôi có thể vẽ lại các hình tôi đã lưu!
Đáp:
Trong Report, bạn vẽ 1 textbox đặt tên là txtpic, đặt thuộc tính visible của nó là False.
Vẽ 1 đối tượng image đặt tên nó là image1
Sau đó cho đoạn code sau vào

Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
On Error GoTo err_Pic
If IsNull(Me.txtPic) Then
Me.Image1.Picture = ""
Me.Image1.Visible = False
Else
Me.Image1.Picture = txtPic.Value
Me.Image1.Visible = True
End If
Exit Sub
err_Pic:
MsgBox Err.Description, vbOKOnly
Exit Sub
End Sub

wll
08-06-10, 08:49 AM
Câu 30: Hỏi: Tôi muốn lấy địa chỉ tập tin file *.mdb (*.mde) để sử dụng như một tham số vào vấn đề khác. Làm sao lấy được địa chỉ một cách tự động khi tập tin cứ luôn bị người dùng thay đổi?

Trả lời: Bạn tạo một hàm GetappPath() trong module với tham số là GetappPath để có thể sử dụng vào mục đích khác. Nội dung như sau:

Function GetAppPath() As String
On Error Resume Next

Dim DBName As String
Dim DBPath As String
Dim intCurrVal As Integer
Dim intLastPosition As Integer

DBName = CurrentDb.Name

intCurrVal = InStr(DBName, "\")
Do Until intCurrVal = 0
intLastPosition = intCurrVal
intCurrVal = InStr(intLastPosition + 1, DBName, "\")
Loop

DBPath = left(DBName, intLastPosition)
GetAppPath = DBPath

End Function


Nếu cần bạn có thể thêm hàm Msgbox() để thông báo đường dẫn hiện tại của tập tin mà ko phu thuộc vào sự thay đổi vị trí tập tin, tức là tham số GetAppPath cũng thay đổi theo sự thay đổi địa chỉ do người dùng.

MsgBox "Duong dan hien tai cua file nay la " & GetAppPath, vbOKOnly, "Thong bao"

wll
08-06-10, 08:57 AM
Tính số ngày sử dụng chương trình
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

Trả lời
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

wll
08-06-10, 08:58 AM
Msgbox dùng Unicode Tiếng việt
Gần đây 1 số bạn ở các forum hay hỏi làm cách nào để hiện câu thông báo kiểu msgbox bằng tiếng Việt.
Có 1 số bạn hướng dẫn theo nhiều cách, tuy nhiên mình thấy vẫn chưa hợp lý:
- Cách 1: chỉnh Regional and Language Options thành Tiếng Việt.
Cách này chưa hợp lý ở kiểu gõ và sẽ bị lỗi ở hệ thống bàn phím dùng số.
- Cách 2: thay đổi font hệ thống trong thẻ Appearance. Chuyển thành font TCVN3 hay VNI. Sau khi đóng chương trình, hệ thống sẽ trả về lại như cũ.


Cách này đáp ứng được nhu cầu gõ tếng Việt. Nhưng các ứng dụng khác của toàn windows có liên quan msgbox sẽ bị ảnh hưởng.( thường là Unicode tiếng Việt không đọc được hoặc xấu hoắc). Mặc dù đây là giải pháp được nhiều lập trình viên lựa chọn vì có thể dùng Code tự động, tuy nhiên mình đánh giá rất thấp vì nó ảnh hưởng hệ thống.
- Cách 3: gọi Code của các ký tự có dấu. Cách này hơi phức tạp mỗi khi gọi 1 thông báo.

wll
08-06-10, 08:59 AM
Hàm thay thế chuỗi trong Access
Đôi khi bạn có nhu cầu thay 1 chuỗi này bằng 1 chuỗi khác. Khi đó bạn có thể dùng hàm Replace. Cú pháp như sau:

Replace ( string1, find, replacement, [start, [count, [compare]]] )



Ví dụ:
Replace("alphabet", "bet", "hydro") would return "alphahydro"
Replace ("alphabet", "a", "e") would return "elphebet"
Replace("alphabet", "a", "e", 2) would return "lphebet"
Replace("alphabet", "a", "e", 1, 1) would return "elphabet"

wll
08-06-10, 08:59 AM
Gọi Form Chờ khi thực hiện tập lệnh !
Hỏi:Em đặt một nút command button, trong đó chạy một số câu lệnh và phải mất khoảng 5 phút.
Trong quá trình thực hiện lệnh, em muốn hiện lên màn hình dòng chữ:
" Đang thực hiện công việc, xin vui lòng chờ trong giây lát"

Đáp:
Giờ bạn thử theo cách sau nhé:

Tạo 1 form đặt tên Form: frmStatus
Title : Watting....

Trong form, vẽ 1 Label, nội dung : Đang nhập dữ liệu, xin chờ trong giây lát

Rồi set các thuộc tính như sau:



Dung nhan Form thông báo của bạn sẽ thế này:




Giờ Quay lại vấn đề chính.
Trong events click của nút thực hiện, bạn làm như sau:
Code:
Private Sub cmdThuchien_Click()
' load form frmStatus lên
DoCmd.OpenForm "frmStatus"
' chờ load xong
DoEvents
' Lệnh thực thi chương trình của bạn ở đây

' Xong rồi thì đóng Flash form lại!
DoCmd.Close acForm, "frmStatus"

wll
08-06-10, 09:00 AM
In hình ảnh khi có đường dẫn hình
Hỏi: Tôi đã lưu hình ảnh vào ổ đĩa G: ( G: là ổ đĩa mạng). Và có 1 cơ sở dữ liệu lưu đường dẫn theo dạng : tvhinh(mahang,txtpic). Bây giờ trong Report làm sao tôi có thể vẽ lại các hình tôi đã lưu!
Đáp:
Trong Report, bạn vẽ 1 textbox đặt tên là txtpic, đặt thuộc tính visible của nó là False.
Vẽ 1 đối tượng image đặt tên nó là image1
Sau đó cho đoạn code sau vào




Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
On Error GoTo err_Pic
If IsNull(Me.txtPic) Then
Me.Image1.Picture = ""
Me.Image1.Visible = False
Else
Me.Image1.Picture = txtPic.Value
Me.Image1.Visible = True
End If
Exit Sub
err_Pic:
MsgBox Err.Description, vbOKOnly
Exit Sub
End Sub

wll
08-06-10, 09:00 AM
Code Kiểm tra sự tồn tại của 1 file trong Access
' kiem tra su ton tai file

Function FileExit(fname As String) As Boolean

If Dir(fname) <> "" Then
FileExit = True
Else
FileExit = False
End If

End Function



Ví dụ: Ở sự kiện Load form của Form chính, bạn chọn cho code này vào:


If not(FileExit("\\May2\DULIEU\LUU.MDB")) then
msgbox " Phải cài file dữ liệu "
docmd.quit
End if

wll
08-06-10, 09:01 AM
Gắn một số phím tắt cho các command button
Hỏi: Tôi muốn gắn một số phím tắt cho các command button trên form để khi bấm phím tắt đó, các câu lệnh sẽ được thực hiện.( cach tao 1 autokeys trong access )


Đáp:
Bạn có thể cài shotcut key bằng cách chọn 1 ký tự trong caption của các button. Và thêm ký tự "&" trước ký tự đó. Khi bạn nhấn ALT + ký tự. Nó sẽ là shotcut key.

Ví dụ nút OK thì bạn viết : &OK

Shotcutkey sẽ là ALT+O

wll
08-06-10, 09:01 AM
Xoá các table theo điều kiện trong Access
Hỏi: Tromg file MDB của em có nhiều table để lưu dữ liệu của các năm khác nhau. EM chỉ muốn lưu 3 năm gần nhất thôi. Ví dụ: năm nay là 2009, em chỉ cần lưu dữ liệu của 2007, 2008, 2009; năm tới 2010: chỉ lưu 2008, 2009, 2010.
Em muốn tự khi lưu dữ liệu ngày đầu tiên của năm mới, thì table từ 3 năm về trước sẽ tự động bị xoá đi. Cụ thể: ngày 01/01/2010, em lưu dữ liệu thì table lưu dữ liệu của 2007 bị xoá đi.
Đồng thời, em muốn xoá table với điều kiện nó tồn tại: Cụ thể: câu lệnh để thực hiện:
Nếu tableA có trong MDB thì xoá tableA
Các bác cho em xin đoạn code nhé

Đáp:
Mình gửi bạn 1 đoạn code xóa table:
Code:
Sub DelTable(T As String)
DoCmd.DeleteObject acTable, T

End Sub
Bây giờ bạn có thể tạo 1 table với thông tin: tblTableInfo(tableName,TableDate)
Ở đây bạn khai báo table nào thuộc năm nào.
sau đó có thể gọi 1 sub xóa table cũ hơn 3 năm:
Code:
sub DelTable3yearOld()
Dim Db As Database, Rs As Recordset, sql1 as string
SQL1="select TableName from tblTableInfo where (year(date())-year(TableDate))>=3
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset(SQL)
Do Until rs.EOF
Deltable rs(0)
rs.MoveNext
Loop

Rs.Close
set DB = Nothing
End Sub

wll
08-06-10, 09:02 AM
Export dữ liệu ra excel
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

wll
08-06-10, 09:03 AM
Tính Toán thời gian giữa hai thời điểm với dateiff
Đôi khi bạn có nhu cầu tính số ngày, số tháng, số quý giữa hai thời kỳ nhằm phục vụ báo cáo.Cụ thể tính tiền trợ cấp hoặc bảo hiểm xã hội!
Mình xin giới thiệu hàm: DateIff( loại, từ ngày, đến ngày)
bạn dùng hàm datediff("d", date1, date2) để tính số ngày
bạn dùng hàm datediff("m", date1, date2) để tính số tháng
bạn dùng hàm datediff("q", date1, date2) để tính số quý ....

Loại ta có:
yyyy Year
q Quarter
m Month
y Day of year
d Day
w Weekday
ww Week
h Hour
n Minute
s Second

sau khi tính duoc số tháng ban dùng dấu chia ngược "\" hoặc dùng hàm roud() kết hợp với lệnh mod để tính ra số năm và số tháng


ví dụ: trên báo cáo BHXH thời gian đóng BHXH cua Nhân viên A là ngày 15 tháng 01 năm 1980 đến ngày 15 tháng 6 năm 1982 là 2 năm 5 tháng ban làm như sau:

datediff("m",#01/15/1980#,#06/15/1982#) --> cho kết quả 29
hoặc
datediff("m", dateserial(1980,01,15), dateserial(1982,06,15)) --> cho kết quả 29

để tìm ra số năm ta có thể lấy 29\12 = 2 hoặc round(29/12,0) = 2
để tinh số tháng ta lấy 29 mod 12 = 5

wll
08-06-10, 09:03 AM
Tự động liên kết các table
Tôi có một cơ sở dữ liệu Access và thực hiện split thành backend

File QLVB đặt trong thư mục Run (thư mục Run nằm trong thư mục QLVB) chứa form, repost, ...
File QLVB_en đặt trong thư mục Data (thư mục Data trong thư mục QLVB) chứa các table


Khi tôi di chuyển (hoặc đồng bộ) thư mục QLVB (từ USB vào máy và ngược lại) là các liên kết của các table không còn nữa.
Bạn nào rành về Access có thể viết đoạn mã giúp tôi tự động nối lại các liên kết đó không.


Đáp:

Với T là tên table, Bạn cho gọi đoạn code sau để link. Có bao nhiêu table thì bạn gọi bấy nhiêu lần với tên table T tương ứng.
Code:
Sub LinkTable(T As String)
' xoa table link cu~
DoCmd.DeleteObject acTable, T
'link lai tablelink moi
DoCmd.TransferDatabase acLink, "Microsoft Access", CurrentProject.Path & "\" & "QLVB_en.mdb", acTable, T, T
End Sub
.

Chú ý, đạon code này chỉ áp dụng trong trường hợp file chương trình và dữ liệu bạn chung 1 thư mục. Còn khác thư mục thì mình sẽ đưa giải pháp khác. Ví dụ bạn phải khai báo thư mục chứa dữ liệu.
Không in số 0 trong report
Khi in 1 trường bằng số thì format #,### sẽ không in nếu dữ liệu bằng 0.
- format : #,###.## : 0 không in ra nhưng 300.00 thì in ra 300. (có 2 khoản trắng phía sau)
- format #,###.00 : 0 thì in ra 0.00; 300.15 in ra 300.15 (đúng)

Mình muốn format trường số với 2 số lẻ (ví dụ trường Ngoại tệ USD) khi dữ liệu bằng 0 sẽ không in ra nếu có dữ liệu thì sẽ in ra với 2 số lẻ:

Trong phần Detail_Format của report, bạn nhập code như sau:
Code:
If Soluongtxt.Value = 0 Then
Soluongtxt.DecimalPlaces = 0
Else
Soluongtxt.DecimalPlaces = 2
End If
soluongtxt là field bạn cần format!

wll
08-06-10, 09:04 AM
Cách chuyển số sang tỷ lệ phần trăm
Bình thường trong excel khi chia hai số cho nhau ta được số thập phân ví dụ 2/3=0.66666. Nếu ta Format lại ra dạng phần trăm thì có thể ra 66.6666%. Vậy trong Access có thể format như vậy được không?

bạn dùng hàm format(number, kiểu format) thử xem.
Ví dụ trong trường hợp của bạn, bạn gọi như sau:

Format(0.25,"Percent") ==>kết quả sẽ cho ra : 25.00%
Trích:
Trả lời
=(Q1/Q2)*100 & "%"

wll
08-06-10, 09:05 AM
Sử dụng Unicode tiếng Việt trong MS Access



Trong Access 2K trở lên chạy trên Windows XP/2K, không cần phải thay thế font hệ thống bằng các font TCVN, VNI, Vietware..., bạn vẫn có thể sử dụng font Unicode tiếng Việt trong các thành phần từ khi lập trình cho đến khi sử dụng: ô nhập liệu, tiêu đề trên form, menu, toolbar... Quan trọng nhất, bạn có thể viết code sử dụng font Unicode để tạo các message box hiển thị tiếng Việt. Điểm mấu chốt là khi tạo các form, report, menubar, toolbar, bạn sử dụng font Unicode dựng sẵn, nhưng khi lập trình (viết code) bạn dùng font Unicode tổ hợp. Lưu ý: khi viết code nhớ chọn font có chữ Vietnamese ở đằng sau, ví dụ font Times New Roman (Vietnamese).

Cài đặt hệ điều hành 2K/XP

Vào Control panel->Regional and Language Options. Trong bảng này có 3 tab:

+ Tab Regional options (gọi là Tab 1)

+ Tab Languages (gọi là Tab 2)

+ Tab Advanced (gọi là Tab 3)

- Đầu tiên bạn vào Tab 2, đánh dấu chọn "Install files for complex script and right-to-left languages (including Thai)" (nếu chưa chọn). Có thể chương trình yêu cầu bạn đưa vào đĩa cài đặt WinXP(2K). Lưu ý: không nên dùng các đĩa cài đặt XP đã được chỉnh sửa như Wesmosiss WinXP,...

- Chọn OK và khởi động lại máy.

- Vào lại Tab 1, chọn Vietnamese.

- Vào Tab 3, chọn Vietnamese.

- Chọn OK và khởi động lại máy.

Cài đặt MS Office

Sau khi đã cài đặt MS Office, bạn vào Start -> Programs -> Microsoft Office Tools -> Microsoft Office Language Settings, chọn ngôn ngữ mặc định là Vietname

wll
08-06-10, 09:06 AM
admin cho cái bình chọn đi admin ơi

lansongso
15-07-10, 13:12 PM
Thầy ơi!
Dùng Macro có thể khai thác tốt CSDL được Access không ạ. Tôi chỉ thực thi một số lệnh cơ bản: Xuất báo lỗi, thêm xóa tới lùi,in ấn,... bằng Macro. Nếu ứng dụng nâng cao hơn thì phải viết bằng VBA đúng không ạ? Vì Tôi chưa làm quen được với cách viết COD.

tuyetnga094
29-08-10, 00:07 AM
hỏi về access cách gán giá trị trị ô textbox của subform lên trị ô textbox của mainform thông qua nút lệnh control
đề bài yêu cầu gán trị ô tongcong của subform vào trị ô trigia của mainform sau khi nhấn nút control Lưu, điều kiện là tổng cộng = soluong*dongia
tôi đã dùng macro trên nút lệnh lưu setvalue, mục item là trigia, mục expression là forms![tên subform].[tongcong] nhưng không được máy báo là k thể phân tích được dữ liệu và không tìm thấy soluong
rất tiếc là không tìm thấy mục gửi file đính kèm để nhờ các thầy cô và các anh chị chỉ giáo
cám ơn rất nhiều ạ

baoquockt
18-10-10, 20:12 PM
Form in bảng lương có 2 textbox, một nút in để mở Report

yêu cầu trong form in bảng lương:
Nếu chọn tháng và năm thì in bảng lương tháng
Nếu chọn năm, không chọn tháng thì in bảng lương năm.
Không chọn gì cả thì chương trình báo lỗi.

Yêu cầu:
Không sử dụng Macros, viết trong code.

tayninhvdb
26-11-10, 14:02 PM
Cám ơn những bài viết của thầy, nó rất hay và bổ ích. Thầy cho hỏi một vấn đề sau. Em có 1 form HocSinh có 1 combobox thể hiện những học sinh trong một lớp. Khi em mở Form này giả sử chỉ có 4 học sinh là A, B, C, D thì trong combobox này chỉ có 4 học sinh. Lúc này em mở 1 Form thêm mới học sinh và thêm vào học sinh E thì có cách nào ko cần thoát khỏi Form HocSinh mà trong combobox vẫn xuất hiện học sinh E không thầy?

doibac2004
29-11-10, 11:20 AM
cách này không khả quan cho lắm, tại sao không làm tìm kiếm trong combox theo mchữ cái hoặc cụm từ nhỉ

cotlaicoco6
20-12-10, 18:30 PM
bài tốt nghiệp của tui là:
"CÁC PHÍM TẮT TRONG ACCESS"
TỐI THIỂU LÀ 10 TRANG WORD
NHƯNG TUI KO BIẾT LÀM SAO CẢ.GIÚP TUI VỚI
NẾU KO TUI CHẾT MẤT.

cuongTHPTLN
28-12-10, 10:15 AM
làm thế nào để xem được các câu lệnh thường dùng trong query
Hãy giúp tôi với

coplepro
11-12-11, 23:15 PM
Cam on Thay!

coho
08-04-13, 10:35 AM
Hỏi: Tôi có 1 chương trình access có sử dụng subform trên subform này sử dụng biến cố AfterUpdate dùng hàm Dlookup nhưng chương trình báo lổi. Xin cho cho hỏi trên subform có sử dụng được ham dlookup không ?
Xin cảm ơn!