Hàm Round của VBA cho kết quả khác hàm Round của WorksheetFunction và của Excel

Liên hệ QC

nghiaphuc

Thành viên gạo cội
Thành viên danh dự
Tham gia
25/9/09
Bài viết
5,730
Được thích
8,847
Giới tính
Nam
Nghề nghiệp
Giáo viên
Hôm nay em vô tình phát hiện ra một vấn đề về hàm Round của VBA, WorksheetFunction và Excel.
Trong file đính kèm là 3 cách tính khác nhau, có sử dụng hàm Round của 3 đối tượng trên và thấy chúng có sự sai lệch. Trong đa số trường hợp thì 3 hàm Round này trả về cùng một kết quả, nhưng có một số trường hợp chúng lại cho kết quả khác nhau.
Rất mong nhận được ý kiến của các anh chị về vấn đề này.
Xin cảm ơn mọi người!
 

File đính kèm

  • Test ham Round.rar
    8.5 KB · Đọc: 53
Em sửa lại câu lệnh như thế này thì kết quả đúng. Còn tại sao thì anh không biết ?
Mã:
DTB_2 = [COLOR=#ff0000][B]Application[/B][/COLOR].Round(WorksheetFunction.Average(HS1, HS2, HS2, HS3, HS3, HS3), 1)
 
Upvote 0
Em sửa lại câu lệnh như thế này thì kết quả đúng. Còn tại sao thì anh không biết ?
Mã:
DTB_2 = [COLOR=#ff0000][B]Application[/B][/COLOR].Round(WorksheetFunction.Average(HS1, HS2, HS2, HS3, HS3, HS3), 1)
Đúng là sửa như vậy thì ra kết quả đúng. Mà cũng lạ thiệt, gõ Application rồi gõ dấu chấm thì lại chẳng thấy cái anh chàng Round này ở đâu cả. Lẽ nào anh chàng Application.Round lại là một hàm Round khác cả 3 anh chàng kia, hay nó chính là hàm Round mà ta vẫn gõ trên Sheet?!
 
Upvote 0
"Application chấm" tức là gọi hàm excel thường dùng trên sheet đó. Nó viết tắt của Application.WorksheetFunction. Nên kết quả của nó và hàm excel trên sheet là như nhau.
Ngoài ra "WorksheetFunction chấm" cũng là gọi tắt của Application.WorksheetFunction "chấm".

"Application chấm" Sum, chấm SumProduct, chấm SubStitute, chấm Transpose, chấm Tương ớt xí muội, ... là gọi hàm Excel.

Round không chấm chiếc gì (lạt nhách) là hàm của VB, VBA
 
Lần chỉnh sửa cuối:
Upvote 0
Như vậy thì cái hàm Round trống trơn kia (cái hàm mà em gọi là "hàm Round của VBA" - không biết có chính xác không) có vẻ như không đáng tin tưởng. Thực ra em phát hiện ra điều này khi có nhu cầu làm tròn số bằng VBA và gán giá trị lên sheet, đây là bài toán tính điểm trung bình trong công việc của em ấy mà.
 
Upvote 0
Đúng Round không chấm gì (lạt nhách) là hàm của VB, VBA
 
Upvote 0
Đúng Round không chấm gì (lạt nhách) là hàm của VB, VBA
Em đang nghĩ "tham lam" một chút, nếu hàm Round không cho kết quả chính xác như vậy thì người ta sẽ xử lý vấn đề này như thế nào trên các phần mềm không có hàm Round "ngon lành" như Excel nhỉ? Chẳng hạn VB6 hoặc VBA cho Word, PowerPoint.
 
Upvote 0
Em đang nghĩ "tham lam" một chút, nếu hàm Round không cho kết quả chính xác như vậy thì người ta sẽ xử lý vấn đề này như thế nào trên các phần mềm không có hàm Round "ngon lành" như Excel nhỉ? Chẳng hạn VB6 hoặc VBA cho Word, PowerPoint.

Bạn không nên nghĩ theo kiểu: Hàm này "không cho kết quả chính xác"
Hàm bạn "cố ý" viết như thế nào thì nó hoạt động như thế ấy. Thế nào là "cho kết quả chính xác"? Hàm "cho kết quả chính xác" là hàm làm đúng như dụng ý của người viết ra nó. Thế thôi.

Trong Toán bạn có qui tắc làm tròn. Qui tắc ấy chỉ có một. Nhưng trong lập trình thì bạn có thể tự viết 3, 4 hàm mà mỗi hàm làm tròn theo một kiểu. Được không? Dĩ nhiên là được. Cùng lắm thì hàm của bạn ít có ứng dụng. Thế thôi. Làm gì có chuyện hàm "cho kết quả chính xác" hay "không cho kết quả chính xác" như bạn nghĩ ở đây. Bạn chỉ có thể nói: Các hàm đó hoạt động khác với qui tắc TÔI từng biết trong Toán. Nhưng dụng ý của người viết hàm là thế. Nếu hàm cho kết quả đúng như dụng ý của người lập trình thì nó là hàm "cho kết quả chính xác". Chấm hết.

Trong Toán làm gì có chuyện LUÔN làm tròn xuống dưới? Thế nhưng người ta viết hàm luôn làm tròn xuống dưới (ROUNDDOWN) đấy. "không cho kết quả chính xác" à? Còn có hàm luôn làm tròn lên trên (ROUNDUP) đấy. "không cho kết quả chính xác" à? Hàm là hàm. Nó làm đúng ý người lập trình. Thế thôi. Còn chuyện nó làm "ngược đời", không giống như bạn đã quen hoặc nó không có ứng dụng nhiều thì đã sao. Không thể vì thế mà nói hàm "không cho kết quả chính xác".

Trong Delphi có hàm Round. Bạn thấy nó đeo huy hiệu Round là bạn nghĩ nó làm đúng như trong Toán bạn từng biết? Nếu không đúng như trong Toán thì là hàm "không cho kết quả chính xác"? Làm gì có chuyện đó. Hàm Round trong Delphi luôn làm tròn đến số nguyên. Và nếu số cần làm tròn nằm chính xác giữa 2 số nguyên thì Round luôn làm tròn tới SỐ CHẴN. Tức không có chuyện LUÔN XUỐNG hay LUÔN LÊN ở đây. Như thế là hàm "không cho kết quả chính xác"? Không thể nói thế được vì hàm người ta viết ra nó hoạt động như thế, và người ta cũng nói rõ là nó sẽ hoạt động như thế. Cùng lắm là nó không đáp ứng được nhu cầu của anh chứ không thể nói nó "không cho kết quả chính xác". Tất nhiên cái hàm "vô dụng" đó đối với anh nó có thể lại thỏa mãn được nhu cầu của người khác.

Tôi đính kèm ảnh. Trong help nói rõ Round của Delphi sẽ hoạt động như thế nào. Và có 1 test nhỏ.
round_zpsc1a14126.jpg




Đúng thế: 2.5 và 4.5 được làm tròn tới 2 và 4 (làm tròn xuống), còn 3.5 và 5.5 được làm tròn tới 4 và 6 (làm tròn lên). Tức chúng được làm tròn tới số chẵn.

Giống trong Toán không? Không giống. Nhưng làm gì có chuyện hàm "không cho kết quả chính xác". Nó được viết để làm đúng như thế. Thế thôi. Đừng cứ thấy là hàm đeo huy hiệu ROUND là nghĩ nó phải làm đúng như qui tắc đã biết trong Toán.

Thay vì cho là hàm "không cho kết quả chính xác" thì nên hiểu một điều là mỗi hàm được viết để hoạt động theo một cách nào đó. Phải biết và nhớ là nó sẽ hoạt động như thế nào để dùng cho đúng với nhu cầu của mình. Nếu không có hàm nào có sẵn đúng y hệt như mình cần thì phải tự viết thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
Quả thật các bài viết của bác siwtom bao giờ cũng rất bài bản và chặt chẽ. Rất cảm ơn bác đã có ý kiến về vấn đề này. Em nhìn nhận vấn đề quả là phiến diện. Nhưng dù sao thì qua vấn đề này, em cũng cẩn thận hơn một chút khi sử dụng các hàm, bởi vì không phải bao giờ mình cũng hiểu được dụng ý của người xây dựng nên hàm đó (hay nói cách khác là không hiểu nguyên tắc làm việc của hàm) dẫn đến có thể có kết quả không đúng như ý muốn.
 
Upvote 0
Cái hàm Round của VBA làm việc theo kiểu hàm tài chính. Luật ngân hàng như vậy. Hình như gốc của Access từ tài chính cho nên hàm của nó gần với tài chính hơn (VBA sử dụng hàm giống Access).

Trên quan điểm tài chính, hàm Round bình thường mà bạn dùng mới là loại "không cho ra kết quả chính xác" bởi vì nó thiên vị sự tăng lên. Số 5 đáng lẽ phải nằm giữa nhưng phép tình thường coi như nó là số lớn, tăng lên 1.

Con toán của tài chính cân bằng vị trí của số 5, tức là nó có 50/50 cơ hội để tăng hay giảm.
 
Upvote 0
vậy cho hỏi h trong vb6 muốn dùng round làm tròn >= 0,5 quy lên , < 0,5 thì bỏ như thì phải viết thêm code gì
 
Upvote 0
Web KT
Back
Top Bottom