To my knowledge, following the TODAY()
approach of setting the date format via a callback is the only way to signal to Excel that the value you're returning from an XLL function is a date. However, it does have a few drawbacks:
- Performance (for very large numbers of calls, although I haven't checked this)
- Requires special handling if the caller is not the worksheet
- Does the wrong thing for
=TODAY() - AnotherDate
, but so does Excel!
- Will override the format on every recalc - may annoy the user if another format is preferred
Excel is able to magically avoid (4) by detecting whether it is being called as part of the calc cycle or not - I'm not sure how to achieve this without seeing the Excel source code. You could wrap you function in something to set the format which would give the user the choice (or to undo your format change as the callback would be queued second), e.g. =SetFormat(MyToday(), "yyyy-mm-dd")
The callback is fairly straightforward in xlOil (disclaimer: I wrote it):
XLO_FUNC_START(testToday())
{
CallerInfo caller;
if (!caller.fullSheetName().empty()) // Check caller is a worksheet
excelPost([=]
{
excelApp().Range[caller.writeAddress().c_str()]->NumberFormat = L"dd-mm-yyyy";
});
std::tm buf;
auto now = std::time(0);
localtime_s(&buf, &now); // Slightly labourious to get current date in C++
return returnValue(buf);
}
XLO_FUNC_END(testToday);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…