อยากทราบ calendar type ของ system
กระทู้เก่าบอร์ด อ.Yeadram

 9,152   12
URL.หัวข้อ / URL
อยากทราบ calendar type ของ system

ถามผู้รู้ผู้ตื่นผู้เบิกบานทั้งหลาย ทุกๆ ท่านครับ
ที่มาของคำถาม :
- ผมเขียนโปรแกรมต้องการนำเลขปีมาใช้ในการทำงาน    format(......,"yy") แต่ว่าเครื่องของ user แต่ละคนที่จะนำโปรแกรมนี้ไปใช้ อาจจะ ตั้งค่า system Date ไม่เหมือนกัน ทำให้บางเครื่องได้คำตอบออกมาเป็น ปี ค.ศ. บางเครื่องได้คำตอบออกมาเป็น พ.ศ. เมื่อเรานำข้อมูลเหล่านี้ไปเก็บในตาราง จะมีปัญหาการเรียงลำดับ เช่น
user อีกคน บันทึก (มาจากอีกเครื่องหนึ่ง) เลขก่อนหน้านี้เป็น INV5201002 (ความหมายคือ ใบเสร็จเลขที่ 2 ของเดือน 1 ของปีนี้)
แล้วผมบันทึก (จากอีกเครื่องหนึ่ง) เลขที่ INV0901003 (ความหมายคือ ใบเสร็จเลขที่3 ของเดือน 1 ของปีนี้)

เมื่อมีการนำเลขที่นี้ไปไว้ในตารางเดียวกัน มันจึงเกิดปัญหาในการเรียงลำดับ
INV0901001
INV0901003
INV5201002
เห็นมั้ยครับ เลขที่ 3 มันไปอยู่ก่อนเลขที่ 2 เพราะว่า เลขปี เป็นสาเหตุ


** notice :
   การตั้งค่า system date ใน regional settings โปรดสังเกต Calendar Type
ถ้าตั้งค่าใช้งาน เป็น en-us calendar type จะเป็นได้อย่างเดียวคือ ค.ศ.
ถ้าตั้งค่าใช้งาน เป็น thai calendar type จะสามารถตั้งได้สองอย่างคือ ค.ศ. หรือ พ.ศ. ก็ได้
เครื่องผม เครื่อง user ในบริษัทผมทุกๆ เครื่อง จะตั้ง(โดยผมเอง) เป็น thai แต่ใช้ calendar type เป็น ค.ศ.
จะเห็นได้ว่ามันสามารถเลือกตั้งค่าได้หลายรูปแบบ


ผมต้องการเก็บให้เป็น รูปแบบเดียวกันทั้งหมด คือให้เก็บเป็น ค.ศ. ไม่ว่าเครื่องนั้นๆ จะถูกตั้งค่า system date เป็นปีแบบใดก็ตาม โดย :

-ถ้าผมรู้ว่ามันเป็น พ.ศ. ผมจะเอา ปี ลบด้วย 543 ก่อนจะเอาไปทำกับฟังก์ชั่นอื่นๆ ต่อไป
-ถ้าผมรู้ว่ามันเป็น ค.ศ. ผมจะเอาปี ไปทำงานกับฟังก์ชั่นเลย ไม่ต้องบวกลบอะไรอีก


[SIZE=3]ทีนี้คำถามครับ ผมจะรู้ได้ยังไง ว่าเครื่องนั้นๆ ตั้งค่า calendar type ใน regional settings เป็นแบบไหน[/SIZE]

12 Reply in this Topic. Dispaly 1 pages and you are on page number 1

1 @R01472
GetLocaleInfo: Regional Locale Date Settings

ค่าที่คืนจาก GetUserLocaleInfo(LCID, LOCALE_ICALENDARTYPE) เป็น 1=ค.ศ. เป็น 7=พ.ศ. ครับ
2 @R01478
ผมหาใน google ตั้งนาน ตั้งหลายที่ หลายคีย์เวิร์ด
เพื่อจะหาตัวนี้แหละครับ
Public Const LOCALE_ICALENDARTYPE        As Long = &H1009 'type of calendar specifier


มันคือ &H1009 นี่เองที่ผมต้องการ ขอบคุณครับอาจารย์
(ปล. หาเจอได้ยังไงครับ สำคัญจริงๆ นะค่านี้ อิอิ &H1009 ประเด็นมันเลยล่ะ
หลายๆ เพจมักจะบอกแต่เลขอื่นๆ ไม่บอก 1009 ซักทีเลย จนต้องมาโพสต์ถามนี่แหละครับ)
3 @R01480
แล้วทำอย่างไรต่อละครับ
ผมก็ติดปัญหาวันที่ของเครื่องที่มันต่างกันเหมือนกัน
4 @R01482
เอานี้ไปวางไว้ในโมดูลครับ

Option Explicit

Public Declare Function GetSystemDefaultLCID Lib "kernel32" () As Long
Public Declare Function GetLocaleInfo Lib "kernel32" _
   Alias "GetLocaleInfoA" _
(ByVal Locale As Long, _
   ByVal LCType As Long, _
   ByVal lpLCData As String, _
   ByVal cchData As Long) As Long

Public Function GetUserLocaleInfo(ByVal dwLocaleID As Long, ByVal dwLCType As Long) As String
   Dim sReturn As String
   Dim r As Long
   r = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, Len(sReturn))
   If r Then
      sReturn = Space$(r)
      r = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, Len(sReturn))
      If r Then GetUserLocaleInfo = Left$(sReturn, r - 1)
   End If
End Function

Public Function mYear(ByVal yourDate As Date) As Long
    mYear = Year(yourDate)
    If GetUserLocaleInfo(GetSystemDefaultLCID(), &H1009) = 7 Then mYear = Year(yourDate) - 543
End Function


ผมต้องการให้โปรแกรมของผม เก็บปีเป็น ค.ศ. ในทุกๆ ที่
เมื่อผมต้องการหาค่าปี ของฟิลด์ใดๆ หรือจากตัวแปรใดๆ (ชนิด Date/Time) แทนที่ผมจะเรียกใช้ฟังก์ชั่นของระบบ คือ Year()
ผมก็จะเรียกใช้ฟังก์ชั่นที่เขียนขึ้นเองแทน คือ mYear()
5 @R01913
แล้วถ้ากลับกันละคะอาจารย์ คือต้องการให้เก็บปีเป็น พ.ศ. ในทุกๆที่ ต้องแก้ฟังชั่นนี้ตรงไหนอย่างไรคะ
6 @R01914
เอาฟังก์ชั่นนี้ไปวางต่อท้ายในโมดูลเดียวกันเลยครับ
เมื่อต้องการหา ค.ศ. ให้ใช้ mYear()
เมื่อต้องการหา พ.ศ. ให้ใช้ bYear()
Public Function bYear(ByVal yourDate As Date) As Long
bYear = Year(yourDate)
If GetUserLocaleInfo(GetSystemDefaultLCID(), &H1009) <>7 Then bYear = Year(yourDate) + 543
End Function


แต่ขอแนะนำเพิ่มครับ
เราไม่ควรเก็บข้อมูลเป็น ปี พ.ศ. ในตาราง เพราะมันจะมีปัญหาจุกจิก หากอนาคตเราจะนำข้อมูลนี้ไปใช้ในโปรแกรมอื่นๆ ฐานข้อมูลอื่นๆ หรือเครื่องอื่นๆ เพราะทุกๆ ชนิดฐานข้อมูล ทุกๆ ภาษาของการเขียนโปรแกรม แม้จะถูกพัตนามาจากคนละเชื้อชาติคนละสัญชาติแต่เมื่อพัฒนาได้สมบูรณ์แล้วเขาจะปรับปรุงให้ คำ, สัญลักษณ์ เป็นสากลเป็นหลัก

ฟังก์ชั่นนี้แนะนำว่าให้ใช้เฉพาะเวลาแสดงผลเท่านั้น เช่นการแสดงผลผ่านฟอร์ม, รายงาน, คิวรี่
7 @R01915
สามารถนำไปขยายผลต่อได้อีกมากมายเลยค่ะอาจารย์ ขอบคุณมากๆนะคะ
8 @R04359
ช่วยอธิบายเพิ่มแบบละเอียดหน่อยครับ
เครื่องผม MS Acess เวอร์ชั่นภาษาไทย และ Regional Setting เป็น พ.ศ. แต่ต้องการให้ Access บันทึกเป็น ค.ศ.
ผมสร้าง Module และ Copy Code ของอาจารย์ yeadram ไปวาง แล้ว Save ชื่อ Module ว่า mYear และเขียนคำสั่งตามด้านล่าง แต่โปรแกรมฟ้อง error อาจเป็นเพราะผมเรียกใช้ไม่เป็น
ขอท่านผู้รู้ทั้งหลายช่วยอธิบายเพิ่มแบบละเอียดละเอียดหน่อยครับ

Private Sub StartCalendar_Click()
    yourDate = StartCalendar.Value
    call mYear (yourDate)
    DoCmd.GoToControl "yourDate"
    StartPMCalendar.Visible = False
End Sub

แล้วหากต้องการค่า yourDate คืนมาให้แสดงใน Textbox ชื่อ "yourDate" ต้องทำอย่างไร

ลำดับการทำงาน และสิ่งที่ต้องการ
1. คลิกที่ปุ่ม Calendar จะปรากฎปฏิทินชื่อ "StartCalendar"
2. คลิกเลือกวันที่ใน "StartCalendar" จะได้วันที่เป็น พ.ศ. เช่น 13/12/2552
(แต่ในปฏิทินจะแสดงวันที่ 13/12/2009 แต่ใน Textbox จะแสดง 13/12/2009 จึงต้องหาวิธีแก้จาก พ.ศ. ให้เป็น ค.ศ.)
3. เรียก Function "call mYear (yourDate) " เพื่อตรวจสอบวันที่ว่าปีเป็น ค.ศ. หรือไม่ หากไม่ให้เปลี่ยนจาก พ.ศ. เป็น ค.ศ.
4. ให้แสดงค่า Textbox ชื่อ "yourDate" ต้องได้ว่า 13/12/2009
5. ให้ซ่อนปฏิทินชื่อ "StartCalendar"

ขอขอบพระคุณทุกท่านเป็นอย่างสูงครับ


9 @R04360
ฟังก์ชั่นนี้มันคืนค่าผลลัพธ์ออกมาด้วยครับ
เรียกใช้แบบ call mYear (yourDate) มันไม่มีผลใดๆ ครับ เพราะไม่มีอะไรไปรับค่าของมัน

คุณต้องหาอะไรไปรับค่าของมันเช่น
dim xx
xx=mYear(yourdate)
แบบนี้ มันถึงจะเห็นผล คือ ให้มันคืนค่าผลลัพธ์ออกมาใส่ในตัวแปร


หรืออย่างกรณีของคุณ
Private Sub StartCalendar_Click()
               ' ฟังก์ชั่นนี้คืนมาเฉพาะเลขปีเท่านั้น ดังนั้นต้องหา วันที่ กับเดือนรอ ไว้ก่อน
dim ss as string
ss = format(StartCalendar,"dd/mm/")
                 ' แล้วไปเอาเลขปี มาต่อท้าย
                 ' ซึ่งเลขปี ก็คือ "ผลลัพธ์" ที่คืนมาจากฟังก์ชั่น
ss = ss & mYear(StartCalendar)
                 ' แล้วค่อยเอาค่าจากตัวแปร กรอกลง textbox
    Me.yourDate = ss
    StartCalendar.Visible = False
End Sub

10 @R05143
จากการเขียน code ดังกล่าวนั้นผมนำไปเปลี่ยนแล้วไม่ได้
ไม่ทราบว่าต้องวาง code ดังกล่าวไว้ที่ไหน จาก code ของผม
เพราะว่าส่วนของ พ.ศ.นั้น ใน calendar เป็น พ.ศ. แต่เมื่อ click แล้วใน text box เป็น พ.ศ. ความต้องการผม ให calendar แสดงเป็น พ.ศ. ไม่ใช่ ค.ศ. ครับ

ส่วนนี้เป็น text box ให้ click เพื่อเรียก calendar
Private Sub tBirthDate_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    ocxCalendar.Visible = True
    ' Note which combo box called the calendar
    Set cboOriginator = tBirthDate
' Unhide the calendar and give it the focus
    ocxCalendar.Visible = True
    ocxCalendar.SetFocus
' Match calendar date to existing date if present or today's date
    If Not IsNull(cboOriginator) Then
        ocxCalendar.Value = cboOriginator.Value
    Else
        ocxCalendar.Value = Date
    End If
End Sub

Private Sub ocxCalendar_Click()

' Copy chosen date from calendar to originating combo box
    tBirthDate.Value = ocxCalendar.Value
' Return the focus to the combo box and hide the calendar and
    tBirthDate.SetFocus
    ocxCalendar.Visible = False
' Empty the variable
    Set cboOriginator = Nothing
    
Dim DayCount As Single
Dim MonthCount As Single
Dim YearCount As Single
    YearCount = Year(tDate) - Year(tBirthDate)
    MonthCount = Month(tDate) - Month(tBirthDate)
    DayCount = Day(tDate) - Day(tBirthDate)
    If tDate < tBirthDate Then
        MsgBox "tDate is less than tBirthDate", vbOKOnly
        Exit Sub
    End If
     If MonthCount < 0 Then
        YearCount = YearCount - 1
        MonthCount = 12 - Month(tBirthDate) + Month(tDate)
    End If
    If DayCount < 0 Then
        If MonthCount > 0 Then
            MonthCount = MonthCount - 1
        Else
            YearCount = YearCount - 1
            MonthRange = 11
            End If
        DayRange = 31 - Day(tBirthDate) + Day(tDate)
        Select Case Month(tBirthDate)
            Case 4, 6, 9, 11
               DayCount = DayCount - 1
            Case 2
               DayCount = DayCount - 3
            End Select
    End If
    tAge = "ÍÒÂØ" & " " & YearCount & " " & "»Õ" & " " & MonthCount & " " & "à´×͹" & " " & DayCount & " " & "Çѹ"

End Sub

รบกวนตอบผ่าน panyapol@tttmaxnet.com นะครับ
11 @R05152
จากการเขียน code ดังกล่าวนั้นผมนำไปเปลี่ยนแล้วไม่ได้
-- ไม่ได้อย่างไร ไม่เข้าใจ มี error หรือเปล่า มีว่าอย่างไร นำไปเปลี่ยนอย่างไร

ไม่ทราบว่าต้องวาง code ดังกล่าวไว้ที่ไหน จาก code ของผม
-- โค้ดที่ให้ไปในกระทู้นี้ ทั้งหมด เอาไปวางในโมดูลที่สร้างขึ้นใหม่ ตั้งชื่อโมดูลตามหลักการตั้งชื่อ (ห้ามตั้งชื่อซ้ำกับ object อื่นๆ, ห้ามใช้คำสงวน, ห้ามตั้งชื่อโมดูล เหมือนชื่อฟังก์ชั่นใดๆ ในโมดูล เพราะฟังก์ชั่นใดๆ ในโมดูล ก็ถือเป็น object เช่นเดียวกัน)


เพราะว่าส่วนของ พ.ศ.นั้น ใน calendar เป็น พ.ศ. แต่เมื่อ click แล้วใน text box เป็น พ.ศ. ความต้องการผม ให calendar แสดงเป็น พ.ศ. ไม่ใช่ ค.ศ. ครับ
-- อันนี้ยิ่งอ่านยิ่งงง


เอาเป็นว่า ถ้าคุณวางโค้ดในโมดูลเรียบร้อยแล้วมาดูกันตรงนี้
Private Sub ocxCalendar_Click()

' Copy chosen date from calendar to originating combo box
    tBirthDate.Value = ocxCalendar.Value

ตรงส่วนที่เน้นหนาแดง เดาว่าคงเป็นคำสั่งเติมค่าวันที่ลงใน textbox
หากคุณต้องการเปลี่ยนให้เป็น พ.ศ. เปลี่ยนดังนี้
tBirthDate = Dateserial(bYear(ocxCalendar),month(ocxCalendar),Day(ocxCalendar))

หากคุณต้องการเปลี่ยนให้เป็น ค.ศ. เปลี่ยนดังนี้
tBirthDate = Dateserial(mYear(ocxCalendar),month(ocxCalendar),Day(ocxCalendar))
12 @R06143
ต้องการทำ เล่มที่ เลขที่ในโปรแกรม access ไม่ทราบว่าทำยังไงครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.3418s