2017-02-23 15 views
5

Tôi mới bắt đầu học VBA ba tuần trước, vì vậy hãy tự do phê bình mã của tôi.VBA - Tuyên bố IIF với CDate (biến thể)

Tôi muốn sử dụng IIF tuyên bố để làm những gì ở bên trong lệnh If:

Dim rng_ModPlanStart as range 
Dim QueryDate as Variant 

Set rng_ModPlanStart = ThisWorkbook.ActiveSheet.Range("AH2:AH" & LastCell) 
rng_ModPlanStart(1).Offset(-1, 0).Value = "Module Planned Start" 

    For Each cl In rng_ModPlanStart 
     QueryDate = Application.VLookup(ActiveSheet.Range("E" & cl.Row), Sheets("Chamber Schedule").Range("B:U"), 20, False) 
     If Not ((IsError(QueryDate))) Then 
     cl.Value = DateDiff("d", CDate(QueryDate), Date) 
     End If 
    Next cl 

Nhưng tôi nhận được một lỗi khi cố gắng sử dụng IIF như

IIF(IsError(QueryDate), "", DateDiff("d", CDate(QueryDate), Date)) 

vì VBA nghĩ QueryDate không phải là một ngày ... mà nó phải là do chức năng CDate phải không? Tôi đang thiếu gì?

+0

Biến thể có thể là mọi thứ. Bạn đã bao giờ kiểm tra nội dung của nó chưa? – RuDevel

Trả lời

6

Bạn không muốn sử dụng IIf cho điều này (hoặc cho hầu hết mọi thứ IMHO). Vấn đề là IIf không phải là "tuyên bố" - đó là chức năng . Điều đó có nghĩa là tất cả các thông số được đánh giá trước khi chúng được chuyển đến hàm IIf. Vì vậy, nó đánh giá (theo thứ tự):

IsError(QueryDate) 
"" 
DateDiff("d", CDate(QueryDate), Date) 'This is still evaluated if IsError returns True. 

Điều đó có nghĩa bạn sẽ nhận được một lỗi thời gian chạy, bởi vì bạn sẽ được gọi DateDiff bất kể QueryDate là một lỗi.

IIf không giống như một biểu thức thứ ba trong các ngôn ngữ khác, vì vậy bạn không thể sử dụng nó cho mệnh đề bảo vệ.

+0

Thú vị, tôi không biết điều đó. Cảm ơn bạn đã giải thích kỹ lưỡng! –

5

Giống như nhà khai thác hợp lý của VBA, IIF không có short-circuiting semantic (không giống như C và gia đình). Do đó, trường hợp lỗi không được xử lý giống như với câu lệnh If Then else.

IIF(IsError(QueryDate), "", DateDiff("d", CDate(QueryDate), Date)) 

đây ngay cả khi IsError trả về true, trường hợp thứ hai bao gồm CDate(QueryDate)sẽ được đánh giá, dẫn đến một lỗi thời gian chạy.

+1

Cảm ơn bạn! Tôi đoán tôi nghĩ nó có vẻ hiệu quả nhưng tôi đã sai! –