thongkorn โพสต์ 2017-12-4 13:13:56

[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) ได้ที่นี่

wut_62 โพสต์ 2017-12-4 15:52:54

ขอบคุณมากครับอาจารย์ ขอรับไปศึกษาต่อนะครับ

MrDen โพสต์ 2017-12-15 14:40:28

ขอบพระคุณมากครับอาจารย์ :)

g2gsoftuser โพสต์ 2022-10-25 17:07:29

ขอบคุณครับ
หน้า: [1]
ดูในรูปแบบกติ: [VB6] การคำนวณหาเวลาการเข้าออกของพนักงาน (Time Attendance) ในระดับนาที