+ - เวลาระหว่างแถว
กระทู้เก่าบอร์ด อ.Yeadram

 1,777   10
URL.หัวข้อ / URL
+ - เวลาระหว่างแถว

อยากให้ข้อมูล ลบกันระหว่างแถวอ่ะค่ะ
ตัวอย่าง

ลำดับที่     เวลา       ค่าที่ได้
     1     7:00     0:20
     2     7:20     0:50
     3     8:10     0:10
     4     8:20     1:00
     5     9:20     0:10
     6     9:30     0:30
     7       10:00     0:30

ตอนนี้หนูมีข้อมูลแค่ ลำดับที่กับเวลา อยากให้ช่อง ค่าที่ได้ช่วยคำนวน Auto อ่ะค่ะ พอจะทำได้ไหมค่ะ
รบกวนช่วยชี้แนะหน่อยค่ะ
ขอบคุณค่ะ

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

1 @R03141
เป็นงานซับซ้อนนิดหน่อยครับ
แต่ก็พอมีหลายทางที่ทำได้ ต้องดูว่าวิธีไหนเหมาะมากกว่า ต้องดูปัจจัยอื่นๆประกอบด้วยครับ

1 ทิศทางการกระทำเป็นอย่างไร
ลำดับ   เวลา ค่าที่ได้
     1       A1       A2
     2       B1       B2
     3       C1       C2
จากข้อมูลสัญญลักษณ์ที่ผมเขียนขึ้น
- ถ้าข้อมูลคุณมีแค่แถวเดียว ค่าของ A2 จะเอามาจากไหน อย่างไร
- ค่าของ B2 เกิดจาก....... B1 - A1 (คำนวนจากแถวก่อนหน้า)..... หรือ....... C1 - B1 (คำนวนจากแถวถัดไป)
- ถ้าคุณใช้วิธี B1-A1 ปัญหาจะเกิดที่แถวแรก เพราะมันมีแต่ตัวตั้ง ไม่มีตัวมาลบ ทางแก้ไขของคุณคืออย่างไร
- ถ้าคุณใช้วิธี C1-B1 จะเกิดปัญหาที่แถวสุดท้าย ทางแก้ของคุณคืออะไร

2 การบันทึก หรือการเก็บ หรือการแสดงผลลัพธ์
- กรณีต้องการบันทึกผลลงตารางทันที จะใช้วิธีเขียนเป็นฟังก์ชั่นเฉพาะทาง ดีกว่าเพราะใช้ if แก้ปัญหาแถวแรก หรือปัญหาแถวสุดท้ายได้ง่ายกว่า
- กรณีต้องการให้คงผลลัพธ์ไว้ในคิวรี่ ต้องใช้วิธี ซ้อนคิวรี่ ค่อนข้างจะใช้ if แก้ปัญหาดังกล่าวได้ยากหน่อย แต่ก็พอทำได้ครับ

2 @R03156
ช่วยต่อให้หน่อยได้ไหมค่ะ ว่าจะใช้สูตรยังไง
มี Field อยู่ 3 Field คือ A - B - C

A = Line
B = Date
C = Time

รูปแบบของข้อมูลจะเป็นลักษณะนี้ค่ะ

Date(B)                  Line(A)      Time(C)
20090830     A     7:29
20090830     A     7:32
20090830     A     7:37
20090830     A     7:42
20090830     A     7:47
20090830     B     7:29
20090830     B     7:57
20090830     B     8:02
20090830     B     8:07
20090830     B     8:12
20090830     B     8:17
20090830     B     8:22
20090830     B     8:27
20090831     A     7:29
20090831     A     7:32
20090831     A     7:35
20090831     A     7:38
20090831     A     7:41
20090831     B     7:29
20090831     B     7:32
20090831     B     7:35
20090831     B     7:38
ส่วน Field ที่จะเพิ่มมาใหม่จะใช้ชื่อว่า Field E
โดยที่ Field E จะคำนวนเวลาระหว่างแถวของ C ออย่างที่ อ. เข้าใจนะค่ะ
ส่วนหัวและถ้าย จะให้สูตร แบบว่า
* ถ้าเป็นข้อมูลใหม่ของวันที่ใหม่ของ Line ให้ตั้งเป็น 0 ไว้เลยไม่ต้องคำนวน
แล้วค่อยเอาข้อมูลที่ 2 มาคำนวนแทน ตัวอย่าง ในรูปเป็นแบบ Excel แต่ใน access จะใช้อย่างไร
รบกวนด้วยนะค่ะ
3 @R03166
ผมเอาฟังก์ชั่นมาดัดแปลงให้ครับ จาก http://www.thai-access.com/yeadram_view.php?topic_id=709

การเขียนสูตรใน Excel มันง่ายตรงที่มันมีตัวระบุ index ให้ นั่นคือ จุดตัด ของคอลัมภ์ กับแถว การอ้างอิงเพื่อนำมาคำนวนก็ง่ายเพราะระบุตัวตั้งตัวลบ ได้สบาย

แต่ใน Access มันจะไม่เหมือนกัน
ถ้าให้ทำโดยการซ้อนคิวรี่ ผมทำไม่ได้ในคิวรี่เดียวแน่ๆ ครับ เพราะในข้อมูลของคุณมันไม่มีตัวระบุแถว ทำให้ใช้ sql ได้ยากครับ
- ทางออกคือ ต้องสร้างตัวระบุแถว หรือ primarykey ขึ้นมาให้มันก่อนถึงจะทำโดยคิวรี่ได้ แต่มันก็จะยาวไปถ้าจะให้พาทำทีละขั้น ผมก็เลยลัด ด้วยการทำผ่าน VBA + ADODB ซะเลยครับ ตัวระบุแถวที่โค้ดมันรับทราบ ที่ผมใช้แทน Primary key ก็คือการใช้เมธอด ของ Recordset เป็นหลักครับ (Absoluteposition, EOF, BOF, Movenext)


Function ReStruct_Table1()
Dim Sql As String
Dim Rs As New ADODB.Recordset
Dim Conn As New ADODB.Connection
Set Conn = CurrentProject.Connection

' job for 1st step and 2nd step
Sql = "select *, cdate(0) as E Into tbTemp From table1 Order by B, A, C;"
Conn.Execute Sql

Sql = "Select * From tbTemp"
Rs.Open Sql, Conn, 1, 3

' safety first
    If Rs.EOF And Rs.BOF Then
        MsgBox "Error cannot create Tempolary Table"
        GoTo ext
    End If

' job of 3rd step
Dim PrevRec As String
Dim PrevTime As Date
Dim CurTime As Date
    Do While Not Rs.EOF
        CurTime = Rs("C")
        If Rs.AbsolutePosition <> 1 Then Rs("E") = CurTime - PrevTime Else Rs("E") = 0
        PrevTime = Rs("C")
        PrevRec = Rs("B") & Rs("A")
        Rs.Update
        Rs.MoveNext
    Loop

ext:
    If Rs.State <> 0 Then Rs.Close
    Set Rs = Nothing
    If Conn.State <> 0 Then Conn.Close
    Set Conn = Nothing
End Function
4 @R03172
ขอบคุณมากๆ ค่ะ
แต่ขอนิดนึ่ง ค่ะ
คือ...
- ในฟร์อมของ table1 มันมีการดึงข้อมูลและ Update ตลอดเวลา เพราะงั้น
ในฟร์อม tbTemp ก็ต้อง Update ด้วยอ่ะค่ะ แต่ ที่ อ.ให้มามันจะสร้างตารางมาแค่ครั้งเดียวพอครั้งที่ 2 มันก็ รันไม่ได้แล้วอ่ะค่ะ ไม่ทราบว่าต้องแก้อย่างไรค่ะ

ขอบคุณมาก ๆค่ะ
5 @R03178
ทางออกที่ 1. เปลียนไปทำโดยวิธีคิวรี่ ต้องหา primarykey ของ table1 มาก่อน
ทางออกที่ 2. ใช้โค้ดเหมือนเดิม ก่อนจะสั่งงานใช้ฟังก์ชั่นทุกครั้งต้องลบ tbTemp ตัวเก่าทิ้งก่อน (อาจแทรกโค้ดเข้าไปในฟังก์ชั่นก็ได้)
6 @R03190
อยากใช้วิธีที่ 1 นะ ค่ะ แต่พอข้อมูลครั้งที่ 2 ที่เข้าไปใน tbTemp มันไม่ยอมให้ Update อ่ะค่ะ
7 @R03194
ครับผม รับทราบครับ ผมก็อยากให้เป็นวิธีที่ 1ครับ
ในความเห็นแรกที่ผมบอกไป ผมก็ได้กล่าวถึงไว้แล้ว
"- กรณีต้องการให้คงผลลัพธ์ไว้ในคิวรี่ ต้องใช้วิธี ซ้อนคิวรี่ ค่อนข้างจะใช้ if แก้ปัญหาดังกล่าวได้ยากหน่อย แต่ก็พอทำได้ครับ "


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

ในความเห็นล่ะสุด ผมก็บอกให้หา Primary Key

คุณพอจะหาได้ไหมล่ะครับ ผมก็หาให้ไม่ได้นะครับ เพราะข้อมูลมันอยู่ที่เครื่องของคุณครับ ผมมองไม่เห็นมันครับ
8 @R03305
งม..มา 2 อาทิตย์แล้วยังไม่สำเร็จเลยค่ะช่วยหน่อยนะค่ะ
เอาวิธีที่ 1 นะค่ะ

ช่วยหน่อยค่ะ

จะเพิ่มเติมอะไรก็ได้ใน ตารางหรือคิวรี่ ก็ได้ค่ะ
ในตางรางข้อมูลจะ Update ไปเลี่อยๆ นะค่ะ
ขอบพระคุณเป็นอย่างสูงค่ะ
เงื่อนไข
- เขตข้อมูล1 - Line
- เขตข้อมูล2 - SN
- เขตข้อมูล3 - Date
- เขตข้อมูล4 - Time

เอาข้อมูล Time มาลบกัน
โดย อยู่ใน Date และ Line เดียวกัน
งงไหมค่ะ....

9 @R03308
ข้อมูลของคุณมันมั่ว มันยังไม่ได้กลั่นกรอง
ทำให้โค้ด vba
รวมทั้ง sql statement ทำงานไม่ได้

อะไรเรียกว่า วันอะไรเรียก เวลา
ลองเลื่อนรายการในตาราง ไปดูรายการที่ 2451 ดูว่า นั่นมันวันที่เท่าไหร่ เวลาอะไรกันแน่ครับ

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

เอ้า นี่เป็นคิวรี่ไปคัดข้อมูลทิ้งก่อนครับ
SELECT Line_H.[เขตข้อมูล1] AS A, DateSerial(Left([เขตข้อมูล3],4),Mid([เขตข้อมูล3],5,2),Right([เขตข้อมูล3],2)) AS B, TimeSerial(Left([เขตข้อมูล4],Len([เขตข้อมูล4])-4),Left(Right([เขตข้อมูล4],4),2),Right([เขตข้อมูล4],2)) AS C, Line_H.[เขตข้อมูล2] AS D INTO Table1
FROM Line_H
WHERE (((Len([เขตข้อมูล3]))=8) AND ((Len([เขตข้อมูล4]))>4) AND ((Left([เขตข้อมูล3],4))=2009))
ORDER BY Line_H.[เขตข้อมูล1], DateSerial(Left([เขตข้อมูล3],4),Mid([เขตข้อมูล3],5,2),Right([เขตข้อมูล3],2)), TimeSerial(Left([เขตข้อมูล4],Len([เขตข้อมูล4])-4),Left(Right([เขตข้อมูล4],4),2),Right([เขตข้อมูล4],2)), Line_H.[เขตข้อมูล2];

10 @R03309
ผมหลงทางกับมันนานไปหน่อยครับ ตอนแรกว่าจะหา key หลักให้มันก่อนเพื่อจะทำ sub query ขั้นต่อไปได้ง่ายขึ้น
ตัวอย่างการทำ เลขที่ให้มันครับ
SELECT (SELECT count(*) FROM [Table1] AS Temp Where [Temp].[c]<=[Table1].[c] and temp.a=table1.a and temp.b=table1.b) AS R, Table1.D, Table1.B, Table1.C
FROM Table1
WHERE (((Table1.A)="GPA"));


แล้วต่อจากนั้นผมก็จะเอาคิวรี่ตัวนี้ ไปทำ sub query อีกครับ ก็ทำได้ครับ ถ้ามีเรคคอร์ด ประมาณ 20เรคคอร์ด อิอิ ถ้ามากไปกว่านี้ CPU 3Gb ของผม ยัง แฮ้งค์เลยครับ อิอิ (นี่ขนาดคัด เอาเฉพาะ ตัวที่เป็น GPA เท่านั้นนะเนี่ย)

ผมเลยหาวิธีใหม่ พอดีข้อมูลของคุณมันเป็นแบบ คีย์ร่วม และเละเทะพอสมควร หลังจาก คัดข้อมูลที่ไม่สมบูรณ์ทิ้งไป ด้วยคิวรี่ที่โพสต์ไปก่อนหน้านี้ (R03308) แล้ว ทีนี้ข้อมูลดูจะสมบูรณ์ขึ้นมาหน่อย ผมก็เลยลองทำ sub query โดยตรงจาก table1 โดยไม่ต้องสร้าง ลำดับ เพื่อลดกำลังการประมวลผล โดยใช้ Where ให้มันมากขึ้น
ทดสอบแล้ว อืมม 3พันกว่าเรคคอร์ด ก็ยังวิ่งสบายอยู่ ลองใช้ดูครับ
SELECT Table1.A, Table1.B, Table1.C, Table1.D, CDate([c]-CDate(nz((select Max(C) from Table1 as tmp where (table1.c > tmp.c and tmp.a=table1.a and tmp.b=table1.b)),[C]))) AS E
FROM Table1;


ปาเข้าไปเที่ยงคืนกว่าๆ เลย แต่สนุกดีครับ นานๆ ที จะได้เล่นกับ sub query ซึ่งโดยปกติ ผมยังอ่อนกับมันอยู่มากๆ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.3523s