[VB6] การคำนวณหาเวลาการเข้าออกของพนักงาน (Time Attendance) ในระดับนาที
http://www.g2gnet.com/webboard/images/vb6/TimeAttendanceRun.pngก็เป็นอีกหนึ่งคำถามที่ถามเข้ามาบ่อยมาก ในเรื่องของการคำนวณเวลา หรือ การหาค่าความแตกต่างของระยะเวลา แอดมินก็เลยจัดให้ทันทีที่หาโค้ดเจอล่ะกันครับ แหะๆๆๆ ... ข้อมูลจริงที่รับค่าเข้ามาจากเครื่องอ่านลายนิ้วมือ (Finger Scan) ค่อนข้างยุ่งเหยิงมากกว่านี้นะครับ เพราะมีการสแกนลายนิ้วมือซ้ำซ้อนกัน แต่โค้ดนี้เอาไว้ใช้เพื่อศึกษาการทำงาน และการคำนวณ แอดมินก็เลยกรองข้อมูลสมมุติขึ้นมาให้ดูล่ะกัน ...
http://www.g2gnet.com/webboard/images/vb6/TimeAttendanceComponent.png
Project --> Components ...
http://www.g2gnet.com/webboard/images/vb6/TimeAttendanceDesign.png
Design Time ...
มาดูโค้ดกันเถอะ ...
' / ---------------------------------------------------------------------------------------------
Private Sub cmdOpenFile_Click()
'On Error Resume Next
On Error GoTo ErrHandler
Dim strFile As String
dlgOpenFile.FileName = ""
dlgOpenFile.CancelError = True ' ไม่สนใจ Error ที่เกิดขึ้น
dlgOpenFile.InitDir = App.Path ' เลือกตำแหน่งปัจจุบันของ Project
dlgOpenFile.DialogTitle = "เลือกตำแหน่งเท็กซ์ไฟล์ *.txt" ' ตั้งค่า Title ของ Dialog
dlgOpenFile.Filter = "Text File (*.txt) | *.txt" ' แสดงผลเฉพาะไฟล์ txt extension
dlgOpenFile.ShowOpen
dlgOpenFile.DefaultExt = "*.txt" ' ตั้งค่านามสกุล txt เป็นค่าเริ่มต้น
strFile = dlgOpenFile.FileName
If strFile = "" Then Exit Sub
txtOpenFile.Text = strFile
ExitProc:
Exit Sub
ErrHandler:
' หากไม่เท่ากับ 32755 ... คือหมายเลข Error 32755 นี้ คือ การกดปุ่ม Cancel น่ะครับ
' พูดง่ายๆ ผมไม่สนใจการเกิด Error นี้น่ะครับ ... แต่ Error อื่นๆ จะคอยดักไว้อีกที
If Err.Number <> 32755 Then
MsgBox "Error: " & Err.Number & vbCrLf & Err.Description
' Resume ExitProc
End If
End Subส่วนของการเลือกไฟล์ (Text File) ข้อมูลของการเข้าออก
http://www.g2gnet.com/webboard/images/vb6/TimeAttendanceData.png
ข้อมูลทดสอบ โดยที่ในแต่ละหลักจะแยกออกจากกันด้วยเครื่องหมายช่องว่าง (Space)
โค้ดในส่วนของการแยกแยะข้อมูลออกจากกัน ก่อนที่จะทำการประมวลผล
' / ---------------------------------------------------------------------------------------------
Private Sub cmdReadText_Click()
Dim iRow, i As Long
Dim iArr As Variant
Dim StrData As String
Dim StrTemp As String
' ตัวแปร Object ใช้กับ ListView Control
Dim LV As ListItem
If Trim$(txtOpenFile.Text) = "" Or Len(Trim$(txtOpenFile.Text)) = 0 Then Exit Sub
' Open Text File
Open Trim$(txtOpenFile.Text) For Input As #1
iRow = 1
' ทำจนกว่าจะหมดข้อมูล (EOF - End Of File)
Do Until EOF(1)
' อ่านข้อมูลเข้ามาทีละบรรทัด
Line Input #1, StrData
StrTemp = Trim(StrData)
' แยกชุดตัวอักษรออกจากกันด้วยคำสั่ง Split
' โดยใช้เครื่องหมายช่องว่าง (Space) ในการจับแยกชุดตัวอักษร แล้วเก็บเข้าไปใน Array
iArr = Split(StrTemp, " ")
' Index = 0 it's Item
Set LV = lvwData.ListItems.Add(, , iRow)
' Employee ID
LV.SubItems(1) = iArr(0)
' Date In/Out
LV.SubItems(2) = iArr(1)
' Time In/Out
LV.SubItems(3) = iArr(2)
' เลขจำนวนเต็มใดๆหารเอาเศษ (MOD) หากได้ 1 คือเลขคี่ หากได้เลข 0 คือเลขคู่
If (iRow Mod 2) = 1 Then
' คำนวณหาค่าความต่างเวลาตอนเข้า 08.00 หากเวลาติดลบคือเข้าก่อน
LV.SubItems(4) = CalTime("08:00", Format(iArr(2), "HH:MM"))
Else
' คำนวณหาค่าความต่างเวลาตอนออก 17.00หากเวลาติดลบคือออกก่อน
LV.SubItems(4) = CalTime("17:00", Format(iArr(2), "HH:MM"))
End If
' Increment Item
iRow = iRow + 1
Loop
' Close Text File
Close #1
End Subการอ่านข้อมูลแบบ Line By Line ... ด้วยการแยกข้อมูลออกจากกันด้วยเครื่องช่องว่าง (Space) หรือค่า ASCII Code = 32 (ฐาน 10)
ฟังค์ชั่นในการคำนวณหาค่าความต่างของเวลา
' / ---------------------------------------------------------------------------------------------
' / ฟังค์ชั่นคำนวณหาค่าความต่างเวลาเป็นนาที
Public Function CalTime(StartTime As Date, EndTime As Date) As Integer
' / ---------------------------------------------------------------------------------------------
Dim cHH As Integer
Dim cMM As Integer
' / ---------------------------------------------------------------------------------------------
' หลักการของการหาค่าความแตกต่างของเวลา
' ใช้การหาค่าความแตกต่างในระดับจำนวนของวินาทีทั้งหมดออกมาก่อน
' แล้วค่อยคิดตัดออกจากจำนวนชั่วโมง นาที และ วินาที ที่ต่างกัน
' 1 ชั่วโมง เท่ากับ 3600 วินาที
' 1 นาที เท่ากับ 60 วินาที
Dim SecInMinute As Integer
Dim SecInHour As Integer
SecInMinute = 60 ' จำนวน 1 นาทีเท่ากับ 60 วินาที
SecInHour = 3600 ' มาจากจำนวน 60 นาทีใน 1 ชั่วโมง คูณเข้ากับ 60 วินาทีในแต่ละนาที ดังนั้น 1 ชั่วโมง = 3600 วินาที
' / ---------------------------------------------------------------------------------------------
' หาจำนวนชั่วโมง (Hour) ... หารตัดเศษ ( \ ) ทิ้งไปเลย ... ทำงานได้เร็วกว่าการหารเอาเศษ ( / )
' การกำหนดชนิดตัวแปรแบบเลขจำนวนเต็ม (Integer หรือ Long) มันไม่มีเลขทศนิยมอยู่แล้วครับ
' หาความแตกต่างของจำนวนชั่วโมง โดยนับเป็นวินาที จากนั้นให้หารตัดเศษด้วย (จำนวนนาที x จำนวนวินาที)
' นั่นคือ ค่าที่ได้ \ (60 นาที x 60 วินาที) ... 1 ชั่วโมงก็จะเท่ากับ 3600 วินาที
cHH = DateDiff("s", StartTime, EndTime) \ SecInHour
' หาจำนวนนาที (Minute) ...ไล่เครื่องหมายวงเล็บให้ถูกด้วยน่ะครับ
' การใส่วงเล็บ จะมีความสำคัญที่สูงกว่าเครื่องหมาย + - * / ... อย่าลืมเด็ดขาด
' ความแตกต่างของจำนวนนาที ค่าที่ได้ให้ลบออกจากจำนวนวินาที
' จำนวนวินาทีที่ได้ ให้ลบออกจากเวลาจำนวนชั่วโมงที่ต่างกันก่อน (ชั่วโมง x วินาที)
' แล้วค่อยหารตัดเศษด้วย 60 ... เพราะ 1 นาที = 60 วินาที
cMM = (DateDiff("s", StartTime, EndTime) - (cHH * SecInHour)) \ SecInMinute
' คืนค่ากลับให้ฟังค์ชั่น โดยเอาจำนวนชั่วโมงคูณ 60 นาที รวมเข้ากับนาทีที่ไม่เกิน 1 ชั่วโมง
CalTime = (cHH * 60) + cMM
End Functionการคืนค่ากลับของฟังค์ชั่นจะเป็นตัวเลขชนิดจำนวนเต็ม (Integer) โดยให้มีหน่วยนับเป็นนาที
โค้ดในส่วนอื่นๆ ... (เผื่อเอาไว้สำหรับท่านที่ดาวน์โหลดไม่ได้)
' / ---------------------------------------------------------------------------------------------
' / Initial ListView
Sub SetupListView()
With Me.lvwData
' Coding with Run Time
.View = lvwReport
.Arrange = lvwNone
.LabelEdit = lvwManual
.BorderStyle = ccFixedSingle
.Appearance = cc3D
.HideColumnHeaders = False
.HideSelection = False
.LabelWrap = False
.MultiSelect = False
.Enabled = True
.AllowColumnReorder = True
.Checkboxes = False
.FlatScrollBar = False
.FullRowSelect = True
.GridLines = True
.HotTracking = False
.HoverSelection = False
.Sorted = False 'True
.SortKey = 0
.SortOrder = lvwAscending 'lvwDescending
' Add header
.ColumnHeaders.Add , , "ลำดับที่", .Width \ 5 - 600
.ColumnHeaders.Add , , "รหัสพนักงาน", .Width \ 5
.ColumnHeaders.Add , , "วันที่เข้า/ออก", .Width \ 5 - 120
.ColumnHeaders.Add , , "เวลาเข้า/ออก", .Width \ 5 - 280
.ColumnHeaders.Add , , "ความต่างเวลา (นาที)", .Width \ 5 + 200, lvwColumnRight
End With
End Sub
Private Sub Form_Load()
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
txtOpenFile.Text = ""
Call SetupListView
End Sub
Private Sub Form_Resize()
On Error Resume Next
If Me.WindowState = vbMinimized Then Exit Sub
' Fix width & height
' width
If Me.Width <> 10380 Then
Me.Width = 10380
Exit Sub
End If
' height
If Me.Height <> 7410 Then
Me.Height = 7410
Exit Sub
End If
End Subดาวน์โหลดโค้ดต้นฉบับแบบเต็ม VB6 (SP6) ได้ที่นี่
ขอบคุณมากครับอาจารย์ ขอรับไปศึกษาต่อนะครับ ขอบพระคุณมากครับอาจารย์ :) ขอบคุณครับ
หน้า:
[1]