Một giáo trình hay diễn giải chi tiết,với nhiều ví dụ sinh động,dễ hiểu bằng tiếng Việt 100% của Tác giả Nguyễn Sơn Hải rất thích hợp cho các bạn mới bắt đầu lập trình CSDL, đồng thời giúp bạn làm quen với VBA( visual basic for application), một ngôn ngữ thân thiện hỗ trợ hầu hết các ứng dụng của Microsoft.
Chủ Nhật, 29 tháng 11, 2009
Tự động tạo CSDL Access bằng VBA
Hôm trước tôi giới thiệu các bạn cách tạo 1 file MDB mớiđể xuất dữ liệu ra đó. Hôm nay xin giới thiệu các bạn cách tạo 1 file Access mới hoàn toàn, đồng thời thông qua VBA để tạo table cùng các field trực tiếp trên đó!
Ví dụ sau đây tạo một database có tên KeToan.MDB trong thư mục chứa database hiện hành, đồng thời tạo luôn một table có tên tbChungTu có cấu trúc: Ngay_ChungTu (Date/Time), So_ChungTu (AutoNumber), Dien_Giai (Text, 30), Ho_Ten (Text, 25), So_Tien (Currency), Ghi_Chu (Memo) Bạn hãy tạo một CSDL mới, thiết kế một form và vẽ nút lệnh có tên cmdCreateMDB, rồi gõ đoạn mã 1 vào thủ tục xử lý tình huống OnClick của nút lệnh đó. Xong, bạn mở form, thử bấm nút lệnh cmdCreateMDB để kiểm tra kết quả. |
Private Sub cmdCreateMDB_Click()
Dim dbKeToan As Database' Khai báo đối tượng Database mới
Dim tdfChungTu As TableDef' Khai báo đối tượng Table mới
Dim sAppPath As String
sAppPath = Me.Application.CurrentProject.Path
Set wrkDefault = DBEngine.Workspaces(0)
If Not (Dir(sAppPath & "\KeToan.mdb") <>"") Then
Set dbKeToan = wrkDefault.CreateDatabase(sAppPath & "\KeToan.mdb", dbLangGeneral)
Else
Set dbKeToan = OpenDatabase(sAppPath & "\KeToan.mdb")
End If
' Tạo đối tượng TableDef mới
Set tdfChungTu = dbKeToan.CreateTableDef("tbChungTu")
' 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)
' Các thuộc tính bổ sung
tdfChungTu.Fields!So_ChungTu.Attributes = dbAutoIncrField
' Thêm table mới vào database
dbKeToan.TableDefs.Append tdfChungTu
' Đóng database
dbKeToan.Close
End Sub
Dim dbKeToan As Database' Khai báo đối tượng Database mới
Dim tdfChungTu As TableDef' Khai báo đối tượng Table mới
Dim sAppPath As String
sAppPath = Me.Application.CurrentProject.Path
Set wrkDefault = DBEngine.Workspaces(0)
If Not (Dir(sAppPath & "\KeToan.mdb") <>"") Then
Set dbKeToan = wrkDefault.CreateDatabase(sAppPath & "\KeToan.mdb", dbLangGeneral)
Else
Set dbKeToan = OpenDatabase(sAppPath & "\KeToan.mdb")
End If
' Tạo đối tượng TableDef mới
Set tdfChungTu = dbKeToan.CreateTableDef("tbChungTu")
' 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)
' Các thuộc tính bổ sung
tdfChungTu.Fields!So_ChungTu.Attributes = dbAutoIncrField
' Thêm table mới vào database
dbKeToan.TableDefs.Append tdfChungTu
' Đóng database
dbKeToan.Close
End Sub
Chủ Nhật, 22 tháng 11, 2009
Tạo Query tạm để xử lý dữ liệu trong VBA
Hỏi: Trước đây em tạo query bằng lưới, nên lúc nào cũng có query tồn tại trong chương trình; bây giờ em học định nghĩa query bằng VBA, để không tồn tại query trong chương trình nữa.Sau khi xử lý xong thì xóa đi
Tải xuống Demo
Private Sub Command0_Click()
Dim DB As Database
' Dim query1 As QueryDef
Dim query1 As QueryDef
Dim SQL1 As String
SQL1 = "select maso, sum(table2.sotien) as sotien, count(sohd) as slhd from table2 group by maso"
Set DB = CurrentDb
Set query1 = DB.CreateQueryDef("query1", SQL1)
DB.Execute "select query1.maso, table1.ten, query1.sotien, query1.slhd into table3 from query1 left join table1 on query1.maso=table1.maso"
' xoa table tam di
DB.QueryDefs.Delete "query1"
msgbox " insert Data to table 3 successful"
Set DB = Nothing
End Sub
Tải xuống Demo
Tạo file Access mới và xuất dữ liệu ra đó
Đoạn code sau cho phép bạn tạo 1 file MDB mới trong cùng 1 thư mục với chương trình
Ứng dụng: bạn có thể có nhu cầu mỗi tháng tạo 1 file chứa dữ liệu riêng 1 cách tự động!...
Sub CreateDatabaseX(DBname as String)
Dim wrkDefault As Workspace
Dim Bomtemp As Database
'Dim prpLoop As Property
' Get default Workspace.
Set wrkDefault = DBEngine.Workspaces(0)
' Make sure there isn't already a file with the name of
' the new database.
If Dir(CurrentProject.Path & "\" & "DBName") <> "" Then Kill CurrentProject.Path & "\"& DBName
' Create a new encrypted database with the specifiedĐoạn Code sau cho phép bạn Export 1 table ra 1 file MDB khác cùng mục với chương trình
' collating order.
Set Bomtemp = wrkDefault.CreateDatabase(CurrentProject.Path & "\" & "DBname", dbLangGeneral, dbEncrypt)
Bomtemp.Close
End Sub
Sub ExportTable(T As String, DBname)
On Error GoTo err
DoCmd.TransferDatabase acExport, "Microsoft Access", CurrentProject.Path & "\" & "DBname", acTable, T, T
Exit Sub
err:
If err.Number = 3024 Then
CreateDatabaseX DBname
ExportTable T
End If
End Sub
Ứng dụng: bạn có thể có nhu cầu mỗi tháng tạo 1 file chứa dữ liệu riêng 1 cách tự động!...
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"
Nguồn: techonthenet
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"
Nguồn: techonthenet
Thứ Năm, 19 tháng 11, 2009
Canh Form giữa màn hình
Như các bạn biết. Mặc định Access đã cho ta thuộc tính auto Center và auto resize.
Nhưng có vẻ như nó không đáp ứng được nhu cầu của chúng ta.
Sau đây mình xin giới thiệu code canh giữa form.
Trong Sự kiện Load Form, bạn cho code sau vào:
Nhưng có vẻ như nó không đáp ứng được nhu cầu của chúng ta.
Sau đây mình xin giới thiệu code canh giữa form.
Trong Sự kiện Load Form, bạn cho code sau vào:
Private Sub Form_Load()
Const t = 567
Dim R As Integer, D As Integer, W As Integer, H As Integer
' với 10 là chieu rong cua form, tinh bang cm
W = 10 * t
' 7 la chieu cao cua form tinh bang cm
H = 7 * t
R = (Me.InsideWidth + W)
D = (Me.InsideHeight + H)
DoCmd.MoveSize R, D, W, H
End Sub
Thứ Tư, 18 tháng 11, 2009
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:
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"
End sub
Lấy về số seri CPU, ổ cứng MainBoard trong Access
Đôi khi có 1 số nhu cầu lấy thông tin phần cứng trong chương trình (chẳng hạn để cấp bản quyền). Dưới đây là Đoạn Code cho phép bạn lấy thông tin CPU máy tính:
Lưu ý rằng trên các máy PC bình thường, chỉ có 1 CPU nên vòng lặp hiển thị thông tin sẽ chỉ chạy 1 lần và hiển thị ID của CPU duy nhất của máy.
nguồn PC word
2. Lấy CPU ổ cứng:
3. Lấy Serial Main Board
Sub GetCPUID()
'ta.o ðo^'i týo+.ng di.ch vu. WMI
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
'ti`m các CPU ðang cha.y cu?a máy
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
'la(.p hie^?n thi. ID cu?a tu+`ng CPU
For Each objItem In colItems
MsgBox "Processor Id: " & objItem.ProcessorId
Next
End Sub
Lưu ý rằng trên các máy PC bình thường, chỉ có 1 CPU nên vòng lặp hiển thị thông tin sẽ chỉ chạy 1 lần và hiển thị ID của CPU duy nhất của máy.
nguồn PC word
2. Lấy CPU ổ cứng:
Sub readserienumber()Dim fso As Object, Drv As Object'Create a FileSystemObject objectSet fso = CreateObject("Scripting.FileSystemObject")'Assign the current drive letter if not specifiedSet Drv = fso.GetDrive() With DrvIf .IsReady ThenDriveSerial = Abs(.SerialNumber)Else '"Drive Not Ready!"DriveSerial = -1End IfEnd With'Clean upSet Drv = NothingSet fso = NothingMsgbox "Serial là: " & DriveSerialEnd Sub
3. Lấy Serial Main Board
Sub readseriemainboard()
Dim objs As Object
Dim obj As Object
Dim WMI As Object
Dim sAns As String
Set WMI = GetObject("WinMgmts:")
Set objs = WMI.InstancesOf("Win32_BaseBoard")
For Each obj In objs
sAns = sAns & obj.SerialNumber
If sAns < objs.Count Then sAns = sAns & ","
Next
Msgbox "Serial main: " & sAns
End Sub
Thứ Ba, 17 tháng 11, 2009
Không cho xoá File Data
Hỏi: File data muốn sử dụng thì phải share full, mà share full thì bị mần thịt là chuyện thường xuyên.
A e cho hỏi có cách nào khắc phục ko cho xoá File Data.Mdb trong môi trường nhiều người dùng. Có chương trình ngoại vi nào không cho xoá File Data mà các Client vẫn hoạt động bình thường không?
Đầu tiên bạn phải chắc rằng file data bạn nằm trong phân vùng NTFS
Bạn vào tool->folder option->view
Check bỏ tùy chọn simle file Sharing( các bứơc này có thể bỏ qua nếu đang dùng Win server 2003 )

Sau đó , click chuột phải vào thư mục chứa data, chọn:

Cách này chỉ hạn chế người ta xóa file của mình thôi! Chứ muốn phá thì dễ ợt! Trừ khi bạn để dữ liệu trên SQL server rồi nối qua Access thì mới an toàn!
A e cho hỏi có cách nào khắc phục ko cho xoá File Data.Mdb trong môi trường nhiều người dùng. Có chương trình ngoại vi nào không cho xoá File Data mà các Client vẫn hoạt động bình thường không?
Đầu tiên bạn phải chắc rằng file data bạn nằm trong phân vùng NTFS
Bạn vào tool->folder option->view
Check bỏ tùy chọn simle file Sharing( các bứơc này có thể bỏ qua nếu đang dùng Win server 2003 )

Sau đó , click chuột phải vào thư mục chứa data, chọn:
| Hình ảnh này đã được thu nhỏ kích thước cho phù hợp. Nhấn vào Menu này để xem hình ảnh gốc. Kích thước của ảnh gốc là 781x594. |

Cách này chỉ hạn chế người ta xóa file của mình thôi! Chứ muốn phá thì dễ ợt! Trừ khi bạn để dữ liệu trên SQL server rồi nối qua Access thì mới an toàn!
Thứ Bảy, 14 tháng 11, 2009
Nhập đường dẫn 1 file ảnh vào chương trình để lưu!
Hôm trước tôi có nêu thủ thuật Insert 1 ảnh vào form/report khi đã có đường dẫn ảnh.
Hôm nay tôi sẽ giới thiệu các bạn cách để nhập liệu đường dẫn ấy sao cho người dùng chỉ cần click chuột.
Trên form, bạn vẽ 1 textbox đặt tên là txtpicture, một nút nhấn tên cmdInsertPic,1 đối tượng ảnh đặt tên là image
bạn phải tạo 1 funtcion để lấy về đường dẫn file ảnh
Code:
Bây giờ trong hành động click của nút nhấn, ta nhập đoạn code sau:
Code:
Hôm nay tôi sẽ giới thiệu các bạn cách để nhập liệu đường dẫn ấy sao cho người dùng chỉ cần click chuột.
Trên form, bạn vẽ 1 textbox đặt tên là txtpicture, một nút nhấn tên cmdInsertPic,1 đối tượng ảnh đặt tên là image
bạn phải tạo 1 funtcion để lấy về đường dẫn file ảnh
Code:
Function getFile(Tit As String, formatName As String, formatType As String)
Dim dlgOpen As FileDialog
Set dlgOpen = Application.FileDialog(msoFileDialogOpen)
With dlgOpen
.Title = Tit
.Filters.Clear
.Filters.Add formatName, formatType
.AllowMultiSelect = False
result = .Show
If (result <> 0) Then
getFile = Trim(dlgOpen.SelectedItems.Item(1))
End If
End With
End Function
Bây giờ trong hành động click của nút nhấn, ta nhập đoạn code sau:
Code:
Me![TxtPic] = GetFile_CLT("c:\", "Select the Picture File","*.jpg|*.bmp")
Me![TxtPic] = LCase(Me![TxtPic])
Me![Image].Picture = Me!TxtPic
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
Đá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_PicIf IsNull(Me.txtPic) ThenMe.Image1.Picture = ""Me.Image1.Visible = FalseElseMe.Image1.Picture = txtPic.ValueMe.Image1.Visible = TrueEnd IfExit Suberr_Pic:MsgBox Err.Description, vbOKOnlyExit SubEnd Sub
Tạo một đường viền cho report
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?
Đáp:
Cho đoạn code sau vào report!
Đáp:
Cho đoạn code sau vào report!
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
Thiết kế Ctrình phân quyền
Phân quyền trong Access
Trong Access đã hỗi trợ phân quyền bằng cách tạo file workGroup *.mdw, *.mda. tuy nhiên cách này hơi nhiêu khê ở chỗ là máy sử dụng phải map tới file này thì mới xài được.
Vì vậy một cách khác mọi người quan tâm là phân quyền trực tiếp trong chương trình access của mình. Nếu mình post 1 đoạn chương trình lên cho mọi người tham khảo thì quá dễ dàng, nhưng điều đó không mang ý nghĩa học tập. Vì vậy, mình quyết định sẽ tiến hành Phân tích bài toán và thiết lập từng bước sao cho dễ hiểu nhất, ai biết Access cũng có thể làm được.
I/Mô tả:
Chương trình sẽ yêu cầu đăng nhập mỗi khi mở, nếu không có user name thì chỉ vào được quyền hạn chế dành cho khách.
II/ Thiết kế và giải thuật:
Mô tả ý tưởng:
- Khi bạn đăng nhập vào, chương trình sẽ ghi nhận username của bạn trong một biến toàn cục(public).
Sau đó sẽ qua một function để biết bạn thuộc group nào.( mình chia group thành các cấp khác nhau, cấp cao thì quyền nhiều hơn cấp dưới)
- Ở mỗi process cụ thể sẽ cho biết cấp tối thiểu để được đăng nhập vào process đó.
Chuẩn bị table:
- Table cần có là danh sách user: tblDSUser(ID,pass)
- Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user)
Trong đó : username là khóa ngoại liên kết với tblDSUser
Dữ liệu nhập thử:
tblDSUser
ID --- Pass
Admin ---- Admin
Duytuan ---- tuan
Guest ----
tblWorkGroup
WGLevel---WgName---User
9---Admin --- Admin
8---User --- Duytuan
0---Guest---guest
Việc đều tiên là bạn vào khai báo một biến toàn cục tên là user, cách làm như sau:
Vào menu Tool => marcr
Visual basic editor
Một cửa sổ VB xuất hiện, tại đây bạn vào menu Inser => module
Trong Module mới tạo, bạn khai báo một biến toàn cục để lưu tên user hiện hành:
Public username as string
OK, bây giờ bạn đã đủ đồ nghề để tạo form đăng nhập.
Xem hình

Đầu tiên, bạn tạo 1 form, đặt tên nó là frmLogin
1/Vẽ 1 lable với caption như sau “Xin mời nhập Username,pass hoặc nhấn vào guest để ghé thử”
2/Vẽ 1 combobox đặt tên là: cbbusername,
thuộc tính row source: SELECT tblDSUser.ID, tblDSUser.Pass FROM tblDSUser;
3/ Vẽ một textbox đặt tên là txtPassWord
Input mask kiểu Password
4/ Vẽ 1 text box đặt tên là txtPassTemp
Thuộc tính visible là No
5/ vẽ một nút đặt tên là cmdLogin
6/Vẽ một nút đặt tên là cmdGuest
Vậy là xong phần giao diện, bây giờ là cái ruột
Mô tả:
Sau khi cập nhật tên user thì txtPassTemp sẽ lấy về cái password , và field này user hoàn toàn không nhìn thấy. Mục đích là để so sánh pass này với cái pass của user nhập vào. Đúng thì tiếp tục log vào form chính, đồng thời gán biến username bằng tên đăng nhập, sai thì báo lỗi.
Như vậy, hành động after Update của ComboBox nhập user như sau:
Me.txtPassTemp.Value = cbbUserName.Column(1)
‘ lấy về password
End Sub
Bây giờ ta xử lý nút Login,
đầu tiên bạn khoan đã xử. Bạn tạo 1 form đặt tên là frmMain rồi chừa trống đấy, form này để dành sau khi login thì nó sẽ gọi lên.
Bây giờ ta quay lại với nút login.
Nó phải làm các việc sau:+
- Kiểm tra password nhập vào có đúng với field : txtPassTemp hay không, nếu đúng thì làm cái việc là gán biến toàn cục username bằng giá trị của ô CbbUsername.
- Chào mừng user đó đăng nhập
- Mở form frmMain
- Đóng form frmLogin lại
Nếu sai thì báo là nhập sai
Đoạn code xử lý như sau:
Bây giờ tới nút cmdGuest
Tương tự nhưng không cần kiểm tra gì cả, tên username được gán bằng tên Guest và vào thẳng form main
Trong khi chờ đợi các bạn cứ thiết kế Main form như hình nhé, nội dung thì thứ 2 No lên phân tích tiếp

Hôm trước mình nhầm lẫn một chút ở khâu chuẩn bị table
sai ở table tblWorkGroup, vì như vậy thì ở mỗi level ta chỉ tạo được một user thôi
Mình xin đính chính lại table này
tblWorkGroup(WgLevel, WgName,user)
Đầu tiên, để chuẩn bị cái ruột cho mainform, chúng ta phải có một đoạn code để lấy về level của user hiện hành.
Các bạn còn nhớ cái module mà bạn đã khai báo biến toàn cục: username chứ?
bây giờ mở nó lên, viết tiếp vào đoạn code lấy về level user
On Error GoTo Err ' nếu user vào trực tiếp bằng quyền guest thì cho level là 0
Dim rs1 As Recordset
Dim sql As String
sql = " select max(WGlevel) from tblWorkGroup where user= '" & Username & "'"
Set rs1 = CurrentDb.OpenRecordset(sql)
rs1.MoveFirst
checkuser = rs1(0).Value
Exit Function
Err:
checkuser = 0
Exit Function
End Function
OK, bây giờ đồ nghề đầy đủ, các bạn vẽ mainform rồi chứ/? Đặt tên cái form đó là frmMain.
Các nút trên form đặt tên lần lượt là: cmdAdmin,cmdUser,cmdGuest
Trong chương trình của mình sẽ chia làm 9 cấp độ đăng nhập, quyền cao nhất Admin,sẽ vào với level 9, các user tùy theo là trưởng phòng hay nhân viên sẽ có level 1-8
Guest sẽ vào với level 0. Giải thuật của ta ứng với mỗi nút là sẽ tạo ra yêu cầu level tối thiểu. Đối với user Admin thì tối thiểu phải level 9
OK.
Bây giờ ta xử lý nút cmd Admin như sau
Tương tự với Nút user, ở ví dụ này, nút user yêu cầu phải level 8 mới vào được. bạn có thể hạ thấp level yêu cầu xuống cho nhân viên.
Và nút guest cũng tương tự
Hihi, đáng lẽ có thể sửa quyền khách cho hợp lý hơn, nhưng mình copy paster cho nhanh
Hướng dẫn cơ bản tương đối ổn rồi, bây giờ ta “ màu mè” một chút là khi vào chương trình bắt buột phải login vào cái frmLogin, cách nào ư? Nhiều lắm, nhưng mình thích dùng cái marcro.
Bạn tạo một marcro, đặt tên nó là AutoExec
Thằng này sẽ tự chạy mỗi khi ta vào chương trình.
Nội dung của marcro AutoExec chỉ có 1 hành động dòng như sau:
Open form
Form name: frmLogin
View: form
Windows mode: Dialog
Sở dĩ tôi bảo các bạn dùng marcro là vì cái Dialog này, nó bắt buột phải đăng nhập mới vào, còn không thì nhấn guest.
Sau đó ta vào menu Tool =>startup bỏ chọn hết tất cả để nó không cho các user táy máy khi đăng nhập.
Chưa xong đâu, bạn quay lại cái Module, mở nó lên, vào menu Tool => “tên chương trình” properties nhảy qua tab protection, cài password cho cái source của bạn luôn. Cho mấy tay táy máy khỏi link vào import mấy cái table quý hóa của mình.
OK.
Đóng chương trình và mở lại. Thử với các quyền thử xem!
Và bây giờ bạn muốn edit chương trình thì làm thế nào? Dễ thôi! Nhấn phím shift trong khi mở nó sẽ không load macro AutoExec nữa, vào cửa sổ design như bình thường!
Vậy chương trình không an toàn về bảo mật? Ồ không đâu, tôi sẽ giới thiệu trong bài khác về cách vô hiệu hóa phím shift, và khi muốn mở lại thì phải Enable phím shift
Nếu các bạn chưa tin về tính bảo mật? Hãy thử chương trình Demo của Noname xem! trừ khi bạn đăng nhập vào quyền admin, còn lại các user kia thì không sửa xóa gì chương trình được cả
http://duyeagle.googlepages.com/phanquyen.rar
Trong Access đã hỗi trợ phân quyền bằng cách tạo file workGroup *.mdw, *.mda. tuy nhiên cách này hơi nhiêu khê ở chỗ là máy sử dụng phải map tới file này thì mới xài được.
Vì vậy một cách khác mọi người quan tâm là phân quyền trực tiếp trong chương trình access của mình. Nếu mình post 1 đoạn chương trình lên cho mọi người tham khảo thì quá dễ dàng, nhưng điều đó không mang ý nghĩa học tập. Vì vậy, mình quyết định sẽ tiến hành Phân tích bài toán và thiết lập từng bước sao cho dễ hiểu nhất, ai biết Access cũng có thể làm được.
I/Mô tả:
Chương trình sẽ yêu cầu đăng nhập mỗi khi mở, nếu không có user name thì chỉ vào được quyền hạn chế dành cho khách.
II/ Thiết kế và giải thuật:
Mô tả ý tưởng:
- Khi bạn đăng nhập vào, chương trình sẽ ghi nhận username của bạn trong một biến toàn cục(public).
Sau đó sẽ qua một function để biết bạn thuộc group nào.( mình chia group thành các cấp khác nhau, cấp cao thì quyền nhiều hơn cấp dưới)
- Ở mỗi process cụ thể sẽ cho biết cấp tối thiểu để được đăng nhập vào process đó.
Chuẩn bị table:
- Table cần có là danh sách user: tblDSUser(ID,pass)
- Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user)
Trong đó : username là khóa ngoại liên kết với tblDSUser
Dữ liệu nhập thử:
tblDSUser
ID --- Pass
Admin ---- Admin
Duytuan ---- tuan
Guest ----
tblWorkGroup
WGLevel---WgName---User
9---Admin --- Admin
8---User --- Duytuan
0---Guest---guest
Việc đều tiên là bạn vào khai báo một biến toàn cục tên là user, cách làm như sau:
Vào menu Tool => marcr
Visual basic editorMột cửa sổ VB xuất hiện, tại đây bạn vào menu Inser => module
Trong Module mới tạo, bạn khai báo một biến toàn cục để lưu tên user hiện hành:
Public username as string
OK, bây giờ bạn đã đủ đồ nghề để tạo form đăng nhập.
Xem hình
Đầu tiên, bạn tạo 1 form, đặt tên nó là frmLogin
1/Vẽ 1 lable với caption như sau “Xin mời nhập Username,pass hoặc nhấn vào guest để ghé thử”
2/Vẽ 1 combobox đặt tên là: cbbusername,
thuộc tính row source: SELECT tblDSUser.ID, tblDSUser.Pass FROM tblDSUser;
3/ Vẽ một textbox đặt tên là txtPassWord
Input mask kiểu Password
4/ Vẽ 1 text box đặt tên là txtPassTemp
Thuộc tính visible là No
5/ vẽ một nút đặt tên là cmdLogin
6/Vẽ một nút đặt tên là cmdGuest
Vậy là xong phần giao diện, bây giờ là cái ruột
Mô tả:
Sau khi cập nhật tên user thì txtPassTemp sẽ lấy về cái password , và field này user hoàn toàn không nhìn thấy. Mục đích là để so sánh pass này với cái pass của user nhập vào. Đúng thì tiếp tục log vào form chính, đồng thời gán biến username bằng tên đăng nhập, sai thì báo lỗi.
Như vậy, hành động after Update của ComboBox nhập user như sau:
Trích:
Private Sub cbbUsername_AfterUpdate()Me.txtPassTemp.Value = cbbUserName.Column(1)
‘ lấy về password
End Sub
Bây giờ ta xử lý nút Login,
đầu tiên bạn khoan đã xử. Bạn tạo 1 form đặt tên là frmMain rồi chừa trống đấy, form này để dành sau khi login thì nó sẽ gọi lên.
Bây giờ ta quay lại với nút login.
Nó phải làm các việc sau:+
- Kiểm tra password nhập vào có đúng với field : txtPassTemp hay không, nếu đúng thì làm cái việc là gán biến toàn cục username bằng giá trị của ô CbbUsername.
- Chào mừng user đó đăng nhập
- Mở form frmMain
- Đóng form frmLogin lại
Nếu sai thì báo là nhập sai
Đoạn code xử lý như sau:
Trích:
| Private Sub cmdLogin_Click() If Me.txtPassWord.Value = Me.txtPassTemp.Value Then Username = Me.cbbUserName MsgBox "Welcom To " & Username DoCmd.OpenForm "frmMain" DoCmd.Close acForm, "frmLogin" Else MsgBox "Login Fail, check your Username and your password" End If End Sub |
Tương tự nhưng không cần kiểm tra gì cả, tên username được gán bằng tên Guest và vào thẳng form main
Trích:
| Private Sub CmdGuest_Click() Username = "Guest" MsgBox "Welcom To " & Username DoCmd.OpenForm "frmMain" DoCmd.Close acForm, "frmLogin" End Sub |
Trong khi chờ đợi các bạn cứ thiết kế Main form như hình nhé, nội dung thì thứ 2 No lên phân tích tiếp
Hôm trước mình nhầm lẫn một chút ở khâu chuẩn bị table
Trích:
| Chuẩn bị table: - Table cần có là danh sách user: tblDSUser(ID,pass) - Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user) Trong đó : username là khóa ngoại liên kết với tblDSUser |
Mình xin đính chính lại table này
tblWorkGroup(WgLevel, WgName,user)
Đầu tiên, để chuẩn bị cái ruột cho mainform, chúng ta phải có một đoạn code để lấy về level của user hiện hành.
Các bạn còn nhớ cái module mà bạn đã khai báo biến toàn cục: username chứ?
bây giờ mở nó lên, viết tiếp vào đoạn code lấy về level user
Trích:
Function checkuser() As IntegerOn Error GoTo Err ' nếu user vào trực tiếp bằng quyền guest thì cho level là 0
Dim rs1 As Recordset
Dim sql As String
sql = " select max(WGlevel) from tblWorkGroup where user= '" & Username & "'"
Set rs1 = CurrentDb.OpenRecordset(sql)
rs1.MoveFirst
checkuser = rs1(0).Value
Exit Function
Err:
checkuser = 0
Exit Function
End Function
OK, bây giờ đồ nghề đầy đủ, các bạn vẽ mainform rồi chứ/? Đặt tên cái form đó là frmMain.
Các nút trên form đặt tên lần lượt là: cmdAdmin,cmdUser,cmdGuest
Trong chương trình của mình sẽ chia làm 9 cấp độ đăng nhập, quyền cao nhất Admin,sẽ vào với level 9, các user tùy theo là trưởng phòng hay nhân viên sẽ có level 1-8
Guest sẽ vào với level 0. Giải thuật của ta ứng với mỗi nút là sẽ tạo ra yêu cầu level tối thiểu. Đối với user Admin thì tối thiểu phải level 9
OK.
Bây giờ ta xử lý nút cmd Admin như sau
Trích:
| Private Sub cmdAdmin_Click() Dim userRequest As String ‘ biến yêu cầu user tối thiểu userRequest = 9 If userRequest <= checkuser Then MsgBox "Xin chao ban đa dang nhap vao quyen admin" Else MsgBox "ban khonn duoc dang nhap function nay" End If End Sub |
Trích:
| Private Sub cmdUser_Click() Dim userRequest As String userRequest = 8 If userRequest <= checkuser Then MsgBox "Xin chao ban da dang nhap vao quyen user" Else MsgBox "ban khong duoc dang nhap function nay" End If End Sub |
Trích:
| Private Sub CmdGuest_Click() Dim userRequest As String userRequest = 0 If userRequest <= checkuser Then MsgBox "Xin chao dang nhap vao quyen khach" Else MsgBox "ban khogn duoc dang nhap function nay" End If End Sub |
Hướng dẫn cơ bản tương đối ổn rồi, bây giờ ta “ màu mè” một chút là khi vào chương trình bắt buột phải login vào cái frmLogin, cách nào ư? Nhiều lắm, nhưng mình thích dùng cái marcro.
Bạn tạo một marcro, đặt tên nó là AutoExec
Thằng này sẽ tự chạy mỗi khi ta vào chương trình.
Nội dung của marcro AutoExec chỉ có 1 hành động dòng như sau:
Open form
Form name: frmLogin
View: form
Windows mode: Dialog
Sở dĩ tôi bảo các bạn dùng marcro là vì cái Dialog này, nó bắt buột phải đăng nhập mới vào, còn không thì nhấn guest.
Sau đó ta vào menu Tool =>startup bỏ chọn hết tất cả để nó không cho các user táy máy khi đăng nhập.
Chưa xong đâu, bạn quay lại cái Module, mở nó lên, vào menu Tool => “tên chương trình” properties nhảy qua tab protection, cài password cho cái source của bạn luôn. Cho mấy tay táy máy khỏi link vào import mấy cái table quý hóa của mình.
OK.
Đóng chương trình và mở lại. Thử với các quyền thử xem!
Và bây giờ bạn muốn edit chương trình thì làm thế nào? Dễ thôi! Nhấn phím shift trong khi mở nó sẽ không load macro AutoExec nữa, vào cửa sổ design như bình thường!
Vậy chương trình không an toàn về bảo mật? Ồ không đâu, tôi sẽ giới thiệu trong bài khác về cách vô hiệu hóa phím shift, và khi muốn mở lại thì phải Enable phím shift
Nếu các bạn chưa tin về tính bảo mật? Hãy thử chương trình Demo của Noname xem! trừ khi bạn đăng nhập vào quyền admin, còn lại các user kia thì không sửa xóa gì chương trình được cả
http://duyeagle.googlepages.com/phanquyen.rar
Tắt Security warning của Access
Hỏi
khi mở database thì xuất hiện thông báo “Security warning Certain content in the database has been disabled” và chọn nút option thì xuất hiện tiếp bảng thông báo và phải chọn Enble this content.
Xin các bạn hướng dẫn viết code để khi sử dụng bất kỳ máy tính nào khi mở database này lên không còn xuất hiện thông báo nữa và mặc định là chọn Enble this content.
Đáp
Cái này là tùy chọn của hệ thống, không liên quan chương trình của bạn.
Để lần sau hệ thống không còn hỏi nữa, bạn mở ms Access lên. Vào Tool->macro ->sercurity. Chọn Low-> OK
--------------------------------------------------------------------
Cách Khác:
Tổng quát, vấn đề này do Windows quản lý trong registry, vì vậy bạn soạn 1 file text và chuyển thành đuôi .reg với nội dung sau. :
Save lại và run trên máy có chạy ứng dụng Access
Chú ý, đây là mình đang dùng với Access2003
Bạn có thể sửa thông số tương ứng cho các bản Office khác.ví dụ Office 2007 thì đổi thành 12.0 [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
khi mở database thì xuất hiện thông báo “Security warning Certain content in the database has been disabled” và chọn nút option thì xuất hiện tiếp bảng thông báo và phải chọn Enble this content.
Xin các bạn hướng dẫn viết code để khi sử dụng bất kỳ máy tính nào khi mở database này lên không còn xuất hiện thông báo nữa và mặc định là chọn Enble this content.
Đáp
Cái này là tùy chọn của hệ thống, không liên quan chương trình của bạn.
Để lần sau hệ thống không còn hỏi nữa, bạn mở ms Access lên. Vào Tool->macro ->sercurity. Chọn Low-> OK
--------------------------------------------------------------------
Cách Khác:
Tổng quát, vấn đề này do Windows quản lý trong registry, vì vậy bạn soạn 1 file text và chuyển thành đuôi .reg với nội dung sau. :
Code:
[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Access\Security]
"Level"=dword:00000001
Chú ý, đây là mình đang dùng với Access2003
Bạn có thể sửa thông số tương ứng cho các bản Office khác.ví dụ Office 2007 thì đổi thành 12.0 [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Chuyển chữ thường thành chữ Hoa
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])
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])
Thay thế báo lỗi tiếng Anh bằng tiếng Việt
Thường khi thao tác với Access, bạn hay gặp các câu báo lỗi bằng tiếng Anh, thay vào đó, bạn muốn khi gặp lỗi tương tự thì phải báo bằng tiếng Việt.
Ta làm như sau:
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 :
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
(hungtano)
Ta làm như sau:
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 :
Code:
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
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
(hungtano)
Code Kiểm tra sự tồn tại của 1 file trong Access
' kiem tra su ton tai file
Ví dụ: Ở sự kiện Load form của Form chính, bạn chọn cho code này vào:
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
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
Một Cách khác (spammail - khoahocphothong.net)
Tạo 1 macro tên phải là AutoKeys :
Macro Name________Action
{F7}_______________Open Report (Nhấn F7 để mở report nào đó)
^{F7}_____________ Open Report (Nhấn Ctrl+ F7 để mở report nào đó)
+{F1}______________Open Report (Nhấn Shift + F7 để mở report nào đó)
^A_________________Msgbox (Nhấn Ctrl+ A sẽ hiện thông báo gì đó)
Đá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
Một Cách khác (spammail - khoahocphothong.net)
Tạo 1 macro tên phải là AutoKeys :
Macro Name________Action
{F7}_______________Open Report (Nhấn F7 để mở report nào đó)
^{F7}_____________ Open Report (Nhấn Ctrl+ F7 để mở report nào đó)
+{F1}______________Open Report (Nhấn Shift + F7 để mở report nào đó)
^A_________________Msgbox (Nhấn Ctrl+ A sẽ hiện thông báo gì đó)
Code kiểm tra sự tồn tại của table
Public Function KIEMTRA(TableName As String)As Boolean
' Khai báo biến cục bộ truy xuất đến Database Access
Dim DB As Database
' Biến N lưu trữ số Tables của Database (dùng Byte là đủ)
Dim N As Byte
' Biến i để duyệt qua từng Table
Dim i As Byte
' Khởi tạo biến DB
Set DB = DBEngine.Workspaces(0).Databases(0)
' Lấy số Tables có trong Database
n = DB.TableDefs.Count
' Duyệt tuần tự từng Table
For i = 0 To n - 1
' Nếu tên Table thứ i bằng với tên Table muốn tìm
If DB.TableDefs(i).Name = TableName Then
' Hàm trả về giá trị TRUE
KIEMTRA = True
' Thoát khỏi hàm
Exit Function
End If
' Chuyển qua Table kế
Next i
' Nếu ra khỏi vòng lặp mà vẫn chưa tìm thấy thì hàm trả về False
KIEMTRA = False
End Function
Thứ Sáu, 13 tháng 11, 2009
Hàm Tách Tên, Họ trong Access
Mình xin giới thiệu 1 hàm tự tách tên, họ trong Access:
Chú Thích: Hàm này dùng hiệu quả trong việc tách tên họ. Truyền đối số như sau:
Ten: Tên đầy đủ ( fullname)
Kiểu: 0 : Tách Tên, 1 Tách Họ
Ví Dụ:
Name=Phạm Thị Mỹ Hạnh
msgbox Split(Name,0) => Hạnh
msgbox Split(Name,1) => Phạm Thị Mỹ
Public Function Split(Ten As String, Kieu As Byte)
Dim bytSpace As Byte
bytSpace = InStrRev(Ten, " ", -1)
If bytSpace = 0 Then
Split = Ten
Exit Function
End If
If Kieu = 0 Then
Split = Right(Ten, Len(Ten) - bytSpace)
Else
Split = Left(Ten, bytSpace - 1)
End If
End Function
Dim bytSpace As Byte
bytSpace = InStrRev(Ten, " ", -1)
If bytSpace = 0 Then
Split = Ten
Exit Function
End If
If Kieu = 0 Then
Split = Right(Ten, Len(Ten) - bytSpace)
Else
Split = Left(Ten, bytSpace - 1)
End If
End Function
Chú Thích: Hàm này dùng hiệu quả trong việc tách tên họ. Truyền đối số như sau:
Ten: Tên đầy đủ ( fullname)
Kiểu: 0 : Tách Tên, 1 Tách Họ
Ví Dụ:
Name=Phạm Thị Mỹ Hạnh
msgbox Split(Name,0) => Hạnh
msgbox Split(Name,1) => Phạm Thị Mỹ
Thứ Năm, 12 tháng 11, 2009
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:
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:
Nhớ lưu trước khi thử nghiệm nhé
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
Ở đâ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
Nhớ lưu trước khi thử nghiệm nhé
Thứ Tư, 11 tháng 11, 2009
Upsize Access lên MS SQL server
Theo thực tế 1 database Access còn rất nhiều hạn chế về :
_ Phân quyền sử dụng.
_ Sử dụng tối đa 10 users .
_ Quản lý và lưu vết user đã ghi/đọc/xóa ...
Trong cuộc sống náo nhiệt, môi trường sử dụng phần mềm quản lý khá phong phú đa dạng với nhiều ngôn ngữ lập trình khác nhau. Đối với việc sử dụng database trong một mạng Lan cũng rất phổ biến.
Nay mình có 1 datbase access quản lý hồ sơ muốn share cho mọi người dùng chung mạng Lan, qua việc đọc 1 số bài hướng dẫn sơ lược và có đề cập đưa database Access lên SQL Server để quản lý cao hơn, chuyên nghiệp hơn.
Mong Noname và các bạn hướng dẫn cụ thể và có hình ảnh minh họa về việc đưa database Access lên SQL Sever, đây cũng là vấn đề khó giải quyết và nóng bỏng nhất đối với các bạn khác. Chân thành cảm ơn
Đáp
Chuyển Access lên SQL server trong những trường hợp bạn muốn phân quyền rõ ràng hơn, cơ sở dữ liệu của bạn đã tương đối lớn, bạn muốn share cho số user lớn...đó là một giải háp hợp lý.
Chuẩn bị cho việc chuyển đổi, bạn phải có một máy tính tương đối mạnh cài windows server như win 2k, win 2k3, win 2k7..
Bạn cài các bản SQL server standard hoặc enterprice. Hoặc để thử nghiệm thì bạn dùng bản personal trên winxp.
Xong phần chuẩn bị, giờ bạn sang phần upsize.
Mở CSDL Access của bạn, từ Access 2k trở đi sẽ hỗ trợ Upsize lên SQL server.
Vào Tool -> database utilities -> upsizing wizard

Trong cửa sổ upsize, chọn create new database rồi nhấn next
Chọn tên server, password SA khi cài SQL server, chọn tên cho database rồi nhấn next

Chọn các table muốn up lên SQL server (nhấn >> để chọn tất cả) ->next

Trong khung thoại hỏi bạn có giữ lại data hay chỉ lấy cấu trúc, có giữ lại các relationship không, bạn tuỳ ý chọn rồi nhấn, Next tiếp nếu bạn không cần thêm tuỳ chỉnh gì hoặc chọn chỉ giữ lại cấu trúc.

Cửa sổ tiếp theo hỏi bạn có tạo ra một ứng dụng trên nền SQL server không. Tuỳ bạn quyết định có tiếp tục dùng Access như một ứng dụng máy chủ/khách hay là viết một ứng dụng khác, chỉ giữ phần dữ liệu. Mình thì mình chọn mục 2: Link SQL table to exit aplication - >next->finish

Sau khi upsize, bạn chỉ link table để nhập liệu, thao tác, truy xuất.

Mọi việc chỉnh sửa cấu trúc và phân quyền đều phải thông qua SQL server.

_ Phân quyền sử dụng.
_ Sử dụng tối đa 10 users .
_ Quản lý và lưu vết user đã ghi/đọc/xóa ...
Trong cuộc sống náo nhiệt, môi trường sử dụng phần mềm quản lý khá phong phú đa dạng với nhiều ngôn ngữ lập trình khác nhau. Đối với việc sử dụng database trong một mạng Lan cũng rất phổ biến.
Nay mình có 1 datbase access quản lý hồ sơ muốn share cho mọi người dùng chung mạng Lan, qua việc đọc 1 số bài hướng dẫn sơ lược và có đề cập đưa database Access lên SQL Server để quản lý cao hơn, chuyên nghiệp hơn.
Mong Noname và các bạn hướng dẫn cụ thể và có hình ảnh minh họa về việc đưa database Access lên SQL Sever, đây cũng là vấn đề khó giải quyết và nóng bỏng nhất đối với các bạn khác. Chân thành cảm ơn
Đáp
Chuyển Access lên SQL server trong những trường hợp bạn muốn phân quyền rõ ràng hơn, cơ sở dữ liệu của bạn đã tương đối lớn, bạn muốn share cho số user lớn...đó là một giải háp hợp lý.
Chuẩn bị cho việc chuyển đổi, bạn phải có một máy tính tương đối mạnh cài windows server như win 2k, win 2k3, win 2k7..
Bạn cài các bản SQL server standard hoặc enterprice. Hoặc để thử nghiệm thì bạn dùng bản personal trên winxp.
Xong phần chuẩn bị, giờ bạn sang phần upsize.
Mở CSDL Access của bạn, từ Access 2k trở đi sẽ hỗ trợ Upsize lên SQL server.
Vào Tool -> database utilities -> upsizing wizard

Trong cửa sổ upsize, chọn create new database rồi nhấn next
Chọn tên server, password SA khi cài SQL server, chọn tên cho database rồi nhấn next

Chọn các table muốn up lên SQL server (nhấn >> để chọn tất cả) ->next

Trong khung thoại hỏi bạn có giữ lại data hay chỉ lấy cấu trúc, có giữ lại các relationship không, bạn tuỳ ý chọn rồi nhấn, Next tiếp nếu bạn không cần thêm tuỳ chỉnh gì hoặc chọn chỉ giữ lại cấu trúc.

Cửa sổ tiếp theo hỏi bạn có tạo ra một ứng dụng trên nền SQL server không. Tuỳ bạn quyết định có tiếp tục dùng Access như một ứng dụng máy chủ/khách hay là viết một ứng dụng khác, chỉ giữ phần dữ liệu. Mình thì mình chọn mục 2: Link SQL table to exit aplication - >next->finish

Sau khi upsize, bạn chỉ link table để nhập liệu, thao tác, truy xuất.

Mọi việc chỉnh sửa cấu trúc và phân quyền đều phải thông qua SQL server.

Hiện thông báo không có dữ liệu khi in report
Cho mình hỏi: Mình tạo 1 form in từ ngày đến ngày,
nếu trong điều kiện đó mà reprt kô có dữ liệu thì hiện ra 1 câu thông báo tại form luôn và kô hiện ra report.
Đáp:
Bất cứ report nào cũng có record source đúng không, thường là 1 query/table.
Như vậy vấn đề ở đây là bạn kiểm tra query/table xem có record nào không, nếu không có=> gởi thông báo.
Nếu có thì cho in report. Đơn giản vậy thôi
Private Sub In_Click()
dim rec as Recordset
dim db as Database
set db = CurrentDB()
set rec = db.Openrecordset("tên bảng")
If rec.recordcount> o then
[in report]
else
[thong bao]
end if
End Sub
nếu trong điều kiện đó mà reprt kô có dữ liệu thì hiện ra 1 câu thông báo tại form luôn và kô hiện ra report.
Đáp:
Bất cứ report nào cũng có record source đúng không, thường là 1 query/table.
Như vậy vấn đề ở đây là bạn kiểm tra query/table xem có record nào không, nếu không có=> gởi thông báo.
Nếu có thì cho in report. Đơn giản vậy thôi
Private Sub In_Click()
dim rec as Recordset
dim db as Database
set db = CurrentDB()
set rec = db.Openrecordset("tên bảng")
If rec.recordcount> o then
[in report]
else
[thong bao]
end if
End Sub
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
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
Tạo chương trình trắc nghiệm bằng Access
Tôi xin trình bày một ví dụ đơn giản nhưng rất cơ bản để từ đó bạn có thể tự "chíp" theo ý đồ của mình. Ví dụ: số câu hỏi cho mỗi lần trắc nghiệm là 30 (được chọn ngẫu nhiên từ ngân hàng câu hỏi), chọn 1 trong 4 đáp án.
Giả sử ứng dụng Access có tên là DataTN.MDB. Bạn tạo một table có tên NganHangCauHoi để chứa ngân hàng các câu hỏi, có cấu trúc như bảng 1. Bảng này chứa số lượng không hạn chế các câu hỏi, mỗi câu hỏi được đánh số tự động, và có 4 mục tin (TraLoi1, TraLoi2, TraLoi3, TraLoi4) chứa nội dung 4 câu trả lời mà thí sinh có thể chọn. Mục tin DapAnDung chứa số thứ tự (từ 1 đến 4) của câu trả lời đúng. Mục tin DaDuocChon dùng để đánh dấu câu hỏi nào đã được chọn trong quá trình lựa chọn ngẫu nhiên 30 câu hỏi dùng cho bộ đề. Bạn cần phải thiết kế một form để nhập liệu vào bảng này.
Tương tự, bạn cần tạo bảng DeThiVaKetQua như trong bảng 2 để chứa bộ đề 30 câu hỏi. Bảng này có mục tin DapAnDuocChon cho biết thí sinh đã chọn câu trả lời nào trong 4 câu trả lời được phép. Giả sử: trả lời đúng được 1 điểm, trả lời sai được 0 điểm. Tạo một query có tên qryDeThiVaKetQua như hình 2 để làm Record Source cho form trắc nghiệm.
Sau khi thiết kế xong cấu trúc các bảng, việc đầu tiên bạn nên làm là nhập hơn 30 câu hỏi vào ngân hàng câu hỏi.
Bạn thiết kế biểu mẫu trắc nghiệm như trong hình 1. Khi thiết kế biểu mẫu này, cần lưu ý:
Đặt thuộc tính AllowAdditions của form là No. Thuộc tính Locked của ô SoThuTu và NoiDung là Yes.
Đặt tên cho frame chứa 4 đáp án là grpTraLoi. Đặt tên cho các label liên kết với mỗi option thuộc grpTraLoi lần lượt là lblTraLoi1, lblTraLoi2, lblTraLoi3, lblTraLoi4 theo thứ tự từ trên xuống.
Đặt tên cho 2 nút lệnh Kết quả và Chọn đề là cmdKetQua và cmdChonDe. Xong, bạn gõ vào đoạn mã 1 (xử lý tình huống).
Đoạn mã 1


H1:Form Trắc nghiệm

Query cho form
CHƯƠNG CAN CHÍP : st từ Theo Echip
Giả sử ứng dụng Access có tên là DataTN.MDB. Bạn tạo một table có tên NganHangCauHoi để chứa ngân hàng các câu hỏi, có cấu trúc như bảng 1. Bảng này chứa số lượng không hạn chế các câu hỏi, mỗi câu hỏi được đánh số tự động, và có 4 mục tin (TraLoi1, TraLoi2, TraLoi3, TraLoi4) chứa nội dung 4 câu trả lời mà thí sinh có thể chọn. Mục tin DapAnDung chứa số thứ tự (từ 1 đến 4) của câu trả lời đúng. Mục tin DaDuocChon dùng để đánh dấu câu hỏi nào đã được chọn trong quá trình lựa chọn ngẫu nhiên 30 câu hỏi dùng cho bộ đề. Bạn cần phải thiết kế một form để nhập liệu vào bảng này.
Tương tự, bạn cần tạo bảng DeThiVaKetQua như trong bảng 2 để chứa bộ đề 30 câu hỏi. Bảng này có mục tin DapAnDuocChon cho biết thí sinh đã chọn câu trả lời nào trong 4 câu trả lời được phép. Giả sử: trả lời đúng được 1 điểm, trả lời sai được 0 điểm. Tạo một query có tên qryDeThiVaKetQua như hình 2 để làm Record Source cho form trắc nghiệm.
Sau khi thiết kế xong cấu trúc các bảng, việc đầu tiên bạn nên làm là nhập hơn 30 câu hỏi vào ngân hàng câu hỏi.
Bạn thiết kế biểu mẫu trắc nghiệm như trong hình 1. Khi thiết kế biểu mẫu này, cần lưu ý:
Đặt thuộc tính AllowAdditions của form là No. Thuộc tính Locked của ô SoThuTu và NoiDung là Yes.
Đặt tên cho frame chứa 4 đáp án là grpTraLoi. Đặt tên cho các label liên kết với mỗi option thuộc grpTraLoi lần lượt là lblTraLoi1, lblTraLoi2, lblTraLoi3, lblTraLoi4 theo thứ tự từ trên xuống.
Đặt tên cho 2 nút lệnh Kết quả và Chọn đề là cmdKetQua và cmdChonDe. Xong, bạn gõ vào đoạn mã 1 (xử lý tình huống).
Đoạn mã 1
Code:
Private Sub Form_Current()
‘ Nội dung 4 đáp án liệt kê mỗi lần chuyển sang câu khác
lblTraLoi1.Caption = Me.TraLoi1
lblTraLoi2.Caption = Me.TraLoi2
lblTraLoi3.Caption = Me.TraLoi3
lblTraLoi4.Caption = Me.TraLoi4
grpTraLoi = Me.DapAnDuocChon
End Sub
Private Sub grpTraLoi_Click()
Me.DapAnDuocChon = grpTraLoi ‘ Khi thí sinh chọn đáp án
End Sub
Private Sub cmdChonDe_Click()
Dim db As Database, tbDeThi As Recordset, tbNganHang As Recordset
Dim rsTamThoi As Recordset
Dim nSoLuongCau As Byte, I As Byte, sSQL As String
Dim nTongSoCauTrongNH As Long, nSoNgauNhien As Long
nSoLuongCau = 30 ' Giả sử 30 câu
Set db = CurrentDb
' Tạm thời không kiểm tra trường hợp số lượng câu hỏi cần chọn có lớn hơn
' hay bằng tổng số câu trong ngân hàng đề thi không
Set tbNganHang = db.OpenRecordset("NganHangCauHoi")
tbNganHang.MoveFirst
If tbNganHang.EOF Then
MsgBox "Không có câu hỏi trong ngân hàng dữ liệu đề thi !"
tbNganHang.Close
db.Close
Exit Sub
End If
' Xóa đề trước đó
sSQL = "DELETE * FROM DeThiVaKetQua;"
db.Execute sSQL
' Tính tổng số câu hỏi trong ngân hàng đề thi
sSQL = "SELECT Max(SoThuTu) AS TongSoCauHoi FROM NganHangCauHoi"
Set rsTamThoi = db.OpenRecordset(sSQL)
rsTamThoi.MoveFirst
nTongSoCauTrongNH = rsTamThoi!TongSoCauHoi
rsTamThoi.Close
Set tbDeThi = db.OpenRecordset("DeThiVaKetQua")
' Tạo đề mới
tbNganHang.Index = "SoThuTu"
For I = 1 To nSoLuongCau
Do While True
nSoNgauNhien = Int((nTongSoCauTrongNH * Rnd) + 1) ‘ Chọn số thứ tự ngẫu nhiên
tbNganHang.Seek "=", nSoNgauNhien
If Not tbNganHang.NoMatch Then ' chắc chắn tìm thấy
If Not tbNganHang!DaDuocChon Then ' Câu này chưa chọn
tbDeThi.AddNew
tbDeThi!SoThuTu = I
tbDeThi!NoiDung = tbNganHang!NoiDung
tbDeThi!TraLoi1 = tbNganHang!TraLoi1
tbDeThi!TraLoi2 = tbNganHang!TraLoi2
tbDeThi!TraLoi3 = tbNganHang!TraLoi3
tbDeThi!TraLoi4 = tbNganHang!TraLoi4
tbDeThi!DapAnDung = tbNganHang!DapAnDung
tbDeThi!DapAnDuocChon = 0
tbDeThi.Update
' Đánh dấu đã chọn câu này để đưa vào bộ đề thi rồi
tbNganHang.Edit
tbNganHang!DaDuocChon = True
tbNganHang.Update
Exit Do
End If
End If
Loop
Next
tbDeThi.Close
' Đánh dấu chưa được chọn đối với các câu hỏi trong ngân hàng đề thi
tbNganHang.Close
sSQL = "UPDATE NganHangCauHoi SET DaDuocChon = False WHERE DaDuocChon = True"
db.Execute (sSQL)
db.Close
' Bộ đề mới đã tạo xong, hiển thị lại trên biểu mẫu
Me.Requery
SoThuTu.SetFocus ‘ Để có thể disable nút Chọn đề
cmdChonDe.Enabled = False ‘ Không cho chọn đề khác nữa
End Sub
Private Sub cmdKetQua_Click()
Dim nTongDiem As Byte, rs As Recordset
Set rs = Me.Recordset
nTongDiem = 0
With rs
.MoveFirst
While Not .EOF
nTongDiem = nTongDiem + IIf(!DapAnDuocChon = !DapAnDung, 1, 0)
.MoveNext
Wend
.MoveFirst
End With
MsgBox "Tổng số điểm đạt được là: " & nTongDiem, vbInformation, Me.Caption
Set rs = Nothing
End Sub

H1:Form Trắc nghiệm

Query cho form
CHƯƠNG CAN CHÍP : st từ Theo Echip
Làm sổ quỹ trong Access
Em muốn làm trình kế toán với số liệu thu chi và quỹ còn lại . Ví dụ như sau:
STT___Thu___Chi_______Quỹ còn lại______Diễn giải
1_____0_____100_______500____________mua vật tư
2_____200___0_________700____________kế hoạch a
3_____300___0_________1000___________kế hoạch b
Quỹ còn lại 3 = [quỹ còn lại 2] + [thu 2] - [chi 2]
Bác nào biết cách làm hướng dẫn chi tiết dùm em với, em làm query trong MS Access.
Đáp:
Cái bạn nêu trên thực ra là phần báo cáo(report) . Bạn cần tổ chức CSDL cho hợp lý thì out ra báo cáo dễ dàng hơn.
Ví dụ bạn có thể tổ chức dữ liệu thế này:
Bảng:Nhật ký
Ngày : Date
ThuChi : Yes/No
SốTiền: number(Douple)
Diễn giải: text
….
Tồn đầu kỳ thực tế chỉ là 1 transaction với diễn giãi là Tồn đầu kỳ, dư nợ sẽ nằm bên phần thu nên thuộc tính của ThuChi là yes.
Xong phần cơ bản của thiết kế CSDL.
Bây giờ bạn chuyển từ dữ liệu thô sang report.Report bao giờ cũng chạy trên nền query, vì vậy bạn nên tạo 1 query trung gian thế này:
giờ bạn chuyển từ dữ liệu thô sang report.Report bao giờ cũng chạy trên nền query, vì vậy bạn nên tạo 1 query trung gian thế này:
Đặt tên là qrSoquy
Bây giờ bạn tạo 1 report , lấy control source là qrSoquy
Các field như bạn đã nêu. Riêng ô số thứ tự là 1 ô có Control source =1, và thuộc tính running sum là over group, field Còn lại của bạn lấy control source là sotien1 và thuộc tính running sum cũng là over group. Còn lại thì gán thuộc tính bình thường.
Mình đã làm thử 1 chương trình soquy đon giản bằng Access, mời bạn tham khảo. http://duyeagle.googlepages.com/soquyDemo.rar
STT___Thu___Chi_______Quỹ còn lại______Diễn giải
1_____0_____100_______500____________mua vật tư
2_____200___0_________700____________kế hoạch a
3_____300___0_________1000___________kế hoạch b
Quỹ còn lại 3 = [quỹ còn lại 2] + [thu 2] - [chi 2]
Bác nào biết cách làm hướng dẫn chi tiết dùm em với, em làm query trong MS Access.
Đáp:
Cái bạn nêu trên thực ra là phần báo cáo(report) . Bạn cần tổ chức CSDL cho hợp lý thì out ra báo cáo dễ dàng hơn.
Ví dụ bạn có thể tổ chức dữ liệu thế này:
Bảng:Nhật ký
Ngày : Date
ThuChi : Yes/No
SốTiền: number(Douple)
Diễn giải: text
….
Tồn đầu kỳ thực tế chỉ là 1 transaction với diễn giãi là Tồn đầu kỳ, dư nợ sẽ nằm bên phần thu nên thuộc tính của ThuChi là yes.
Xong phần cơ bản của thiết kế CSDL.
Bây giờ bạn chuyển từ dữ liệu thô sang report.Report bao giờ cũng chạy trên nền query, vì vậy bạn nên tạo 1 query trung gian thế này:
giờ bạn chuyển từ dữ liệu thô sang report.Report bao giờ cũng chạy trên nền query, vì vậy bạn nên tạo 1 query trung gian thế này:
Code:
SELECT soquy.sochungtu, soquy.ngay, soquy.thuchi, soquy.sotien, soquy.diengiai, IIf([thuchi],[sotien],[sotien]*-1) AS sotien1, IIf([thuchi],[sotien],0) AS Thu, IIf([thuchi],0,[sotien]) AS Chi
FROM soquy
ORDER BY soquy.ngay;
Bây giờ bạn tạo 1 report , lấy control source là qrSoquy
Các field như bạn đã nêu. Riêng ô số thứ tự là 1 ô có Control source =1, và thuộc tính running sum là over group, field Còn lại của bạn lấy control source là sotien1 và thuộc tính running sum cũng là over group. Còn lại thì gán thuộc tính bình thường.
Mình đã làm thử 1 chương trình soquy đon giản bằng Access, mời bạn tham khảo. http://duyeagle.googlepages.com/soquyDemo.rar
Thứ Ba, 10 tháng 11, 2009
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:
soluongtxt là field bạn cần format!
- 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
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.
Và sau đây mình xin giới thiệu 2 phương pháp để có thể có msgbox bằng tiếng Việt Unicode mà không phải thay đổi hệ thống hay phức tạp gì. Mời bạn xem ứng chương trình demo.
Có thắc mắc gì xin hỏi tại đây!
Tải Demo
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.
Và sau đây mình xin giới thiệu 2 phương pháp để có thể có msgbox bằng tiếng Việt Unicode mà không phải thay đổi hệ thống hay phức tạp gì. Mời bạn xem ứng chương trình demo.
Có thắc mắc gì xin hỏi tại đây!
Tải Demo
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:
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.
.
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. [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
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. [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Thứ Hai, 9 tháng 11, 2009
thao tác với registry
Đôi khi bạn có nhu cầu làm việc với registry trong Access, ví dụ lưu vị trí form, lưu đường dẫn mặc định để lấy dữ liệu. Hoặc lưu username mặc định, kiểm tra 1 computer có phải lần đầu tiên sử dụng chương trình không... Mọi việcsẽ dễ dàng hơn nhiều nếu bạn thao tác với registry....
SaveSetting (appname, section, key, setting) : dùng ghi vào registry
GetSetting(appname, section, key[, default]) : đọc giá trị từ registry
DeleteSetting (appname, section[, key] ) : xoá giá trị trong registry
GetAllSettings(appname, section) : Lấy hết giá trị của ứng dụng được lưu tại section
Ví dụ:
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
SaveSetting (appname, section, key, setting) : dùng ghi vào registry
GetSetting(appname, section, key[, default]) : đọc giá trị từ registry
DeleteSetting (appname, section[, key] ) : xoá giá trị trong registry
GetAllSettings(appname, section) : Lấy hết giá trị của ứng dụng được lưu tại section
Ví dụ:
Code:
' Variant to hold 2-dimensional array returned by GetAllSettings
' Integer to hold counter.
Dim MySettings As Variant, intSettings As Integer
' Place some settings in the registry.
SaveSetting appname := "MyApp", section := "Startup", _
key := "Top", setting := 75
SaveSetting "MyApp","Startup", "Left", 50
' Retrieve the settings.
MySettings = GetAllSettings(appname := "MyApp", section := "Startup")
For intSettings = LBound(MySettings, 1) To UBound(MySettings, 1)
Debug.Print MySettings(intSettings, 0), MySettings(intSettings, 1)
Next intSettings
DeleteSetting "MyApp", "Startup"
Website : http://www.khoahocphothong.net [/right]
Chặn xoay chuột để tới lui record
Chặn xoay chuột để tới lui record
Thiết kết trên Form mình đã tắc Record Selector để không cho tới lui các Record đã nhập trước đó, nhưng khi dùng nút giữa xoay chuột nó vẫn chạy tới lui.
Hỏi: Làm sao để chặn thao tác xoay chuột "Cuộn lên xuống bằng nút xoay trên Mouse".
Đáp: Form Wheel
Trong sự kiện xoay chuột, ta chèn code này vào:
Thiết kết trên Form mình đã tắc Record Selector để không cho tới lui các Record đã nhập trước đó, nhưng khi dùng nút giữa xoay chuột nó vẫn chạy tới lui.
Hỏi: Làm sao để chặn thao tác xoay chuột "Cuộn lên xuống bằng nút xoay trên Mouse".
Đáp: Form Wheel
Trong sự kiện xoay chuột, ta chèn code này vào:
Code:
Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long)
MsgBox "Can't use Wheel Button"
If Count = -3 Then
DoCmd.GoToRecord , , acNext
Else
DoCmd.GoToRecord , , acPrevious
End If
End Sub
Lệnh Tạm ngưng trong Access
Trong Access, khi bạn cần tạm ngưng chương trình trong một khoảng thời gian nào đó trước khi thực hiện lệnh mới. Ta dùng hàm Sleep. Để sử dụng được hàm này, ta khai báo :
Public Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Và sử dụng:
Sleep (5000)
để tạm ngưng 5 giây!
Lấy về tên của máy tính đang dùng:
Lấy về tên của máy tính đang dùng:
Environ("ComputerName")
Ứng dụng bạn có thể phân quyền cho user cụ thể nào đó như chief accountant...hoặc vị trí cố định mà bắt buộc phải dùng PC đó mới có thể chạy được Module.
Đơn giản hơn là trong hành động Form Load, bạn chào hỏi bằng hàm này:
msgbox "Hello " & Environ("ComputerName")
Environ("ComputerName")
Ứng dụng bạn có thể phân quyền cho user cụ thể nào đó như chief accountant...hoặc vị trí cố định mà bắt buộc phải dùng PC đó mới có thể chạy được Module.
Đơn giản hơn là trong hành động Form Load, bạn chào hỏi bằng hàm này:
msgbox "Hello " & Environ("ComputerName")
Tạo đồng hồ trong Access
Đó hỏi: Có cách nào để tạo đồng hồ trong chương trình Access (dưới dạng text box chẳng hạn) đồng bộ với đồng hồ máy tính?
Đây trả lời: Bạn có thể sử dụng thuộc tính Timer Interval và thủ tục xử lý tình huống OnTimer. Cụ thể, trên form vẽ một text box có tên txtDongHo. Gán trị 1000 cho thuộc tính Timer Interval của form, rồi gõ đoạn mã 1 vào thủ tục xử lý tình huống OnTimer của form.
Đoạn mã 1
Private Sub Form_Timer()
txtDongHo = Format(Hour(Time()), "00") & ":" & _
Format(Minute(Time()), "00") & ":" & _
Format(Second(Time()), "00")
End Sub
CHƯƠNG CAN CHÍP
theo echip [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Tạo report có chiều cao co dãn theo dữ liệu
Trong khi làm report. Có những dữ liệu vượt quá chiều ngang của field trình bày. Nhưng nếu ta set cho field đó có khả năng can grow thì nó sẽ nhảy dòng, làm lệch các khung ta đã canh chỉnh.Những người có kinh nghiệm giải quyết bằng cách chừa 1 khoảng trống đủ lớn để không bị "rớt dòng" đại loại như thế! Tuy nhiên, nếu không có dữ liệu nào thừa rớt dòng thì khoảng trống đó lãng phí trong report!
Vấn đề đặt ra là làm cách nào để report có thể tự do dãn chiều cao ở mỗi dòng khác nhau cho phù hợp với dữ liệu
Mình gợi ý theo một hướng khác là ta dùng hàm line để vẽ các đối tượng draw trên report, như vậy bạn sẽ có các đường kẻ đứng co dãn theo field.
Dưới đây là ví dụ mình sẽ vẽ hai đường thẳng đứng tự co dãn, bạn về tùy biến cho phù hợp nha
Copy dòng code vào thủ tục Detail_Print cuả report:
- Bạn print preview sẽ có 2 đường thẳng rộng 0.01cm, chiều dài bằng chiều cao phần detail (đã co dãn, tối đa là 56cm). 2 đường có top-đỉnh là 0 cm, mép trái là 0cm và 3cm.
- Code trong report của Access dùng đơn vị twip, 1cm=567twips
Các đường ngang bạn chỉ cần vẽ 1 đường có Top=0, left=0 và chiều dài bằng chiều dài report ở phần detail.
Copy 1 đường tương tự cho các Group Footer và Report Footer như vậy bạn đã có thể co giãn như ý rồi

DownLoad Chương trình demo
Vấn đề đặt ra là làm cách nào để report có thể tự do dãn chiều cao ở mỗi dòng khác nhau cho phù hợp với dữ liệu
Mình gợi ý theo một hướng khác là ta dùng hàm line để vẽ các đối tượng draw trên report, như vậy bạn sẽ có các đường kẻ đứng co dãn theo field.
Dưới đây là ví dụ mình sẽ vẽ hai đường thẳng đứng tự co dãn, bạn về tùy biến cho phù hợp nha
Code:
Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
Me.Line (0, 0)-Step(0.01 * 567, 56 * 567), , BF
Me.Line (3 * 567, 0)-Step(0.01 * 567, 56 * 567), , BF
End Sub
- Bạn print preview sẽ có 2 đường thẳng rộng 0.01cm, chiều dài bằng chiều cao phần detail (đã co dãn, tối đa là 56cm). 2 đường có top-đỉnh là 0 cm, mép trái là 0cm và 3cm.
- Code trong report của Access dùng đơn vị twip, 1cm=567twips
Các đường ngang bạn chỉ cần vẽ 1 đường có Top=0, left=0 và chiều dài bằng chiều dài report ở phần detail.
Copy 1 đường tương tự cho các Group Footer và Report Footer như vậy bạn đã có thể co giãn như ý rồi
DownLoad Chương trình demo
Mở nút Close(x) khi đã khóa
Hỏi: Theo hướng dẫn trên, tôi đã khoa nút close , giờ muốn mở lại thì làm thế nào?
Đáp:
Bạn tạo 1 Module mới với nội dung sau:
Trong form Admin hãy tạo 1 nút để gọi hàm UnHideAccessCloseButton nhấn nút và đóng lại rồi xem kết quả nhé!
Đáp:
Bạn tạo 1 Module mới với nội dung sau:
Code:
Private Const GWL_EXSTYLE = (-20)
Private Const GWL_STYLE = (-16)
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_SYSMENU = &H80000
Private Const HWND_TOP = 0
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const SWP_FRAMECHANGED = &H20
Private Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) _
As Long
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
Sub UnHideAccessCloseButton()
Dim lngStyle As Long
lngStyle = GetWindowLong(hWndAccessApp, GWL_STYLE)
lngStyle = lngStyle Or WS_SYSMENU
Call SetWindowLong(hWndAccessApp, GWL_STYLE, lngStyle)
Call SetWindowPos(hWndAccessApp, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_DRAWFRAME)
End Sub
Khóa phím close trong Access
Hỏi: Tôi đã cung cấp cho người dùng nút đóng trên chương trình Access của tôi và kh6ong muốn họ dùng nút nhất close(x) sẵn của Windows thì phải làm thế nào!
Đáp:
Bạn có thể ẩn nút close bằng đoạn code sau:
Bây giờ trong form Admin của bạn, bạn có thể tạo 1 nút nhấn và gọi hàm HideAccessCloseButton để ẩn nút close. Nếu vẫn chưa được. Hãy đ1ong Access và mở lại.
Xem các hình
Access trước khi ẩn nút

Access sau khi ẩn nút
Đáp:
Bạn có thể ẩn nút close bằng đoạn code sau:
Code:
Private Const GWL_EXSTYLE = (-20)
Private Const GWL_STYLE = (-16)
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_SYSMENU = &H80000
Private Const HWND_TOP = 0
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const SWP_FRAMECHANGED = &H20
Private Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) _
As Long
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
Sub HideAccessCloseButton()
Dim lngStyle As Long
lngStyle = GetWindowLong(hWndAccessApp, GWL_STYLE)
lngStyle = lngStyle And Not WS_SYSMENU
Call SetWindowLong(hWndAccessApp, GWL_STYLE, lngStyle)
Call SetWindowPos(hWndAccessApp, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_DRAWFRAME)
End Sub
Bây giờ trong form Admin của bạn, bạn có thể tạo 1 nút nhấn và gọi hàm HideAccessCloseButton để ẩn nút close. Nếu vẫn chưa được. Hãy đ1ong Access và mở lại.
Xem các hình
Access trước khi ẩn nút

Access sau khi ẩn nút
Khoá phím ctrl-F4 và Alt-F4 , shift
1) Khoá phím ctrl-F4 và Alt-F4
Ý tưởng của hungtano
Bạn tạo 1 macro tên AutoKeys,
- ở cột Macro Name, bạn điền ^{F4}, ở cột Action bạn chọn Msgbox, ở phần dưới Action Argument bạn tạo 1 thông báo "Phím này đã bị khóa"
- ở cột Macro Name, bạn điền %{F4}, ở cột Action bạn chọn Msgbox, ở phần dưới Action Argument bạn tạo 1 thông báo "Phím này đã bị khóa"
2) Phím shisft có công dụng gì ? sao lại khoá phím shift ?
Khi viết xong 1 chương trình trên Access, khi đưa vào sử dụng bạn phải giấu cửa sổ database. Phím shift có công dụng mở cửa sổ database để xem các object của chuơng trình như table, macro, query, ...Để tránh không cho users mở cửa sổ database "quậy phá" các object của CT, người ta phải khóa phím shift. [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Ý tưởng của hungtano
Bạn tạo 1 macro tên AutoKeys,
- ở cột Macro Name, bạn điền ^{F4}, ở cột Action bạn chọn Msgbox, ở phần dưới Action Argument bạn tạo 1 thông báo "Phím này đã bị khóa"
- ở cột Macro Name, bạn điền %{F4}, ở cột Action bạn chọn Msgbox, ở phần dưới Action Argument bạn tạo 1 thông báo "Phím này đã bị khóa"
2) Phím shisft có công dụng gì ? sao lại khoá phím shift ?
Khi viết xong 1 chương trình trên Access, khi đưa vào sử dụng bạn phải giấu cửa sổ database. Phím shift có công dụng mở cửa sổ database để xem các object của chuơng trình như table, macro, query, ...Để tránh không cho users mở cửa sổ database "quậy phá" các object của CT, người ta phải khóa phím shift. [right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Đánh Số Thứ Tự Cho report
Hỏi:
Báo cáo của tôi có rất nhiều dòng, tôi muốn đánh số thứ tự cho mỗi record thì phải làm sao?
Đáp:
Trong phần detail của report, tạo một text box.
Vô Properties của textbox đó,nhảy qua tab Data, đặt thuộc tính Control Source là =1, Thuộc tính runing Sum là Over All. Hehe , nó sẽ đánh số thứ tự toàn bộ các phần tử.
Nếu chỉ muốn đánh số thú tự trong 1 Group thì chon Over Group
Hình minh Họa:

Chúc may mắn!
Báo cáo của tôi có rất nhiều dòng, tôi muốn đánh số thứ tự cho mỗi record thì phải làm sao?
Đáp:
Trong phần detail của report, tạo một text box.
Vô Properties của textbox đó,nhảy qua tab Data, đặt thuộc tính Control Source là =1, Thuộc tính runing Sum là Over All. Hehe , nó sẽ đánh số thứ tự toàn bộ các phần tử.
Nếu chỉ muốn đánh số thú tự trong 1 Group thì chon Over Group
Hình minh Họa:
Chúc may mắn!
Phục Hồi Table lỡ xóa
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
' Notes: Ham nay chi su dung cho Access 95 tro len va con tuy thuoc vao mot so dieu kien sau:
' - Da xoa nham Table nhung chua dong CSDL (đóng rồi thì tui chưa thử)
' - CSDL chua su dung che do compact and comact repair (dọn rác rồi lấy đâu ra mà phục hồi?)
' - CSDL bi xoa boi phan quyen User trong ung dung access cua ban (tui thu roi khoi test nua)
' - Ham nay chi phuc hoi cho mot Table bi xoa gan nhat (những cái trước đó tui bó tay chưa nghĩ ra)
Xin lỗi các bạn chịu khó đọc phần notes kô dấu nhé mình copy cho lẹ (^_^)
------------------------------------------
Chúc thành công!
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
' Notes: Ham nay chi su dung cho Access 95 tro len va con tuy thuoc vao mot so dieu kien sau:
' - Da xoa nham Table nhung chua dong CSDL (đóng rồi thì tui chưa thử)
' - CSDL chua su dung che do compact and comact repair (dọn rác rồi lấy đâu ra mà phục hồi?)
' - CSDL bi xoa boi phan quyen User trong ung dung access cua ban (tui thu roi khoi test nua)
' - Ham nay chi phuc hoi cho mot Table bi xoa gan nhat (những cái trước đó tui bó tay chưa nghĩ ra)
Xin lỗi các bạn chịu khó đọc phần notes kô dấu nhé mình copy cho lẹ (^_^)
------------------------------------------
Chúc thành công!
Enable phím shift khi lỡ chạy module khóa mà quên viết module mở khóa
(bài này là ý tưởng của bạn hungtano)
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à :
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
nén file Access bằng VBA
Bình thường,khi mà các câu lệnh Make, Append, delete thực hiện nhiều lần thì file access của bạn sẽ phình to không tưởng tượng được, có khi lên tới hàng GB, để nén access ta vào menu tool-->database Ulities-->Compact and repair Database
Nhưng đôi khi chúng ta cần thực hiện điều đó bằng VBA vì đã khóa Menu, thay bằng customise menu, hoặc với mục đích thân thiện với người dùng chỉ trên một nút nhấn.
hãy copy đoạn code sau của tác giả Juan M. Afan de Ribera để làm điều đó
Code:
' ***** Code Start *****
Public Sub CompactDB()
CommandBars("Menu Bar"). _
Controls("Tools"). _
Controls("Database utilities"). _
Controls("Compact and repair database..."). _
accDoDefaultAction
End Sub
' ***** Code End *****
Website : http://www.khoahocphothong.net [/right]
Hiện duy nhất một cửa sổ khi mở nhiều form
Trích:
| Các bạn giúp mình với, làm sao khi mở một From VD From này la From Main, trong From Main này có các Nút lệnh để mở các From khác. Thì làm sao khi mở một From khác thì trên Takbar không xuất hiện From này mà vẩn còn From Main hiện diện trên Taskbar. Vì nếu tôi mở nhiều Fron trên một chương trình thì Taskbar sẻ đầy. |
Bỏ dấu check ở mục Windows on Taskbar. khi đó trên Task bar chỉ còn duy nhất 1 màn hình Access thôi, bạn thư nhé.
----------------------
sanyovietnam in MaNguon
Trích:
Nguyên văn bởi hungtano Bổ sung : Vì Access luôn chọn Check box Windows on Taskbar = True (default) nên nếu đem file mdb của bạn sang máy khác thì sẽ gặp lại trường hợp nhiều cửa sổ trên taskbar. Cách tổng quát hơn : Khi mở form Startup bạn thêm dòng lệnh : Private Sub Form_Open(Cancel As Integer) Application.SetOption "ShowWindowsInTaskbar", False End Sub Xem thêm : http://msdn.microsoft.com/library/de...baloptions.asp |
Website : http://www.khoahocphothong.net [/right]
Kiểm tra 1 form trong chương trình đã được mở hay chưa!
Trong access, đôi khi bạn cần kiểm tra một form có đang load hay chưa để lấy về thông số, tránh động tác thừa vì đôi khi load lên một form dạng bảng, có nhiều đối tượng là rất lâu.
Function dưới đây sẽ giúp bạn giải quyết vấn đề đó một cách dễ dàng
Code:
Function fIsLoaded(ByVal strFormName As String) As Boolean
'Giá trị trả về là 0 nếu chưa mở, -1 là đã mở rồi
If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> 0 Then
If Forms(strFormName).CurrentView <> 0 Then
fIsLoaded = True
End If
End If
End Function
'****** Code End ********
Website : http://www.khoahocphothong.net [/right]
Xuống dòng trong Msgbox
Access 97 trở về trước khi xuống dòng dùng ký tự @. Access gần đây dùng vbCrLf để xuống dòng. Việc chủ động xuống dòng trong Msgbox giúp hiển thị thông báo rõ ràng hơn.
MsgBox "1. Hello!" & vbCrLf & "2. Xin chào các bạn!" & vbCrLf & "3. Seeuagain!", vbInformation, "Message"
MsgBox "1. Hello!" & vbCrLf & "2. Xin chào các bạn!" & vbCrLf & "3. Seeuagain!", vbInformation, "Message"
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
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
Convert Null thành zero
Khi bạn phải cộng trừ với 1 giá trị rỗng, lập tức sẽ bị báo lỗi dữ liệu. Nhất là trường hợp các bạn dùng left join sẽ bị cộng khi bên kia không tìm thấy khóa. Vì vậy một mẹo nhỏ là bạn tạo một hàm đển convert giá trị null thành số 0. Sau đó, mỗi khi cộng trừ nhân chia thì ta thêm trước field đó dòng NZ([field chứa giá trị])
Convert Null-Zero
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Convert Null-Zero
Trích:
| Function NZ(anyValue As Variant) As Variant NZ = IIf(IsNull(anyValue), 0, anyValue) End Function |
Website : http://www.khoahocphothong.net [/right]
Ký Tự xuống dòng trong SQL
Hỏi
Cho tôi hỏi khi mình nhập bằng textare có ký bấm enter để xuống dòng vậy phim enter này lưu xuống SQl bằng ký tự gì vậy? bạn nào biết chỉ dùm nha, tôi đã dùng thử "\n" nhưng không đúng
Đáp
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Cho tôi hỏi khi mình nhập bằng textare có ký bấm enter để xuống dòng vậy phim enter này lưu xuống SQl bằng ký tự gì vậy? bạn nào biết chỉ dùm nha, tôi đã dùng thử "\n" nhưng không đúng
Đáp
Trích:
| Nguyên văn bởi huynhvantham Nó là kết hợp 2 ký tụ: CHAR(13) và CHAR(10) Ví dụ bạn muốn Insert: Chạy trong Sql Query: In sert into tablename(firstname,lastname) values('Nguyen' + CHAR(13) + CHAR(10) + 'Van', 'A') Nếu bạn dùng TEXTAREA thì khi insert vào database thì bạn không cần phài thêm ký tụ xuống dòng. Vì TEXTAREA nó đả hổ trợ bạn chỉ cần gán giá trị của TEXTAREA cho Field dưới database là ok. |
Website : http://www.khoahocphothong.net [/right]
Tạo Dòng Chữ chạy trên form
Hỏi
Tạo dòng chữ chạy trên Form của Access: Cũng như mong muốn ở trên, trên 1 Form bất ký mình muốn chạy một dòng chữ để cần thông tin về vấn đề nào đó ví dụ như là "Chương trình này được tạo bởi...."
Đáp:
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Tạo dòng chữ chạy trên Form của Access: Cũng như mong muốn ở trên, trên 1 Form bất ký mình muốn chạy một dòng chữ để cần thông tin về vấn đề nào đó ví dụ như là "Chương trình này được tạo bởi...."
Đáp:
Trích:
| Nguyên văn bởi HungTano Hùng Tano + Bạn tạo 1 label , tên : LblWelcome - 1 nút lịnh, tên CmdRun Nhập các đoạn code sau : Private Sub CmdRun_Click() LblWelcome.Caption = "This program is designed by ..." & Space(3) Me.TimerInterval = 200 End Sub Private Sub Form_Timer() Dim x, y As String x = Left(LblWelcome.Caption, 1) y = Right(LblWelcome.Caption, Len(LblWelcome.Caption) - 1) LblWelcome.Caption = y + x End Sub |
Website : http://www.khoahocphothong.net [/right]
Sử dụng Unicode tiếng Việt trong MS Access
TG:Võ hùng- PC world
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
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
Phân quyền sửa Chương trình trong Access
Hỏi
Bạn nào có biết cách phân quyền sử dụng trong Access không chỉ cho mình với. Có nghĩa là với chương trình mình tạo ra thì chỉ có mình mới có thể sửa source code được, có thể sửa design... được thôi, người sử dụng chỉ được quyền sử dụng và không có quyền truy cập vào source code cũng như table... để sửa chương trình. Ở bên mình mọi người cũng có kiến thức về Access nên biết là cứ bấm F11 là vào được data của chương trình.
Đáp
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Bạn nào có biết cách phân quyền sử dụng trong Access không chỉ cho mình với. Có nghĩa là với chương trình mình tạo ra thì chỉ có mình mới có thể sửa source code được, có thể sửa design... được thôi, người sử dụng chỉ được quyền sử dụng và không có quyền truy cập vào source code cũng như table... để sửa chương trình. Ở bên mình mọi người cũng có kiến thức về Access nên biết là cứ bấm F11 là vào được data của chương trình.
Đáp
Trích:
Nguyên văn bởi hungtano Bạn phải làm 2 việc : 1) Vào Tools --> Startup : bỏ chọn tất cả các check box trên biểu mẫu này. (không cho users sử dụng các phím tắt) Còn muốn triệt để hơn, không cho xem code thì .mdb --> .mde 2) Disable phím SHIFT Nguyên lý : trong database có 1 thuộc tính (property) gọi là : AllowBypassKey. Thuộc tính này cho phép bạn enable/disable phím SHIFT. + Nếu AllowBypassKey = False --> disable phím SHIFT + Nếu AllowBypassKey = True --> enable phím SHIFT Cách làm : bạn tạo 1 Form (tạm gọi : F_ShiftKey) có 2 nút lịnh : 1 để enable và 1 disable phím SHIFT. Đưa 2 private sub dưới đây vào.......... Private Sub DisableSHIFTButton_Click() On Error GoTo ErrHandler Dim db As Database Dim ThuocTinh As Property Set db = CurrentDb db.Properties("AllowBypassKey") = False Set db = Nothing Egress: On Error Resume Next Set db = Nothing Set ThuocTinh = Nothing Exit Sub ErrHandler: MsgBox Err.Number If Err.Number = 3270 Then ' Property not found. Set ThuocTinh = db.CreateProperty("AllowBypassKey", dbBoolean, False) db.Properties.Append ThuocTinh Resume Next Else MsgBox Err.Description Resume Egress End If End Sub ================================================= Private Sub EnableSHIFTButton_Click() On Error GoTo ErrHandler Dim db As Database Dim ThuocTinh As Property Set db = CurrentDb db.Properties("AllowBypassKey") = True Set db = Nothing Egress: On Error Resume Next Set db = Nothing Set ThuocTinh = Nothing Exit Sub ErrHandler: MsgBox Err.Number If Err.Number = 3270 Then ' Property not found. Set ThuocTinh = db.CreateProperty("AllowBypassKey", dbBoolean, True) db.Properties.Append ThuocTinh Resume Next Else MsgBox Err.Description Resume Egress End If End Sub ++++++++++++++++++++++++++++++++++++++++++++++++++ OK chưa bạn ? .............................................. Chưa đâu ! Bây giờ đặt F_ShiftKey ở đâu trong chương trình để không ai được quyền mở ngoại trừ Admin ? Có nhiều cách : cách đơn giản nhất là đặt ….ở đâu cũng được với 1 điều kiện : để mở F_ShiftKey cần phải biết password. Ở sự kiện Form_Open, bạn yêu cầu nhập đúng password : Lambada mới cho mở form này. Private Sub Form_Open(Cancel As Integer) Dim Message, Title, MyValue Message = "Ban vui long cho biet mat khau :" ' Set prompt. Title = "Kiem tra" ' Set title. MyValue = InputBox(Message, Title) If MyValue <> "Lambada" Then DoCmd.Close End If End Sub |
Website : http://www.khoahocphothong.net [/right]
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
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Trích:
| Nguyên văn bởi hungtano 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 |
Website : http://www.khoahocphothong.net [/right]
Truyền thông số từ Combobox
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 đó.
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Trích:
| Nguyên văn bởi ndtoan123 :Cách 1 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) |
Trích:
| Nguyên văn bởi pinkair Cách 2 Ví dụ bạn có Table la NhanVien gồm hai trường MaNV, TenNV Bạn tạo Form có 1 Combo la CmbMaNV; 1 Text Box là txtTenNV Source của CmbMaNV là table NhanVien trên. Đoạn code như sau: Private Sub cmbMaNV Click() Me.txtTenNV.Value = Me.cmbMaNV.Column(1) End Sub Mình đã làm rồi, rất là OK bạn ah, bạn có thể sử dung |
Website : http://www.khoahocphothong.net [/right]
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?
[right] Nguồn Từ : Khoa Học Phổ Thông.
Website : http://www.khoahocphothong.net [/right]
Trích:
| Nguyên văn bởi Duytuannguyen Trả lời 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:
| Nguyên văn bởi hungtano Trả lời =(Q1/Q2)*100 & "%" |
Website : http://www.khoahocphothong.net [/right]
Đăng ký:
Nhận xét (Atom)