Tạo hàm chấm công.
Vấn đề: ở một số công ty, nhà
máy nhỏ việc chấm công thông thường được
thực hiện trên Excel. Qua trao đổi tôi thấy rằng
đa số khi nhân viên có đi làm thì sẽ được chấm
là X , nghĩ phép là P , ...vv. Sau đó sẽ sử
dụng một số hàm trong Excel để tính số ngày công
trong một tháng của nhân viên. Tôi nghĩ rằng thông
thường số ngày làm việc sẽ nhiều hơn số
ngày nghĩ, nếu chấm công như trên nghĩa là bạn
phải nhập vào bảng tính Excel nhiều hơn nếu
bạn chỉ nhập vào những ngày nghĩ của nhân
viên ấy. Giả sử rằng trong một ngày nhân viên
nghĩ phép ½ ngày, sau đó do nhu cầu công việc yêu cầu
họ tăng ca 3 tiếng thì công việc chấm công
sẽ như thế nào. Tôi thấy một số nơi sẽ đưa
việc chấm tăng ca qua một sheet khác, hay bảng dữ
liệu khác...Hoặc có những ngày thì tính công
nhật (công thời gian), có những ngày tính theo năng
suất...thì bạn phải làm như thế nào. Tôi
nghĩ ở một số công ty việc chấm công
sẽ rắc rối hơn như trên vì hiện nay ở
một số công ty có cả công nhân thời vụ và công
nhân chính thức,...!
Vâng, vấn đề chắc chắn là
rắc rối. Ở đây tôi không có tham vọng giải
quyết tất cả các vấn đề trên. Tôi chỉ
muốn đưa ra hàm chấm công để cho công việc chấm
công dễ dàng hơn.
Cấu trúc của hàm chấm công như sau:
Public Function Chamcong(ByVal Khoang As Range, ByVal Chucnang As String) As Single
_ Khoang: là khoảng (Thông thường
là một hàng từ cột...đến cột...) tương ứng
với hàng hay khoảng mà bạn chấm công cho một nhân
viên.
_ Chucnang: là chuổi hay ký
tự đại diện cho một chức năng chấm công
của bạn.
Giả sử ở đây tôi quy định:
ü
Nghĩ phép là:
A
ü
Nghĩ bệnh là:
S
ü
Nghĩ ma chay là:
C
ü
Nghĩ không lương là:
U
ü
Tăng ca ngày thường (tính nhân cho
1.5) là: N
ü
Tăng ca ngày nghĩ (tính nhân cho 2)
là: D
Vậy nếu trong một ngày nhân viên đó
nghĩ phép ½ ngày, tăng ca (ngày thường) 3 tiếng thì tôi
sẽ chấm như sau: (Giả sử tên nhân viên là Triệu
Nhất Đông, ngày áp dụng là 27/02/2002)

Trong hàm chấm công của tôi, tôi có
sử dụng một Class tên clsString của Thấy Lê
Đức Hồng (HTTP:
www.vovisoft.com).
Bạn chỉ việc copy đoạn mã sau và đưa vào class
module trong cửa sổ VBE của bạn.

|
'Author:
Le Duc Hong
http://www.vovisoft.com
Option
Explicit
Private
SText As String
Private SDelimiter As String
Private IPos As Integer
Private ILen As Integer
Public MaxToken As Integer
Private Tokens() As String Public
Property Get Text() As Variant
Text = SText
End
Property
Public
Property Let Text(ByVal vNewValue As Variant)
SText = vNewValue
ILen = Len(SText): IPos = 1
End
Property Public Property Get Delimiter() As Variant
Delimiter = SDelimiter
End
Property Public Function TokenAt(TNum) As String
If (TNum > 0) And (TNum <= MaxToken)
Then
TokenAt = Tokens(TNum)
Else
TokenAt = ""
End If End Function
Public
Property Let Delimiter(ByVal vNewValue As Variant)
SDelimiter = vNewValue
Tokenise
End
Property
Private
Sub Tokenise()
Dim i
i = 0: IPos = 1
Do Until IPos > ILen
i = i + 1
ReDim Preserve Tokens(i)
Tokens(i) = GetToken
Loop
MaxToken = i
IPos = 1
End
Sub
Public
Sub ReplaceToken(TNum, NewToken)
If (TNum > 0) And (TNum <= MaxToken)
Then
Tokens(TNum) = NewToken
ReconstructText
End If
End
Sub
Private
Sub ReconstructText()
Dim i
SText = ""
For i = 1 To MaxToken
SText = SText & Tokens(i)
If i < MaxToken Then SText = SText
& SDelimiter
Next End SubPublic Function KeepLeftPart(NumChar) As String
If ILen >= NumChar Then
SText = Left(SText, NumChar): ILen =
Len(SText)
End If
KeepLeftPart = SText
End
Function
Public
Function KeepRightPart(NumChar) As String
If ILen >= NumChar Then
SText = Right(SText, NumChar): ILen =
Len(SText)
End If
KeepRightPart = SText End Function
Public
Function KeepMidPart(SPos, NumChar) As String
If ILen >= SPos Then
SText = Mid(SText, SPos): ILen =
Len(SText)
End If
If ILen >= NumChar Then
SText = Right(SText, NumChar)
End If
KeepMidPart = SText
End
Function
Public
Property Get CurrentPos() As Variant
CurrentPos = IPos
End
Property
Public
Property Let CurrentPos(ByVal vNewValue As Variant)
IPos = vNewValue
End
Property Public Function GetToken() As String
Dim Pos
GetToken = ""
If SDelimiter = " " Then
Do While Mid(SText, IPos, 1) = "
"
IPos = IPos + 1
If IPos > ILen Then
Exit Function
End If
Loop
End If
Pos = InStr(IPos, SText, SDelimiter)
If Pos > 0 Then
GetToken = Mid(SText, IPos, Pos - IPos)
IPos = Pos + Len(SDelimiter)
Else
GetToken = Mid(SText, IPos, ILen - IPos
+ 1)
IPos = ILen + 1
End If End Function
Public
Sub Substitude(Param, ParamValue)
Dim Pos, PLen
PLen = Len(Param)
Pos = InStr(SText, Param)
Do While Pos > 0
SText = Left(SText, Pos - 1) &
ParamValue & Mid(SText, Pos + PLen)
Pos = InStr(SText, Param)
Loop
ILen = Len(SText) End SubPublic Function GetLastToken() As String
Dim Pos, Tlen
Tlen = Len(SDelimiter)
GetLastToken = ""
If ILen = 0 Then
Exit Function
End If
Pos = ILen - Tlen + 1
Do While Pos > 0
If Mid(SText, Pos, Tlen) = SDelimiter
Then
GetLastToken = Mid(SText, Pos +
Tlen)
End If
Pos = Pos - 1
Loop
End
Function
Public
Property Get Length() As Integer
Length = ILen
End
Property Public Property Get TokenCount() As Variant
TokenCount = MaxToken
End
Property |
|
Public Function Chamcong(ByVal Khoang As Range, ByVal Chucnang As String) As Single
Dim
Socot As Integer, Sohang As Integer
Dim i As
Integer, j As Integer, k As Integer
Dim
Btotal As Single
Dim
Bgiatriso As Single
Dim
Bchucnang As String
Dim
SoLoai As Byte ' Bien nay nham xac dinh so loai ngay nghi, tang ca... trong
mot chuoi
Dim
BChuoi As clsString
Dim
BGiatri
On error resume next
'Xac dinh so cot trong bien Khoang
Socot = Khoang.Columns.Count
'Xac dinh so hang trong bien Khoang
Sohang = Khoang.Rows.Count
' Nham bao dam so sanh dung ta dung ham UCase
Chucnang = UCase(Chucnang)
'Duyet qua cac cell trong bien Khoang
For i = 1 To Sohang
For j =
1 To Socot
BGiatri
= Khoang.Cells(i, j).Value
BGiatri = Trim(BGiatri)
'
Bat dau xu ly bgiatri qua Class clsString
Set
BChuoi = New clsString
BChuoi.Text = BGiatri
'Ky
tu de phan cach cac Chuc nang
BChuoi.Delimiter = ";"
'Xac dinh so Chuc nang trong 1 cell
SoLoai = BChuoi.TokenCount
For
k = 1 To SoLoai
'Chuoi cua tung chuc nang
BGiatri = BChuoi.TokenAt(k)
Bchucnang = UCase(Left(BGiatri, Len(Chucnang)))
Bgiatriso = Val(Right(BGiatri,
Len(BGiatri) - len(Chucnang)))
Select Case Bchucnang
Case Chucnang
Btotal = Btotal +
Bgiatriso
End Select
Next k
Next j
Next i
Chamcong = Btotal End Function |
Trong ví dụ này, ngày 22/02 tôi chấm công
nghiphep1, ngày 23/02 tôi chấm công nghiphep0.5;tangca3.
Công thức trong ô AM8, tôi sẽ nhập vào
=chamcong(G8:AH8,AM7) (ô AM7
chứa chữ Nghiphep)
=chamcong(G8:AH8,AN7) (ô AN7 chứa
chữ Tangca)
Vâng, dĩ nhiên là bạn có thể
sử dụng các chuổi ký tự như trên sẽ
dễ hiểu, nhưng bảng chấm công của bạn
sẽ rất lượm thuộm.
Hình vẽ sau minh họa ví dụ
trên của tôi.

Tôi hy vọng rằng bài viết trên
sẽ giúp ích các bạn phần nào trong công việc chấm
công nhàm chán (nhưng không được sai) hàng ngày của bạn.
Mọi ý kiến góp ý xin các
bạn gởi về:
PcLeHoan
1996 - 2002
Mirror :
http://www.pclehoan.com
Mirror :
http://www.lehoanpc.net
Mirror :
http://www.ktlehoan.com