[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 ได้ที่นี่ ...
ขอบคุณครับ อาจารย์ :) ขอบพระคุณอย่างสูงครับ อาจารย์แข็งแรง++ ร่ำรวย ++ ครับ. :) ขอบคุณมากคะอาจารย์
หน้า:
[1]