สอบถาม วิธีหา reccord สุดท้าย
กระทู้เก่าบอร์ด อ.Yeadram

 6,501   18
URL.หัวข้อ / URL
สอบถาม วิธีหา reccord สุดท้าย

ถามอาจารย์หรือผู้ที่รู้ครับ ขอบคุณไว้ร่วงหน้าครับ

คือผมต้องการหา Reccord สุดท้ายให้โชว์ใน TextBox จะได้
Text.Value = DLast("ฟิว", "ตาราง")

แต่ถ้า Reccord สุดท้ายเป็นค่าว่าง ผมต้องการให้เอา Reccord ก่อนรองสุดท้ายของฟิว หรือ ตัวสุดท้ายที่มีข้อมูล ผมจะใส่เงื่อนไขอย่างไรครับ ขอความกรุณาด้วครับ ขอบคุณครับ

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

1 @R15211
อยากรู้คำสั่งเหมือนกันครับ แต่เบื้องต้นวิธีที่ผมคิด
ผมจะทำ Query โดยจะใส่เงื่อนไขที่ฟิลด์นี้ Not Null
มันก็น่าจะแก้ปัญหาได้ระดับนึง ก่อนที่อาจารย์จะมาตอบครับ ^^
2 @R15213
ช่วยได้เหมือนกันครับ ผมนำไปใช้อีกส่วน ขอบคุณมากครับ รออาจารย์ในส่วนของคำสั่งครับ
3 @R15214
ยังไม่ถึงระดับอาจารย์นะครับ แต่ช่วยคิดให้ เท่าที่นึกได้ตอนนี้ ประมาณนี้ครับ

Dim rs As DAO.Recordset
Dim ai As String
Set rs = CurrentDb.OpenRecordset("ชื่อตาราง")
rs.MoveLast
Do While rs("ชื่อฟิลด์") & "" = ""
    rs.MovePrevious
Loop
Text.Value = rs("ชื่อฟิลด์")

- ใช้แนวคิดคือให้ไปยังเรคคอร์ดสุดท้าย แลัวค่อยๆไล่ขึ้นที่ละเรคคอร์ดหากฟิลด์นั้นไม่มีค่า
4 @R15215
DFirst( ) และ DLast( ) ไม่ใช่เอาเรคอร์ดแรกและสุดท้ายที่ป้อนมาให้ แต่เป็นการเอาเรคอร์ดแรกและสุดท้ายตามที่ระบบมันจัดเก็บ เรคอร์ดสุดท้ายที่เพิ่งป้อนไป ไม่จำเป็นต้องเก็บไว้ท้ายสุด เพราะแล้วแต่ว่ามันจะจัดเก็บตอนนั้นยังไง เมื่อข้อมูลน้อยๆมักได้เรคอร์ดแรกสุดและท้ายสุดตามลำดับที่เราป้อน แต่เมื่อเรคอร์ดเพิ่มขึ้น อาจจะไม่เป็นอย่างนั้น ดังนั้นพูดง่ายๆก็คือ DFirst( ) และ DLast( ) จะให้เรคอร์ดที่สุ่มออกมา

วิธีตามที่คุณ Un บอกไปนั้นก็เป็นวิธีหนึ่งที่ถูกต้องแล้ว ต้องสร้างคิวรี่ที่เลือกไม่เอาค่า NULL และเรียงจากมากไปหาน้อย (ปัญหาอยู่ตรงนนี้ว่าคุณมีเก็บค่าอะไรที่เป็นตัวบ่งบอกว่าเรคอร์ดไหนป้อนก่อนหรือหลังหรือไม่ หรืออาจเพิ่มฟิลด์ที่เป็น AutoNumber ขึ้นมาก็ได้) แล้วเลือกเอาเพียงเรคอร์ดแรกเรคอร์ดเดียว

SELECT TOP 1 ฟิลด์ FROM เทเบิล WHERE ฟิลด์ Is Not Null Order by ฟิลด์ Desc;

แล้วสั่ง DFirst( ) หรือ DLast( ) จากคิวรี่นี้แทนเทเบิล แม้มันจะสุ่มแต่ยังไงมันก็มีแค่เรคอร์ดเดียวอยู่แล้ว
5 @R15216
ขอบคุณทุกๆคำตอบครับ
6 @R15218
แก้ไข
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("ชื่อตาราง")
rs.MoveLast
Do While rs("ชื่อฟิลด์") & "" = ""
    rs.MovePrevious
Loop
Text.Value = rs("ชื่อฟิลด์")
rs.Close: Set rs = Nothing
7 @R15222
MoveLast ก็เช่นเดียวกัน ไม่จำเป็นต้องได้เรคอร์ดสุดท้ายที่ป้อนนะครับ ยกเว้นจะ OpenRecordset(SQL Select statement หรือ คิวรี่ ที่กำหนด Order By ไว้แล้ว)
8 @R15226
ประเด็นนี้ดีเลยครับ ฟังก์ชั่น MS Access มีคำสั่งที่เป็น Last, Fisrt หลายตัว ตัวอย่างหากผมใช้ DoCmd.GoToRecord , , acLast ก็อาจไม่ใช่เรคคอร์ดสุดท้ายที่ป้อนข้อมูล ถ้าเป็นอย่างนั้นคงต้องคอยตรวจสอบดู ข้อมูลที่ผมใช้งานอยู่เป็นประจำอยู่ในระดับ 2-3 หมื่นเรคคอร์ด ก็ยังไม่เคยเจอลักษณะอย่างที่ อาจารย์ว่านะครับ แต่ก็เป็นประเด็นที่ทำให้ต่อจากนี้ผมต้องคอยสังเกตุดูเหมือนกัน ขอบคุณครับ งั้นแก้ไขโค๊ดลองปรับดูนะครับ จะได้ประมาณนี้

    Dim rs As DAO.Recordset
    Dim sql As String
    sql = "SELECT TOP 1 ตาราง.ฟิลด์ FROM ตาราง WHERE (ตาราง.ฟิลด์) Is Not Null ORDER BY ตาราง.ฟิลด์ID DESC;"
    Set rs = CurrentDb.OpenRecordset(sql)
    Me.Text1.Value = rs!MemoTest
    rs.Close: Set rs = Nothing
9 @R15231
ขอบคุณ อ.สันติสุขครับ ผมก็สังเกตุอยู่เหมือนกัน กับคำสัง Last ต่างๆ ว่ามัน
ไม่ได้ค่าที่ Last จริง ต่อไปต้องระวังให้มากกว่านี้ ต้องกลับไปแก้ Query อีกเยอะเลย T T
10 @R15232
อื่ม! ประเด็นนี้บอกตรงๆว่าผมก็ยังสงสัยอยู่ ไม่ใช่ไม่เชื่อ อ.สันติสุข นะครับ เพียงแต่หากเป็นยังงี้เราจะเชื่อคำสั่งเล่านี้ได้อย่างไร ปกติไม่ว่าเราจะทำ pk ในตารางหรือไม่ ระบบก็จะมีการบันทึก pk ไว้ในตารางของระบบอยู่แล้ว ฉนั้นมันจึงไม่ควรพลาด แล้วผมเองก็ยังไม่เคยพบความผิดพลาดจากคำสั่งเล่านี้เลย ผมจึงอยากขอตัวอย่าง หรือเหตุการณ์ ที่จะทำให้คำสั่งเล่านี้ผิดพลาดได้ไหมครับ จะได้เมลไปถามทาง Microsoft ดูครับ
11 @R15235
ผมว่ามันไม่ได้ทำงานอะไรผิดพลาดนะครับ มันก็เอาเรคอร์ดแรกสุดและท้ายสุดตามที่เรียงโดย Order By clause มาให้ ปัญหาคือเมื่อเราไม่กำหนด Order By clause แล้ว มันจะเรียงเรคอร์ดอย่างไร ซึ่งก็ขึ้นกับระบบจัดการฐานข้อมูล (DBMS, ของ Access คือ JET Engine) แต่คำอธิบายต่างๆไม่ได้บอกเลยว่ามันจะเรียงตามลำดับการป้อนอย่างที่คุณ arampong ต้องการ กลับบอกว่ามันจะเลือกสุ่มบ้าง ไม่กำหนดบ้าง

ลองสร้างเทเบิลให้มี1ฟิลด์เป็น PK ก็ได้ ให้เป็น Long Integer แล้วป้้อน 3 เรคอร์ดมีค่าเป็น2,3 และ 1 ตามลำดับ จากนั้นเปลี่ยนจาก 2 เป็น 4 เมื่อคุณสั่ง select first(ฟิลด์) from เทเบิล คุณจะได้ 4 ออกมา ไม่ใช่ 3   แสดงว่ามันไม่ได้เรียงตามลำดับที่ป้อนและไม่ได้เรียงตาม PK ด้วย เพราะถ้ามันจะเรียงลำดับที่ป้อนจริง มันต้องเป็น 3,1,4 หรือถ้าเรียงตาม PK จากน้อยไปมาก มันก็ต้องเป็น 1,3,4 จริงไหมครับ


คำอธิบายของคำสั่ง Application.DLast Method (Access)
http://msdn.microsoft.com/en-us/library/office/ff845086.aspx
You can use the DLast function to return a random record from a particular field in a table or query when you simply need any value from that field. .


คำอธิบายของฟังก์ชั่น First, Last (Microsoft Access SQL)
http://office.microsoft.com/en-us/access-help/first-last-functions-HP001032232.aspx
Return a field value from the first or last record in the result set returned by a query. ไม่ใช่ result set returned by entry order


คำอธิบายของ Recordset.MoveFirst Method (DAO)
http://msdn.microsoft.com/en-us/library/office/ff192329.aspx
If recordset refers to a table-type Recordset (Microsoft Access workspaces only), movement follows the current index. You can set the current index by using the Index property. If you don't set the current index, the order of returned records is undefined.
12 @R15236
แล้วคุณ Un อย่าสับสนระหว่าง First( ), Last( ) กับ Min( ), Max( ) นะครับ
13 @R15237
คืองี้ครับ แสดงว่าเข้าใจกันผิด ที่อาจารย์ยกตัวอย่างเป็นการแก้ไขเรคคอร์ด ซึ่งแน่นอนอยู่แล้วครับ คำว่า Last หรือ First หมายถึงเรคคอร์ด ไม่ได้หมายถึงการ Edit อันนี้เข้าใจดีครับ การแก้ไขไม่ว่าแก้ไขหลังสุดอย่างไร ลำดับเรคคอร์ดก็ไม่เปลี่ยนอยู่ดี จะแก้จาก 2 เป็น 4 มันก็คงเป็นเรคคอร์ดแรก เมื่อสั่ง First แน่นอน แต่ที่ผมอ่านที่อาจารย์ตอบที่แรก ผมนึกว่าเป็นการป้อนเรคคอร์ดใหม่ แล้วมันมีโอกาสที่จะไม่แสดงเป็นเรคคอร์ดสุดท้ายหากเรียกใช้คำสั่ง Last แต่หากเป็นการแก้ไขเรคคอร์ดครั้งสุดท้าย อันนี้หาไม่ได้อยู่ ผมพอเข้าใจครับ อย่างนั้นคงต้องใช้คำว่าเรคคอร์ดใหม่หรือเก่าที่ระบบบันทึกไว้มากกว่าที่จะใช้กับคำสั่ง First หรือ Last
สุดท้ายผมคงเข้าใจคนละเรื่องมั้งครับ เพราะ เจ้าของกระทู้ใช้คำว่า Reccord สุดท้าย ไม่ได้ใช้คำว่า Edit สุดท้าย
ขอบคุณข้อมูลที่แบ่งปันด้วยนะครับ
14 @R15240
ผมไม่ได้หมายถึงเฉพาะกรณีแก้ไขเรคอร์ดเก่าเท่านั้น แต่ยังรวมถึงเพิ่มเรคอร์ดใหม่เข้าไปด้วย แต่ ผมยังไม่สามารถยกตัวอย่างให้เห็นตามกรณีเพิ่มเรคอร์ดใหม่ได้ เราไม่ควรจะเชื่อว่ามันจะทำอย่างนั้นอย่างนี้ เพราะไม่มีเอกสารใดของ Access ที่ระบุไว้ว่าถ้าไม่ระบุ Order By cluase แล้ว ผลลัพธ์จะเรียงตามลำดับการป้อนก่อนหลัง แต่กลับมีการบอกไว้อย่างชัดเจนว่าได้เรคอร์ดที่สุ่มมา ดังนั้นแม้สมมุติว่าจริงๆแล้วระบบจะเรียงตามลำดับการป้อนก่อนหลังก็ตาม แต่เราก็ยังควรป้องกันโดยการกำหนด Order By clause เอาไว้นะครับ มันเป็นเครื่องการันตีว่าผลลัพธ์ที่ได้นั้นจะถูกต้องตามต้องการเสมอ
15 @R15243
ขอบคุณครับ ไว้จะลองหาข้อมูลเพิ่มดูครับ
16 @R15245
ผมบันทึกข้อมูลการให้บริการรายวันเรียงลำดับตาม SEQ(AotonumberX
มีฟิลด์ที่บันทึกเป็น Date/time เป็นวันที่ให้บริการ ซึ่งสามารถบันทึกย้อนหลังได้
สมมุติวันนี้เป็นวันที่ 21/2/2013 ผมบันทึกไปแล้ว 2 ราย แล้วก็มาบันทึกวันที่ 18/2/2013 อีก 2 ราย วันที่ 19/2/2013 อีก 1 ราย
SEQ        วันที่บันทึก     ข้อมูล
1              21/2/2013       10
2              21/2/2013       11
3              18/2/2013       12
4              18/2/2013       13
5              19/2/2013       14
จะเห็นว่าเรียงตามลำดับวันที่บันทึกจะเป็นแบบนี้
SEQ        วันที่บันทึก     ข้อมูล
3              18/2/2013       12
4              18/2/2013       13
5              19/2/2013       14
1              21/2/2013       10
2              21/2/2013       11
ซึ่งผมจะหา ข้อมูล Last ของการให้บริการ มันก็จะได้ 11
แต่ว่าข้อมูล มันอาจจะออกมา 14 ก็ได้ ซึ่งผมไม่แน่ใจมานานแล้ว
ว่ามันจะเอา Last ไหนมา

ข้อมมูลตัวอย่างประมาณนี้รึปล่าวครับ อาจารย์ทั้ง 2 ท่าน

เวลาทำ Query ผมก็จะทดสอบทุกครั้ง แต่ไม่รู้ว่า User ไปทำอะไรกับข้อมมูล
บางทีมันก็ออกมาผิด แล้วไม่รู้ว่ามันเกิดจากอะไร
17 @R15246
ตามหลักที่ผมเข้าใจ
ตัวอย่าง
- ถ้าใช้ select Last(...) หรือ DLast() หรือ rs.MoveLast จะได้เรคคอร์ดใหม่ล่าสุดที่เราเพิ่มเข้าไปเสมอ (แบบไม่ใส่เงื่อนไขใดๆในฟังก์ชั่น แต่หากใส่ก็จะได้ล่าสุดที่ตรงตามเงื่อนไขนั้น) ไม่จำเป็นต้องตามที่เราเห็น ในตัวอย่างคือ 14

- ถ้าใช้ DoCmd.GoToRecord , , acLast บนฟอร์ม จะได้เรคคอร์ดสุดท้ายที่ขึ้นอยู่กับการจัดเรียงเรคคอร์ด Ascending ไม่ว่าจากตาราง คิวรี่ ฟอร์ม คือตามที่เราเห็น ในตัวอย่างคือ 11

ซึ่งหากเป็นอย่างที่ผมว่า มันมีเหตุผล เข้าใจได้ครับ อันนี้ปรับใช้ได้ แต่ประเด็นที่น่าสนใจอยู่ตรงคำว่า สุ่ม Random ซึ่งหากเกิดขึ้นจริง อันนี้จัดการยาก ผมเลยอยากหาเหตุการณ์ที่ใช้แล้วเป็นลักษณะแบบ สุ่ม มาทดสอบหน่อยอ่ะครับ เพราะผมยังไม่เคยเจอจริงๆ และส่วนตัวผมเขียน Database ไว้เยอะพอควร และใช้คำสั่งจำพวกนี้อยู่มากเหมือนกัน จะได้รับมือถูก
ขอบคุณ คุณ Un นะครับ มีอะไรแนะนำได้เช่นกันครับ
18 @R15247
ให้ลองนึกถึงเวลาใช้งาน Access ไปสักพัก แล้ว file โต พอ compact แล้วเหลือขนาดนิดเดียว
ลักษณะนี้เกิดจาก เวลาเก็บข้อมูล Access ไม่ได้เอาข้อมูลไปวางเรียงกัน ต่อจาก record ก่อนหน้า (ตอน compact จึงจะทำการจัดเรียงข้อมูล เหมือนทำ defragment ของ windows)
เพราะฉะนั้น ก็เป็นไปได้ที่ DLast จะไปหยิบข้อมูล ที่อยู่ท้ายสุด (ซึ่งผมเข้าใจว่า ท้ายสุดตามตำแหน่งใน disk) อาจจะได้ข้อมูลที่บังเอิญจัดเรียงไม่เรียบร้อยไว้ - ซึ่งที่ใน web ที่อ้างอิงมาบอกว่า สุ่มมา (random) ออกจะเกินจริงไปหน่อยครับ
แต่โดยสรุปแล้ว DLast ก็เป็นคำสั่งที่ต้องใช้งานอย่างระวังนั่นเองครับ
จากประสบการณ์ของผม จำไม่ได้เลยว่าเคยใช้ คำสั่งนี้หรือไม่ (คิดว่าไม่นะ)
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2175s