thongkorn โพสต์ 2017-12-28 03:06:02

[VB6] การป้อนข้อมูลรายละเอียดการขายสินค้าเข้าสู่ตาราง FarPoint Spread

http://www.g2gnet.com/webboard/images/vb6/FPInputDataRun.png

จากโปรแกรมการพิมพ์ใบเสร็จ ที่แอดมินได้ทำการแจกจ่ายให้ผู้ใช้งานทั่วไปได้ใช้งานฟรี (อ่านรายละเอียดและดาวน์โหลดได้ที่นี่) แอดมินใช้ Visual Basic 6 ในการพัฒนา โดยให้ FarPoint Spread ป้อนหรือรับข้อมูลรายละเอียดของสินค้าในแต่ละแถว ซึ่งวันนี้แอดมินจะมาถ่ายทอดความรู้ไว้เป็นวิทยาทานให้แก่ผู้ที่ยังไม่รู้ แต่ใฝ่รู้ทั้งหลายได้รับรู้กันครับ อย่างที่แอดมินได้เกริ่นนำไปในตอนที่แล้วว่า ลักษณะการใช้งานของ FarPoint มันเหมือนกับการใช้ตารางใน Excel โดยเราต้องรู้หลักและแถว เพื่อเข้าไปจัดการในแต่ละเซลล์ ซึ่งบทความนี้แอดมินยิ่งจะย้ำให้เห็นถึง วิธีการ UnBound Data หรือ ไม่มีแหล่งจ่ายข้อมูล (Data Source) มาให้ เราจะอาศัยการป้อนข้อมูลลงไปเท่านั้น (ตอนหน้าถึงจะโหลดข้อมูลเข้าอีกที เพื่อทำการพิมพ์รายงาน) ในบทความตอนนี้สิ่งที่ท่านจะได้เรียนรู้ก็คือ ...

- วิธีการตั้งค่าคุณสมบัติ (Properties) เพื่อให้รับค่าเฉพาะตัวเลขจำนวนเต็ม เลขทศนิยม หรือข้อมูลชนิดอื่นๆตามที่เราต้องการได้เท่านั้น (Validating Data)
- วิธีการนำข้อมูลในแต่ละเซลล์ที่กำหนดไว้ เพื่อมาคำนวณหาค่าตัวเลขผลรวม
- วิธีการเพิ่ม หรือ ลบแถว จากจุดที่ต้องการ

อนึ่ง แม้ว่า FarPoint Spread มันมี Designer ติดมาให้ด้วย เพื่อช่วยให้เราสามารถออกแบบตารางได้อย่างไม่ยากเย็น แต่แอดมินไม่นิยมใช้รูปแบบของ Design Time มากนัก เพราะมันยากต่อการจดจำ และขาดความยืดหยุ่นในความต้องการที่อาจจะเกิดการเปลี่ยนแปลง ดังนั้นบทความนี้แอดมินจะใช้การเขียนโค้ดแบบ Run Time ทั้งหมด รายละเอียดของการใช้ Designer ท่านต้องไปศึกษาเพิ่มเติมกันเอาเองนะครับ

ดาวน์โหลดชุดติดตั้ง FarPoint Spread ActiveX และ Update 8.0.21 ล่าสุดจากผู้ผลิต (เฉพาะสมาชิกเท่านั้น)

http://www.g2gnet.com/webboard/images/vb6/FPInputDataDesigner.png
FarPoint Spread Designer ...

http://www.g2gnet.com/webboard/images/vb6/FPInputDataComponent.png
หน้าจอของการออกแบบ และการเรียกใช้ Component ...

โค้ดการตั้งค่าคุณสมบัติของ FarPoint Spread ในแบบ Run Time ...
' / --------------------------------------------------------------------------------
' / โปรแกรมย่อยที่กำหนดค่าคุณสมบัติ (Properties) ต่างๆ ให้กับ Spread
Sub SetupSpread()
' / --------------------------------------------------------------------------------
    ' แสดงแถบแสงหรือไม่แสดง
    fpData.OperationMode = OperationModeNormal   ' เอาไว้ป้อนข้อมูล
    'fpData.OperationMode = OperationModeSingle    ' แถบ Selection
    'fpSpread.OperationMode = OperationModeRead   ' ไม่มีแถบ
    'fpSpread.OperationMode = OperationModeRow
   
    ' สามารถจัดเรียง หรือ Sort Order บนหัวคอลัมภ์ได้
    fpData.UserColAction = UserColActionSortNoIndicator ' = UserColActionSort
   
    ' ปรับหน่วยวัด
    'fpData.UnitType = UnitTypeNormal
    'fpData.UnitType = UnitTypeTwips
    'fpData.UnitType = UnitTypeVGABase
   
    ' การปรับความสูงของแถวทุกๆแถว (ค่า -1 หมายถึงทุกแถวครับ)
    fpData.RowHeight(-1) = 18    ' หน่วยวัด Point
    fpData.Appearance = Appearance3D
    fpData.AppearanceStyle = AppearanceStyleEnhanced ' = AppearanceStyleVisualStyles
   
    ' เวลากด F2 เพื่อแก้ไขข้อมูลในแต่ละเซลล ์ให้เลือกข้อมูลทั้งหมด หรือสามารถเริ่มคีย์ค่าใหม่ได้ทันที
    fpData.EditModeReplace = True
    fpData.CellType = CellTypeEdit
   
    ' การกำหนด Column แบบ Run Time
    With fpData
      ' หลักแรก คือ หลักที่ 0 ... จะเป็นการแสดงหมายเลขแถว เพื่ออ้างอิงในลักษณะ Excel เช่น
      .SetText 1, 0, "รหัสสินค้า"
      .SetText 2, 0, "รายละเอียด"
      .SetText 3, 0, "หน่วยละ"
      .SetText 4, 0, "จำนวน"
      .SetText 5, 0, "รวมจำนวนเงิน"
      .SetText 6, 0, " "
      .SetText 7, 0, " "
      
      ' จำนวนหลักทั้งหมด
      .MaxCols = 7
      ' เป็นแถวว่าง 1 แถว
      .MaxRows = 1
      
      ' กำหนดคุณสมบัติต่างๆของแต่ละหลักแบบ Run Time
      ' ID หรือ รหัสสินค้า
      .Col = 1
      .TypeTextWordWrap = True
      .TypeVAlign = TypeVAlignCenter
      ' จำกัดความยาวในเซลล์ หากเวลาที่เราใช้กับฐานข้อมูล จะได้ไม่มีปัญหาในการจัดเก็บที่กำหนดจากฟิลด์ข้อมูล
      .TypeMaxEditLen = 50
      
      ' Description
      .Col = 2
      .TypeTextWordWrap = True
      .TypeVAlign = TypeVAlignCenter
      .TypeMaxEditLen = 175
      
      ' หน่วยละ
      .Col = 3
      ' การจัดตำแหน่งแนวนอน
      .TypeHAlign = TypeHAlignRight
      ' การจัดตำแหน่งแนวตั้ง
      .TypeVAlign = TypeVAlignCenter
      ' กำหนดการป้อนค่าตัวเลขจำนวนเงินเท่านั้น (หรือหากต้องการให้เป็นเลขจำนวนเต็มก็กำหนด CellTypeNumber แทน)
      .CellType = CellTypeCurrency
      ' ตามหลังจุศนิยม
      .TypeNumberDecPlaces = 2
      ' ไม้แสดงสัญลักษณ์ตัวเงิน
      .TypeCurrencyShowSymbol = False
      ' ค่าต่ำสุด
      .TypeCurrencyMin = 1
      
      ' จำนวน
      .Col = 4
      ' การจัดตำแหน่งแนวนอน
      .TypeHAlign = TypeHAlignRight
      ' การจัดตำแหน่งแนวตั้ง
      .TypeVAlign = TypeVAlignCenter
      ' กำหนดการป้อนค่าตัวเลขจำนวนเงินเท่านั้น (เลขทศนิยม)
      .CellType = CellTypeCurrency
      ' ตามหลังจุศนิยม
      .TypeNumberDecPlaces = 2
      ' ไม่แสดงสัญลักษณ์ตัวเงิน
      .TypeCurrencyShowSymbol = False
      .TypeCurrencyMin = 0
      
      ' รวมจำนวนเงิน
      .Col = 5
      ' ล็อคการคีย์ข้อมูล
      .Lock = True
      .TypeHAlign = TypeHAlignRight
      .TypeVAlign = TypeVAlignCenter
      .CellType = CellTypeCurrency
      .TypeCurrencyShowSymbol = False
      ' จุดทศนิยม 2 ตัว
      .TypeNumberDecPlaces = 2
      ' แสดงเครื่องหมายคอมม่า (,)
      .TypeCurrencyShowSep = True
      
      ' ปุ่มเพิ่มแถว
      .Col = 6
      .CellType = CellTypeButton
      .TypeButtonText = "เพิ่ม F3"
      .ColWidth(4) = 120
      .Lock = True
      .BlockMode = False
      ' ปุ่มลบแถว
      .Col = 7
      .CellType = CellTypeButton
      .TypeButtonText = "ลบ F5"
      .ColWidth(4) = 120
      .Lock = True
   
    End With
   
End Subการ Validating Data สามารถทำได้ง่ายดายมาก เช่น กรณีต้องการรับค่าเลขจุดทศนิยมเท่านั้น เราก็กำหนด fpData.CellType = CellTypeCurrency ทำให้เกิดความสะดวกและรวดเร็วต่อการพัฒนาโปรแกรมของเรา


โค้ดตั้งค่าเริ่มต้นในแต่ละหลักให้กับ FarPoint Spread ...
' / --------------------------------------------------------------------------------
' / ข้อมูลทดสอบ
Sub SampleData()
' / --------------------------------------------------------------------------------
    ' ใส่ข้อมูลทดสอบ
    With fpData
      .MaxRows = 1
      .Row = 1
      .Col = 1: .Text = ""    ' รหัสสินค้า
      .Col = 2: .Text = ""    ' ชื่อหรือรายละเอียดสินค้า
      .Col = 3: .Text = "0.00"    ' ราคาต่อหน่วย
      .Col = 4: .Text = "1"         ' จำนวน
      .Col = 5: .Text = "0.00"    ' ผลรวมราคา X จำนวน
      .ForeColor = &HFF0000
    End With
    ' ActiveCell ไปที่หลัก 2 (รายละเอียด) แถวปัจจุบัน
    fpData.SetActiveCell 2, fpData.ActiveRow
    '/ หาผลรวม
    Call CalTotalRow(1)
End Sub
โค้ดเหตุการณ์ที่สำคัญในการใช้งาน FarPoint Spread ...
' / --------------------------------------------------------------------------------
' / เหตุการณ์ก่อนทำการแก้ไขข้อมูลในเซลล์
Private Sub fpData_BeforeEditMode( _
    ByVal Col As Long, _
    ByVal Row As Long, _
    ByVal UserAction As FPUSpreadADO.BeforeEditModeActionConstants, _
    CursorPos As Variant, Cancel As Variant _
    )
' / --------------------------------------------------------------------------------
    ' / ค่าที่สำคัญคือ Col, Row
    ' รับค่าหลัก, แถว
    fpData.Col = Col: fpData.Row = Row
    ' ปกติเราจะเก็บค่าเดิมก่อนมีการเปลี่ยนแปลง เผื่อว่าต้องการคืนค่ากลับ เช่น
    'strDataCol = fpData.Value'<-- strDataCol ต้องประกาศแบบ Public สำหรับให้ทุกโมดูลในฟอร์มนี้มองเห็น
End Sub

' / --------------------------------------------------------------------------------
' / เมื่อเกิดการคีย์ข้อมูลเข้าไปในแต่ละเซลล์
Private Sub fpData_Change(ByVal Col As Long, ByVal Row As Long)
' / --------------------------------------------------------------------------------
    fpData.Row = Row
    ' เลือกหลักที่ต้องการให้ตรวจสอบ
    Select Case fpData.ActiveCol
      ' ราคาต่อหน่วย
      Case 3:
            ' จำนวน
            fpData.Col = 4
            ' หากไม่ป้อนจำนวนตัวเลขใดๆ ก็กำหนดให้เป็น 1
            If fpData.Value = "" Then fpData.Value = "1.00"
   
      ' จำนวน
      Case 4:
            ' หน่วยละ
            fpData.Col = 3
            If fpData.Value = "" Then fpData.Value = "0.00"
   
    End Select
    '/ หาผลรวมใหม่
    Call CalTotalRow(fpData.ActiveRow)
End Sub

' / --------------------------------------------------------------------------------
' / โปรแกรมย่อยคำนวณหาราคา x จำนวน ในทุกๆแถวของตารางกริด (FarPoint)
' / หากเกิดค่าเปลี่ยนแปลงในหลักที่ 3 และหลักที่ 4 จะมาคำนวณผลต่างๆที่นี่
Sub CalTotalRow(ByVal sRow As Long)
' / --------------------------------------------------------------------------------
   
    Dim UnitPrice As Currency
    Dim Amount As Double
    Dim i As Byte
    Dim sGrandTotal As Currency
   
    With fpData
      ' รับค่าแถวปัจจุบัน
      .Row = sRow
      ' เก็บค่าในหลักที่ 3 ไว้ในตัวแปร (หน่วยละ)
      .Col = 3
      ' .Text คือข้อมูลในเซลล์นั้นๆ เช่น จากหลักที่ 3 และแถวตามตัวแปร sRow ที่ถูกส่งมาจากเหตุการณ์ fpData_Change
      If .Text <> "" Then
            UnitPrice = Format(.Text, "0.00")
      Else
            UnitPrice = "0.00"
      End If
      
      ' เก็บค่าในหลักที่ 4 ไว้ในตัวแปร (จำนวน)
      .Col = 4
      If .Text <> "" Then
            Amount = Val(.Text)
      Else
            Amount = "0.00"
      End If
      
      ' นำค่าในหลักที่ 3 (ราคาต่อหน่วย) คูณกับหลักที่ 4 (จำนวนสินค้า) ผลลัพธ์เก็บในหลักที่ 5 (จำนวนเงิน)
      .Col = 5
      .Text = Format(UnitPrice * Amount, "#,##0.00")
      ' รวมจำนวนเงินทั้งหมด ตั้งแต่แถวที่ 1 ไปถึงแถวสุดท้ายของ Spread (FarPoint)
      For i = 1 To .DataRowCnt ' .MaxRows
            ' ไล่ไปทีละแถว
            .Row = i
            ' หลัก 5 คือผลรวม
            .Col = 5
            If Trim(.Text) <> "" Then sGrandTotal = CDbl(.Text) + sGrandTotal
      Next
      
      ' แสดงจำนวนเงินทั้งหมด
      txtGrandTotal.Text = Format(sGrandTotal, "#,##0.00")
      
      ' เรื่องของภาษี
      Select Case cmbTaxType.ListIndex
            '/ ไม่คิดภาษี
            Case 0:
                txtVat.Text = "0.00"
                ' รวมเป็นจำนวนเงินทั้งสิ้น
                txtNetTotal.Text = Format(CDbl(txtGrandTotal.Text) + CDbl(txtVat.Text), "#,##0.00")
            
            ' รวมภาษีใน
            Case 1:
                Dim VatTemp As Currency
                VatTemp = (100 * Val(TAXRATE)) / (100 + Val(TAXRATE))
                ' คิดภาษี
                txtVat.Text = Format(CCur(txtGrandTotal.Text) * VatTemp / 100, "#,##0.00")
                txtGrandTotal.Text = Format(sGrandTotal - CCur(txtVat.Text), "#,##0.00")
                ' รวมเป็นจำนวนเงินทั้งสิ้น
                txtNetTotal.Text = Format(CDbl(txtGrandTotal.Text) + CDbl(txtVat.Text), "#,##0.00")
            
            ' ภาษีนอก
            Case 2:
                ' คิดภาษี
                txtVat.Text = Format(CCur(txtGrandTotal.Text) * Val(TAXRATE) / 100, "#,##0.00")
                ' รวมเป็นจำนวนเงินทั้งสิ้น
                txtNetTotal.Text = Format(CCur(txtGrandTotal.Text) + CDbl(txtVat.Text), "#,##0.00")
      End Select
   
    End With
   
End Sub

' / --------------------------------------------------------------------------------
' / เกิดเหตุการณ์นำเมาส์ไปคลิ๊กในเซลล์
Private Sub fpData_Click(ByVal Col As Long, ByVal Row As Long)
' / --------------------------------------------------------------------------------
    ' หากคลิ๊กเลือกที่ Header
    If Row = 0 Then Exit Sub
    '
    Dim sRow As Integer
    ' เลือกหลักที่ต้องการตรวจสอบ
    Select Case Col
      ' แสดงว่าคลิ๊กเพื่อเพิ่มแถว
      Case 6
            fpData.Col = 2
            ' ตรวจสอบก่อนว่าในแถวนั้นๆ (sRow) มีการป้อนรายละเอียดของสินค้าหรือไม่
            sRow = CheckDataColumn(fpData.Col, False)
            If sRow > 0 Then
                MsgBox "กรุณาป้อนรายละเอียดก่อนเพิ่มแถวใหม่ด้วย.", vbOKOnly + vbInformation, "รายงานสถานะ"
                ' ActiveCell
                fpData.SetActiveCell 2, sRow
                Exit Sub
            End If
            
            '/ หน่วยละ
            fpData.Col = 3
            ' ตรวจสอบก่อนว่าในแถวนั้นๆ (sRow) มีการป้อนราคาของสินค้าหรือไม่
            sRow = CheckDataColumn(fpData.Col, True)
            If sRow > 0 Then
                MsgBox "กรุณาป้อนราคาต่อหน่วยก่อนเพิ่มแถวใหม่ด้วย.", vbOKOnly + vbInformation, "รายงานสถานะ"
                ' ActiveCell บังคับให้โฟกัสไปอยู่ในเซลล์ที่ต้องใส่ราคาก่อน
                fpData.SetActiveCell 3, sRow
                Exit Sub
            End If
            
            ' เมื่อตรวจสอบถูกต้องหมด ก็กำหนดแถวสูงสุด ไว้ล่วงหน้าขึ้นไปอีก 1 เพื่อทำรายการเพิ่มแถวใหม่เข้าไป
            fpData.MaxRows = fpData.MaxRows + 1
            ' เพิ่มรายการแถว ถัดจากแถวที่มันอยู่ (ActiveRow)
            fpData.InsertRows fpData.ActiveRow + 1, 1
            ' ใส่ค่าใหม่ลงไป
            With fpData
                .Row = .ActiveRow + 1
                ' ProductID
                .Col = 1
                .Value = ""
                ' Description
                .Col = 2
                .Value = ""
                ' หน่วยละ
                .Col = 3
                .Value = "0.00"
                ' จำนวน
                .Col = 4
                .Value = "1.00"
                ' รวม
                .Col = 5
                .Value = "0.00"
                .ForeColor = &HFF0000
            End With
            ' ActiveCell ไปที่หลัก 2 (รายละเอียด) แถวปัจจุบัน + 1
            fpData.SetActiveCell 2, fpData.ActiveRow + 1
      
      ' ลบแถว
      Case 7:
            ' ดักเอ้อเหรอ (Error) กรณีที่ไม่มีแถวข้อมูลอยู่เลย
            If fpData.MaxRows = 1 Then Exit Sub
            ' ลบแถวปัจจุบันที่มันอยู่ออกไปก่อน
            fpData.DeleteRows fpData.ActiveRow, 1
            ' กำหนดแถวสูงสุด โดยลดค่าลง 1
            fpData.MaxRows = fpData.MaxRows - 1
            '/ คำนวณผลรวมใหม่
            Call CalTotalRow(fpData.ActiveRow)
    End Select

End Sub

' / --------------------------------------------------------------------------------
' / ตรวจสอบการป้อนข้อมูลในตารางกริด FarPoint
Function CheckDataColumn(Col As Long, blnNumber As Boolean) As Integer
' / --------------------------------------------------------------------------------
    CheckDataColumn = 0
    Dim sRow As Integer
    fpData.Col = Col
    For sRow = 1 To fpData.DataRowCnt
      fpData.Row = sRow
      ' Check ว่าค่าที่ส่งมาเป็นตัวเลขหรือไม่
      If blnNumber Then
            If CDbl(fpData.Text) <= 0# Then
                CheckDataColumn = sRow
                Exit Function
            End If
      ' เป็นตัวอักษร
      Else
            If fpData.Text = "" Then
                CheckDataColumn = sRow
                Exit Function
            End If
      End If
    Next
End Function
โค้ดที่เหลือของโปรเจค ... (เผื่อท่านขี้เกียจสมัครสมาชิกเข้ามาแสวงหาความรู้)
Option Explicit

' ค่าคงที่อัตราภาษี 7%
Const TAXRATE As Byte = 7

' / --------------------------------------------------------------------------------
' / คำนวณหาภาษี
Private Sub cmbTaxType_Click()
' / --------------------------------------------------------------------------------
    If fpData.DataRowCnt > 0 Then Call CalTotalRow(1)
End Sub

' / --------------------------------------------------------------------------------
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
' / --------------------------------------------------------------------------------
    Select Case KeyCode
      
      Case vbKeyF1: 'MsgBox "No help now."
      Case vbKeyF3: Call fpData_Click(6, fpData.ActiveRow)
      Case vbKeyF5: Call fpData_Click(7, fpData.ActiveRow)
      Case vbKeyF10: Unload Me
   
   End Select
End Sub

' / --------------------------------------------------------------------------------
Private Sub Form_Load()
' / --------------------------------------------------------------------------------
    Me.Move (Screen.Width - Width) \ 2, (Screen.Height - Height) \ 2
    txtGrandTotal.Text = "0.00"
    txtVat.Text = "0.00"
    txtNetTotal.Text = "0.00"
    With cmbTaxType
      .AddItem "ไม่คิดภาษี"
      .AddItem "รวมภาษีใน"
      .AddItem "แยกภาษีนอก"
    End With
    cmbTaxType.ListIndex = 0
    lblSummary(1).Caption = "คิดภาษี " & TAXRATE & " %"
    ' จัดระเบียบ Spread แบบ Run Time
    Call SetupSpread
    Call SampleData
End Sub

' / --------------------------------------------------------------------------------
Private Sub Form_Resize()
' / --------------------------------------------------------------------------------
    On Error Resume Next
    '//
    fraFP.Move 0, 60
    fraFP.Width = Me.ScaleWidth - 30
   
    txtGrandTotal.Left = fraFP.Width - txtGrandTotal.Width - 300
    txtVat.Left = txtGrandTotal.Left
    txtNetTotal.Left = txtGrandTotal.Left
    '//
    lblSummary(0).Left = txtGrandTotal.Left - lblSummary(0).Width - 90
    cmbTaxType.Left = txtVat.Left - cmbTaxType.Width - 90
    lblSummary(1).Left = cmbTaxType.Left - lblSummary(1).Width - 90
    lblSummary(2).Left = txtNetTotal.Left - lblSummary(2).Width - 90
    '/
    ' ตั้งค่าการขยายของ FarPoint ซึ่งต้องตั้งค่าตามหน่วย Twip ก่อน
    fpData.Width = fraFP.Width - 60
    With fpData
      .UnitType = UnitTypeTwips
      .RowHeight(-1) = 365
      .ColWidth(1) = .Width \ 6 - 300
      .ColWidth(2) = .Width \ 6 + 1600
      .ColWidth(3) = .Width \ 6 - 600
      .ColWidth(4) = .Width \ 6 - 800
      .ColWidth(5) = .Width \ 6 - 500
      .ColWidth(6) = 800
      .ColWidth(7) = 800
    End With
End Sub

' / --------------------------------------------------------------------------------
Private Sub Form_Unload(Cancel As Integer)
' / --------------------------------------------------------------------------------
    ' ลบไฟล์ Temporary ออกให้หมด
    If Dir$(App.Path & "\*.tmp") <> "" Then Kill App.Path & "\*.tmp"
    '//
    Set frmFarPointData = Nothing
    End
End Sub
ดาวน์โหลดโค้ดต้นฉบับเต็ม VB6 ได้ที่นี่ ...

wut62 โพสต์ 2017-12-29 13:48:49

ขอบคุณครับ อาจารย์ :)

MrDen โพสต์ 2017-12-30 15:41:28

ขอบพระคุณอย่างสูงครับ อาจารย์แข็งแรง++ ร่ำรวย ++ ครับ. :)

prawpun โพสต์ 2018-10-21 23:04:57

ขอบคุณมากคะอาจารย์
หน้า: [1]
ดูในรูปแบบกติ: [VB6] การป้อนข้อมูลรายละเอียดการขายสินค้าเข้าสู่ตาราง FarPoint Spread