Sai số khi làm việc với đối tượng Calendar Control

Liên hệ QC

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,952
Trước tiên xin nói rõ, máy tính của tôi đang định dạng DATE trong Regional Language Optionsdd/mm/yyyy
Tôi vẽ 1 Calendar lên bảng tính và tiến hành làm cuộc thí nghiệm sau với đoạn code sau:
PHP:
Private Sub Calendar1_Click()
  [A1] = Calendar1.Value
  ThisWorkbook.Names("DateVal").Value = Calendar1.Value
  [B1] = Evaluate("DateVal")
End Sub
Tức là:
- Mổi lần click vào Calendar thì sẽ chèn giá trị của nó vào cell A1
- Đồng thời chèn luôn giá trị Calendar vào Name DateVal (đương nhiên name này đang tồn tại)
- Cell B1 nhận giá trị từ name DateVal
Nhận xét:
- Giá trị tại Cell A1 và B1 khác nhau xa lắc.... Ví dụ khi tôi click vào ngày 1 tháng 5 năm 2009 thì cell A1 hiển thị 01/05/2009 còn B1 thì hiển thị 05/01/2009 (đượng nhiên 2 cell này được Format Custom là dd/mm/yyyy)
- Có cảm giác như sau khi đưa giá trị vào name thì ngày và tháng bị "đảo lộn" với nhau vậy
- Nếu thay đổi định dạng trong Regional Language Options theo kiểu Mỹ (mm/dd/yyyy) thì tất cả đều đúng
Xin hỏi:
- Tại sao lại có sai số này? Và cách khắc phục?
 

File đính kèm

- Tại sao lại có sai số này?

Trời biết! Anh Bill biết! Lỗi là lỗi của Name không chơi với dd/mm/yy, lúc nào nó cũng mm/dd/yy. Nên 13/05/09 bị biến thành text.

- Và cách khắc phục?
Hì, dễ lắm, nhân Calendar.Value với 1 là xong.

Kể cả xài DateSerial(Year(Cld1), Month(Cld1), Day(Cld1)) cũng chẳng ăn thua.
 
Upvote 0
- Tại sao lại có sai số này?

Trời biết! Anh Bill biết! Lỗi là lỗi của Name không chơi với dd/mm/yy, lúc nào nó cũng mm/dd/yy. Nên 13/05/09 bị biến thành text.

- Và cách khắc phục?
Hì, dễ lắm, nhân Calendar.Value với 1 là xong.

Kể cả xài DateSerial(Year(Cld1), Month(Cld1), Day(Cld1)) cũng chẳng ăn thua.
Em kiểm tra rõ rằng giá trị của name DateVal là SỐ cơ mà (đâu phải text nhỉ)
Ẹc... Ẹc... món DateSerial(Year(Cld1), Month(Cld1), Day(Cld1)) em đã thử từ chiều rồi... đúng là trớt qướt
 
Upvote 0
Xin tò te góp thêm một cách khắc phục nữa.
Em thì không chơi *1 vào Calendar.value, vì hổng hiểu sao vẫn có lúc nó sai.
Em chơi cái này:
PHP:
ThisWorkbook.Names("DateVal").Value = Format(Calendar1.Value, "#")
Khi đó thì tha hồ mà định dạng cho B1, định dạng kiểu nào nó ra kiểu ấy, không phụ thuộc vào định dạng của hệ thống.
 
Upvote 0
Xin tò te góp thêm một cách khắc phục nữa.
Em thì không chơi *1 vào Calendar.value, vì hổng hiểu sao vẫn có lúc nó sai.
Em chơi cái này:
PHP:
ThisWorkbook.Names("DateVal").Value = Format(Calendar1.Value, "#")
Khi đó thì tha hồ mà định dạng cho B1, định dạng kiểu nào nó ra kiểu ấy, không phụ thuộc vào định dạng của hệ thống.
Nghe chừng có lý!
Nếu vậy nó có tương đương với:
ThisWorkbook.Names("DateVal").Value = CDbl(Calendar1.Value)
Hoặc
ThisWorkbook.Names("DateVal").Value = Clng(Calendar1.Value)
không ta?
Ẹc... Ẹc...
 
Upvote 0
Em kiểm tra rõ rằng giá trị của name DateVal là SỐ cơ mà (đâu phải text nhỉ)
Chỉ có ngày lớn hơn 12 mới bị biến thành text thôi. Còn nhỏ hơn 12 thì name vẫn bằng giá trị số 39 ngàn mấy mấy đó.
Còn định dạng như BNTT nói thì vẫn OK.
Mí lị, lão chết tiệt hông chơi evaluate(), chơi zầy:
[B1] = "=DateVal"

cho khỏe.
 
Lần chỉnh sửa cuối:
Upvote 0
Chỉ có ngày lớn hơn 12 mới bị biến thành text thôi. Còn nhỏ hơn 12 thì name vẫn bằng giá trị số 39 ngàn mấy mấy đó.
Còn định dạng như BNTT nói thì vẫn OK.
Mí lị, lão chết tiệt hông chơi evaluate(), chơi zầy:
[B1] = "=DateVal"

cho khỏe.
Quả đúng em test chưa kỹ... khi ngày > 12 thì ông nội DateVal... biến thành Pê đê mất rồi
Điên thế!
Có điều sư phụ chơi kiểu [B1] = "=DateVal" em thấy hơi nguy hiểm!
Ở trên chỉ là ví dụ... trong 1 file thật, em cần giá trị chính xác cơ (bất chấp định dang hệ thống) Mấy vụ Regional Language Options này đôi lúc hành xác ghê!
 
Upvote 0
Nghe chừng có lý!
Nếu vậy nó có tương đương với:
ThisWorkbook.Names("DateVal").Value = CDbl(Calendar1.Value)
Hoặc
ThisWorkbook.Names("DateVal").Value = Clng(Calendar1.Value)
không ta?
Ẹc... Ẹc...
Anh cứ thử, là biết nó có tương đương hay không liền!

Em đã bị VBA vật cái "Ngày tháng năm" này quá trời! Phát điên được với nó. Chỉ cần cho nó ghi vô ô, mà ghi xong, nó canh lề bên trái, là biết ngay trật lất! Không Sort được, không Filter được! Chỉ từ khi em mò ra cái trò Format cho nó theo kiểu "#" thì mọi chuyện... hết điên. Và từ đó đến giờ, em chỉ xài mỗi cú này...
 
Upvote 0
Nói thêm cái này để mọi người chú ý:
Xài cái DateTimePicker so với Calendar Control cũng bị điên giống vậy mà có phần điên hơn.
Xem file thí dụ, là 1 bảng dữ liệu nhập bằng form, chọn ngày tháng bằng DateTimePicker. Rồi dùng công thức thông thường tính tổng với 1 điều kiện hoặc 2 điều kiện về ngày tháng:
=SUMIF(A2:A6;E2;B2:B6)

=SUMPRODUCT((A2:A6>=E5)*(A2:A6<=E6)*B2:B6)

thế mà ra kết quả sai.

Nguyên nhân là thằng DateTimePicker có ghi cả giờ nữa. Cái giờ này có thể chỉnh thành 00:00:00 nhưng không phải chỉnh trong Property thông thường như các control khác. Nó có 1 cái Property riêng!
 

File đính kèm

Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom