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), 
&quot;Standard.Module1.OnTime&quot;
+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;

Reply via email to