thongkorn โพสต์ 2023-5-8 17:52:40

[VB.NET] การนำข้อมูลรายชื่อจังหวัดจาก JSON แบบออนไลน์/ออฟไลน์ มาแสดงผลในตารางกริด

http://www.g2gsoft.com/webboard/images/VBNet/JsonProvince.png
http://www.g2gsoft.com/webboard/images/VBNet/jsonformat.png

http://www.g2gsoft.com/webboard/images/VBNet/Newtonsoft.png
Add References ...

การนำข้อมูลรายชื่อจังหวัดจาก JSON (JavaScript Object Notation) แบบออนไลน์/ออฟไลน์ มาแสดงผลในตารางกริด ก็มีหลักการเดียวกันกับเอกสาร XML (eXtensible Markup Language) เพราะมันก็เป็นข้อมูลแบบ Text ธรรมดานั่นแหละครับ เพียงแต่จะมีการจัดทำเอกสารในรูปแบบที่แตกต่างกัน เราจึงต้องทำการดึงข้อมูลเหล่านั้นออกมาให้ได้ โดยโค้ดชุดนี้จะต้องใช้ของฟรีจาก NewtonSoft สามารถดาวน์โหลดได้จากที่นี่ ... (ในชุดโค้ดมี Newtonsoft.Json เวอร์ชั่น 13 ติดมาให้เรียบร้อยแล้วครับผม) ... หลักการคือเมื่ออ่านเอกสาร JSON เข้ามาเรียบร้อย ก็ทำการ Deserialize หรือการแยกชุดข้อมูลออกมา จากนั้นก็นำไปเก็บไว้ใน DataTable เพื่อนำมาแสดงผลอีกทีในตารางกริด ...

Thailand Geography JSON ... ทางผู้ที่ให้ข้อมูลมาบอกว่าเป็นรายชื่อจังหวัด อำเภอ ตำบล และรหัสไปรษณีย์ ที่อัพเดตจากกรมการปกครอง ปี พ.ศ.2565

กรณีของ Visual Basic .NET เวอร์ชั่น 2010 จะสามารถใช้งาน .Net Framework ได้สูงสุดที่ 4.0 ดังนั้นในงานที่ต้องติดต่อผ่านอินเทอร์เน็ต ซึ่งในปัจจุบันเว็บไซต์หรือผู้ให้บริการ API จะมีความปลอดภัยสูงขึ้น เราจึงต้องใช้คำสั่งชุดนี้เอาไว้ทุกครั้ง ...
      '// Provide Security in VS2010 and .Net Framework lower than version 4.5
      System.Net.ServicePointManager.SecurityProtocol = DirectCast(3072, System.Net.SecurityProtocolType)
มาดูโค้ดกันเถอะ ...
'// Special Thank ... Original JSON data.
'// https://github.com/thailand-geography-data/thailand-geography-json

Public Class frmJsonProvince

    Private Sub frmJsonProvince_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      '// Provide Security in VS2010 and .Net Framework lower than version 4.5
      System.Net.ServicePointManager.SecurityProtocol = DirectCast(3072, System.Net.SecurityProtocolType)
      '//
      lblRecordCount.Text = ""
      Me.Size = New Size(1180, 800)
      Me.CenterToScreen()
    End Sub

    Private Sub btnOnline1_Click(sender As System.Object, e As System.EventArgs) Handles btnOnline1.Click
      Call GetDataJson("https://raw.githubusercontent.com/thailand-geography-data/thailand-geography-json/main/src/geography.json")
      Me.lblRecordCount.Text = "Total : " & Format(dgvData.RowCount, "#,##") & " Records."
    End Sub

    Private Sub btnOnline2_Click(sender As System.Object, e As System.EventArgs) Handles btnOnline2.Click
      Call GetDataJsonObject("https://raw.githubusercontent.com/thailand-geography-data/thailand-geography-json/main/src/geography.json")
      Me.lblRecordCount.Text = "Total : " & Format(dgvData.RowCount, "#,##") & " Records."
    End Sub

    Private Sub btnOffline_Click(sender As System.Object, e As System.EventArgs) Handles btnOffline.Click
      Try
            'Dim FileJson As String = MyPath(Application.StartupPath) & "src\provinces.json"
            'Dim FileJson As String = MyPath(Application.StartupPath) & "src\districts.json"
            'Dim FileJson As String = MyPath(Application.StartupPath) & "src\subdistricts.json"
            Dim FileJson As String = MyPath(Application.StartupPath) & "src\geography.json"
            Dim json As String = File.ReadAllText(FileJson)
            Dim dt As New DataTable
            dgvData.DataSource = DeserializeDataTable(json)
            With dgvData.Columns
                .Remove("provinceCode")
                .Remove("districtCode")
                .Remove("subdistrictCode")
            End With
            Call SetupGridView()
            Me.lblRecordCount.Text = "Total : " & Format(dgvData.RowCount, "#,##") & " Records."
      Catch ex As Exception
            MessageBox.Show("Error: " & ex.ToString())
      End Try
    End Sub

    '// Get JSON From URL.
    Private Sub GetDataJson(ByVal url As String)
      Dim request As HttpWebRequest
      Dim response As HttpWebResponse = Nothing
      Dim reader As StreamReader
      Try
            request = DirectCast(WebRequest.Create(url), HttpWebRequest)
            response = DirectCast(request.GetResponse(), HttpWebResponse)
            reader = New StreamReader(response.GetResponseStream())
            Dim s As String
            s = reader.ReadToEnd
            s = s.Replace("null", "0")'// Trap Error.
            Dim dt As DataTable
            If Microsoft.VisualBasic.Left(s, 1) = "[" Then
                dt = DeserializeDataTable(s)
            Else
                dt = DeserializeDataTable("[" & s & "]")
            End If
            dgvData.DataSource = dt
            Call SetupGridView()
      Catch ex As Exception
            MessageBox.Show(ex.Message)
      End Try
    End Sub

    '// Deserialized JSON and return DataTable.
    Public Function DeserializeDataTable(json As String) As DataTable
      Dim dt As DataTable = TryCast(JsonConvert.DeserializeObject(json, (GetType(DataTable))), DataTable)
      Return dt
    End Function

    '// Get JSON by Object From URL.
    Private Sub GetDataJsonObject(ByVal url As String)
      Dim request As HttpWebRequest
      Dim response As HttpWebResponse = Nothing
      Dim reader As StreamReader
      Try
            request = DirectCast(WebRequest.Create(url), HttpWebRequest)
            response = DirectCast(request.GetResponse(), HttpWebResponse)
            reader = New StreamReader(response.GetResponseStream())
            Dim s As String
            s = reader.ReadToEnd.Replace("null", "0")
            If Microsoft.VisualBasic.Left(s, 1) <> "[" Then
                s = "[" & s & "]"
            End If
            '//
            Dim res() = Newtonsoft.Json.JsonConvert.DeserializeObject(Of ItemsProvince())(s)
            Dim dt As New DataTable
            With dt.Columns
                .Add("ID", GetType(Integer))
                .Add("Province En", GetType(String))
                .Add("Province Th")
                .Add("Amphur En")
                .Add("Amphur Th")
                .Add("Tumbon En")
                .Add("Tumbon Th")
                .Add("Postcode")
            End With
            For Each province As ItemsProvince In res
                Dim dr As DataRow = dt.NewRow()
                If province IsNot Nothing Then
                  dr(0) = province.id
                  dr(1) = province.provinceNameEn
                  dr(2) = province.provinceNameTh
                  dr(3) = province.districtNameEn
                  dr(4) = province.districtNameTh
                  dr(5) = province.subdistrictNameEn
                  dr(6) = province.subdistrictNameTh
                  dr(7) = province.postalCode
                End If
                '// Add row.
                dt.Rows.Add(dr)
            Next
            dgvData.DataSource = dt
            Call SetupGridView()
      Catch ex As Exception
            MessageBox.Show(ex.Message)
      End Try
    End Sub

    '// 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", 11)
            .RowTemplate.MinimumHeight = 27
            .RowTemplate.Height = 27
            '// Column Header
            .ColumnHeadersHeight = 30
            .ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
            '// Autosize Column
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            '// Header
            With .ColumnHeadersDefaultCellStyle
                .BackColor = Color.SeaGreen
                .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.BlanchedAlmond
            '// 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

    '// Show row number in row header of a DataGridView.
    Private Sub dgvData_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles dgvData.RowPostPaint
      Dim grid As DataGridView = CType(sender, DataGridView)
      Dim rowIdx As String = (e.RowIndex + 1).ToString()
      Dim rowFont As New System.Drawing.Font("Tahoma", 10.0!, _
            System.Drawing.FontStyle.Regular, _
            System.Drawing.GraphicsUnit.Point, CType(0, Byte))

      Dim centerFormat = New StringFormat()
      centerFormat.Alignment = StringAlignment.Center
      centerFormat.LineAlignment = StringAlignment.Center

      Dim headerBounds As Rectangle = New Rectangle( _
                                        e.RowBounds.Left - 10, e.RowBounds.Top, _
                                        grid.RowHeadersWidth + 20, e.RowBounds.Height)
      e.Graphics.DrawString(rowIdx, rowFont, SystemBrushes.ControlText, _
                              headerBounds, centerFormat)
    End Sub

    Private Sub frmJsonProvince_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      Me.Dispose()
      GC.SuppressFinalize(Me)
      Application.Exit()
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / 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 Class

Public Class ItemsProvince
    Public Property id As String
    Public Property provinceNameEn As String
    Public Property provinceNameTh As String
    Public Property districtNameEn As String
    Public Property districtNameTh As String
    Public Property subdistrictNameEn As String
    Public Property subdistrictNameTh As String
    Public Property postalCode As Integer
End Class
ดาวน์โหลดโค้ดชุดต้นฉบับ VB.NET (2010) ได้จากที่นี่ ...



หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] การนำข้อมูลรายชื่อจังหวัดจาก JSON แบบออนไลน์/ออฟไลน์ มาแสดงผลในตารางกริด