sc/CppunitTest_sc_inlinearray.mk                     |   63 +++++++++++++++++
 sc/Module_sc.mk                                      |    1 
 sc/qa/unit/InlineArray.cxx                           |   70 +++++++++++++++++++
 sc/qa/unit/data/ods/LOOKUP_inlineArray.ods           |binary
 sc/qa/unit/data/ods/tdf167134_LOOKUP_inlineArray.ods |binary
 sc/source/core/tool/interpr1.cxx                     |   14 +++
 6 files changed, 146 insertions(+), 2 deletions(-)

New commits:
commit 0aa79813e0e2d5b2984aa97b657f675ffa2824af
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Wed Jul 2 22:18:38 2025 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Jul 3 19:19:20 2025 +0200

    tdf#167134 Allow different directions in LOOKUP
    
    ... for search vector and result vector when such vectors are given as
    inline array.
    
    AOO, Excel, Gnumeric and older LO versions allow it. Different
    directions are also possible if the vector is given by a cell range.
    
    The unintended change slipped in with commit
    5079e1fb668b31989672efc097c82ced6cbf4137.
    
    Besides the unit test for tdf#167134, I have added a second unit test
    about other situations that have inline arrays as parameter of LOOKUP.
    LO does currently not fail for them, but this test might prevent
    unintended behavior changes in the future. Such tests do not yet exist.
    
    Change-Id: I21dd6b75d54aa938dcffbd2375acc51d3168b904
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187289
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>
    Tested-by: Jenkins
    (cherry picked from commit 5c0961129820fbc9dc8ec12c8a43a352ef1856a3)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187302
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    (cherry picked from commit f422d1366269a0fa611f7018dd73d933e7d2ca6e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187311

diff --git a/sc/CppunitTest_sc_inlinearray.mk b/sc/CppunitTest_sc_inlinearray.mk
new file mode 100755
index 000000000000..97d3dd50dd3c
--- /dev/null
+++ b/sc/CppunitTest_sc_inlinearray.mk
@@ -0,0 +1,63 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sc_inlinearray))
+
+$(eval $(call gb_CppunitTest_use_externals,sc_inlinearray, \
+       boost_headers \
+       mdds_headers \
+       libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sc_inlinearray))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sc_inlinearray, \
+    sc/qa/unit/InlineArray \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sc_inlinearray, \
+    cppu \
+    cppuhelper \
+    sal \
+    sc \
+    scqahelper \
+    sfx \
+    subsequenttest \
+    svl \
+    svx \
+    svxcore \
+    test \
+    tl \
+    unotest \
+    utl \
+    vcl \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sc_inlinearray,\
+    -I$(SRCDIR)/sc/source/ui/inc \
+    -I$(SRCDIR)/sc/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sc_inlinearray))
+
+$(eval $(call gb_CppunitTest_use_ure,sc_inlinearray))
+$(eval $(call gb_CppunitTest_use_vcl,sc_inlinearray))
+
+$(eval $(call gb_CppunitTest_use_rdb,sc_inlinearray,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,sc_inlinearray))
+
+$(eval $(call gb_CppunitTest_add_arguments,sc_inlinearray, \
+    
-env:arg-env=$(gb_Helper_LIBRARY_PATH_VAR)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}"
 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index 63dc4b92b90d..8b4ebee3ed39 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -65,6 +65,7 @@ $(eval $(call gb_Module_add_check_targets,sc,\
        CppunitTest_sc_cache_test \
        CppunitTest_sc_parallelism \
     CppunitTest_sc_shapetest \
+    CppunitTest_sc_inlinearray \
 ))
 endif
 
diff --git a/sc/qa/unit/InlineArray.cxx b/sc/qa/unit/InlineArray.cxx
new file mode 100755
index 000000000000..cd17895bacba
--- /dev/null
+++ b/sc/qa/unit/InlineArray.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "helper/qahelper.hxx" // contains class ScModelTestBase
+
+#include <sfx2/dispatch.hxx>
+
+using namespace css;
+
+class ScInlineArray : public ScModelTestBase
+{
+public:
+    ScInlineArray()
+        : ScModelTestBase(u"sc/qa/unit/data"_ustr)
+    {
+    }
+};
+
+/*  These tests cover cases that use inline arrays. The actual visible 
separators depend on user
+    settings. The default of these settings depend on local. The markup in the 
ODF file uses the
+    semicolon as column separator and the pipe symbol as row separator. These 
separators are used
+    in below comments.*/
+
+CPPUNIT_TEST_FIXTURE(ScInlineArray, testLOOKUP_special)
+{
+    // LOOKUP has some special rules. These are tested here.
+
+    // Load a document with test cases and force recalculation.
+    createScDoc("ods/LOOKUP_inlineArray.ods");
+    dispatchCommand(mxComponent, u".uno:CalculateHard"_ustr, {});
+    ScDocument* pDoc = getScDoc();
+
+    // Test results. Explanations can be found in the test file.
+    CPPUNIT_ASSERT_EQUAL(u"Y"_ustr, pDoc->GetString(ScAddress(1, 1, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"#N/A"_ustr, pDoc->GetString(ScAddress(1, 2, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"Z"_ustr, pDoc->GetString(ScAddress(1, 5, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"10"_ustr, pDoc->GetString(ScAddress(1, 6, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"#N/A"_ustr, pDoc->GetString(ScAddress(1, 8, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"200"_ustr, pDoc->GetString(ScAddress(1, 11, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"200"_ustr, pDoc->GetString(ScAddress(1, 12, 0)));
+    CPPUNIT_ASSERT_EQUAL(u"6"_ustr, pDoc->GetString(ScAddress(1, 13, 0)));
+}
+
+CPPUNIT_TEST_FIXTURE(ScInlineArray, testTdf67134)
+{
+    // Search and result array in LOOKUP need not have the same direction.
+    // This also applies to inline arrays.
+    // Before the fix the #N/A error was returned in case of different 
directions.
+
+    // Load a document with test cases and force recalculation.
+    createScDoc("ods/tdf167134_LOOKUP_inlineArray.ods");
+    dispatchCommand(mxComponent, u".uno:CalculateHard"_ustr, {});
+    ScDocument* pDoc = getScDoc();
+
+    // A2: string "D"
+    // B2: formula =LOOKUP(A2;{"B";"C";"D"};{"X"|"Y"|"Z"})
+    CPPUNIT_ASSERT_EQUAL(u"Z"_ustr, pDoc->GetString(ScAddress(1, 1, 0)));
+    // B3: formula =LOOkUP(A2;{"B"|"C"|"D"};{"X";"Y";"Z"})
+    CPPUNIT_ASSERT_EQUAL(u"Z"_ustr, pDoc->GetString(ScAddress(1, 2, 0)));
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/data/ods/LOOKUP_inlineArray.ods 
b/sc/qa/unit/data/ods/LOOKUP_inlineArray.ods
new file mode 100644
index 000000000000..ebd1e0d3dec1
Binary files /dev/null and b/sc/qa/unit/data/ods/LOOKUP_inlineArray.ods differ
diff --git a/sc/qa/unit/data/ods/tdf167134_LOOKUP_inlineArray.ods 
b/sc/qa/unit/data/ods/tdf167134_LOOKUP_inlineArray.ods
new file mode 100644
index 000000000000..c575feae7207
Binary files /dev/null and 
b/sc/qa/unit/data/ods/tdf167134_LOOKUP_inlineArray.ods differ
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index dcf767a69c5e..6be24e4ff778 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -6968,6 +6968,11 @@ void ScInterpreter::ScLookup()
                     PushIllegalParameter();
                     return;
                 }
+                if (eResArrayType == svMatrix) // inline-array
+                {
+                    nResCol2 = nC - 1;
+                    nResRow2 = nR - 1;
+                }
             }
             break;
             case svDouble:
@@ -7022,6 +7027,11 @@ void ScInterpreter::ScLookup()
             pDataMat->GetDimensions(nC, nR);
             bVertical = (nR >= nC);
             nLenMajor = bVertical ? nR : nC;
+            if (eDataArrayType == svMatrix) // inline array
+            {
+                nCol2 = nC - 1;
+                nRow2 = nR - 1;
+            }
         }
         break;
         case svDouble:
@@ -7324,7 +7334,7 @@ void ScInterpreter::ScLookup()
 
         if (pResMat)
         {
-            VectorMatrixAccessor aResMatAcc(*pResMat, bVertical);
+            VectorMatrixAccessor aResMatAcc(*pResMat, (nResRow2 - nResRow1) > 
0);
             // Result array is matrix.
             // Note this does not replicate the other dimension.
             if (o3tl::make_unsigned(nDelta) >= aResMatAcc.GetElementCount())
@@ -7458,7 +7468,7 @@ void ScInterpreter::ScLookup()
 
     if (pResMat)
     {
-        VectorMatrixAccessor aResMatAcc(*pResMat, bVertical);
+        VectorMatrixAccessor aResMatAcc(*pResMat, (nResRow2 - nResRow1) > 0);
         // Use the matrix result array.
         // Note this does not replicate the other dimension.
         if (o3tl::make_unsigned(nDelta) >= aResMatAcc.GetElementCount())

Reply via email to