ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 34|ตอบกลับ: 0

[VB.NET] การสร้าง QRCode PromptPay เพื่อสแกนโอนเงินโดยระบุจำนวนเงินได้

[คัดลอกลิงก์]

341

กระทู้

538

โพสต์

8311

เครดิต

ผู้ดูแลระบบ

ทองก้อน ทับทิมกรอบ

Rank: 9Rank: 9Rank: 9

เครดิต
8311
โพสต์ เมื่อวานซืน 10:17 | ดูโพสต์ทั้งหมด |โหมดอ่าน



โค้ด VB.NET ในการสร้าง QR Code แบบกำหนดจำนวนเงิน (หรือที่เรียกว่า Dynamic QR Code) เพื่อให้ผู้อื่นสแกนและชำระเงินตามจำนวนที่เราล็อกยอดไว้ จุดประสงค์ก็เพื่ออำนวยความสะดวกให้กับผู้โอนเงินและผู้รับเงิน จะได้ไม่มีข้อผิดพลาดในเรื่องของจำนวนเงิน ข้อมูลทั้งหมดเกี่ยวกับรูปแบบ QR Code พร้อมเพย์ ไม่ได้เป็นข้อมูลความลับแต่อย่างใด เป็นมาตรฐานที่ ** ธนาคารแห่งประเทศไทย ประกาศเผยแพร่อย่างเป็นทางการ ** เพื่อให้ทุกคนและหน่วยงานสามารถนำไปใช้งานได้อย่างถูกต้องครับ ไม่มีลิขสิทธิ์ห้ามเผยแพร่ครับผม ...

หลักการทำงานสร้าง QR พร้อมเพย์ แบบสรุป 4 ขั้นตอน ...
### เตรียมข้อมูลผู้รับเงิน
- เบอร์โทร --> แปลงเป็นรูปแบบสากล เช่น 0812345678 --> 0066812345678
- หรือ เลขบัตรประชาชน 13 หลัก
- ใส่ลงในรูปแบบ **รหัส-ความยาว-ค่า** เช่น 01130066812345678

### ประกอบชุดข้อมูลหลัก (Payload) เรียงข้อมูลตามลำดับมาตรฐาน:
ส่วน                หน้าที่
Tag 00        เวอร์ชันมาตรฐาน = 01
Tag 01        ประเภท: มีเงิน = 12 / ไม่มี = 11
Tag 29        ข้อมูลบัญชีผู้รับ (เบอร์/บัตร)
Tag 53        รหัสสกุลเงิน = 764 = บาทไทย
Tag 54        จำนวนเงิน (ถ้ามี) เช่น 100.50
Tag 58        รหัสประเทศ = TH

### คำนวณค่าตรวจสอบ CRC (Cyclic Redundancy Check)
- นำข้อความทั้งหมดที่ประกอบเสร็จแล้ว มาคำนวณ **CRC16-CCITT**
- ต่อท้ายข้อความด้วย 6304 + ค่า CRC 4 หลัก เช่น 6304A3B5
- เพื่อให้แอพธนาคารตรวจสอบว่าข้อมูลถูกต้อง ไม่ผิดพลาด

### สร้างภาพ QR Code
- นำข้อความทั้งหมดที่ได้ ส่งให้ไลบรารีสร้างภาพ QR Code (ใช้ของฟรี ZXing ในการแปลงข้อความเป็น QR Code)
- เสร็จเรียบร้อย สแกนจ่ายเงินได้เลยครับ

หมายเหตุ:
โค้ดที่แอดมินได้แจกจ่ายออกไปจะเป็นแบบ CopyLeft หรือ MIT License โดยที่ ...
- ให้ใช้ได้อย่างอิสระ แค่อย่าแอบอ้างและรับผิดเอง
- ใส่ชื่อเจ้าของเดิมไว้ ไม่ต้องกราบไหว้ แค่บอกไว้ว่าใครเป็นคนทำเดิมก็พอ
- ถ้ามีอะไรพังหรือเกิดความเสียหาย เจ้าของโค้ดไม่ต้องรับผิดชอบ ใช้ไปแล้วเกิดปัญหา เป็นหน้าที่ของคนที่นำไปใช้ครับ ไม่ใช่หน้าที่คนทำเดิม


Add References ...

เครื่องมือหรือ Component ของฟรีที่นำมาใช้งาน
- SunnyUI ทำ GUI (Graphices User Interface)
- ZXing เอาไว้แปลงข้อความให้เป็น QR Code

มาดูโค้ดฉบับเต็มกันเถอะ ...
  1. '// ZXing.Net release download.
  2. '// https://github.com/micjahn/ZXing.Net/releases

  3. '// แนวนโยบายการใช้มาตรฐาน Thai QR Code ในธุรกรรมการชำระเงิน ธนาคารแห่งประเทศไทย
  4. '// https://www.bot.or.th/content/dam/bot/fipcs/documents/FPG/2562/ThaiPDF/25620084.pdf

  5. Imports System.Globalization
  6. Imports System.Text
  7. Imports ZXing
  8. Imports ZXing.Common
  9. Imports ZXing.QrCode
  10. Imports ZXing.Rendering
  11. Imports System.IO
  12. Imports System.Drawing.Imaging
  13. Imports Sunny.UI

  14. Public Class frmQRCodePromptPay

  15.     Private Sub frmQRCodePromptPay_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
  16.         Select Case e.KeyCode
  17.             Case Keys.F3
  18.                 btnGenerate.PerformClick()
  19.             Case Keys.F10
  20.                 Me.Close()
  21.         End Select
  22.     End Sub

  23.     Private Sub frmQRCodePromptPay_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  24.         ' SunnyUI
  25.         UIStyles.CultureInfo = CultureInfos.en_US
  26.         '// เปิดใช้งานการตั้งค่าฟอนต์ทั่วทั้งแอพพลิเคชัน
  27.         UIStyles.GlobalFont = True
  28.         '// กำหนดชื่อฟอนต์ที่ต้องการใช้ เช่น "TH Sarabun New" หรือ "Segoe UI"
  29.         UIStyles.GlobalFontName = "Tahoma" '"Segoe UI"
  30.         '// ตั้งค่าขนาดฟอนต์ (100 คือขนาด 12pt, 75 คือขนาด 9pt, 125 คือขนาด 15pt)
  31.         UIStyles.GlobalFontScale = 100
  32.         '// บังคับให้ UI รีเฟรชเพื่อใช้การตั้งค่าใหม่
  33.         UIStyles.SetDPIScale()

  34.         ' Form
  35.         Me.KeyPreview = True    ' ใช้สำหรับการกดปุ่มฟังค์ชั่นต่างๆได้
  36.         txtAccount.Text = ""
  37.         txtAmount.Text = ""
  38.         txtPayload.Text = ""
  39.     End Sub

  40.     ' /-----------------------------------------------------------------------------
  41.     ' Select All ข้อมูลทั้งหมดใน UiTextBox ของ SunnyUI
  42.     Private Sub frmQRCodePromptPay_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
  43.         Me.BeginInvoke(New MethodInvoker(
  44.         Sub()
  45.             txtAccount.Focus()
  46.             txtAccount.SelectAll()
  47.         End Sub))
  48.     End Sub

  49.     ' /-----------------------------------------------------------------------------
  50.     ' / นำค่าจาก txtPayload เพื่อทำการสร้าง QRCode Payload ด้วย ZXing
  51.     ' /-----------------------------------------------------------------------------
  52.     Private Sub txtPayload_TextChanged(sender As Object, e As EventArgs) Handles txtPayload.TextChanged
  53.         If String.IsNullOrWhiteSpace(txtPayload.Text) Then
  54.             picQRCode.Image = Nothing
  55.             Return
  56.         End If
  57.         '//
  58.         Dim options As EncodingOptions = New QrCodeEncodingOptions
  59.         With options
  60.             .NoPadding = True
  61.             .Width = picQRCode.Width
  62.             .Height = picQRCode.Height
  63.             .Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8")
  64.             .PureBarcode = False
  65.         End With
  66.         '//
  67.         Dim objWriter As BarcodeWriter = New BarcodeWriter With {
  68.                 .Format = BarcodeFormat.QR_CODE,
  69.                 .Options = options,
  70.                 .Renderer = New BitmapRenderer
  71.             }
  72.         picQRCode.Image = New Bitmap(objWriter.Write(txtPayload.Text))
  73.         picQRCode.SizeMode = PictureBoxSizeMode.StretchImage
  74.     End Sub

  75.     ' /-----------------------------------------------------------------------------
  76.     ' / สร้าง QR พร้อมยอดเงิน
  77.     ' /-----------------------------------------------------------------------------
  78.     Private Sub btnGenerate_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
  79.         ' อ่านค่า
  80.         Dim amount As Decimal = 0D
  81.         Decimal.TryParse(txtAmount.Text.Trim(), amount)
  82.         amount = Math.Abs(amount)

  83.         ' เรียกสร้าง Payload (ตรวจสอบเองภายใน ถ้าผิดจะแจ้งและคืนค่าว่าง)
  84.         Dim payload As String = BuildPromptPayPayload(txtAccount.Text.Trim(), amount)
  85.         ' ตรวจสอบผลลัพธ์
  86.         If payload = "" Then
  87.             txtAccount.Focus()
  88.             Exit Sub
  89.         End If
  90.         ' แสดงผล
  91.         txtPayload.Text = payload
  92.         txtAccount.Focus()
  93.     End Sub

  94.     ' /-----------------------------------------------------------------------------
  95.     ' / ประกอบ Tag-Length-Value ตามมาตรฐาน EMVCo
  96.     ' /-----------------------------------------------------------------------------
  97.     Private Function TagLengthValue(ByVal tagId As String, ByVal value As String) As String
  98.         Return tagId & value.Length.ToString("00") & value
  99.     End Function

  100.     ' /-----------------------------------------------------------------------------
  101.     ' / แปลงเบอร์โทรเป็นรูปแบบสากล
  102.     ' /-----------------------------------------------------------------------------
  103.     Private Function FormatPhoneNumber(ByVal phone As String) As String
  104.         Dim digits As String = New String(phone.Where(AddressOf Char.IsDigit).ToArray())
  105.         If digits.Length = 10 AndAlso digits.StartsWith("0") Then
  106.             Return "0066" & digits.Substring(1)
  107.         ElseIf digits.Length = 9 Then
  108.             Return "0066" & digits
  109.         ElseIf digits.Length = 11 AndAlso digits.StartsWith("66") Then
  110.             Return "00" & digits
  111.         End If
  112.         Return digits
  113.     End Function

  114.     ' /-----------------------------------------------------------------------------
  115.     ' / สร้าง Payload PromptPay/พร้อมเพย์ มาตรฐานรองรับทุกธนาคาร
  116.     ' / การคืนค่า = สำเร็จจะคืนค่า Payload String , หากไม่สำเร็จ คืนค่าว่าง
  117.     ' /-----------------------------------------------------------------------------
  118.     Public Function BuildPromptPayPayload(ByVal target As String, ByVal amount As Decimal) As String
  119.         ' เก็บเฉพาะตัวเลข
  120.         Dim id As String = New String(target.Where(AddressOf Char.IsDigit).ToArray())
  121.         Dim subTag As String = ""
  122.         Dim targetType As String = ""

  123.         ' ตรวจสอบว่าเลือกเบอร์หรือบัตรประชาชน จากภายนอกไม่ได้ (ตรวจตามความยาวแทน)
  124.         ' เบอร์โทรศัพท์ ยาว 10 หลัก
  125.         If id.Length = 10 Then
  126.             ' เบอร์โทร
  127.             Dim formattedPhone As String = FormatPhoneNumber(id)
  128.             If formattedPhone.Length = 13 AndAlso formattedPhone.StartsWith("0066") Then
  129.                 subTag = TagLengthValue("01", formattedPhone)   ' 011300668XXXXXXXX เมื่อ X คือเบอร์โทร 8 หลักขวาสุดของเรา
  130.                 targetType = "เบอร์โทร"
  131.             Else
  132.                 UIMessageBox.ShowMessageDialog("รูปแบบเบอร์โทรไม่ถูกต้อง", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
  133.                 Return ""
  134.             End If

  135.             ' หมายเลขบัตรประชาชน 13 หลัก
  136.         ElseIf id.Length = 13 Then
  137.             ' ตรวจสอบความถูกต้องของบัตรประชาชน / เลขผู้เสียภาษี
  138.             If Not CheckCorrectID(id) Then
  139.                 UIMessageBox.ShowMessageDialog("เลขบัตรประจำตัวประชาชนไม่ถูกต้อง", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
  140.                 Return ""
  141.             End If
  142.             subTag = TagLengthValue("02", id)
  143.             targetType = "บัตรประชาชน"

  144.         Else
  145.             UIMessageBox.ShowMessageDialog("รูปแบบไม่ถูกต้อง" & vbCrLf & "เบอร์โทร : 10 หลัก (เริ่มต้นด้วย 0)" & vbCrLf & "บัตรประชาชน : 13 หลัก", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
  146.             Return ""
  147.         End If

  148.         ' ข้อมูลผู้รับเงิน
  149.         Dim merchantInfo As String = TagLengthValue("00", "A000000677010111") & subTag

  150.         ' ประกอบ Payload หลัก
  151.         Dim sb As New StringBuilder()

  152.         ' Tag 00: เวอร์ชัน
  153.         sb.Append(TagLengthValue("00", "01"))

  154.         ' Tag 01: ประเภทธุรกรรม
  155.         ' 11 = เรียกเก็บเงินซ้ำได้ / 12 = จ่ายครั้งเดียว
  156.         If amount > 0D Then
  157.             sb.Append(TagLengthValue("01", "12"))
  158.         Else
  159.             sb.Append(TagLengthValue("01", "11"))
  160.         End If

  161.         ' Tag 29: ข้อมูลบัญชีผู้รับ
  162.         sb.Append(TagLengthValue("29", merchantInfo))

  163.         ' Tag 53: รหัสสกุลเงิน 764 = บาทไทย
  164.         sb.Append(TagLengthValue("53", "764"))

  165.         ' Tag 54: จำนวนเงิน (ถ้ามี)
  166.         If amount > 0D Then
  167.             ' ใช้จุดทศนิยมเสมอ ไม่สนใจ Culture
  168.             Dim amountStr As String = amount.ToString("0.00", CultureInfo.InvariantCulture)
  169.             sb.Append(TagLengthValue("54", amountStr))
  170.         End If

  171.         ' Tag 58: รหัสประเทศ
  172.         sb.Append(TagLengthValue("58", "TH"))

  173.         ' คำนวณ CRC ท้ายสุด
  174.         Dim crcBase As String = sb.ToString() & "6304"
  175.         Dim crcValue As String = CalcCRC16(crcBase)
  176.         sb.Append("6304" & crcValue)

  177.         Return sb.ToString()
  178.     End Function

  179.     ' /-----------------------------------------------------------------------------
  180.     ' / คำนวณ CRC16‑CCITT (รูปแบบ 0x1021, ค่าเริ่มต้น 0xFFFF)
  181.     ' /-----------------------------------------------------------------------------
  182.     ' / CRC ย่อมาจาก Cyclic Redundancy Check คือ "รหัสตรวจสอบความถูกต้องของข้อมูล"
  183.     ' / ใช้ทำอะไรใน QR พร้อมเพย์?
  184.     ' / - ตามมาตรฐาน EMVCo บังคับให้ 4 หลักสุดท้ายของข้อความ QR เป็นค่า CRC
  185.     ' /   ที่คำนวณจากข้อมูลทั้งหมดก่อนหน้า
  186.     ' /
  187.     ' / - ฝั่งเรา (สร้าง QR) : คำนวณค่า CRC แล้วต่อท้ายข้อความเสมอ
  188.     ' / - ฝั่งแอพธนาคาร (สแกน) : คำนวณ CRC ใหม่จากข้อมูลที่อ่านได้
  189.     ' /   แล้วเปรียบเทียบกับค่าที่ติดมากับ QR
  190.     ' / - ถ้าไม่ตรงกัน - แอพปฏิเสธทันที เพราะข้อมูลอาจเสียหายหรือถูกแก้ไข
  191.     ' /-----------------------------------------------------------------------------
  192.     Private Function CalcCRC16(ByVal data As String) As String

  193.         ' ตั้งค่าเริ่มต้นตามมาตรฐาน: 16 บิตเริ่มเป็น 1 ทั้งหมด = 0xFFFF
  194.         Dim crc As Integer = &HFFFFI    ' I = บอกว่าค่านี้เป็นชนิด Integer (จำนวนเต็ม 32 บิต)

  195.         ' แปลงข้อความเป็นไบต์ ASCII เพราะ CRC คำนวณทีละไบต์ Payload ของ PromptPay
  196.         ' เป็นตัวเลขและตัวอักษรอังกฤษเท่านั้น จึงใช้ ASCII ได้
  197.         Dim bytes() As Byte = Encoding.ASCII.GetBytes(data)

  198.         ' ประมวลผลทีละค่า ทีละตัว
  199.         For Each b As Byte In bytes

  200.             ' นำแต่ละไบต์มาเลื่อนไปทางซ้าย 8 บิต เพื่อให้ไปตรงกับไบต์สูงของ CRC แล้ว XOR เข้าไป
  201.             crc = crc Xor (CInt(b) << 8)

  202.             ' คำนวณทีละ 1 บิต รวม 8 รอบต่อ 1 ค่า
  203.             For i As Integer = 0 To 7

  204.                 ' เช็กเลขตัวแรกทางซ้ายว่าเป็น 1 หรือไม่
  205.                 If (crc And &H8000I) <> 0 Then
  206.                     ' เป็น 1 - เลื่อนค่าทางซ้าย 1 ตำแหน่ง ผสมกับรูปแบบ 0x1021
  207.                     ' (&H1021 คือ ค่าคงที่มาตรฐานที่ทุกคนตกลงกันใช้สำหรับ CRC16‑CCITT)
  208.                     ' And &HFFFFI บังคับให้ค่าคงเหลือแค่ 16 บิตเสมอ ไม่ให้เกิน
  209.                     crc = ((crc << 1) Xor &H1021I) And &HFFFFI
  210.                 Else
  211.                     ' เป็น 0 - เลื่อนทางซ้ายอย่างเดียว
  212.                     ' And &HFFFFI บังคับให้ค่าคงเหลือแค่ 16 บิตเสมอ ไม่ให้เกิน
  213.                     crc = (crc << 1) And &HFFFFI
  214.                 End If
  215.             Next
  216.         Next
  217.         'Debug.Print(crc)
  218.         ' แปลงผลลัพธ์เป็นเลขฐาน 16 ตัวพิมพ์ใหญ่ ยาว 4 หลักเสมอ
  219.         ' เติม 0 ข้างหน้าถ้าน้อยกว่า 4 หลัก เช่น "AB" --> "00AB"
  220.         Return crc.ToString("X4")
  221.     End Function

  222.     ' /-----------------------------------------------------------------------------
  223.     ' / บันทึก QR Code ให้เป็นไฟล์ภาพ
  224.     ' /-----------------------------------------------------------------------------
  225.     Private Sub btnSaveQRCode_Click(sender As Object, e As EventArgs) Handles btnSaveQRCode.Click
  226.         Const TARGET_SIZE As Integer = 256 ' กำหนดขนาดภาพที่ต้องการ

  227.         ' ตรวจสอบว่ามีภาพหรือไม่
  228.         If picQRCode.Image Is Nothing Then
  229.             UIMessageBox.ShowMessageDialog("ยังไม่มีภาพ QR Code ที่จะบันทึก", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Warning)
  230.             Exit Sub
  231.         End If

  232.         ' บันทึกไฟล์
  233.         Dim dlgSaveFile As New SaveFileDialog()
  234.         With dlgSaveFile
  235.             .Title = "บันทึกไฟล์ QRCode เป็นภาพ"
  236.             .Filter = "JPEG Image (*.jpg)|*.jpg|Png Image (*.png)|*.png|Bitmap Image (*.bmp)|*.bmp"
  237.             .FilterIndex = 1
  238.             .RestoreDirectory = True
  239.         End With

  240.         If dlgSaveFile.ShowDialog() = DialogResult.OK Then
  241.             Dim resizedImage As Bitmap = Nothing
  242.             Dim fs As FileStream = Nothing
  243.             Try
  244.                 ' สร้างภาพใหม่ขนาด 256 x 256
  245.                 resizedImage = New Bitmap(TARGET_SIZE, TARGET_SIZE)
  246.                 Dim g As Graphics = Graphics.FromImage(resizedImage)

  247.                 ' ตั้งค่าคุณภาพการวาด
  248.                 g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
  249.                 g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
  250.                 g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality

  251.                 ' เติมพื้นหลังสีขาว แล้ววาด QR Code ลงไป
  252.                 g.Clear(Color.White)
  253.                 g.DrawImage(picQRCode.Image, 0, 0, TARGET_SIZE, TARGET_SIZE)
  254.                 g.Dispose() ' ปล่อยหน่วยความจำทันทีเมื่อวาดเสร็จ

  255.                 ' เปิดไฟล์และบันทึก
  256.                 fs = CType(dlgSaveFile.OpenFile(), FileStream)
  257.                 Select Case dlgSaveFile.FilterIndex
  258.                     Case 1
  259.                         resizedImage.Save(fs, ImageFormat.Jpeg)
  260.                     Case 2
  261.                         resizedImage.Save(fs, ImageFormat.Png)
  262.                     Case 3
  263.                         resizedImage.Save(fs, ImageFormat.Bmp)
  264.                 End Select
  265.                 fs.Close()

  266.                 UIMessageBox.ShowMessageDialog("บันทึกไฟล์ภาพ QRCode เรียบร้อยแล้ว.", "รายงานสถานะ", _
  267.                     False, _
  268.                     UIStyle.Green, _
  269.                     MessageBoxButtons.OK, _
  270.                     MessageBoxIcon.Information)

  271.             Catch ex As Exception
  272.                 UIMessageBox.ShowMessageDialog("เกิดข้อผิดพลาด: " & ex.Message, "ผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
  273.             Finally
  274.                 ' ทำความสะอาดหน่วยความจำ
  275.                 If fs IsNot Nothing Then fs.Dispose()
  276.                 If resizedImage IsNot Nothing Then resizedImage.Dispose()
  277.             End Try
  278.         End If
  279.     End Sub

  280.     ' /-----------------------------------------------------------------------------
  281.     ' / คัดลอก QR Code สู่คลิปบอร์ดเพื่อนำไปวางแปะในเอกสาร
  282.     ' /-----------------------------------------------------------------------------
  283.     Private Sub btnClipboard_Click(sender As System.Object, e As System.EventArgs) Handles btnClipboard.Click
  284.         ' ตรวจสอบว่ามีภาพหรือไม่
  285.         If picQRCode.Image Is Nothing Then
  286.             UIMessageBox.ShowMessageDialog( _
  287.                 "ยังไม่มีภาพ QR Code ที่จะคัดลอก", _
  288.                 "แจ้งเตือน", _
  289.                 False, _
  290.                 UIStyle.Red, _
  291.                 MessageBoxButtons.OK, _
  292.                 MessageBoxIcon.Information)
  293.             Exit Sub
  294.         End If

  295.         Try
  296.             ' ========== คัดลอกภาพโดยตรง ==========
  297.             Clipboard.Clear()
  298.             Clipboard.SetImage(picQRCode.Image)

  299.         Catch ex As Exception
  300.             ' จัดการข้อผิดพลาด
  301.             UIMessageBox.ShowMessageDialog( _
  302.                 "เกิดข้อผิดพลาด: " & ex.Message, _
  303.                 "ผิดพลาด", _
  304.                 False, _
  305.                 UIStyle.Red, _
  306.                 MessageBoxButtons.OK, _
  307.                 MessageBoxIcon.Error)
  308.         End Try
  309.         txtAccount.Focus()
  310.         txtAccount.SelectAll()
  311.     End Sub

  312.     Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
  313.         Me.Close()
  314.     End Sub

  315.     Private Sub frmQRCodePromptPay_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
  316.         Me.Dispose()
  317.         GC.SuppressFinalize(Me)
  318.         Application.Exit()
  319.     End Sub

  320.     Private Sub txtAmount_Enter(sender As Object, e As System.EventArgs) Handles txtAmount.Enter
  321.         txtAmount.SelectAll()
  322.     End Sub

  323.     Private Sub txtAmount_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtAmount.KeyDown
  324.         If e.KeyCode = 13 Then
  325.             btnGenerate.PerformClick()
  326.             e.Handled = True
  327.         End If
  328.     End Sub

  329.     Private Sub txtReference_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtPayload.KeyPress
  330.         e.Handled = True
  331.     End Sub

  332.     Private Sub txtAccount_Enter(sender As Object, e As System.EventArgs) Handles txtAccount.Enter
  333.         txtAccount.SelectAll()
  334.     End Sub

  335.     Private Sub txtAccount_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtAccount.KeyPress
  336.         If Asc(e.KeyChar) = Keys.Enter Then
  337.             e.Handled = True
  338.             SendKeys.Send("{TAB}")
  339.         Else
  340.             e.Handled = CheckDigitOnly(Asc(e.KeyChar))
  341.         End If
  342.     End Sub

  343.     Private Sub ToolStripStatusLabel2_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripStatusLabel2.Click
  344.         Process.Start("https://www.facebook.com/g2gnet")
  345.     End Sub

  346. #Region "FUNCTION"
  347.     ' ฟังค์ชั่นในการตรวจสอบความถูกต้องของหลักที่ 13 บัตรประชาชน
  348.     Private Function CheckCorrectID(ByVal ID As String) As Boolean
  349.         CheckCorrectID = False
  350.         Dim Sum As Integer
  351.         Dim Count As Short
  352.         '// หลักการคิด
  353.         ' หาผลรวมตั้งแต่หลักที่ 1 ไปจนถึงหลักที่ 12 (นับจากซ้ายไปขวา)
  354.         ' โดยให้หลักที่ 1 คูณด้วยน้ำหนักประจำหลัก = 13
  355.         ' โดยให้หลักที่ 2 คูณด้วยน้ำหนักประจำหลัก = 12
  356.         ' โดยให้หลักที่ 3 คูณด้วยน้ำหนักประจำหลัก = 11
  357.         ' โดยให้หลักที่ .. คูณด้วยน้ำหนักประจำหลัก = ...
  358.         ' โดยให้หลักที่ 12 คูณด้วยน้ำหนักประจำหลัก = 2
  359.         ' จากนั้นนำผลการคูณของแต่ละหลักมารวมกันเข้าไป
  360.         '
  361.         ' หลักแต่ละหลัก คือ Val(Mid(txtIDcard.Text, Count, 1))
  362.         ' น้ำหนักของแต่ละหลัก คือ (14 - Count) เมื่อ Count เริ่มต้นจาก 1 ไปสิ้นสุดที่ 12 ดังนั้นค่านี้ (14 - Count) จึงเริ่มต้นค่าจาก 13, 12, 11, ..., สิ้นสุดที่ 2 ครับผม
  363.         ' หลักที่ 3 ที่มีน้ำหนักประจำหลัก 11 นั่นแหละคือที่เรากำลังพูดถึง
  364.         Sum = 0
  365.         For Count = 1 To 12
  366.             Sum = Sum + Val(Mid(ID, Count, 1)) * (14 - Count)
  367.         Next
  368.         ' วิธีการคิดความถูกต้องของหลักที่ 13 (Check Digit)
  369.         ' จากนั้นให้ลบออกด้วย 11 ก็จะทำให้ได้ค่าตั้งแต่ 1, 2, 3, ... , 11 (11 - (Sum Mod 11))
  370.         ' แล้วให้เลือกตัวขวามือสุดมาหนึ่งตัว ด้วยคำสั่ง Right --> Right(Str(11 - (Sum Mod 11)), 1)
  371.         ' สุดท้ายก็ให้นำมาเปรียบเทียบกับหลักที่ 13 ของหมายเลขบัตรประชาชน ว่ามันตรงกันหรือไม่ ?
  372.         ' หากตรงกันก็แสดงว่า เป็นบัตรแท้, หากไม่ตรงกัน ก็คือ บัตรเก๊ เท่านี้เองครับพี่น้อง
  373.         If Microsoft.VisualBasic.Right(ID, 1) = Microsoft.VisualBasic.Right(Str(11 - (Sum Mod 11)), 1) Then Return True
  374.     End Function

  375.     ' /-----------------------------------------------------------------------------
  376.     ' / ฟังก์ชั่นในการป้อนเฉพาะค่าตัวเลขได้เท่านั้น
  377.     ' / คืนค่า True = ไม่อนุญาตให้พิมพ์, False = อนุญาตให้พิมพ์
  378.     ' /-----------------------------------------------------------------------------
  379.     Function CheckDigitOnly(ByVal keyAscii As Integer) As Boolean
  380.         ' อนุญาต: 0-9, Backspace, Enter, Tab, Delete
  381.         Select Case keyAscii
  382.             ' ตัวเลข 0-9
  383.             Case 48 To 57
  384.                 ' Backspace, Tab, Enter
  385.             Case 8, 9, 13
  386.                 ' Delete
  387.             Case 46
  388.             Case Else
  389.                 Return True ' ไม่อนุญาต
  390.         End Select
  391.         Return False ' อนุญาต
  392.     End Function

  393. #End Region

  394. End Class
คัดลอกไปที่คลิปบอร์ด

ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) แบบตัวเต็ม ...


ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2026-11-13 02:00 , Processed in 0.079690 second(s), 4 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้