Thứ Ba, 29 tháng 12, 2009

Thuộc tính Startup MS Access toàn tập với VBA

Xin chào các tín đồ Access. Có lẽ nhiều người biết các ngăn chặn vọc phá cũng như tùy biến thuộc tính startup Access bằng cách vào Tool--> Startup.
Tuy nhiên, không phải bao giờ điều đó cũng làm các bạn hài lòng, và chúng ta luôn luôn muốn hơn nữa với VBA.Sau đây, mình xin giới thiệu các lệnh sửa thuộc tính trong VBA. Có lẽ vài bạn đã từng thử với việc Disable phím shift. Nhưng trong phạm vi bài viết này, mình sẽ nêu đầy đủ hơn về các thuộc tính đó.Để thuận tiện hơn trong việc thay đổi thuộc tính, bạn nên tạo 1 module và  copy hàm sau:


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 có thuộc tính đó
  ChangeProperty = False
  Resume Change_KetThuc
  End If
End Function
Và dưới đây là tập hợp các thuộc tính trong (ngoài) form Startup mà bạn có thể gọi bất cứ đâu. Sau khi gọi, nó sẽ có hiệu lực từ lần mở chương trình kế tiếp:
Sub SercurityDB(locker As Boolean)
' Gọi đoạn module này ở form lock hay chỗ nào bạn thích.
'SecurityDB True ( False)
' Thuộc tính nào không cần dùng, abn5 chỉ việc cho dấu nháy (') đằng trước là được
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Đổi tên Tiêu đề ứng dụng
  ChangeProperty "Apptitle", dbText," Tên Tiêu Đề"
' Đặt lại Form gọi khi mở chương trình
  ChangeProperty "StartupForm", dbText, "MainForm"
' Cho nhìn thấy Khung Database hay không
  ChangeProperty "StartupShowDBWindow", dbBoolean, locker
'Cho nhìn thấy thanh Status hay không
  ChangeProperty "StartupShowStatusBar", dbBoolean, True
' Cho phép hiển thị thanh  design hay không
  ChangeProperty "AllowBuiltinToolbars", dbBoolean, locker
' Cho phép thêm bớt 1 item vào các thanh công cụ hay không
  ChangeProperty "AllowToolbarChanges", dbBoolean, locker
' Cho phép hiện thanh bar khi nhấn chuột phải hay không
  ChangeProperty "AllowShortcutMenus", dbBoolean, locker
  ' Cho phép hiện toàn bộ thanh menu hay không
  ChangeProperty "AllowFullMenus", dbBoolean, locker
'Cho phép ngừng chương trình lại bằng phím Ctrl+ Break khi đang run hay không
  ChangeProperty "AllowBreakIntoCode", dbBoolean, locker
' Vô hiệu hóa phím đặc biệt như F11
  ChangeProperty "AllowSpecialKeys", dbBoolean, locker
' Vô hiệu hóa phím shift
  ChangeProperty "AllowBypassKey", dbBoolean, locker
'Cho phép design/ sửa thuộc tính form/ report khi đang mở hay không.
  ChangeProperty "AllowDesignChanges", dbBoolean, locker
' Set lại đường dẫn Icon cùng với nơi lưu chương trình
 ChangeProperty "AppIcon", dbText, Access.CurrentProject.Path & "Icon1.ico"
  ' Gắn lại tên menubar tự tạo:
Application.MenuBar = "My menubar"
'Gắn lại tên shotcuts menubar ( tạo bằng macro)
Application.ShotcutMenuBar = "My ShotCut Menubar"
End Sub
 Các đoạn mình tô màu xanh đậm, các bạn có thể thay đổi cho phù hợp với chương trình của bạn.
Các thuộc tính không cần thay đổi, bạn có thể xóa bỏ hoặc đặt dấu nháy đơn (') đằng trước.

Thứ Hai, 28 tháng 12, 2009

So sánh - tổng hợp 2 table với Union

Hỏi:Mình hiện nay có 2 table A và table B :
Giờ mình muốn lọc bằng lệnh SQL hoặc query :
điều kiện
1_những record nào trùng file mahang và tenhang trùng giữa 2 table A và B .
2_Lọc ra những record không trùng giữa 2 table A và B .
3 -Làm thế nào để Hợp nhất hai table A và B: lấy tất cả những record trùng và không trùng của 2 table (các record trùng nhau sẽ thành 1 record)
Đáp: Ví dụ bạn có 2 table
tableA có các mahang: 001, 002, 003.
TableB có các mahang: 001, 004, 005.

 1_những record nào trùng file mahang và tenhang trùng giữa 2 table A và B .
SELECT ArticleNo FROM TableA WHERE ArticleNo In (select ArticleNo from TableB)
Union
SELECT ArticleNo FROM TableB WHERE ArticleNo In (select ArticleNo from TableA)
kết quả ví dụ tabletonghop có mã: 001
2_Lọc ra những record không trùng giữa 2 table A và B .
[CODE]SELECT ArticleNo FROM TableA WHERE ArticleNo Not In (select ArticleNo from TableB)
Union
SELECT ArticleNo FROM TableB WHERE ArticleNo Not In (select ArticleNo from TableA);
 kết quả ví dụ: 002,003,004,005
3/ -Làm thế nào để Hợp nhất hai table A và B: lấy tất cả những record trùng và không trùng của 2 table (các record trùng nhau sẽ thành 1 record)
SELECT ArticleNo FROM TableA
Union
SELECT ArticleNo FROM TableB ;
kết quả ví dụ: 001,002,003,004,005
4/ Làm thế nào lấy tổng hợp tất cả các record không quan tâm chúng có trùng mã hay không?
SELECT ArticleNo FROM TableA
Union All
SELECT ArticleNo FROM TableB ;
 kết quả ví dụ: 001,001,002,003,004,005

Đồng Bộ hai table

Hỏi: Tôi có 2 table có cấu trúc gần giống nhau. Tuy nhiên có khác biệt 1 ít về dữ liệu. Xin hướng dẫn đồng bộ table1 sang table 2.
Ví dụ: table1( Maso, ten). Table2(maso, ten, diachi, ...)
Tôi muốn
1/Thêm maso,ten từ table 1 sang table nếu trong table 2 thiếu.
2/Update lại tên nếu cùng 1 mã số nhưng tên table1 khác trong table 2
3/ xóa những recode trong table2 không có mã trong table1

Đáp run các query sau:

1/Thêm maso,ten từ table 1 sang table nếu trong table 2 thiếu
INSERT INTO Table2 ( Maso, TEN )
SELECT Table1.Maso, Table1.Ten
FROM Table1
WHERE (((Table1.Maso) Not In (select maso from table2)));[/code]
2/Update lại tên nếu cùng 1 mã số nhưng tên table1 khác trong table 2
UPDATE Table1 INNER JOIN Table2 ON Table1.Maso = Table2.Maso SET Table2.TEN = table1.ten
WHERE (((Table2.TEN)<>[table1].[ten]));
3/ xóa những recode trong table2 không có mã trong table1
DELETE Table2.*
FROM Table2
WHERE (((Table2.Maso) Not In (select maso from table1)));
DownLoaddemo

Lập Hàm có lượng tham số thay đổi

Hỏi: Bạn HaQuocQuan có hỏi làm sao tạo một hàm có số lượng tham số tùy ý.
Đáp: Điển hình của các hàm có tham số tùy ý ta có thể thấy ở Excel, nó thường ở dạng
Hàm( mảng các tham số, hằng số 1, hằng số 2...)

Với hằng số để cho ta biết trong trường hợp nào thì trả về giá trị nào.
Dưới đây, mình xin tạo 1 hàm có số tham số thay đổi tương tự hàm sum của Excel

Function SumC(A As Variant)
Dim tong
   tong = 0
   For Each I In A
   tong = tong + I
   Next I
   SumC = tong
End Function
 Và bây giờ ta có thể gọi hàm sum như sau:
Private Sub Command7_Click()
   MsgBox "Tong cua 10,20,50,60 la " & SumC(Array(10,20,50,60))
End Sub

Kết quả hiện lên 1 messenge: 170

Thứ Ba, 22 tháng 12, 2009

Phân quyền truy cập menu trong Access


Mình đã giới thiệu với các bạn chương trình phân quyền
thiet-ke-ctrinh-phan-quyen
Mình cũng giới thiệu các bạn cách bạn cách tạo 1 thanh menu
huong-dan-tao-menu-trong-access.html
Hôm nay mình xin giới thiệu cách để hiển thị 1 menu với user này và ẩn với user khác.


Ta hãy mở 1 module và soạn thủ tục sau:
Sub ViewMenu(User as String, mnBar as string, mnItem as String, IsView as Boolean)

If currUser= User Then
CommandBars(mnBar).Controls(mnItem).Visible = isView
End If
End Sub
Thủ tục trên cho ta hiện 1 menu với
User : user muốn cho phép xem
CurrUser: User hiện tại đăng nhập vào hệ thống. ( bạn có thể gán 1 biến toàn cục, mỗi khi có người đăng nhập thành công, thì gán : CurrUser bằng UserName)
 mnBar: tên thanh menu do bạn tự tạo
mnItem : tên menu (caption) do bạn tạo và gắn trên thanh Menu

Ví dụ:
Trong bài đăng về tạo menu http://thuthuataccess.blogspot.com/2009/12/huong-dan-tao-menu-trong-access.html

Bạn tạo 1 thanh menu "QuanLyCongVan" với 2 Item là : "Cập Nhật", và "Thoát".Bây giờ bạn muốn chỉ hiện menu "Cập Nhật" cho User, và Admin. ( nhóm guest không được thấy) ta gọi sau khi người dùng đăng nhập thành công:

ViewMenu "User", "QuanLyCongVan", "Cập Nhật", True
ViewMenu "Admin", "QuanLyCongVan", "Cập Nhật", True
ViewMenu "Guest", "QuanLyCongVan", "Cập Nhật", False

Chủ Nhật, 20 tháng 12, 2009

Tạo số phiếu tăng theo mẫu : date+STT

 Hôm trước mình giới thiệu thủ thuật tạo số phiếu tăng tự động theo đoạn code của anh phatnq2002  trang Dân Kế Toán
Tạo số chứng từ tăng dần và reset mỗi tháng

Hôm nay, mình giới thiệu đoạn code tạo số chứng từ tăng dần theo mẫu dạng: dd/mm/yy + số TT
Để số thứ tự tự động tăng dần để trường STT là Text. Đồng thời ta thêm 1 trường couter kiểu Number - Integer để đếm số phiếu trong ngày. Trường này sẽ tăng khi bạn nhập phiếu mới với giá trị = max giá trị ngày đó.
Trường STT của bạn sẽ được set giá trị = Date & "-" & format(Couter,"000")

* Chú ý: để biết 1 record có phải được thêm mới hay không, bạn xét ở sự kiện Form_Current() của form. Nếu STT của bạn là null thì nó là record mới.
Private Sub Form_Current()
'Kiểm Tra số thứ tự, nếu Null thì đó là recodr mới
If IsNull(Me.STT) Then
STT.Value = SoTT
End If
End Sub

Function SoTT() As String
Dim so As Integer
so = Nz(DMax("[Couter]", "BangChi", "[Date]= date()"))
Couter.Value = so + 1
SoTT = Date & "-" & Format(Couter, "000")
End Function
 Mời các bạn xem demo về xem:
DownLoad

Thứ Bảy, 19 tháng 12, 2009

Tính ngày làm việc thực tế giữa khoảng thời gian

Rất nhiều nhà quản lý kế hoạch ( planning) muốn tính ngày làm việc thực tế giữa hai khoảng thời gian.
Dưới đây mình xin giới thiệu đoạn code tính ngày làm việc thực tế. Trừ thứ 7 và chủ nhật. Mời các bạn tham khảo.


Function CalcWorkdays(StartDate, EndDate) As Integer
    Dim LTotalDays As Integer
    Dim LSaturdays As Integer
    Dim LSundays As Integer
    On Error GoTo Err_Execute
    CalcWorkdays = 0
    If IsDate(StartDate) And IsDate(EndDate) Then
        If EndDate <= StartDate Then
            CalcWorkdays = 0
        Else
            LTotalDays = DateDiff("d", StartDate - 1, EndDate)
            LSaturdays = DateDiff("ww", StartDate - 1, EndDate, 7)
            LSundays = DateDiff("ww", StartDate - 1, EndDate, 1)
            'Workdays is the elapsed days excluding Saturdays and Sundays
            CalcWorkdays = LTotalDays - LSaturdays - LSundays
        End If
    End If
    Exit Function
Err_Execute:
    'If error occurs, return 0
    CalcWorkdays = 0
End Function
Chú ý:
1/Nếu chúng ta làm luôn thứ bảy thì thay thế:
CalcWorkdays = LTotalDays - LSaturdays - LSundays
Thành:
CalcWorkdays = LTotalDays -LSundays
 2/ Phạm vi hàm này không bao gồm ngày lễ. Lẽ ra mình có thể thiết kế tính luôn ngày lễ nếu như chúng ta không có nghỉ tết âm lịch và giỗ tổ Hùng Vương. Mình sẽ bổ sung nếu tìm thấy module chuyển ngày dương thành âm lịch!

Thân mến!

Thứ Sáu, 18 tháng 12, 2009

Không tạo được ActiveX trong Access

 Hỏi: Em có tạo một sổ địa chỉ lấy dữ liệu từ tập tin MDB. Khi chạy chương trình trên máy nhà em thì bình thường nhưng khi chạy trên máy khác thì không được và có thông báo lỗi "Run-time error '429': Active X component can't create object". Thông báo này là sao, xin chỉ cho em cách khắc phục.

Trả lời: Khi sử dụng Access, thông báo lỗi "ActiveX component can't create object" xảy ra có thể do một hay nhiều nguyên nhân:
- Thư viện DAO 3.6 không được đăng ký thích hợp. Cách giải quyết: Trên Windows, chọn Start > Run và gõ dòng lệnh (tùy theo máy, đường dẫn có thể khác):
regsvr32 "C:\Program Files\Common Files\Microsoft Shared\DAO\DAO360.DLL"
- Thiếu một hay nhiều References. Cách giải quyết: Mở database đã gặp lỗi này, nhấn ALT+F11 để mở Microsoft Visual Basic Editor, chọn Tools > References, kiểm tra thư viện nào cần có nhưng chưa được đánh dấu chọn thì đánh dấu chọn vào checkbox bên cạnh. Thường thì Microsoft DAO 3.6 Object Library là thư viện cần có.
- Có một tham chiếu không hợp lệ đến Utility Database. Cách giải quyết: Mở database đã gặp lỗi này, nhấn ALT+F11 để mở Microsoft Visual Basic Editor, chọn Tools > References, xóa đánh dấu chọn ở bất kỳ tham chiếu nào đến Utility Database hoặc Utility.MDA.
- Không có quyền truy cập đến các thư viện cần thiết. Cách giải quyết: Phải bảo đảm các user có quyển “read” đối với tất cả các tập tin trong thư mục:
\Windows\System32 (nếu là Windows XP) hoặc \Winnt\System32 (nếu là Windows NT, 2000) hoặc \Windows\System (nếu là Windows 95, 98, Me).
- Có một tập tin wizard gặp nguy hiểm. Cách giải quyết: Sử dụng Windows Explorer để tìm các tập tin wizard sau: Acwzmain.mde, Acwztool.mde và Acwzlib.mde, đổi phần đuôi tên tập tin của mỗi tập tin thành .old, dùng Add or Remove Programs của Control Panel để Reinstall or Repair Office (trong đó chọn Access) nhằm khôi phục các tập tin này.
CHƯƠNG CAN CHÍP (echip)

Thứ Ba, 15 tháng 12, 2009

Kiểm tra sự tồn tại của Fields trong table

Hỏi : tôi có 1 table là: tblHOSO; tôi muốn dùng code để kiểm tra xem trong tblHOSO có field KIEMTRA không?


Đáp: Bạn chép Function sau:

Function DoesFieldExist (tableName As String, fieldName As String) As Boolean
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim i As Integer

Set db = CurrentDb
Set tdf = db.TableDefs(tableName)

For i = 0 To tdf.Fields.Count - 1

If fieldName = tdf.Fields(i).Name Then
DoesFieldExist = True
Exit Function
End If
Next
End Function
Giờ bạn có thể gọi

If DoesFieldExist("tblHoso","KiemTra") then
Msgbox " Co Field ton tai trong table"
Else
Msgbox " khong co field ton tai trong table"
End If
Theo Spammail-KHPT.net

Lỗi khi Chuyển từ File mdb thành mde

Gần đâydo nhu cầu bảo mật chống sửa form/ Report , chống luc lọi trong các đoan code cũng như cải thiện tốc độ chương trình do VBA đã được biên dịch. Một số bạn đã chuyển ứng dụng Access của mình thành file *. mde nhưng vướng lỗi. Sau đây, mình xin thống kê và cách xử lý.


Cách chuyển:
Vào menu Tool -->Database Utility--> make MDE file...

 Lỗi 1: Lỗi thường gặp phải là do bạn đang dùng phiên bản Access cũ hơn. Bạn phải dùng phiên bản Access đó để chuyển hoặc convert file MDB sang phiên bản Access hiện hành.
Cách Convert. Vào Tool--> Database Utilities -> Convert Database --> To Access 2002 2003 Database ( hoặc mới hơn)
Sau khi thành công, nó sẽ tạo cho bạn 1 file MDB mới có phiên bản. Bạn vào file này để tiến hành make sang file *.MDE

Lỗi 2: Hệ Thống báo như sau
"This error is usually associated with compiling a large database into an MDE file.  Due to the method used to compile the database, a considerable number of TableID references are created for each table.  The Microsoft Jet database engine version 4.0 can only create a maximum of 2048 open TableIDs at one time.  Exporting a database as an MDE potentially can exceed this limit if the database has a large number of objects (table, macro, form, report, etc).
There is no accurate method to estimate the number of TableIDs the Jet database engine uses during the process of compiling a database as an MDE.  However, each VBA module and each form uses one TableID, as a result, if the database has 500 forms, and each form's HasModule property is set to Yes, as many as 1,000 TableIDs are used."

Thường lỗi này do có 1 số đoạn code bạn dùng wizard tạo ra. ( ví dụ event Click của các nút nhấn). Sau đó bạn đổi tên đối tượng nên các code này trở nên  "vô thừa nhận" và thông báo lỗi trên.
Giải pháp tốt  là bạn nhấn Alt + F11, nhảy ra khung soạn VBA. Trong khung soạn, bạn vào Debug--> Compiler. Nó sẽ nhảy đến đoạn code bị thừa đó và bạn xóa đi.

Nếu vẫn không được. Bạn tạo file MDB trống và tiến hành import tất cả qua. Thực hiện lại!

Thứ Hai, 14 tháng 12, 2009

Tạo số chứng từ tăng và reset khi sang tháng khác

Hỏi: Tôi muốn chứng từ phát sinh trong tháng thì tăng tự động, qua tháng tính lại từ đầu.

Đáp:

Dim so
so = DMax("SOCT", "table", "Year(ngayhachtoan) = " & Year(Date()) & " AND Month(ngayhachtoan) = " & Month(Date()))
If Nz(so, 0) = 0 Then
soct = "0001"
Else
soct = Right("000" & CInt(so) + 1, 4)
End If


Trả lời của phatnq2002  trang Dân Kế Toán

Thiết kế textbox, command ...sao cho đẹp

Hỏi: Một số form mình thiết kế các textbox, command, combobox theo hình thức thủ công, mặc dù mình đã O kỹ rồi nhưng thấy cũng chưa hài lòng lắm.
Các bạn làm ơn chỉ mình cách làm sao để: canh đều trái phải; kích thước dài, rộng bằng nhau để xem cho đẹp mắt hơn.
Đáp:
Access cung cấp cho ta công cụ Align và Size ( Click chuột phải vào tập các đối tượng đã chọn hoặc vào menu Format)

Đối với Align, ta có: (dùng chỉnh vị trí của đối tượng : Lable, Combobox, Textbox, button...)
Left: Canh theo đối tượng ngoài cùng phía bên trái
Right:Canh theo đối tượng ngoài cùng phía bên phải
Top:Canh theo đối tượng trên cùng
Bottom: Canh theo đối tượng thấp nhất

Đối với size của đối tượng ta có:
To Tallest : Format Chiều Cao của các đối tượng theo đối tượng có chiều cao lớn nhất
To Shortest Makes :Format Chiều cao của các đối tượng theo đối tượng có chiều cao nhỏ nhất
To Widest Makes:Format chiều rộng của các đối tượng theo đối tượng có chiều rộng lớn nhất
To Narrowest :Format chiều rộng của các đối tượng theo đối tượng có chiều rộng nhỏ nhất

To Fit: Format size đối tượng phù hợp với nội dung (chữ hoặc hình) của nó
To Grid: Format size đối tượng vừa với lưới định sẵn của Access

Format có điều kiện cho field trong Access

Hỏi:Tôi có bảng
tblViDu:
TK
111:Tiền mặt Mẹ,
1111:Tiền việt nam Con.
Em muốn là sau khi mở bảng xem ở chế độ Datasheet thì chữ Mẹ thành màu đỏ,Chữ Con thành Màu xanh thì đinh dạng như thế nào?

Bạn mở form ở dạng datasheet.
Mở lên , vào format--> conditional formating->

( Hoặc Ở chế độ Form Design, click phải chuột ở textbox bạn muốn format, bạn sẽ thấy thuộc tính Conditional Formatting... (theo Spammail))

Chọn Value Is
Equal : "Con" (hoặc mẹ)
Rồi chọn màu chữ hay màu nền tùy thích.
 Demo

Thứ Sáu, 11 tháng 12, 2009

Xóa Đối tượng Access từ 1 File Access Khác

Hỏi: Làm thế nào để xóa các Object (table, query, form, report) của DBLUU từ một nút lệnh trên form của DBSYS.


 Đáp:
Hôm trước tôi có giớ thiệu các bạn thủ thuật tạo 1 File Access rồi xuất dữ liệu ra đó hoặc tạo mới dữ liệu trong đó.
Đôi khi, việc tạo mới hay export chỉ nhầm làm 1 temp để xử lý, vì vậy ta cần xóa đi cho bớt rác. Mình xin giới thiệu code xóa Table :

Private Sub DelTableFrom(DataPath As String, tblName As String)
Dim db As Database
Set db = OpenDatabase(DataPath)
db.TableDefs.Delete  tblName
' Ðóng database
db.Close
Set db = Nothing
End Sub 
Tương Tự cho QueryDefs, Forms, Reports

Thêm Field vào 1 table trong file Access khác

Hỏi: Tôi có 2 file DB, một file lưu dữ liệu DBLUU.mdb, một file chương trình DBSYS.mdb. Trong file DBLUU.MDB có 1 tblLuu.
Làm Sao code từ một nút lệnh trên FORM tại DBSYS.mdb có thể thêm field vào tblLuu trong DBLUU.mdb



Đáp:
Đoạn Code dưới đây cho phép bạn thêm các field vào tblLuu với kiểu dữ liệu theo kèm. Bạn có thể tùy biến lại đuồng dẫn, tên và các file cũng như format của chúng theo ý riêng!



Sub CreateField()
Dim db As Database
Dim tdfChungTu As TableDef
Dim sAppPath As String
sAppPath = Application.CurrentProject.Path
Set db = OpenDatabase(sAppPath & "\DBLUU.mdb")
' Gan doi tuong table
Set tdfChungTu = db.TableDefs("tblLuu")
' Thêm các field
tdfChungTu.Fields.Append tdfChungTu.CreateField("Ngay_ChungTu", dbDate)
tdfChungTu.Fields.Append tdfChungTu.CreateField("So_ChungTu", dbLong)
tdfChungTu.Fields.Append tdfChungTu.CreateField("Dien_Giai", dbText, 30)
tdfChungTu.Fields.Append tdfChungTu.CreateField("Ho_Ten", dbText, 25)
tdfChungTu.Fields.Append tdfChungTu.CreateField("So_Tien", dbCurrency)
tdfChungTu.Fields.Append tdfChungTu.CreateField("Ghi_Chu", dbMemo)
db.TableDefs.Refresh
db.Close
Set db = Nothing
End Sub 

Thứ Tư, 9 tháng 12, 2009

Sử dụng thư viện hàm của Excel trong Access

Những ai thao tác quen với Excel sẽ thấy ở đây có một thư viện hàm khổng lồ mà Access không có được. Và câu hỏi là làm sao sử dụng được thư viện hàm này.


để sử dụng được thư viện hàm của Excel, bạn cần vào khung soạn VBA - > tool- > References
Chọn Microsoft Excel 11.0 Object Library. (10.0 với Office XP, 12.0 với Office 2007)



Sau đó tìm và chọn Chọn Microsoft Excel 11.0 Object Library. (10.0 với Office XP, 12.0 với Office 2007)



Giờ bạn có thể tạo 1 hàm tương tự và Gọi hàm từ Excel. Tôi ví dụ với hàm Days360 của Excel, các bạn làm tương tự các hàm khác nhé!
Function Days360(StarDate As Date, EndDate As Date) As Integer
       Days360 = Excel.WorksheetFunction.Days360(StarDate, EndDate)
End Function

Thứ Ba, 8 tháng 12, 2009

9 Shortcut Key giúp bạn tiết kiệm thời gian

Nếu sử dụng thành thạo các phím nóng sau, bạn có thể tăng tốc một cách đáng kể cho việc nhập hoặc di chuyển giữa các dữ liệu:

- Để hủy bỏ tác dụng của lệnh vừa thực hiện (undo) sử dụng CTRL+Z hoặc ALT+BACKSPACE

- Để hủy bỏ việc thay đổi dữ liệu ấn ESC một lần cho trường hiện hành, ấn ESC hai lần cho bản ghi hiện hành.

- Để chèn ngày hiện hành ấn CTRL + dấu ;

- Để chèn giờ hiện hành ấn CTRL + dấu :

- Để chèn giá trị ngầm định cho một trường ấn CTRL+ALT+SPACEBAR

- Để chèn giá trị từ trường tương ứng trong bản ghi trước đó ấn CTRL + dấu ''

- Để thêm một bản ghi mới ấn CTRL+ dấu +

- Để hủy bỏ bản ghi hiện hành ấn CTRL+ dấu -

- Để tính lại các trường trong cửa sổ ấn F9

Nguồn : Sưu tầm

Xóa các bản ghi bị trùng trong bảng của bạn?

Trên thực tế Access không cho phép bạn xóa các bản ghi bị trùng, nhưng bạn có thể thực hiện được tác vụ trên bằng cách tạo một table mới từ table cũ với các bản ghi không bị trùng sau đó xóa table cũ và đổi tên table mới tạo thành table cũ.

1. Sử dụng truy vấn tạo table (make-table query) từ table cần xóa. Lưu ý bạn phải chắc chắn là đã bao gồm tất cả các trường của table gốc trên lưới QBE (Query by Example), nếu không bạn có thể sẽ bị mất dữ liệu.

2. Mở bảng thuộc tính của Query bằng cách ấn vào menu VIEW, QUERY, PROPERTIES, và thiết lập thuộc tính Unique Values thành Yes

3. Bởi vì bạn đã chọn Unique Values thành Yes nên khi bạn chạy query, Access sẽ tạo ra một bảng mới với các bản ghi không bị trùng. Bây giờ bạn có thể xóa table cũ và đổi tên cho table mới.

Ẩn/ Hiện các đối tượng trong Access

Show / Hide Object ( tables, querys, forms, reports )
Question : Làm thế nào để có thể ẩn nhiều abngr cùng lúc.Hay là ta phải chọn từng bảng rôi ẩn.Vì trong CSDL có nhiều bảng mà ẩn từng cái bảng một thì rất là lâu.Tưng tụ với Form hay Report



Bạn làm copy thủ tục sau:

Sub hideTable(H As Boolean)
On Error Resume Next
Dim DB As Database
Dim N As Byte
Dim i As Byte
Set DB = DBEngine.Workspaces(0).Databases(0)
N = DB.TableDefs.Count
For i = 1 To N - 1
Application.SetHiddenAttribute acTable, DB.TableDefs(i).Name, H
Next

End Sub
Tương tự với query, form, report, bạn thay các dòng :
N = DB.TableDefs.Count
bằng:
N = DB.QueryDefs.Count
N= Forms.Count
N = Reports.Count

Và thay dòng
Application.SetHiddenAttribute acTable, DB.TableDefs(i).Name, H

bằng

Application.SetHiddenAttribute acQuery, DB.QueryDefs(i).Name, H

Application.SetHiddenAttribute acForm, Forms(i).Name, H
Application.SetHiddenAttribute acReport, Reports(i).Name, H
trong thủ tục


Giờ bạn muốn có thể tạo 2 nút nhấn và gọi:
Hidetable True
Để ẩn

HideTable false
để hiện trở lại
DemoDowload

Tùy biến Tiêu Đề Report

Queston: Tôi có 1 report chia làm nhiều group. Mỗi cuối group tôi dùng page break để sang trang. Tôi muốn vài thông tin Page header chỉ hiển thị khi sang group mới.


Reply : Bạn có thể lợi dụng ô Số thứ tự trong report khi set giá trị Control Soure=1 và thuộc tính Running Sum: Over Group . Đặc điểm ô này khi nhảy qua Group mới nó sẽ reset lại giá trị là 1 và tăng dần sau mỗi record thuộc group đó.
rong sự kiện format của page. Bạn có thể set cho tiêu đề visible true/ false. Cụ thể trong ví dụ của bạn, bạn viết thế này:

Private Sub PageHeaderSection_Format(Cancel As Integer, FormatCount As Integer)
If SOKU.Value = 1 Then
Label590.Visible = True
Label586.Visible = True
Else
Label590.Visible = False
Label586.Visible = False
End If
End Sub
Demo: Dowload

Thứ Hai, 7 tháng 12, 2009

Hướng Dẫn Tạo Menu Trong Access

Có nhiều cách để tạo Menu!
Sau đây, mình xin giới thiệu 1 tài liệu hướng dẫn tạo menu trong Access. Theo mình đánh giá là rất tốt và rõ ràng!
DownLoad


Bạn đã có các form công việc giờ bạn muốn tạo Thanh menu để chạy các form đó, hãy theo hướng dẫn sau:
Mình dùng hình cho nhanh nhé, tuần tự theo các bước đánh số 1,2,3,...

I – Tạo thanh menu
TaoMenu01.png



TaoMenu02.png

TaoMenu03.png


II - Tạo menu Thoát từ menu Exit của hệ thống:
TaoMenu04.png
TaoMenu05.png



III – Tạo menu Cập Nhật và các menu con
TaoMenu06.png
TaoMenu07.png
TaoMenu08.png

Đổi tên menu mới “Custom” đó thành “Thêm Công văn”
Tương tự tạo thêm menu “Danh sách Công văn” phía dưới menu “Thêm Công văn”
* To đường phân cách gia các menu con:
TaoMenu09.png

Đưa Thanh menu vào vị trí:
TaoMenu10.png
TaoMenu11.png



IV – Đặt Action cho menu “Thêm Công văn để mở form “frmCongVan
Với các thao tác trên menu “Thoát” đã dùng được rồi, bây giờ ta đặt Action cho menu “Thêm Công văn  để khi bấm vào nó là mở form “frmCongVan”:
TaoMenu13.png

TaoMenu14.png

Đặt tên nó là mcrThemCongVan

TaoMenu15.png

TaoMenu16.png

TaoMenu17.png

Tương tự với các menu khác dùng để mở các form khác.

Đóng gói chương trình Access

Nhiều bạn làm Access rất hay trăn trở làm thế nào đóng gói chương trình Access của mình cho trông nó chuyên nghiệp một tý.


Nhân đây tôi cũng xin nhắc trước, cần phân biệt đóng gói với biên dịch thành file tự chạy độc lập nhé. Đóng gói chỉ giúp ta lôi các thành phần phụ, tạo shortcut   và làm 1 số tác vụ hỗ trợ người dùng thôi
Và xin giới thiệu mọi người chương trình đóng gói: CreateInstall Free

Các bạn có thể down tại trang chủ DownLoad
Hoặc tại :DownLoad

CreateInstall Free



Output settings



Dialog settings

 Setup files


Uninstaller settings
Installations

Example #1


Example #2


Example #3


Example #4

So Sanh chính Xác chữ Hoa- Thường trong Access

Muốn so sánh chính xác từng ký tự một, hoa ra hoa, thường ra thường thì ở đầu trang module, thay câu lệnh Option Compare Database nếu có bằng Option Compare Binary là OK thôi.

Hàm đọc số dùng mã Unicode trong Access

Do môi trường VBA chưa hỗ trợ Unicode đầy đủ nên việc thiết lập hàm đọc số tiếng Việt với mã (font) Unicode trong Access cũng như Excel có khó khăn. Bài viết này giới thiệu một cách thiết lập hàm đọc số dùng font Unicode trong Access (bạn cũng có thể áp dụng trong Excel, VB...).


Các bước thực hiện như sau:
1. Mở CSDL Access.
2. Tạo một form đặt tên là FormTam, trên FormTam tạo hai label:
LabSo, nhập chuỗi: “không một hai ba bốn năm sáu bảy tám chín mốt lẻ lăm mươi mười trăm ”, cuối chuỗi có một khoảng trắng.
LabDonvi, nhập chuỗi: “đồng. nghìn triệu tỷ”, cuối chuỗi cũng có khoảng trắng.
3. Trong Module, nhấn New để tạo mới một module với tên mặc định là Module1. Sau đó nhấn Design để vào cửa sổ soạn code và nhập đoạn mã sau:
Khai báo 2 biến toàn cục là 2 mảng chứa chuỗi ký tự số và chuỗi đơn vị được lấy từ LabSo và LabDonvi thông qua thủ tục Docchu và Docdonvi.
Public Solay(0 To 15) As String
Public Donvilay(0 To 4) As String
Private Sub Docchu() 'Lấy chuỗi chữ số từ LabSo đặt vào mảng Solay
Dim tp, Stp, ii
ii = 0: tp = Form_FormTam.LabSo.Caption
Stp = InStr(tp, “ “)
Do While Stp <> 0
Solay(ii) = Left(tp, Stp)
tp = Right(tp, Len(tp) - Stp)
1Stp = InStr(tp, “ “)
ii = ii + 1
Loop
End Sub
'''''
Private Sub Docdonvi() 'Lấy chuỗi đơn vị từ LabDonvi đặt vào mảng Donvilay
Dim tp, Stp, ii
ii = 0: tp = Form_FormTam.LabDonvi.Caption
Stp = InStr(tp, “ “)
Do While Stp <> 0
Donvilay(ii) = Left(tp, Stp)
tp = Right(tp, Len(tp) - Stp)
Stp = InStr(tp, “ “)
ii = ii + 1
Loop
End Sub

'Tạo hàm đọc số:

Public Function DocVND(Sodoc As String) As String
If Len(Sodoc) > 12 Then
DocVND = “So qua lon qua hang tram ty. Hay xem lai!”
Exit Function
End If
Sodoc = Round(Sodoc, 0)
Dim Cht As String
Dim fg0 As Boolean
Dim fg1 As Boolean
Dim So As String
Dim ch As String
Dim tp As String
Dim i As Byte
Dim dv
Dim chs
Docchu Gọi hàm đọc chữ số
chs = Solay
Docdonvi Gọi hàm đọc đơn vị
dv = Donvilay
Do While Sodoc <> “”
Cht = “”
If Len(Sodoc) <> 0 Then
If (Len(Sodoc) >= 3) Then
So = Right(Sodoc, 3)
Else
So = Right(Sodoc, Len(Sodoc))
End If
Sodoc = Left(Sodoc, Len(Sodoc) - Len(So))
If Left(So, 1) = “0” And Mid(So, 2, 1) = “0” And Right(So, 1) = “0” Then
ch = ch
Else
If Len(So) = 3 Then
If Left(So, 1) <> “ “ Then
Cht = chs(Left(So, 1)) + chs(15)
End If
So = Right(So, 2)
End If
If Len(So) = 2 Then
If Left(So, 1) = “0” Then
If Right(So, 1) <> “0” Then
Cht = Cht + chs(11)
End If
fg0 = True
Else
If Left(So, 1) = “1” Then
Cht = Cht + chs(14)
Else
Cht = Cht + chs(Left(So, 1)) + chs(13)
fg1 = True
End If
End If
So = Right(So, 1)
End If
If Right(So, 1) <> 0 Then
If Left(So, 1) = “5” And Not fg0 Then
If Len(tp) = 1 Then
Cht = Cht + chs(4)
Else
Cht = Cht + chs(12)
End If
Else
If Left(So, 1) = 1 And Not (Not fg1 Or fg0) And Cht <> “” Then
Cht = Cht + chs(10)
Else
Cht = Cht + chs(Left(So, 1))
End If
End If
End If
ch = Cht + dv(i) + ch
End If
i = i + 1
End If
Loop
If Right(Trim(ch), 1) <> “.” Then
ch = ch + dv(0)
End If
DocVND=UCase(Left(ch, 1))&Mid(ch,2)
End Function
Ở đây tôi không phân tích hàm đọc số bởi TGVT đã có bài về vấn đề này (TGVT A 3/2001, t.76; 7/2001, t.88).
4. Sử dụng hàm DocVND
Tạo một Textbox có tên là Text1, nhấn phải lên Text1 chọn Build Event, trong Choose Builder chọn Code Builder và nhấn OK. Cửa sổ Microsoft VB hiện ra, nhập đoạn code sau:
Private Sub Text1_BeforeUpdate(Cancel As Integer)
Ketqua.Caption = DocVND(Text1.Text)
End Sub
Mở form, nhập vào các con số và gõ Enter, bạn sẽ có kết quả như hình. Mã nguồn chương trình có thể tải về tại website của TGVT – PCW VN.

DownLoad Demo

-------------------------------------
Trên đây là bài mình đăng nguyên văn từ báo PC-Word. Mình cũng xin góp ý với chương trình này : Thay vì làm bước:

2. Tạo một form đặt tên là FormTam, trên FormTam tạo hai label:
LabSo, nhập chuỗi: “không một hai ba bốn năm sáu bảy tám chín mốt lẻ lăm mươi mười trăm ”, cuối chuỗi có một khoảng trắng.
LabDonvi, nhập chuỗi: “đồng. nghìn triệu tỷ”, cuối chuỗi cũng có khoảng trắng.
 Ta có thể thay bằng cách tạo 1 table và lưu các giá trị trên vào. Sau đó gọi ra bằng 1 biến chuỗi hoặc hàm Dlookup tùy ý. Như vậy, ta có thể gọi hàm đọc số bất cứ đâu mà không cần tạo formTam

Report Footer luôn nằm ở cuối của trang cuối cùng

Giả sử bạn muốn đặt Textbox Txt01 luôn nằm ở cuối của trang cuối cùng. Đừng đặt nó ở Report Footer mà đặt ở Page Footer và thêm đoạn code sau :
Private Sub PageFooter_Format(Cancel As Integer, FormatCount As Integer)
if Me.Page = Me.Pages then
Me.Txt01.Visible = True
else
Me.Txt01.Visible = False
End Sub

Xử lý hiện thông báo khi không nhập dữ liệu vào texbox

Bạn sử dụng event on Lost Focus của textbox muốn ktra. Khi thoát khỏi thì check có IsNull hay kô? nếu IsNull là true thì quay lại ô đó textbox.SetFocus


Vd: bạn có textbox Date

Private Sub txtDate_LostFocus()
If IsNull(txtDate) Then
MsgBox "Ban phai nhap ngay vao o nay", vbCritical, "Thong bao"
txtDate.SetFocus
Cancel = True
End Sub

Chọn mẫu tin bằng Listbox

Hỏi:Giúp em phần từ (Item) listbox sang textbox
Đáp:



Có lẽ bạn không cần viết một dòng lệnh nào. Wizard của Access đã giúp bạn làm chuyện này. Cách làm như sau:
Bạn vẽ một list box lên form (sử dụng Wizard). Access cho phép bạn lựa chọn 1 trong 3 tùy chọn. Bạn chọn mục 3 (tìm kiếm mẩu tin dựa vào giá trị được chọn trong list box). Xong, nhắp Next.
Trong màn hình tiếp theo, bạn có thể chọn các trường IDBao, TenBao,...
Màn hình tiếp theo, bạn có thể chọn mục Hide Key Column để ẩn trường IDBao đi. Xong, nhắp Next...
Như vậy, khi bạn chọn một giá trị trong list box, Access sẽ nhảy tới mẩu tin chứa giá trị IDBao mà bạn chọn, tức nó sẽ hiển thị các thông tin của các trường khác.
Bạn lưu ý: Sau khi thiết kế xong list box, bạn không nên đổi tên (name) của nó, vì Access đã phát sinh một đoạn mã trong sự kiện After Update của list box này.
Không biết như vầy có đúng ý bạn không?

nguồn :http://my.opera.com/bvlbp/blog/thu-thuat-acc

View report ở chế độ cố định

Hỏi: Làm thế nào để View report ở chế độ cố định


Trả lời :

Dim stDocName As String
stDocName = "R01_Du An Moi"
DoCmd.OpenReport stDocName, acPreview
DoCmd.Maximize
DoCmd.RunCommand acCmdZoom75

' Các chế độ zoom khác :

' DoCmd.RunCommand acCmdFitToWindow
' DoCmd.RunCommand acCmdZoom10
' DoCmd.RunCommand acCmdZoom25
' DoCmd.RunCommand acCmdZoom50
' DoCmd.RunCommand acCmdZoom75
' DoCmd.RunCommand acCmdZoom100
' DoCmd.RunCommand acCmdZoom150
' DoCmd.RunCommand acCmdZoom200


Nguồn: http://my.opera.com/bvlbp/blog/thu-thuat-acc

Import Dữ Liệu Từ Excel Vào Access

Để nhập mới nội dung một table (trong Access) từ một tập tin Excel, ta có thể dùng một trong những cách sau đây:


1. Chọn File \ Get External Data \ Import từ trình đơn Access. Trên hộp thoại Import, chọn mục Microsoft Excel từ danh sách Files of type, rồi chọn tập tin Excel muốn đưa dữ liệu vào Access và bấm OK. Sau đó, theo từng bước hướng dẫn của Access. Tuy nhiên, dữ liệu luôn luôn được đưa vào một table mới, chứ không đưa vào table có sẵn cấu trúc được.
2. Tạo một macro, rồi trên form vẽ một nút lệnh để chạy macro này. Tuy nhiên, các thông số như TableName, FileName cần phải được gõ sẵn, hoặc phải bổ sung thêm một số “kỹ xảo” nữa rất mất công.
3. Cách khác hay hơn: dùng đối tượng DoCmd, một hình thức sử dụng macro của Access trong VBA. Ví dụ: Tạo form như hình 1, gồm có một textbox (đặt tên txtTapTinExcel), một nút lệnh (có dấu 3 chấm, đặt tên cmdTimTapTin), một nút lệnh (để đọc dữ liệu từ tập tin Excel có tên chứa trong ô txtTapTinExcel, đặt tên cmdDocDuLieuTuExcel) và một ActiveX Control có tên dlgTimTapTin. ActiveX Control này được tạo bằng cách bấm nút More Controls (nút cuối cùng) trên ToolBox, rồi chọn mục Microsoft Common Dialog Control. Lần lượt gõ vào các thủ tục xử lý tình huống OnClick của các nút lệnh cmdDocDuLieuTuExcel và cmdTimTapTin (đoạn mã 1). Bạn lưu ý, thứ tự và tên các cột trong tập tin Excel phải giống như cấu trúc table đã khai báo trong Access.

Đoạn mã 1


Private Sub cmdTimTapTin_Click()
With dlgTimTapTin
.ShowOpen
txtTapTinExcel = .FileName
End With
End Sub

Private Sub cmdDocDuLieuTuExcel_Click()
Dim sTenTable As String
sTenTable = "tbNhanVien" ‘ Vñ duå
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, _
sTenTable, txtTapTinExcel, True
End Sub


Nguồn: echip

Thứ Bảy, 5 tháng 12, 2009

Đăng nhập sai 5 lần chờ 15 phút

Question :Thấy các diễn đàn chỉ cho đăng nhạp 5 lần,nếu sai thì 15 phút sau mới cho đang nhập lại.Thế thì mình nghĩ ra ý tương rằng,cái này chúng ta có thể áp dụng trong Form đăng nhập được không.Điều kiện:
 Đăng nhập sai 5 lần thì dù có đăng nhập đúng đi chăng nữa cũng không vào đuợc CSDL.


Reply :
Xin giới thiệu bạn hàm Sleep( số miligiây) dùng để delay chương trình
Để dùng hàm nay, bạn phải khai báo API.
Tạo 1 module và khai báo API sau:
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Trong form đăng nhập, bạn tạo 1 biến để đếm. Sau mỗi lần nhập pass nó sẽ đếm lên 1.

Code:
dem=dem+1
If Dem mod 5 =0 then
MsgBox "Sai Pass 5 lan, ban phai cho 15 phut moi duoc dang nhap"
Sleep (1800000)
End If
---------------------------------------------------------------------
Bạn cũng có thể lợi dụng timer của Form ( set interval 1000 )để đếm giờ bằng cách tạo 1 biến demgiay. Khi nhập pass sai lần thứ 5, thì demgiay=0.
Trong sự kiện timer , demgiay =demgiay +1
Như vậy. bắt đầu kiểm tra pass, bạn đặt điều kiện:
If (dem mod 5 =0 ) and (demgiay < 180 =0) then
msgbox " bạn nhap sai pass 5 lan, ban phai doi 15 phut moi nhap lai duoc, thoi gian con lai : " & 180 - demgiay & "giay"
else
' doan code kiem tra pass
dem = dem +1
demgiay=0
End If

Thứ Năm, 3 tháng 12, 2009

Link table từ MDB có password

TransferDatabase to open password protect database

Question : Tôi xây dựng chương trình có 2 file: 1 file để thực hiện các thao tác trên FORM và xử lý thông tin (DBSYS.mdb) và 1 file để lưu trữ dữ liệu(DBDATA.mdb)
- Để cho người khác không thể vào được các dữ liệu lưu trữ, tôi đặt pass vào file DBDATA.
- Tôi tạo biến về đường dẫn để có thể tùy ý người sử dụng thay đổi thư mục của chương trình. Khi thay đổi thư mục của chương trình, thì sẽ tự tạo lại các link đến các table trong DBDATA.
Vấn đề là: để thực hiện các lệnh link thì phải gõ pass. Nhưng mỗi một lệnh linktable, lại phải gõ pass một lần.
Các PRO xem có cách nào giúp tôi: đặt sẵn và dùng VBA tại file chính (DBSYS) có thể link table từ DBDATA mà không cần phải gõ pass không (chỉ có sử dụng lệnh trong DBSYS mới không yêu cầu pass, còn các hình thức khác đều yêu cầu pass)



Reply:
Đầu tiên bạn kết nối với file ở dạng exclusive :

Dim TempDb as Database
Dim P as String ' Password
P= "mypassword"
Set tempDB = OpenDatabase(CurrentProject.Path & "\" &  "DBDATA.MDB", True, False, "MS Access;PWD= " & p)


Sau đó xóa pass đi

tempDB.NewPassword p, ""
tempDB.Close

Tiến hành liên kết table:
DoCmd.TransferDatabase acLink, "Microsoft Access", CurrentProject.Path & "\" &"DBDATA.MDB", acTable, "TableName", "Tablename"

'Sau đó set password lại cho file Data

Set tempDB = OpenDatabase(CurrentProject.Path & "\" & "DBDATA.MDB", True, False)
tempDB.NewPassword "", p
tempDB.Close
Set tempDB = Nothing



Chú ý : Khi sử dụng chương trình thì phải unSet Password đi. Và khi sử dụng xong hoặc có lỗi ta sẽ setPassword trở lại:
Bạn tạo  thủ tục 1
Sub setPass(oldPass as String, newPass As String)
Set tempDB = OpenDatabase(CurrentProject.Path & "\" & "DBDATA.MDB", True, False, "MS Access;PWD=" & oldPass)
tempDB.NewPassword oldPass, NewPass
tempDB.Close
End Sub


Như Vậy, khi cần xài dữ liệu, bạn gọi : setPass mypassword, "" mục đích xóa pass của file đi
Và khi sử dụng xong hoặc chương trình có lỗi, bạn nhớ setPass trở lại password gốc setPass  "", mypassword
Xem Demo