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

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

[VB.NET] การค้นหาข้อมูลด้วยการใช้เงื่อนไขของวันที่ใน MS Access

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

320

กระทู้

512

โพสต์

6583

เครดิต

ผู้ดูแลระบบ

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

Rank: 9Rank: 9Rank: 9

เครดิต
6583




เรื่องของวันที่เป็นปัญหาอันน่าปวดขมับพอสมควรสำหรับคนที่พึ่งเริ่มต้นใช้งาน MS Access แต่แท้ที่จริงแล้วแอดมินขอบอกเลยว่ามันไม่ได้ยากหรอกครับ หากเราเข้าใจหลักการ (ง่ายๆ) ของมัน ซึ่งไม่ว่าเราจะตั้งค่าอย่างไรก็ตาม
ที่อยู่ใน Control Panel --> Region/Language ให้เป็นปี พ.ศ. หรือ ปี ค.ศ. ก็ยังมีวิธีคิดแบบเดิม ...

รูปแบบการเก็บข้อมูลชนิดวันที่ใน MS Access คือ เดือน/วันที่/ปี ค.ศ. เช่น 1/30/2019 คือ วันที่ 30 เดือน 1 ปี ค.ศ.2019 ...


หลักการคิด ... ตรวจสอบก่อนว่าปีที่อยู่ในเครื่องเป็นปี ค.ศ. หรือ ปี พ.ศ. แอดมินคิดง่ายๆคือ เอา 4 หลักท้ายสุดของวันที่ซึ่งจะเป็นค่าปี (yyyy) มาคิด หากได้ค่ามากกว่า 2500 มันคือปี พ.ศ. (เช่น 2562) หากน้อยกว่า (เช่น 2019) เป็นปี ค.ศ. กรณีที่เป็นปี พ.ศ. ให้เอา 543 มาลบออกก่อน แล้วทำการจัดรูปแบบใหม่ให้ตรงกับฟอร์แมตของ MS Access นั่นคือ เดือน/วันที่/ปี ค.ศ. ... อนึ่ง!!! การตั้งค่าเงื่อนไขไว้ที่ 2500 หากลบจาก 2019 คุณๆทั้งหลายจะสามารถใช้งานโปรแกรมได้ไปถึงอีก 481 ปี ไม่ต้องห่วงหรอกครับว่าจะเกิดบั๊กในอนาคต 5555+ ...


มาดูโค้ดฉบับเต็มกันเถอะ ...
  1. #Region "ABOUT"
  2. ' / --------------------------------------------------------------------------
  3. ' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
  4. ' / eMail : thongkorn@hotmail.com
  5. ' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
  6. ' / Facebook: https://www.facebook.com/g2gnet (For Thailand)
  7. ' / Facebook: https://www.facebook.com/commonindy (Worldwide)
  8. ' / Purpose: How to search data by date with VB.NET (2010).
  9. ' / Microsoft Visual Basic .NET (2010) + MS Access
  10. ' /
  11. ' / This is open source code under @CopyLeft by Thongkorn/Common Tubtimkrob.
  12. ' / You can modify and/or distribute without to inform the developer.
  13. ' / --------------------------------------------------------------------------
  14. #End Region

  15. Imports System.Data.OleDb
  16. Imports Microsoft.VisualBasic

  17. Public Class frmSearchByDate
  18.     '// Declare variable one time but use many times.
  19.     Public Conn As OleDbConnection
  20.     Public Cmd As OleDbCommand
  21.     Public DS As DataSet
  22.     Public DR As OleDbDataReader
  23.     Public DA As OleDbDataAdapter
  24.     Public strSQL As String '// Major SQL
  25.     Public strStmt As String    '// Minor SQL

  26.     '// Data Path
  27.     Public strPathData As String = MyPath(Application.StartupPath)

  28.     Public Function ConnectDataBase() As System.Data.OleDb.OleDbConnection
  29.         strPathData = MyPath(Application.StartupPath) & "Data"
  30.         '"Provider = Microsoft.Jet.OLEDB.4.0;"
  31.         Dim strConn As String = _
  32.             "Provider = Microsoft.ACE.OLEDB.12.0;"
  33.         strConn += _
  34.             "Data Source = " & strPathData & "Sample.accdb"

  35.         Conn = New OleDb.OleDbConnection(strConn)
  36.         ' Create Connection
  37.         Conn.ConnectionString = strConn
  38.         ' Return
  39.         Return Conn
  40.     End Function

  41.     ' / --------------------------------------------------------------------------------
  42.     ' / Get my project path
  43.     ' / AppPath = C:\My Project\bin\debug
  44.     ' / Replace "\bin\debug" with ""
  45.     ' / Return : C:\My Project\
  46.     Function MyPath(AppPath As String) As String
  47.         '/ MessageBox.Show(AppPath);
  48.         AppPath = AppPath.ToLower()
  49.         '/ Return Value
  50.         MyPath = AppPath.Replace("\bin\debug", "").Replace("\bin\release", "").Replace("\bin\x86\debug", "")
  51.         '// If not found folder then put the \ (BackSlash) at the end.
  52.         If Microsoft.VisualBasic.Right(MyPath, 1) <> "" Then MyPath = MyPath & ""
  53.     End Function

  54.     Private Sub frmSearchByDate_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
  55.         If Conn.State = ConnectionState.Open Then Conn.Close()
  56.         Me.Dispose()
  57.         Application.Exit()
  58.     End Sub

  59.     Private Sub frmSearchByDate_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  60.         Conn = ConnectDataBase()
  61.         '// Load Data
  62.         Call RetreiveData(False)
  63.     End Sub

  64.     ' / --------------------------------------------------------------------------------
  65.     '// Data Retrieval if blnSearchDate is True, it's search data by date.
  66.     Private Sub RetreiveData(Optional ByVal blnSearchDate As Boolean = False)
  67.         '// Show all data.
  68.         If Not blnSearchDate Then
  69.             strSQL = _
  70.                 "SELECT * FROM Sample ORDER BY PrimaryKey"

  71.             '// Between Date condition.
  72.         Else
  73.             strSQL = _
  74.                 "SELECT * FROM Sample " & _
  75.                 " WHERE " & _
  76.                 " (CDate(Sample.DateField) BETWEEN " & _
  77.                 "#" & FormatMyDate(dtpDateBegin.Value) & _
  78.                 "#" & " AND " & _
  79.                 "#" & FormatMyDate(dtpDateEnd.Value) & "#)" & _
  80.                 " ORDER BY PrimaryKey "
  81.         End If
  82.         '// START
  83.         Try
  84.             '// Open connection
  85.             If Conn.State = ConnectionState.Closed Then Conn.Open()
  86.             DA = New OleDb.OleDbDataAdapter(strSQL, Conn)
  87.             DS = New DataSet
  88.             DA.Fill(DS, "Sample")
  89.             Me.dgvData.DataSource = DS.Tables("Sample").DefaultView
  90.             Label1.Text = "Total: " & DS.Tables("Sample").Rows.Count & " Records."
  91.             Call SetupDataGridView(dgvData)
  92.             DS.Dispose()
  93.             DA.Dispose()
  94.             Conn.Close()
  95.         Catch ex As Exception
  96.             MessageBox.Show(ex.Message)
  97.         End Try
  98.     End Sub

  99.     Private Sub btnSearchDate_Click(sender As System.Object, e As System.EventArgs) Handles btnSearchDate.Click
  100.         Call RetreiveData(True)
  101.     End Sub

  102.     ' / --------------------------------------------------------------------------------
  103.     '// Adjust Date Format in MS Access.
  104.     Function FormatMyDate(ByVal MyDate As Date) As String
  105.         FormatMyDate = String.Empty
  106.         Dim sYear As Integer
  107.         Dim sDay As Integer = Microsoft.VisualBasic.Left(Format(MyDate, "dd/MM/yyyy"), 2)
  108.         Dim sMonth As Integer = Microsoft.VisualBasic.Mid(Format(MyDate, "dd/MM/yyyy"), 4, 2)
  109.         Dim y As Integer = Microsoft.VisualBasic.Right(Format(MyDate, "dd/MM/yyyy"), 4)
  110.         '// If more than 2500, it is the year of the Buddhist era.
  111.         If y > 2500 Then
  112.             sYear = CStr(y - 543)
  113.             '// Month/Date/Year in AD.
  114.             FormatMyDate = CStr(Microsoft.VisualBasic.Right("00" & CStr(sMonth), 2) & "/" & Microsoft.VisualBasic.Right("00" & CStr(sDay), 2) & "/" & "20" & Microsoft.VisualBasic.Right("00" & CStr(sYear), 2))
  115.         Else
  116.             FormatMyDate = CStr(Microsoft.VisualBasic.Right("00" & CStr(sMonth), 2) & "/" & Microsoft.VisualBasic.Right("00" & CStr(sDay), 2) & "/" & Microsoft.VisualBasic.Right("00" & CStr(y), 2))
  117.         End If
  118.     End Function

  119.     Private Sub SetupDataGridView(ByRef DGV As DataGridView)
  120.         With DGV
  121.             .RowTemplate.Height = 22
  122.             .AllowUserToOrderColumns = True
  123.             .AllowUserToDeleteRows = False
  124.             .AllowUserToAddRows = False
  125.             .ReadOnly = True
  126.             .MultiSelect = False
  127.             .SelectionMode = DataGridViewSelectionMode.FullRowSelect
  128.             .Font = New Font("Tahoma", 8)
  129.             .AlternatingRowsDefaultCellStyle.BackColor = Color.Orange
  130.             .DefaultCellStyle.SelectionBackColor = Color.LightSkyBlue

  131.             '.AlternatingRowsDefaultCellStyle.BackColor = Color.LightYellow
  132.             '.DefaultCellStyle.SelectionBackColor = Color.LightBlue

  133.             '/ Auto size column width of each main by sorting the field.
  134.             .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
  135.             .AutoResizeColumns()
  136.             '//
  137.         End With
  138.     End Sub

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


ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่ ...



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

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

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

11

กระทู้

31

โพสต์

437

เครดิต

ผู้ดูแลบอร์ด

Rank: 7Rank: 7Rank: 7

เครดิต
437
โพสต์ 2019-2-5 08:58:34 | ดูโพสต์ทั้งหมด

ขอบพระคุณอาจารย์ทองก้อนเป็นอย่างสูงครับ
ผมขออนุญาตอาจารย์ทองก้อนแบ่งปันให้สมาชิกทุกท่านในอีกรูปแบบหนึ่ง
นั่นก็คือการเรียกใช้คลาสใน .Net (CultureInfo Class & DateTimeFormatInfo Class)
ทุกท่านสามารถดูเพิ่มเติมได้ที่
CultureInfo Class => https://docs.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo?view=netframework-4.7.2
DateTimeFormatInfo Class => https://docs.microsoft.com/en-us/dotnet/api/system.globalization.datetimeformatinfo?view=netframework-4.7.2

ช่วยจัดการเกี่ยวกับวันที่ , สกุลเงิน ให้อยู่ในรูปแบบสอดคล้องกับการตั้งค่า Region/Language
(อธิบายให้เข้าใจง่ายขึ้นคือ เช่น ได้ค่าปี พ.ศ. มาจาก DatetimePicker = 2019
กรณีที่ผมกำหนด CultureInfo = "th-TH" ผลลัพธ์ที่ได้คือ เลข พ.ศ. = 2562

กรณีที่ผมกำหนด CultureInfo = "en-US" ผลลัพธ์ที่ได้คือ เลข ค.ศ. = 2019 เป็นต้น)

ก่อนอื่น ต้อง Import Namespace: Imports System.Globalization เข้ามาใน Project เพื่ออ้างอิงการใช้ CultureInfo Class & DateTimeFormatInfo Class


มาดูตัวอย่างโค้ดกันครับ
วิธีที่ 1 : ผมจะเขียนให้มันยืดหยุ่น เพื่อกำหนด CultureInfo และ Date_Format ได้
เวลานำไปใช้งาน เช่น
พ.ศ.
FormatMyDate(วันที่,"th-TH","MM/dd/yyyy") ผลลัทธ์ที่ได้ คือ พ.ศ. => รูปแบบวันที่ เดือน/วัน/ปี (สำหรับ MS-Access)
FormatMyDate(วันที่,"th-TH","dd/MM/yyyy") ผลลัทธ์ที่ได้ คือ พ.ศ. => รูปแบบวันที่ วัน/เดือน/ปี
FormatMyDate(วันที่,"th-TH","dd-MM-yyyy") ผลลัทธ์ที่ได้ คือ พ.ศ. => รูปแบบวันที่ วัน-เดือน-ปี
FormatMyDate(วันที่,"th-TH","yyyy-MM-dd") ผลลัทธ์ที่ได้ คือ พ.ศ. => รูปแบบวันที่ ปี-เดือน-วัน (สำหรับ SQL Server)
FormatMyDate(วันที่,"th-TH","yyyy") ผลลัทธ์ที่ได้ คือ พ.ศ. => รูปแบบวันที่ ปี (เช่น 2562)


ค.ศ.
FormatMyDate(วันที่,"en-US","MM/dd/yyyy") ผลลัทธ์ที่ได้ คือ ค.ศ. => รูปแบบวันที่ เดือน/วัน/ปี (สำหรับ MS-Access)
FormatMyDate(วันที่,"en-US","dd/MM/yyyy") ผลลัทธ์ที่ได้ คือ ค.ศ. => รูปแบบวันที่ วัน/เดือน/ปี
FormatMyDate(วันที่,"en-US","dd-MM-yyyy") ผลลัทธ์ที่ได้ คือ ค.ศ. => รูปแบบวันที่ วัน-เดือน-ปี
FormatMyDate(วันที่,"en-US","yyyy-MM-dd") ผลลัทธ์ที่ได้ คือ ค.ศ. => รูปแบบวันที่ ปี-เดือน-วัน (สำหรับ SQL Server)
FormatMyDate(วันที่,"en-US","yyyy") ผลลัทธ์ที่ได้ คือ ค.ศ. => รูปแบบวันที่ ปี (เช่น 2019)



หมายเหตุ หากต้องการใช้ร่วมกับ SQL Server ตรง Return ให้ลบ String "#" ตามที่ผมแต้มสีแดงออก
Return "#" & MyDate.ToString(Date_Format, dtfi) & "#"
  1. '// Return Date by CultureInfo Class(Ex. th-TH / en-US) and Date format(Ex. MM/dd/yyyy or dd/MM/yyyy)
  2.     Function FormatMyDate(ByVal MyDate As Date, ByVal CultureInfo_Name As String, ByVal Date_Format As String) As String

  3.         Dim dtfi As DateTimeFormatInfo = CultureInfo.GetCultureInfo(CultureInfo_Name).DateTimeFormat
  4.         Return "#" & MyDate.ToString(Date_Format, dtfi) & "#"

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


วิธีที่ 2 : หากท่านใดต้องการใช้งานฟังก์ชั่นแบบตรง ๆ ไม่ต้องการกำหนดค่าพารามิเตอร์จะเขียนแบบนี้
เช่น ต้องการรูปแบบวันที่ => เดือน/วัน/ปี (โดยปีอยู่ในรูปแบบของ ค.ศ.)
  1. '// Return Date by CultureInfo Class with condition (CultureInfo= en-US and Dateformat = MM/dd/yyyy)
  2.     Function FormatMyDate2(ByVal MyDate As Date) As String

  3.         Dim dtfi As DateTimeFormatInfo = CultureInfo.GetCultureInfo("en-US").DateTimeFormat
  4.         Return "#" & MyDate.ToString("MM/dd/yyyy", dtfi) & "#"

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


ส่วนการใช้งานคิวรี่ ผมใช้ฟังก์ชั่นในวิธีที่ 1 เขียนดังนี้
  1. strSQL = "SELECT * FROM Sample " &
  2.                      " WHERE " &
  3.                      " DateField BETWEEN " &
  4.                      FormatMyDate(dtpDateBegin.Value, "en-US", "MM/dd/yyyy") &
  5.                      " AND " &
  6.                      FormatMyDate(dtpDateEnd.Value, "en-US", "MM/dd/yyyy") &
  7.                      " ORDER BY PrimaryKey "
คัดลอกไปที่คลิปบอร์ด


สุดท้ายนี้ ผมอยากแบ่งปันในสิ่งที่ผมได้จากอาจารย์มาแบ่งปันให้กับสมาชิกหลาย ๆ ท่าน
เพื่อให้ท่านใดที่สนใจได้นำไปศึกษาต่อยอดแล้วกลับมาแบ่งปันกันต่อไปแบบไม่สิ้นสุดครับ
ไม่ว่าจะเป็นวิธีที่อาจารย์ถ่ายทอดให้ (ท่านก็ต้องรู้จักวิธีคิด ถึงจะได้ผลลัพธ์) หรือวิธีที่ผมใช้ (ท่านก็ต้องรู้จักคลาสใน .Net)
สิ่งที่เหมือนกันคือต้องเรียนรู้และเข้าใจใช้งานครับ

ท่านสามารถดาวน์โหลดตัวอย่างโปรแกรมได้ตามด้านล่างนี้




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

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

x

0

กระทู้

3

โพสต์

77

เครดิต

ผู้ดูแลพิเศษ

Rank: 8Rank: 8

เครดิต
77
โพสต์ 2019-2-5 10:14:12 | ดูโพสต์ทั้งหมด

ผมก็ชอบสั้นๆ เหมือนกันครับ
sSQL = "Select * From QueryDispenseDay Where Ddate= #" & DateTimePicker1.Value.ToString("M/dd/yyyy", New System.Globalization.CultureInfo("en-US")) & "#"

320

กระทู้

512

โพสต์

6583

เครดิต

ผู้ดูแลระบบ

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

Rank: 9Rank: 9Rank: 9

เครดิต
6583
 เจ้าของ| โพสต์ 2019-2-5 12:35:48 | ดูโพสต์ทั้งหมด

ขอบคุณทั้ง 2 ท่านที่เข้ามาให้คำแนะนำเพิ่มเติมครับ ... ผมลืมบอกกับทุกๆท่านไปว่าฟังค์ชั่นที่ผมเขียนให้ดูนั้น ผมเอามาจาก VB6 ที่ผมใช้งานประจำก่อนหน้าจะย้ายมา VB.NET ครับผม ความหมายที่ผมสื่อออกมา คือการไม่เสียเวลาไปทำการค้นหาคำสั่งที่มันมีอยู่เยอะแยะมากมายใน Dot Net เพราะกว่าที่จะหามันเจอ อาจจะใช้เวลานานมากเกินไป แต่ใช้กลวิธีในการคิดแก้ปัญหาแบบพื้นฐานแทนครับ ...

  1.     '// Adjust Date Format in MS Access.
  2.     Function FormatDateGlobal(ByVal MyDate As Date) As String
  3.         FormatDateGlobal = MyDate.ToString("MM/dd/yyyy", New System.Globalization.CultureInfo("en-US")) ' th-TH
  4.     End Function
คัดลอกไปที่คลิปบอร์ด

สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

3

กระทู้

17

โพสต์

265

เครดิต

Full Member

Rank: 3Rank: 3

เครดิต
265
โพสต์ 2019-2-6 14:26:05 | ดูโพสต์ทั้งหมด

ขอบคุณทุกความรู้นะครับ

0

กระทู้

3

โพสต์

22

เครดิต

Newbie

Rank: 1

เครดิต
22
โพสต์ 2020-4-11 20:44:10 | ดูโพสต์ทั้งหมด

ผมติดปัญหานี้นานอยู่พอสมควร ลองแก้อะไรหลายๆอย่างให้มันเข้ากับระบบงานของผม ก็ไม่สามารถทำได้สักทีจนเริ่มเซ็งแต่ก็พยายามทุกครั้งจนมาเจอวิธีขั้นตอนในทีนี้ผมลองเอามาปรับใช้จนกับระบบงานของผมจนประสบความสำเร็จ ดีใจน้ำตาไหลพราก ขอบคุณความรู้ในที่นี้ครับ

1

กระทู้

7

โพสต์

107

เครดิต

Member

Rank: 2

เครดิต
107
โพสต์ 2021-5-10 19:04:38 | ดูโพสต์ทั้งหมด

อาจารย์ครับ ถ้าต้องการให้ค้นหา และ แสดงเฉพาะ field ที่ต้องการ มีแนวทางอย่างไรบ้างครับ

320

กระทู้

512

โพสต์

6583

เครดิต

ผู้ดูแลระบบ

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

Rank: 9Rank: 9Rank: 9

เครดิต
6583
 เจ้าของ| โพสต์ 2021-5-10 23:42:45 | ดูโพสต์ทั้งหมด

ooddog ตอบกลับเมื่อ 2021-5-10 19:04
อาจารย์ครับ ถ้าต้องการให้ค้นหา และ แสดงเฉพาะ field ที่ต้องการ มีแนวทางอย่างไรบ้างครับ

ไม่ค่อยเคลียร์คำถามครับ หากเราต้องการเฉพาะฟิลด์ที่ต้องการ ก็แค่ SELECT ฟิลด์นั้นๆออกมาเลย เช่น SELECT Name FROM TableName WHERE คือเงื่อนไข ... แต่เงื่อนไขการค้นหาข้อมูลแบบ String กับ Number จะมีความแตกต่างกัน เช่น String จะเป็นแบบ WHERE Name = 'ทองก้อน' ส่วน Number ก็จะเป็น WHERE PK = 123 ... ประมาณนี้ครับ
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

2

กระทู้

6

โพสต์

74

เครดิต

Member

Rank: 2

เครดิต
74
โพสต์ 2022-3-2 18:31:05 | ดูโพสต์ทั้งหมด

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

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

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

GMT+7, 2024-11-27 22:45 , Processed in 0.378673 second(s), 4 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

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