[VB.NET] การนำข้อมูลรหัสไปรษณีย์จากรูปแบบ JSON มาแสดงผลลงในตารางกริด และค้นหาข้อมูลได้
ก็เป็นอีกหนึ่งแหล่งที่มาของไฟล์ JSON ที่มีข้อมูลรหัสไปรษณีย์ทั่วประเทศไทย แต่รูปแบบ JSON ของผู้จัดทำเขาออกแนวกลับด้าน คือใช้รหัสไปรษณีย์ในการค้นหาชื่อตำบล อำเภอและจังหวัด แต่โดยปกติเราจะค้นหาด้วยชื่อตำบล อำเภอและจังหวัด เพื่อหารหัสไปรษณีย์มากกว่า พอนำ JSON ชุดนี้มาใช้งาน ก็เลยต้องเขียนโค้ดขึ้นมายากสักหน่อย ในการแยกเอาข้อมูลตำบล อำเภอ จังหวัดที่มันตรงกันเท่านั้น ด้วยการใช้งาน Lambda Expression ... อย่างไรก็ตามเราก็ใช้หลักการเดิม คือ การ Deserialize JSON แยกเอาข้อมูลมาเก็บไว้ใน DataTable ก่อน จากนั้นก็จะทำ BindingSource อีกที แล้วนำไปแสดงผลลงในตารางกริด ส่วนในการค้นหาก็จะใช้ Method Filter ...แหล่งข้อมูลต้นฉบับไฟล์ JSON ...
http://www.g2gsoft.com/webboard/images/VBNet/jsonpostcode.png
http://www.g2gsoft.com/webboard/images/VBNet/Newtonsoft.png
Add Reference ... NewtonSoft
ตัวอย่างรูปแบบ JSON ...
{
"zipCode": "10100",
"subDistrictList": [
{
"subDistrictId": "100801",
"districtId": "1008",
"provinceId": "10",
"subDistrictName": "ป้อมปราบ"
},
{
"subDistrictId": "100802",
"districtId": "1008",
"provinceId": "10",
"subDistrictName": "วัดเทพศิรินทร์"
},
{
"subDistrictId": "100803",
"districtId": "1008",
"provinceId": "10",
"subDistrictName": "คลองมหานาค"
},
{
"subDistrictId": "100804",
"districtId": "1008",
"provinceId": "10",
"subDistrictName": "บ้านบาตร"
},
{
"subDistrictId": "100805",
"districtId": "1008",
"provinceId": "10",
"subDistrictName": "วัดโสมนัส"
},
{
"subDistrictId": "101301",
"districtId": "1013",
"provinceId": "10",
"subDistrictName": "จักรวรรดิ"
},
{
"subDistrictId": "101302",
"districtId": "1013",
"provinceId": "10",
"subDistrictName": "สัมพันธวงศ์"
},
{
"subDistrictId": "101303",
"districtId": "1013",
"provinceId": "10",
"subDistrictName": "ตลาดน้อย"
}
],
"districtList": [
{
"districtId": "1008",
"districtName": "ป้อมปราบศัตรูพ่าย",
"provinceId": "10"
},
{
"districtId": "1013",
"districtName": "สัมพันธวงศ์",
"provinceId": "10"
}
],
"provinceList": [
{
"provinceId": "10",
"provinceName": "กรุงเทพมหานคร"
}
]
}
มาดูโค้ดฉบับเต็มกันเถอะ ...
'// Special Thank ... Original JSON data.
'// https://gist.github.com/mennwebs/8ff8e27a01fd06ca2ac965a1c7317552
Imports Newtonsoft.Json
Imports System.IO
Public Class frmJsonPostCode
Private JsonSource As New BindingSource()
Private Sub frmJsonPostCode_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'// JSON data as a string
Dim json = File.ReadAllText(MyPath(Application.StartupPath) & "src\th-address.json")
'// Deserialize JSON into a List(Of LocationData)
Dim dataList As List(Of LocationData) = JsonConvert.DeserializeObject(Of List(Of LocationData))(json)
Dim DT As New DataTable()
'// Add Columns to DataTable.
With DT.Columns
.Add("zipCode", GetType(String))
.Add("subDistrictId", GetType(String))
.Add("subDistrictName", GetType(String))
.Add("districtId", GetType(String))
.Add("districtName", GetType(String))
.Add("provinceId", GetType(String))
.Add("provinceName", GetType(String))
End With
'// Loop for add row data to DataTable.
Try
For Each LocationData In dataList
For Each subDistrict In LocationData.subDistrictList
Dim row As DataRow = DT.NewRow()
row("zipCode") = LocationData.zipCode
row("subDistrictId") = subDistrict.subDistrictId
row("subDistrictName") = subDistrict.subDistrictName
'//
Dim matchingDistrict = LocationData.districtList.FirstOrDefault(Function(d) d.districtId = subDistrict.districtId)
If matchingDistrict IsNot Nothing Then
row("districtId") = matchingDistrict.districtId
row("districtName") = matchingDistrict.districtName
End If
'//
Dim matchingProvince = LocationData.provinceList.FirstOrDefault(Function(p) p.provinceId = subDistrict.provinceId)
If matchingProvince IsNot Nothing Then
row("provinceId") = matchingProvince.provinceId
row("provinceName") = matchingProvince.provinceName
End If
DT.Rows.Add(row)
Next
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
'// Set DataTable as the DataSource for BindingSource.
JsonSource.DataSource = DT
'// Set BindingSource as the DataSource for DataGridView.
dgvData.DataSource = JsonSource
'// Remove some columns.
With dgvData.Columns
.Remove("subDistrictId")
.Remove("districtId")
.Remove("provinceId")
End With
'//
With dgvData
.Columns("zipCode").HeaderText = "รหัสไปรษณีย์"
.Columns("subDistrictName").HeaderText = "ตำบล/แขวง"
.Columns("districtName").HeaderText = "อำเภอ/เขต"
.Columns("provinceName").HeaderText = "จังหวัด"
End With
Call SetupGridView()
Me.lblRecordCount.Text = "Total: " & Format(dgvData.RowCount, "#,##") & " Records."
End Sub
' / --------------------------------------------------------------------------------
'// Filter data.
' / --------------------------------------------------------------------------------
Private Sub txtFilterJson_TextChanged(sender As Object, e As System.EventArgs) Handles txtFilterJson.TextChanged
If rdoFilterAll.Checked Then
'// Filter for All.
JsonSource.Filter = _
" provinceName LIKE " & "'%" & txtFilterJson.Text & "%'" & _
" OR districtName LIKE " & "'%" & txtFilterJson.Text & "%'" & _
" OR subDistrictName LIKE " & "'%" & txtFilterJson.Text & "%'" & _
" OR zipCode LIKE " & "'%" & txtFilterJson.Text & "%'"
'// Filter ProvinceName.
ElseIf rdoProvinceName.Checked Then
JsonSource.Filter = "provinceName LIKE " & "'%" & txtFilterJson.Text & "%'"
'// Filter DistrictName.
ElseIf rdoDistrictName.Checked Then
JsonSource.Filter = "districtName LIKE " & "'%" & txtFilterJson.Text & "%'"
'// Filter SubDistrictName.
ElseIf rdoSubDistrictName.Checked Then
JsonSource.Filter = "subdistrictName LIKE " & "'%" & txtFilterJson.Text & "%'"
'// Filter ZipCode.
ElseIf rdoZipCode.Checked Then
JsonSource.Filter = "zipCode LIKE " & "'%" & txtFilterJson.Text & "%'"
End If
'//
Me.lblRecordCount.Text = "Total: " & Format(dgvData.RowCount, "#,##") & " Records."
End Sub
Private Sub rdoFilterAll_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles rdoFilterAll.CheckedChanged
txtFilterJson.Focus()
End Sub
Private Sub rdoProvinceName_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles rdoProvinceName.CheckedChanged
txtFilterJson.Focus()
End Sub
Private Sub rdoDistrictName_CheckedChanged(sender As Object, e As System.EventArgs) Handles rdoDistrictName.CheckedChanged
txtFilterJson.Focus()
End Sub
Private Sub rdoSubDistrictName_CheckedChanged(sender As Object, e As System.EventArgs) Handles rdoSubDistrictName.CheckedChanged
txtFilterJson.Focus()
End Sub
Private Sub rdoZipCode_CheckedChanged(sender As Object, e As System.EventArgs) Handles rdoZipCode.CheckedChanged
txtFilterJson.Focus()
End Sub
#Region "DATAGRIDVIEW"
'// Initialized DataGridView.
Private Sub SetupGridView()
With dgvData
.RowHeadersVisible = True
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeRows = False
.MultiSelect = False
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.ReadOnly = True
'// Data rows
.Font = New Font("Tahoma", 10)
.RowTemplate.MinimumHeight = 27
.RowTemplate.Height = 27
'// Autosize Column
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
'// Header
With .ColumnHeadersDefaultCellStyle
.BackColor = Color.RoyalBlue
.ForeColor = Color.White
.Font = New Font(dgvData.Font, FontStyle.Bold)
End With
.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
.ColumnHeadersHeight = 36
'/ Accept changes to the header's background color.
.EnableHeadersVisualStyles = False
'// Even-Odd Color of Rows.
.AlternatingRowsDefaultCellStyle.BackColor = Color.Beige
'// Even-Odd Color of Columns.
For iCol As Integer = 0 To dgvData.Columns.Count - 1
'// If any integer Mod by 2 and gets the answer is 0 so even number, 1 is an odd number.
If iCol Mod 2 = 1 Then
dgvData.Columns(iCol).HeaderCell.Style.BackColor = Color.BlueViolet
Else
dgvData.Columns(iCol).HeaderCell.Style.BackColor = Color.SeaGreen
End If
Next
End With
End Sub
#End Region
#Region "FUNCTION"
' / --------------------------------------------------------------------------------
' / Get my project path
' / AppPath = C:\My Project\bin\debug
' / Replace "\bin\debug" with "\"
' / Return : C:\My Project\
Function MyPath(ByVal AppPath As String) As String
'/ Return Value
MyPath = AppPath.ToLower.Replace("\bin\debug", "\").Replace("\bin\release", "\").Replace("\bin\x86\debug", "\")
'// If not found folder then put the \ (BackSlash) at the end.
If Microsoft.VisualBasic.Right(MyPath, 1) <> Chr(92) Then MyPath = MyPath & Chr(92)
End Function
#End Region
End Class
'// Define data model classes.
Public Class SubDistrict
Public Property subDistrictId As String
Public Property districtId As String
Public Property provinceId As String
Public Property subDistrictName As String
End Class
Public Class District
Public Property districtId As String
Public Property districtName As String
Public Property provinceId As String
End Class
Public Class Province
Public Property provinceId As String
Public Property provinceName As String
End Class
Public Class LocationData
Public Property zipCode As String
Public Property subDistrictList As List(Of SubDistrict)
Public Property districtList As List(Of District)
Public Property provinceList As List(Of Province)
End Class
ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่ ...
หน้า:
[1]