sc/qa/extras/macros-test.cxx | 27 +++++++++++++++++++ sc/qa/extras/testdocuments/OnTime.fods | 31 ++++++++++++++++++++++ vbahelper/source/vbahelper/vbaapplicationbase.cxx | 17 ++++++++---- 3 files changed, 70 insertions(+), 5 deletions(-)
New commits: commit 11314c7387dcbb84c7ebcb3bae5c3cd6a83b6524 Author: Mike Kaganski <[email protected]> AuthorDate: Thu Nov 6 11:40:29 2025 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Sat Nov 8 22:49:33 2025 +0100 tdf#169278: handle css::bridge::oleautomation::Date in OnTime Similar to commit e90e4b81b049a9d7c36de8d7f0371e2da7c60c01 (tdf#167378: handle css::bridge::oleautomation::Date in CellValueSetter, 2025-07-04). Change-Id: Icce5ca2248895a1a386b005b9ce232e45aecd633 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193625 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index 735775c1b516..0973796d20ec 100644 --- a/sc/qa/extras/macros-test.cxx +++ b/sc/qa/extras/macros-test.cxx @@ -13,12 +13,15 @@ #include <svx/svdpage.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/propertyvalue.hxx> +#include <vcl/scheduler.hxx> #include <vcl/svapp.hxx> #include <conditio.hxx> #include <document.hxx> #include <scitems.hxx> +#include <chrono> + #include <com/sun/star/sheet/XCellRangeAddressable.hpp> #include <com/sun/star/sheet/XCellRangeMovement.hpp> #include <com/sun/star/sheet/XFunctionAccess.hpp> @@ -1104,6 +1107,30 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testDdePoke) } #endif +CPPUNIT_TEST_FIXTURE(ScMacrosTest, testVbaOnTime) +{ + // A document with a sub that sets value in its A1, and a sub scheduling the other sub's + // execution using Application.OnTime: + createScDoc("OnTime.fods"); + ScDocument* pDoc = getScDoc(); + // A1 is empty initially: + CPPUNIT_ASSERT(pDoc->IsEmptyData(0, 0, 0, 0, 0)); + + executeMacro(u"vnd.sun.star.script:Standard.Module1.ScheduleOnTime" + "?language=Basic&location=document"_ustr); + + // A1 is still empty, because the timer has not yet fired: + CPPUNIT_ASSERT(pDoc->IsEmptyData(0, 0, 0, 0, 0)); + + // Let the timer fire and run the OnTime sub. The minimal timeout of VbaTimer is 50 ms: + using namespace std::chrono_literals; + std::this_thread::sleep_for(50ms); + Scheduler::ProcessEventsToIdle(); + + // A1 has the expected number now: + CPPUNIT_ASSERT_EQUAL(42.0, pDoc->GetValue(0, 0, 0)); +} + ScMacrosTest::ScMacrosTest() : ScModelTestBase(u"/sc/qa/extras/testdocuments"_ustr) { diff --git a/sc/qa/extras/testdocuments/OnTime.fods b/sc/qa/extras/testdocuments/OnTime.fods new file mode 100644 index 000000000000..d3118827156c --- /dev/null +++ b/sc/qa/extras/testdocuments/OnTime.fods @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.spreadsheet"> + <office:scripts> + <office:script script:language="ooo:Basic"> + <ooo:libraries> + <ooo:library-embedded ooo:name="Standard"> + <ooo:module ooo:name="Module1"> + <ooo:source-code> +Option VBASupport 1 + +Sub ScheduleOnTime + ' Make start time 1 s in the past, to force minimal timer timeout: + Application.OnTime Now() - TimeSerial(0, 0, 1), "Standard.Module1.OnTime" +End Sub + +Sub OnTime() + ThisWorkbook.Sheets(1).Cells(1, 1).Value = 42 +End Sub + </ooo:source-code> + </ooo:module> + </ooo:library-embedded> + </ooo:libraries> + </office:script> + </office:scripts> + <office:body> + <office:spreadsheet> + <table:table table:name="Sheet1"/> + </office:spreadsheet> + </office:body> +</office:document> \ No newline at end of file diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx index e10443c865e3..c4f91f01044a 100644 --- a/vbahelper/source/vbahelper/vbaapplicationbase.cxx +++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx @@ -21,6 +21,7 @@ #include <sal/macros.h> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/bridge/oleautomation/Date.hpp> #include <com/sun/star/container/XIndexAccess.hpp> #include <com/sun/star/lang/XMultiComponentFactory.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> @@ -382,11 +383,17 @@ void SAL_CALL VbaApplicationBase::OnTime( const uno::Any& aEarliestTime, const O if ( aFunction.isEmpty() ) throw uno::RuntimeException( u"Unexpected function name!"_ustr ); - double nEarliestTime = 0; - double nLatestTime = 0; - if ( !( aEarliestTime >>= nEarliestTime ) - || ( aLatestTime.hasValue() && !( aLatestTime >>= nLatestTime ) ) ) - throw uno::RuntimeException( u"Only double is supported as time for now!"_ustr ); + auto getTime = [](const uno::Any& aTime) + { + if (double nTime; aTime >>= nTime) + return nTime; + if (css::bridge::oleautomation::Date date; aTime >>= date) + return date.Value; + throw uno::RuntimeException(u"Invalid type of argument"_ustr); + }; + + double nEarliestTime = getTime(aEarliestTime); + double nLatestTime = aLatestTime.hasValue() ? getTime(aLatestTime) : 0; bool bSetTimer = true; aSchedule >>= bSetTimer;
