Module - Funtion การปัดจุดทศนิยม
กระทู้เก่าบอร์ด อ.สุภาพ ไชยา

 425   15
URL.หัวข้อ / URL
Module - Funtion การปัดจุดทศนิยม

รบกวน อ.สุภาพ ครับ 
คือ ผมมีปัญหากับ จุดทศนิยม ครับ ผมต้องการเพียง 2 ตำแหน่ง 
แต่ Access จะสะสมมากกว่า 2 ตำแหน่ง และ ทำให้เวลา Sum จะผิด 
เช่น  Part    จุดทศนิยม 2 ตำแหน่ง    จุดทศนิยม 3 ตำแหน่ง  
         A                  2.34                                 2.345 
         B                  2.48                                 2.475 
         Sum            5.83                                 5.830   
ซึ่งบางทีก็ปัดขึ้น บางทีก็ไม่ปัดขึ้น ไม่ทราบว่า อ.สุภาพ              
มี Funtion แก้ไขไหมครับ หรือมีวิธีอื่นๆ รบกวนแนะนำด้วยครับ 
( Update รูปลูกชาย/ลูกสาว ใหม่หรือครับ โตขึ้นแล้ว ) 
ขอบพระคุณมากๆ ครับ 
Suchat

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

1 @R00361
ถ้าใช้ Access 97 จะไม่มีฟังก์ชัน Round() มาให้ แต่จะมีตั้งแต่เวอร์ชัน 2000 ขึ้นไป แต่จะมีบักอยู่ ผมจะใช้ฟังก์ชัน Round() ซึ่ง Ken Getz เขียนไว้ดีมาก ที่ http://www.mvps.org/access/modules/mdl0054.htm นี่คือโค้ดที่เขาให้ไว้ครับ Public Function Round( _ ByVal Number As Variant, NumDigits As Long, _ Optional UseBankersRounding As Boolean = False) As Double ' ' --------------------------------------------------- ' From "Visual Basic Language Developer's Handbook" ' by Ken Getz and Mike Gilbert ' Copyright 2000; Sybex, Inc. All rights reserved. ' --------------------------------------------------- ' Dim dblPower As Double Dim varTemp As Variant Dim intSgn As Integer If Not IsNumeric(Number) Then ' Raise an error indicating that ' you've supplied an invalid parameter. Err.Raise 5 End If dblPower = 10 ^ NumDigits ' Is this a negative number, or not? ' intSgn will contain -1, 0, or 1. intSgn = Sgn(Number) Number = Abs(Number) ' Do the major calculation. varTemp = CDec(Number) * dblPower + 0.5 ' Now round to nearest even, if necessary. If UseBankersRounding Then If Int(varTemp) = varTemp Then ' You could also use: ' varTemp = varTemp + (varTemp Mod 2 = 1) ' instead of the next If ...Then statement, ' but I hate counting on TRue == -1 in code. If varTemp Mod 2 = 1 Then varTemp = varTemp - 1 End If End If End If ' Finish the calculation. Round = intSgn * Int(varTemp) / dblPower End Function วิธีการใช้ ถ้าต้องการที่จะปัด 2 ตำแหน่ง ทำได้ดังนี้ ? MRound(2.345,2) 2.35
2 @R00363
ขอบพระคุณ อ.สุภาพ มากๆ ครับ
3 @R00370
เพิ่มเติม ครับ จากการที่ผมส่ง File ไปให้ อาจารย์ ตรวจสอบว่าเกิดอะไรขึ้น เมื่อผม Add New Record แล้วจะพบ Error ใน Funtion Round ขอเล่าเรื่องก่อนนะครับ ผมมี Form 2 Form (Main Form และ Sub Form) Form ทั้ง 2 Form ผม Link มาจาก Table โดยตรง (ไม่ได้ผ่านทาง Query) ทีนี้ใน Sub Form ผมใช้การคูณระหว่าง Field เช่น ก x ย x ส = M3 ผมต้องการ ทศนิยม 2 ตำแหน่ง ก็สร้าง Field ใหม่ เช่น =Round([M3],2) และผมทำการ Sum ในทุกๆ Field ปรากฏว่าเมื่อผม Add New Record ก็จะพบ Error ขณะนี้ผมแก้ไขได้แล้วครับ ก็คือ ใน Sub Form ให้ Link มาจาก Query และไปสร้าง Field จุดทศนิยมไว้ที่นั่น เสร็จแล้ว Sub Form ก็ Link ตามปกติ เวลา Sum Total ก็ Sum([ชื่อ Field]) เมื่อ Add New Record ก็จะไม่มี Error เกิดขึ้นครับ ก็ขอบพระคุณ อ.สุภาพ มากๆ นะครับ สำหรับความรู้ดีๆ พอดีผมเจอ Funtion Round จากใน website อีกที่หนึ่ง คือ Function SRound(Number As Double, num_digits As Integer) As Double On Error GoTo Err_round digits = 10 ^ (num_digits * -1) Round = Int(Number / digits + 0.5) * digits Exit_round: Exit Function Err_round: MsgBox Error$ Resume Exit_round End Function รบกวน อ.สุภาพ ตรวจสอบดูด้วยครับว่า ผลลัพธ์ ที่ออกมาถูกต้อง เหมือนกับ Funtion ที่ อ.สุภาพ ให้มาหรือไม่ ขอบพระคุณมากๆ ครับ Suchat
4 @R00371
ยังมีปัญหาครับ เช่น เช่น ถ้าต้องการ Round เลข .2405 ให้เป็นทศนิยม 3 ตำแหน่ง ถ้าทำแบบโค้ดของฝรั่ง หรือทำใน Excel (=Round(.2405,3) จะได้ .241 ? Round(.2405,3) .241 แต่ถ้าเป็นโค้ดที่ให้ผลทดสอบ จะได้ .24 ซึ่งไม่ถูกต้อง ? SRound(.2405,3) .24 ซึ่งจะมีบักเหมือน Round() ที่มากับ Access 2000 และ Access XP ตรงนี้เหมือนกันครับ ผมเคยใช้สูตร Round คล้ายนี้เมื่อ 4 ปีที่แล้วในการปัดเกรดนักศึกษาวิศวะแห่งหนึ่ง ดังนี้ ? sround(2.405,2) 2.4 ซึ่งเขาต้องได้ 2.41 ผมเลยถูกตรวจสอบจากทางทบวงมหาวิทยาลัย โดยไล่มาเป็นขั้นๆ จนถึงตัวโปรแกรมของผม แต่ผมก็พิสูตร์ให้เห็นว่า มันเป็นบักของฟังก์ชัน Int() ของ Access ถ้าทำการปัดทศนิยมด้วยเครื่องคิดเลยตามสูตร จะได้ผลที่ถูกต้อง ถ้าว่างๆ ก็ลองทดสอบกับตัวเลขต่อไปนี้อีกก็ได้ .2845 .3445 .3545 .3645 .4145 .4245 .4745 .4845 .5045 .5145 .5245 .5345 .5445 .6345 .7545 .7645 .8845 โดยทำการปัดทศนิยมแบบ GPA คือ ปัดจากหลักที่สี่เป็นต้นมา แต่เอาแค่ 2 หลัก ? sround(sround(.3545,3),2) .35 แทนที่จะเป็น .36 ก่อนที่ผมจะได้เจอโค้ดที่ถูกต้องและสั้นของฝรั่งนั้น ผมได้แก้ปัญหาของบักโดยการเขียนโค้ดขึ้นมาเอง ซึ่งยาวเหยียด ดังนี้ครับ Function Round3(Value As Variant, Decimals As Variant) If Decimals >= 0 Then If InStr(Value, ".") = 0 Then Round3 = Value ElseIf Value < 0 Then Round3 = Left((Value * 10 ^ Decimals - 0.5) _ / 10 ^ Decimals, InStr(Value, ".") + Decimals) Else Round3 = Left((Value * 10 ^ Decimals + 0.5) _ / 10 ^ Decimals, InStr(Value, ".") + Decimals) End If Else If InStr(Value, ".") = 0 Then If Len(Abs(Value)) > Abs(Decimals) Then If Value < 0 Then If InStr((Value * 10 ^ Decimals) - 0.5, ".") = 0 Then Round3 = ((Value * 10 ^ Decimals) - 0.5) * 10 ^ Abs(Decimals) Else Round3 = Left(((Value * 10 ^ Decimals) - 0.5), _ InStr(((Value * 10 ^ Decimals) - 0.5), ".") - 1) * 10 ^ Abs(Decimals) End If Else If InStr((Value * 10 ^ Decimals) + 0.5, ".") = 0 Then Round3 = ((Value * 10 ^ Decimals) + 0.5) * 10 ^ Abs(Decimals) Else Round3 = Left(((Value * 10 ^ Decimals) + 0.5), _ InStr(((Value * 10 ^ Decimals) + 0.5), ".") - 1) * 10 ^ Abs(Decimals) End If End If ElseIf Left(Abs(Value), 1) <= 4 Or Len(Abs(Value)) < Abs(Decimals) Then Round3 = 0 Else If Value < 0 Then If InStr((Value * 10 ^ Decimals) - 0.5, ".") = 0 Then Round3 = ((Value * 10 ^ Decimals) - 0.5) * 10 ^ Abs(Decimals) Else 'Having problems here Round3 = Left(((Value * 10 ^ Decimals) - 0.5), _ InStr(((Value * 10 ^ Decimals) - 0.5), ".") - 1) * 10 ^ Abs(Decimals) End If Else If InStr((Value * 10 ^ Decimals) + 0.5, ".") = 0 Then Round3 = ((Value * 10 ^ Decimals) + 0.5) * 10 ^ Abs(Decimals) Else Round3 = Left(((Value * 10 ^ Decimals) + 0.5), _ InStr(((Value * 10 ^ Decimals) + 0.5), ".") - 1) * 10 ^ Abs(Decimals) End If End If End If Else If Len(Left(Abs(Value), InStr(Abs(Value), ".") - 1)) > Abs(Decimals) Then If Value < 0 Then Round3 = Left(((Value * 10 ^ Decimals) - 0.5), _ InStr(((Value * 10 ^ Decimals) - 0.5), ".") - 1) * 10 ^ Abs(Decimals) Else Round3 = Left(((Value * 10 ^ Decimals) + 0.5), _ InStr(((Value * 10 ^ Decimals) + 0.5), ".") - 1) * 10 ^ Abs(Decimals) End If ElseIf Left(Abs(Value), 1) <= 4 Or Len(Left(Abs(Value), _ InStr(Abs(Value), ".") - 1)) < Abs(Decimals) Then Round3 = 0 Else If Value < 0 Then Round3 = Left(((Value * 10 ^ Decimals) - 0.5), _ InStr(((Value * 10 ^ Decimals) - 0.5), ".") - 1) * 10 ^ Abs(Decimals) Else Round3 = Left(((Value * 10 ^ Decimals) + 0.5), _ InStr(((Value * 10 ^ Decimals) + 0.5), ".") - 1) * 10 ^ Abs(Decimals) End If End If End If End If Round3 = Val(Round3) End Function และทดสอบแล้วว่าตั้งแต่ 0.0001 ถึง 3.9999 จะไม่มีปัญหากับการปัดแบบ GPA
5 @R00372
ขอบพระคุณ อ.สุภาพ มากๆ ครับ สำหรับผลการทดสอบ แล้วไม่ทราบว่า ผมควรใช้ Funtion อันไหนดีครับ ระหว่าง Funtion Round() ซึ่งเขียนโดย Ken Getz กับ Function Round3 ของ อาจารย์ ซึ่งจะทำให้ผลการปัดจุดทศนิยม ถูกต้องครับ ขอบพระคุณครับ Suchat ชลบุรี
6 @R00373
ใช้ของ Ken Getz ก็น่าจะดี เพราะโค้ดมันสั้นดี ส่วนของผมจะลองตรวจสอบตัวเลขที่มีมากกว่า 4.00 ดูก่อนครับ หรือจะช่วยทดสอบก็ยินดีมากเลขครับ
7 @R00374
ขอบพระคุณมากๆ ครับ Suchat ชลบุรี
8 @R00376
ผมไปลองทดสอบการใช้ฟังก์ชัน Round() ซึ่งมีมาพร้อมกับ Visual FoxPro 6.0 ไม่มีปัญหาอะไรครับ ใช้ได้ถูกต้องดีมาก ? round(.2405,3) .241 แต่ทำไม่โปรแกรมแต่ละตัวของ Microsoft เหมือนกัน แต่ใช้ฟังก์ชัน Round ที่ต่างกันไม่ทราบ และที่น่าสนใจคือ Round() ใน Worksheet ของ Excel จะไม่มีปัญหาเหมือน Round ใน VBA ของ Excel ทั้งๆ ที่เป็นโปรแกรมเดียวกัน
9 @R00377
อ.สุภาพ ครับ แล้วเรามีวิธีดึงเอา Funtion Round จาก Excel หรือ Visual FoxPro 6.0 มาใช้ใน Excel ได้หรือไม่ครับ รบกวนอีกครั้งครับ Suchat ชลบุรี
10 @R00378
การดึง Round ของ Excel ที่อยู่ใน Worksheet มาใช้ใน Access ทำได้ดังนี้ครับ 1. เปิด Module แล้วไปที่เมนู Tools>References> ให้คลิกเลือก Microsoft Excel X.0 Object Library เข้ามาอยู่ใน References ด้วย 2. จากนั้นก็เรียกใช้ฟังก์ชันข้างล่างนี้ได้ทันทีครับ Function XcelRound(dbl As Double, exp As Integer) As Double XcelRound = Excel.WorksheetFunction.Round(dbl, exp) End Function
11 @R00379
ขอบพระคุณ อ.สุภาพ มากๆ อีกครั้งครับ ขอบพระคุณครับ Suchat ชลบุรี
12 @R00380
เรียน อ.สุภาพ ครับ ที่บริษัทฯ ที่ผมทำงาน ใช้ Windows ME + Access97 และ Office 2000 Pro (Thai) ผมทำตามที่ vอ.สุภาพ แนะนำในข้อ 1 คือ เปิด Module แล้วไปที่เมนู Tools>References> ให้คลิกเลือก Microsoft Excel X.0 Object Library เข้ามาอยู่ใน References ด้วย ในนั้นจะมีอยู่ 2 ตัวคือ 1. Microsoft Excel 5.0 Object Library 2. Microsoft Excel 9.0 Object Library ผมเลือกไม่ว่าจะเป็นรายการที่ 1 หรือ 2 ก็จะขึ้น Dialog Microsoft Visual Basic และขึ้นข้อความว่า Name conflicts with existing module , project or library เมื่อผมปิด Program ทั้งหมด และเปิดใหม่ ก็พบว่า library ที่ผมเลือกไว้ไม่ได้ถูก mark เลือกไว้ ก็จะมาพบ Error อีก แต่ขณะเดียวกัน ที่บ้านของผมใช้ WindowsXP Pro + Access 97 และ Office XP Pro กลับไม่พบปัญหานี้ รบกวน อ.สุภาพแนะนำด้วยครับ ขอบพระคุณครับ Suchat ชลบุรี
13 @R00381
อ.สุภาพ ครับ ผมได้ลองสร้าง Access 2000 ใหม่ แล้วทำตามขั้นตอนใหม่ ตามที่ อ.แนะนำ การดึง Round ของ Excel ที่อยู่ใน Worksheet มาใช้ใน Access ทำได้ดังนี้ครับ 1. เปิด Module แล้วไปที่เมนู Tools>References> ให้คลิกเลือก Microsoft Excel X.0 Object Library เข้ามาอยู่ใน References ด้วย 2. จากนั้นก็เรียกใช้ฟังก์ชันข้างล่างนี้ได้ทันทีครับ Function XcelRound(dbl As Double, exp As Integer) As Double XcelRound = Excel.WorksheetFunction.Round(dbl, exp) End Function ผลปรากฏว่า เมื่อผม Add Library เข้ามาใหม่ ไม่พบข้อความ Name conflicts with existing module , project or library ครับ แต่เมื่อใช้ Funtion ปรากฏว่าไม่สามารถใช้งานได้ Debug ที่ Module และเมื่อผม ไปที่เมนู Tools>References ปรากฏว่า Library ทั้ง 2 ตัว คือ 1. Microsoft Excel 5.0 Object Library 2. Microsoft Excel 9.0 Object Library หายไปหมดเลยครับ รบกวน อ.สุภาพ แนะนำวิธีการนำกลับมาด้วยครับ หรือต้องไป D/L ที่ไหนครับ ขอบพระคุณมากๆ ครับ Suchat ชลบุรี
14 @R00382
ทั้ง 2 ตัว มีฟังก์ชัน Round() เหมือนกัน Microsoft Excel 5.0 Object Library Microsoft Excel 9.0 Object Library แต่ตัวเวอร์ชัน 5.0 จะมีวิธีการเรียกใช้ที่ต่างไปหน่อยหนึ่ง ผมเคยเขียนบทความเกี่ยวกับเรื่องนี้ไว้อยู่ เดี๋ยวผมจะค้นแล้วนำมาโพสต์ไว้ที่นี่ให้ก็แล้วกันครับ แนะนำให้ใช้เวอร์ชัน 9.0 ดีกว่า ที่เกิดปัญหา Error เพราะทั้ง 2 ตัวมีชื่อเหมือนกัน ให้เลือกเอาตัวหลังก็แล้วกันครับ หรือตัวอย่างที่ผมเคยทำไว้อยู่ที่ http://agserver.kku.ac.th/basiceng/Computer/download/BahtText.zip ลองเอาไปลองศึกษาดูครับ
15 @R00383
ขอบพระคุณ อ.สุภาพ มากๆ ครับ ผมแก้ได้แล้วครับ เป็นอย่างที่ อ.สุภาพ บอกครับ ต้องใช้ Microsoft Excel 9.0 Object Library ถึงใช้ได้ครับ ผมไป Copy File XL5EN32.OLB จากเครื่องอื่นๆ ที่ลง OfficeXP มาลงทับที่ C:\Program Files\Microsoft Office\Office หรือ Office10\ แล้ว Add Library Microsoft Excel 9.0 Object Library ก็ใช้ได้ครับ จากตัวอย่างที่ อ.สุภาพให้ไว้ ผม D/L มาแล้วครับ กำลังศึกษาอยู่ ผมขอบพระคุณ อ.สุภาพ มากๆ ครับ ขอบพระคุณครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.0806s