PDA

View Full Version : สืบเนื่องจากกระทู้ : รบกวนถามวิธีการสั่งให้ accessทำงานซ้ำกันไปเรื่อยๆทีค่ะ



choco2006
28-08-2007, 12:33 PM
http://citecclub.org/forum/index.php?showt...opid=26318& (http://citecclub.org/forum/index.php?showtopic=10301&st=0&gopid=26318&)

ต้องขอขอบคุณคุณ hinaloveมากที่เข้าช่วยเข้ามาตอบให้
แต่ว่า....

มันยังไม่ได้ค่ะ ประมาณว่าสูตรการคำนวนเค้าบอกให้ทำเป็นแบบใหม่ค่ะจาก

สร้าง Table : TEST1
name|site|minute
A|5|20
A|5|40
A|6|10
A|6|40
A|5|30
B|4|40
B|3|30
B|4|25
A|4|20
C|4|20
E|3|40
B|2|40

เป็น
A|4|20
A|5|20
A|5|30
A|5|40
A|6|10
A|6|40
และเอามาคิดส่วนต่างเป็นค่าเฉลี่ย
A|4|0
A|5|20 กะ A|5|30 ต่างกัน 10
A|5|20 กะ A|5|30 ต่างกัน 10
A|5|30 กะ A|5|40 ต่างกัน 10
สรุป เป็น A|5|10+10+10/3
A|6|10 กะ A|6|40 ต่างกัน 30

ต้องได้เป็น
A|4|20
A|5|10
A|6|30


และก็คิดอย่างงี้ไปเรื่อยๆกะทุกคนค่ะ
รบกวนตอบใหม่อีกทีนะคะ

hina_lovex
29-08-2007, 10:37 AM
อันนี้ต้องใช้เวลาครับ เพราะ ลองคิดดูแล้ว ถ้าใช้ Query เลยยังคิดไม่ออก ที่นึกออก คือ สั่ง PIVOT Table ใน Access แต่มันติดตรงที่ว่า พอได้ PIVOT แล้ว มันต้องมาทำเป็น Sub Query อีก ซึ่งถ้าข้อมูล มันไม่ได้ระบุบว่า มี PIVOT กี่ตัวนี่มันก็ ไม่ Dynamic อีก ดังนั้น วิธีที่คิดว่าดีที่สุด คือ ต้องเขียน VBA เข้าไปดึงข้อมูล แล้วใส่ Condition เข้าไปคำนวณ ครับผม
จริงๆ ถ้า Access มันมี Store Procedure ก็จะดี แต่เท่าที่ทราบ Access มันเขียน Store Procedure ไม่ได้ ดังนั้นก็เลยต้องเขียนโดย VBA, VB, PHP, ASP, .. ฯลฯ ที่เป็นภาษาด้าน Programming ที่ Connect DB ได้
ถ้ามีเวลาจะลองทำดูนะครับ

hina_lovex
29-08-2007, 04:29 PM
เขียนใน VBA ตามนี้ครับผม

**Hidden Content: Check the thread to see hidden data.**
ได้ผลออก มาตามนี้ครับ
name site IntervalAVG
A 4 20
A 5 10
A 6 15
B 2 40
B 3 30
B 4 40
C 4 20
E 3 40

hina_lovex
29-08-2007, 05:21 PM
ผมมีข้อคิดเห็นเพิ่มเติมครับ ปัญหาของคุณ cho มันจัดเป็น ปัญหาที่ได้ผลเฉลย ไม่ตรงกันทุกครั้งครับ เพราะ ถ้าเราไม่ใส่ Order By minute เช่น
A 5 20
A 5 40
A 5 30
ได้ AVG = 20+10/3 = 10

แต่ถ้า เป็น
A 5 20
A 5 30
A 5 40
ได้ AVG = 10 + 10/3 = 6.6667
ซึ่งทางทฤษฏี แล้วถ้า ไม่ sort ตาม minute จัดเป็นปัญหาแบบ NFA(Nondeterministic Finite Automata) ได้ผลไม่เท่ากันทุกครั้ง
แต่ถ้า เปลี่ยนเป็น order by minute จะกลายเป็น DFA(Deterministic Finite Automata)
เรื่องทฤษฏี ผมไม่แม่นมากนัก เพราะเรียนมานานแล้ว ถ้าผิดก็ขออภัยนะครับ

choco2006
29-08-2007, 07:56 PM
เพิ่งเห็นว่าโพสโจทย์ผิดค่า
สร้าง Table : TEST1
name|site|minute
A|5|20
A|5|40
A|6|10
A|6|40
A|5|30
B|4|40
B|3|30
B|4|25
A|4|20
C|4|20
E|3|40
B|2|40

เป็น
A|4|20
A|5|20
A|5|30
A|5|40
A|6|10
A|6|40
และเอามาคิดส่วนต่างเป็นค่าเฉลี่ย
A|4|0

A|5|20 กะ A|5|30 ต่างกัน 10
A|5|20 กะ A|5|30 ต่างกัน 10
A|5|30 กะ A|5|40 ต่างกัน 10
สรุป เป็น A|5|(10+10+10)/3 (3 มาจากจำวนแถวในไซต์ เดียวกัน)

A|6|10 กะ A|6|40 ต่างกัน (30)/2

ต้องได้เป็น
A|4|0
A|5|10
A|6|15



และเพิ่มเติมนิดนึงค่ะคือว่า
หากเราต้องการจะเพิ่มว่าค่าเฉลี่ยของA รวมแล้วทั้งหมดเป็นเท่าไหร่จะต้องเพิ่มตรงไหนคะ เช่น สมมุติตอนนี้ได้
A|3|30
A|4|40
A|5|50

ต้องการจะหา A เฉลี่ยรวมโดยตัวหารจะคงที่คือ 30 siteงาน
30+40+50/30 =4
กับต้องการจะหาส่วนเบี่ยงเบนมาตราฐาน
คือ(ค่าเวลาเข้างานในแต่ละไชต์ - ค่าเฉลี่ยโดยรวม)ยกกำลังสองหารด้วยจำนวนไซต์
((30 -4)(30-4)+(40-4)(40-4)+(50-4)(50-4))/30


ยังไงรบกวนตอบต่ออีกนิดนึงนะคะ ขอบคุณล่วงหน้าค่า

ps. code เนี่ยเอาไปแปะตรงไหนเหรอคะ

hina_lovex
30-08-2007, 08:54 AM
โจทก์ใหม่ ก็ใช้ Code เดิมครับ แค่แก้ จากบรรทัด ที่ใส่ If(TempInt =1) เอามันออกเท่านั้นเอง ก็จะได้ตามโจทย์ใหม่ ที่คุณ cho ต้องการ
If (TempInt = 1) Then
Debug.Print RsTemp!Name & " " & RsTemp!Site & " " & Rs!Minute
Rs.MoveNext
Else

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

ส่วน Code เอาไปใส่ไว้ไหน ให้เอาไปใส่ไว้ใน Access ที่ Menu Tools-> Macro -> Visual Basic Editor หรือพอเข้า Access แล้วกดปุ่ม Alt+F11 ครับผม
Code ที่ผมให้ไปจะสร้าง TempTable ขึ้นมาตัวหนึ่ง เหมือนเป็นกระดานทดเลข บางคนเขาจะให้ Array กัน แต่ผมสร้าง TempTable แล้วลบทิ้ง ถ้าอยากให้ข้อมูลมัน คงอยู่ในตาราง ก็ไม่ต้องสั่งลบ ตารางออก
โดย ลบบรรทัดนี้ออก Set RsTemp = Conn.Execute("Drop Table TempTable;")
แต่ก็คงต้องตรวจสอบ ว่ามันมีอยู่ไหม ตอน Create ตารางเวลาสั่งรอบต่อไป

ผมไม่เขียน Code เพิ่มให้ เพราะอยากให้คุณ cho ลองศึกษา Code ผมก่อน รู้แล้วเขียนเพิ่มเข้าไป (เราต้องสอนให้คนอื่นให้รู้จักหาปลาครับ ไม่ใช่จับปลาไปให้เขา)

choco2006
30-08-2007, 12:29 PM
พอเข้า atl+f11แล้วก็กดตรงnew moduleใช่มั้ยคะ
แล้วก็เอาโค้ดไปวาง แล้วทีนี้มันจะรันยังไงคะ
หรือว่าต้องสร้างฟอร์มก่อนถึงรันได้

เราลองสร้างฟอร์ม แล้วเอาโค้ดไปใส่พอรันมันก็errer ตรงOption Compare Database
ขึ้นว่า invalid inside procedure ค่ะ ทำไงต่อดี

hina_lovex
30-08-2007, 01:54 PM
ขออภัยครับ บอกไม่ละเอียด ปกติถ้าได้ Code มาก็ต้องอ่าน Code ของเขาก่อน กรณีที่ไม่มี Readme.txt ให้อ่าน
ถ้า copy ไปแป๊ะ แล้ว Run เลย ไม่ได้แน่ๆ ครับ
ผมเขียน Readme ให้ล่ะกันครับ

1. ก่อนอื่นต้องดูที่ Connection String ของ Code ก่อนว่า ที่เขาใส่มาให้ของตัวเอง เป็นตามนั้นหรือเปล่า
บรรทัด Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\db1.mdb"
จะเห็นว่า Data Source=E:\db1.mdb หมายถึง Database Access ของผมอยู่ที่ Drive E:\db1.mdb
ถ้าของคุณ cho ไม่ใช่ก็ต้องแก้ Code เป็น Drive ของเครื่องตัวเอง และชื่อ Database ของตัวเองด้วย

2. QueryString
บรรทัด Set Rs = Conn.Execute("SELECT TEST1.name, TEST1.site,count(TEST1.minute) As rNum FROM TEST1 group by test1.name,test1.site;")
ต้องตรวจ Conn.Execute ทุกตัวว่า Table ที่อยู่ใน Dabase ของตัวเองเป็นอะไร ผมตั้งชื่อว่า TEST1 โดยใน TEST1 ประกอบด้วย Fields : name,site,minute
ถ้าชื่อ Table ไม่ได้ใช้ว่า TEST1 ก็ต้องแก้ TEST1 เป็นชื่อ Table ของคุณ cho ซึ่งผมไม่รู้ว่าใช้อะไร

3. ทีนี้พอแก้แล้ว ก็ Run ในหน้า Visual Basic Editor โดยการกดปุ่ม F5 ใน Function ที่เอา Code ไปแป๊ะ กรณีที่ต้องการดูการทำงานทีละบรรทัด ให้กด F8

4. ทีนี้ถ้าทำตามนั้นจะ Run ได้แต่ก็จะไม่เห็นผลของการคำนวณ เพราะ การแสดงผลของโปรแกรม ใช้คำสั่ง Debug.Print ถ้าไม่เปิดหน้าจอ Immediate ก็จะไม่เห็นผลของโปรแกรมครับ
บรรทัด Debug.Print RsTemp!Name & " " & RsTemp!Site & " " & DataDiff / RsTemp!rNum เป็นการเขียนแบบ Debug Code ครับ ถ้าจะให้ผลที่ได้ลงในตาราง ต้องเขียน Query Update ข้อมูล กลับไปที่ TempTable แล้วไม่ต้องลบ ตาราง TempTable โดยมาแทน บรรทัด Debug.Print ครับผม
อันนี้ก็ออกกำลังกันสมอง และออกกำลังนิ้วมือหน่อย อ่าน Code เข้าใจแล้วจะแก้ได้ครับ ผมเขียนแบบไม่เสร็จ (ตั้งใจครับ)

choco2006
30-08-2007, 04:21 PM
อ๋อออ เริ่มเข้าใจแล้วว่าต้อง
1.เปิด access
2. กด alt +f11
3.insert module หรือ class module ดีอ่า เราลอง class module
4. แปะโค้ด
5. กด f5 เพื่อรันโค้ดทั้งหมด

เราเข้าใจถูกป่ะคะ

hina_lovex
30-08-2007, 06:31 PM
กรณีที่ เป็น Database เปล่าๆ ต้องสร้าง Table TEST1 ที่มี Fields name,site,minute ด้วยครับ จากนั้นก็ใส่ข้อมูลเข้าไปใน Table ถึงจะ Runได้ครับผม
ส่วน Readme ที่เขียนให้ก็ Check ตามนั้น ถ้าตรงตาม Readme จะ Run ได้ครับผม