รันเลขที่อัตโนมัติครับ
กระทู้เก่าบอร์ด อ.Yeadram

 10,632   20
URL.หัวข้อ / URL
รันเลขที่อัตโนมัติครับ

คือว่าต้องการให้เลขที่ใบเบิกมันรันอัตโนมัติอะครับ พอดีผมค้นหาดูแล้วมันงงๆ อะครับ
ผมต้องการให้เลขที่มันเป็นแบบนี้ครับ คือปีคศ./เลขที่ เช่น 2009/1 , 2009/2,...
แล้วผมต้องการให้มันรันอัตโนมัติ ไปเรื่อยๆครับ แต่ถ้าเปลี่ยนปีคศ.ก็ต้องรันเลขที่ตั้งแต่ 1 ใหม่ (2010/1)ครับ
เลขที่ใบเบิกนี้ผมเก็บไว้ที่ตาราง inv_namestock ฟิลด์ที่เก็บชื่อ documentsno ครับผม

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

1 @R02863
ปีที่จะนำมารัน ดูจากไหนครับ
ปีของ วันที่ปัจจุบัน
หรือว่า ปีของ วันที่เอกสาร
ถ้าเป็นปี ของวันที่เอกสาร ต้องขอ แหล่งข้อมูลด้วยครับ ว่า วันที่ดังกล่าว อยู่ที่ตารางไหน ชื่อฟิลด์อะไร หรือจาก textbox ตัวไหน
2 @R02864
ปีเอามาจากปีปัจจุบันครับ เช่นปีนี้ 2009 ครับ
ต้องการให้เปลี่ยนแค่เลขที่หลังเครื่องหมาย / ครับ
3 @R02865
function AutoNo() as string
dim x as variant
dim bk as string
        x=dmax("mid(documentsno,6)","inv_namestock","left(documentsno,4) = " & year(now()))
        if isnull(x) then bk=1 else bk=x+1
    AutoNo = year(now()) & "/" & bk
End Function
4 @R02866
นี่คือสิ่งที่ผมเขียน
Private Sub cmdnewid_Click()
Me.documentsno = AutoNo
End Sub

Function AutoNo() As String
Dim x As Variant
Dim bk As String
        x = DMax("mid(documentsno,6)", "inv_NameStockRemove", "left(documentsno,4) = " & Year(Now()))
        If IsNull(x) Then bk = 1 Else bk = x + 1
    AutoNo = Year(Now()) & "/" & bk
End Function

ก็คือถ้าคลิกปุ่ม cmdnewid ให้ไปทำงานที่ autono
แต่ว่ามันติดปัญหาตรงที่ว่ามันไม่ยอมนับจากฐานข้อมูลครับ
ไม่รู้ว่ามันนับจากไหนครับ
5 @R02867
debug ดูว่า ค่าของ x มันได้อะไรมา
มันไปหาดูที่ตารางไหน
inv_namestock หรือ inv_NameStockRemove


ถ้ายังไม่รู้ ลองถอด เงื่อนไขของ Dmax ออกก่อน ดูว่ามันได้ข้อมูลล่าสุดของตารางนั้นมาหรือเปล่า
x = DMax("mid(documentsno,6)", "ชื่อตาราง")

ถ้ายังได้ค่า null ลองถอด ฟังก์ชั่น mid() ออกอีกที
x = DMax("documentsno", "ชื่อตาราง")

ถ้าได้ค่าสุดท้ายแล้ว ลองปรับเปลี่ยน ใส่เงื่อนไขเข้าใน Dmax โดยยังไม่ต้องใส่ฟังก์ชั่น mid()
x = DMax("documentsno", "ชื่อตาราง", "left(documentsno,4) = " & Year(Now()))

หรือลองดูว่า ค่าของ year() ในเครื่องนั้นๆ เป็น ค.ศ. หรือ พ.ศ. เพื่อจะได้เปรียบเทียบกับเรคคอร์ดในตารางว่า รูปแบบเหมือนกันหรือเปล่า
debug.print year(now())
6 @R02871
ขอบคุณมากเลยครับ ผมแก้ได้แล้วครับ
แต่ผมมีเรื่องถามอีกอย่างนึงครับ คือว่าผมสร้างฟอร์มข้อมูลพนักงานทั้งหมดเป็นแบบ Datasheet ครับ
พอดับเบิ้ลคลิกที่รหัสพนักงานก็ให้ไปโชว์หน้าฟอร์มที่มี textbox ลองรับสำหรับให้แก้ข้อมูลครับ
ทีนี้ผมก็เขียนโค๊ดโดยเก็บข้อมูลรหัสตอน login มาเปรียบเทียบกับฟอร์มที่ 2 ถ้ารหัสตอน login ตรงกับข้อมูลรหัสพนักงานในหน้าฟอร์มที่2 ก็ให้แก้ได้
แต่ถ้าไม่ตรงจะไม่สามารถแก้ได้ครับ
ทีนี้มันมีปัญหาตรงที่ว่าถ้าดับเบิ้ลคลิกจากหน้าที่ 1 ไป หน้าที่ 2 มันแก้ได้หมดเลยครับ ไม่ว่าจะใช่รหัสของตัวเองหรือเปล่า แต่ว่าถ้าผม กดเปลี่ยนหน้าฟอร์มที่ 2 เป็น Design ก่อน แล้วค่อยมาเลือกเป็น Form View มันก็จะตรวจสอบโค๊ดให้ครับว่าตรงหรือไม่ตรง ผมไม่แน่ใจว่าเป็นเพราะอะไร โดยโค๊ดที่ผมเขียนผมใส่ไว้ในฟอร์มที่ 2 ที่ Form_Load และผมลองไว้ที่ Form_Open ก็ไม่ได้เหมือนกันครับ เพราะอะไรหรอครับ


ปล.ฟอร์มที่1 คือ หน้าข้อมูลพนักงานทั้งหมด (Datasheet)
     ฟอร์มที่ 2 คือ หน้าที่มี textbox สำหรับแก้ไขข้อมูลที่เลือกมาจากหน้าที่ 1
7 @R03206
test
8 @R03250
if me.id = strSessionLogin then
DoCmd.OpenForm "ฟอร์ม ที่2", acNormal, , , acFormEdit
else
DoCmd.OpenForm "ฟอร์ม ที่2", acNormal, , , acFormReadOnly
end if
9 @R03581
Private Sub cmdnewid_Click()
Me.documentsno = AutoNo
End Sub

Function AutoNo() As String
Dim x As Variant
Dim bk As String
        x = DMax("mid(documentsno,6)", "inv_NameStockRemove", "left(documentsno,4) = " & Year(Now()))
        If IsNull(x) Then bk = 1 Else bk = x + 1
    AutoNo = Year(Now()) & "/" & bk
End Function


คือตอนนี้มันมีปัญหาเพิ่มอะครับ
พอมันรันถึง 2009/10 มันจะไม่ยอกเพิ่มเป็น 2009/11 ครับ
พอผมกดบันทึก แล้วรันเลขใหม่ ก็ยังเป็น 2009/10 มันเป็นเพราะอะไรหรอครับ
รบกวนท่าน yeadram หน่อยนะครับ
10 @R03585
-ตรวจสอบดูให้แน่ใจว่า ฟิลด์ documentsno เก็บข้อมูลเป็นชนิด Text
-ตรวจสอบดูค่าของ documentsno ในตาราง ว่ามันเก็บ เลข 0 ที่ต่อท้ายหรือเปล่า

-debug ดูค่าของ x หลังจากใช้ฟังก์ชั่น Dmax แล้ว
x = DMax("mid(documentsno,6)", "inv_NameStockRemove", "left(documentsno,4) = " & Year(Now()))
debug.print x

-debug ดูค่าของ bk หลังจบเงื่อนไข if
If IsNull(x) Then bk = 1 Else bk = x + 1
debug.print bk

-ลองเปิดตาราง inv_NameStockRemove แล้วสั่งเรียงลำดับตามค่าของ Documentsno จากมากไปหาน้อย ดูว่า
เลข   2009/10 กับ 2009/2 อะไรมาก่อนกัน

คุณรู้ไหมว่า คำว่า leading zero มันหมายถึงอะไร และมันมีประโยชน์อย่างไร

11 @R03717
---ตรวจสอบดูให้แน่ใจว่า ฟิลด์ documentsno เก็บข้อมูลเป็นชนิด Text ?
เป็น Text ครับ...

---ตรวจสอบดูค่าของ documentsno ในตาราง ว่ามันเก็บ เลข 0 ที่ต่อท้ายหรือเปล่า ?
เก็บครับ...

---ลองเปิดตาราง inv_NameStockRemove แล้วสั่งเรียงลำดับตามค่าของ Documentsno จากมากไปหาน้อย ดูว่า
เลข   2009/10 กับ 2009/2 อะไรมาก่อนกัน ?
2009/10 มาก่อนครับ...

---คุณรู้ไหมว่า คำว่า leading zero มันหมายถึงอะไร และมันมีประโยชน์อย่างไร ?
ไม่ทราบครับ....

เอ่อผมลองใส่โค๊ตตามที่คุณ yeadram บอกแล้วครับ ไม่เห็นมันโชว์ตรงไหนเลยครับ คือผมไม่เคยใช้ debug เลยครับผม
12 @R03719
debug เป็นสิ่งจำเป็นในการเขียนโปรแกรมครับ ลองหัดใช้ดู ไม่ยาก เหมือนขับรถก็ต้องเปิดฝากระโปรงให้เป็น
13 @R03720
เอ่อ....
แล้วการที่เราจะใช้ debug ได้นี่เราต้องดูตรงไหนบ้างหรอครับ
ผมเขียนตามที่คุณ yeadram บอกแล้วครับ ไม่เห็นมีอะไรแสดงเลยครับ
14 @R03721
กด ctl+G
จะเห็นสิ่ง ที่ debug ออกมา ให้เราตรวจสอบค่าของมัน แล้ววิเคราะห์หาปัญหาต่อไป เช่น
ถ้ามันแสดงออก มาเป็น ก จงวิเคราะห์ต่อไปว่า ทำไมถึงเป็น ก
ตอนเราเขียนโค้ด เราคิดว่า ตัวแปรของเราต้องได้เลข 3หลัก แต่ผลไม่เป็นเช่นนั้น เราก็ต้อง debug ดู ว่ามันได้เลข สามหลักจริงหรือเปล่า ถ้ามันได้เลข สามหลัก ถูกต้อง เราก็ต้องไปสันนิษฐานหาสาเหตุอื่น แต่ถ้ามันไม่ได้เลข สามหลัก เราก็ต้องย้อนดูโค้ดของเราในบรรทัดก่อนหน้าดูอีกที ว่าทำไมมันถึงคืนค่ามาผิดๆ
ทั้งหมดนั่นคือ วิธีใช้ประโยชน์จากการ debug ครับ เป็นคนที่จะเขียนโปรแกรม หรือจะเป็นโปรแกรมเมอร์ ต้องรู้จักใช้ตรงนี้ให้เป็นประโยชน์ครับ เพราะคนที่ผลิต vb vba หรือภาษาอะไรก็ตาม เขาทำส่วนนี้ไว้ให้เราใช้ครับ user ไม่ได้ใช้ด้วยแน่ๆ ครับ
15 @R03723
---debug ดูค่าของ x หลังจากใช้ฟังก์ชั่น Dmax แล้ว
ได้ 9 ครับ...

---debug ดูค่าของ bk หลังจบเงื่อนไข if
ได้ 10 ครับ...

---ตรวจสอบดูให้แน่ใจว่า ฟิลด์ documentsno เก็บข้อมูลเป็นชนิด Text ?
เป็น Text ครับ...

---ตรวจสอบดูค่าของ documentsno ในตาราง ว่ามันเก็บ เลข 0 ที่ต่อท้ายหรือเปล่า ?
เก็บครับ...

---ลองเปิดตาราง inv_NameStockRemove แล้วสั่งเรียงลำดับตามค่าของ Documentsno จากมากไปหาน้อย ดูว่า
เลข   2009/10 กับ 2009/2 อะไรมาก่อนกัน ?
2009/10 มาก่อนครับ...

---คุณรู้ไหมว่า คำว่า leading zero มันหมายถึงอะไร และมันมีประโยชน์อย่างไร ?
ไม่ทราบครับ....
16 @R03739
เรียงจากมากไปหาน้อย เลข 10 มาก่อน เลข 2
แล้วทำไม เวลา dmax มันถึงไม่เจอเลข 10
ทำไมมันถึงไปเจอแต่เลข 9

แน่ใจหรือครับว่าเรียงจากมาก ไปหาน้อย
ถ้าแน่ใจ งั้นต้องคิดใหม่ ลองเรียงจาก น้อยไปหามาก ดูว่า 2009/10 กับ 2009/2 มันเรียงลำดับกันถูกต้องหรือไม่

อืมม ไล่ไปไล่มา มันก็ยากสำหรับการแก้ไขนะ ข้อมูลคุณมีของเก่าเยอะแล้วหรือเปล่า จะลำบากไหม ถ้าจะเปลี่ยนไปใช้ระบบ leading zero

จากปกติ เลขที่ของคุณเป็น
2009/1
2009/2
2009/10
2009/11
ให้เปลี่ยนเป็น leading zero
2009/001
2009/002
2009/003
2009/010
2009/011
เพราะฟิลด์เลขที่ของคุณมันเป็น text การเรียงลำดับมันใช้ อัลกอริธฺม คนละแบบกับการเรียง number

* การเรียงแบบ number
- ไม่สนใจเลข 0 ข้างหน้า
- สนใจเลข 0 ที่อยู่ข้างหลัง ค่าของตัวเลขทั้งชุดคือค่าเดียว เมื่อนำไปเปรียบเทียบกับข้อมูลชุดอื่น
** การเรียงแบบ text
จะวัดกันแบบตัวต่อตัว ถ้ามีข้อมูลสองชุด จะทำการเปรียบเทียบอักขระตัวที่ 1 ของทั้งสองชุด ว่าตัวไหนมากกว่าหรือน้อยกว่ากัน ถ้าปรากฎว่าเท่ากัน จะไปทำการเปรียบเทียบตำแหน่งที่ 2 ต่อไป แต่.........
ถ้า ณ ตำแหน่งที่ 1 หรือตำแหน่งที่เปรียบเทียบในรอบปัจจุบันมีการเหลื่อมล้ำไม่เท่ากัน ก็จะคืนค่าทันที พร้อมกับหยุดทำงานการเปรียบเทียบ
เพราะฉะนั้น
2009/10
2009/2
ถ้าเรียงแบบ text (จากน้อยมาหามาก) เลข 10 จะมาก่อน เลข 2
เพราะมันได้คำตอบตั้งแต่ตำแหน่งที่ 6 แล้วมันก็จะหยุดทำงาน เลข 0 ที่อยู่หลังของเลฃ 10 ก็จะไม่ถูกนำมาประมวลผลแต่อย่างใด

เพื่อแก้ปัญหาดังกล่าว จึงได้มีการคิดระบบ Leading Zero ขึ้นมา มันสำหรับแก้ปัญหาเรียง ลำดับ text ที่เขียนด้วยอักขระตัวเลข หรือบ้างก็เรียกว่า "ตัวเลขในสายอักขระ"
(ตัวเลขที่ไม่นำมาประมวลผลทางคณิตศาสตร์ เช่น บ้านเลขที่, เบอร์โทรศัพท์ ฯลฯ)

หากคุณเข้าใจระบบ leading zero และคิดจะนำมาปรับใช้กับ project ของคุณ ก็ให้คุณไปแก้ข้อมูลเก่าที่เคยบันทึกไปแล้ว ให้เป็น leading zero ให้หมดก่อน (อาจจะด้วยวิธีแม่นวล หรือใช้ คิวรี่ แอคชั่น (update query) ช่วยก็สุดแล้วแต่ถนัด)

แล้วค่อยมาปรับแก้ไขโค้ด AutoNo ของคุณให้เป็นดังนี้
Function AutoNo() As String
Dim x As Variant
Dim bk As String
        x = DMax("Right(documentsno,3)", "inv_NameStockRemove", "left(documentsno,4) = " & Year(Now()))
        If IsNull(x) or cint(x) = 0 Then bk = 1 Else bk = x + 1
    AutoNo = Year(Now()) & "/" & format(bk,"000")
End Function

** บริเวณที่ผม มาร์คสีแดง ต้องสัมพันธ์กัน
- จำนวนเลข 0 ต้องเท่ากับตัวเลข ข้างบน
- มันคือตำแหน่งที่คุณต้องการจะจัดเรียง อาจจะ 2 หรือ 3 หรือ 4 ตำแหน่งหรือมากกว่านั้นก็ได้ตามใจชอบ แต่ต้องสัมพันธ์กัน ทั้งสามจุด คือ
1 ในคำสั่ง Dmax
2 ในคำสั่ง Format
3 รูปแบบของข้อมูลเก่าในตาราง
17 @R03740
คือมีปัญหาเกิดครับ
1. ถ้าในฐานข้อมูลเป็นค่าว่างเวลา AutoNo() ทำงานจะเกิด error ว่า Invalid use of Null
แต่้ถ้าในฐานข้อมูลมีข้อมูลอยู่แล้วก็จะไม่เป็นไรครับ
2. ถ้าเกิดเปลี่ยนปีก็จะ error ว่า Invalid use of Null เช่นเดียวกันครับ แล้วทีนี้ผมควรจะแก้ไขอย่างไรดีครับ โดยที่ปีเปลี่ยนแต่เลขที่ข้างหลังก็ต้องรันต่อจากปีก่อนครับ รวบกวนคุณ yeadram ด้วยนะครับ
18 @R03742
อ้าว ขึ้นปีใหม่ ไม่รันเลขใหม่เหรอครับ
ต้องรันเลขใหม่ซิครับ แบบนี้ถ้าโปรแกรมของคุณทำ leading zero ไว้สามหลัก พอมันรันรวมกันทั้งสองปี สามปี มันก็เกิน 1000 เลขที่ แล้วโปรแกรมคุณก็จะ error อีกซิครับ ไหนๆ มันก็มีเลขปี กำกับอยู่แล้ว ยังไงมันก็ไม่ซ้ำ
ถ้าจะรันต่อเนื่องข้ามปี แล้วจะเอาเลขปีมาใส่ให้มันยุ่งยากอีกทำไม ล่ะครับ

แต่ก็เอาเหอะ ไหนๆ ก็จะทำ ต่อไป ไม่ต้องยุ่งกับเลขปีอีกเลย สังเกตโค้ด Dmax ที่จะไม่ยุ่งกับเลขปี อย่าเอามันเข้าไปยุ่งอีก เพราะมันไม่ได้ใช้ประโยชน์อะไรเลย และแนะนำให้ทำ leading zero สัก 9 หลักนะครับ

Function AutoNo() As String
Dim x As Variant
Dim bk As String
        x = DMax("Right(documentsno,9)", "inv_NameStockRemove")
        If IsNull(x) then bk = 1 Else bk = x + 1
    AutoNo = Year(Now()) & "/" & format(bk,"000000000")
End Function
19 @R03748
ขอบคุณครับ
20 @R21772
ตามที่คุณ yeadram บอกผมไปทำตามแล้ว แต่ทำไม เวลาเราบักทึกเข้าไปมากๆ แล้วทำไมมันถึงลบลายการของเราไปทีละลายการครับ งงมาก
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.3550s