/* -*- 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/.
*/
class ScMacrosTest : public ScModelTestBase
{ public:
ScMacrosTest(); virtualvoid setUp() override;
};
// I suppose you could say this test doesn't really belong here, OTOH // we need a full document to run the test ( it related originally to an // imported Excel VBA macro ) It's convenient and fast to unit test // this the problem this way. Perhaps in the future there will be some sort // of slowcheck tests ( requiring a full document environment in the scripting // module, we could move the test there then ) - relates to fdo#67547
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testMSP)
{
createScDoc("MasterScriptProviderProblem.ods");
Any aRet = executeMacro(u"vnd.sun.Star.script:Standard.Module1.TestMSP?language=Basic&location=document"_ustr);
OUString sResult;
aRet >>= sResult;
SAL_INFO("sc.qa", "Result is " << sResult );
CPPUNIT_ASSERT_EQUAL_MESSAGE("TestMSP ( for fdo#67547) failed", u"OK"_ustr, sResult);
}
// User defined types
executeMacro(u"vnd.sun.Star.script:Standard.Module1.LoadAndExecuteTest?language=Basic&location=document"_ustr);
OUString aValue = pDoc->GetString(0,0,0);
CPPUNIT_ASSERT_EQUAL_MESSAGE("User defined types script did not change the value of Sheet1.A1", u"success"_ustr, aValue);
// User defined types
executeMacro(
u"vnd.sun.Star.script:Standard.Module1.LoadAndExecuteTest?language=Basic&location=document"_ustr);
OUString aValue = pDoc->GetString(0, 0, 0);
CPPUNIT_ASSERT_EQUAL_MESSAGE("User defined types script did not change the value of Sheet1.A1",
u"success"_ustr, aValue);
// Big Module
executeMacro(
u"vnd.sun.Star.script:MyLibrary.BigModule.bigMethod?language=Basic&location=document"_ustr);
aValue = pDoc->GetString(1, 0, 0);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Big module script did not change the value of Sheet1.B1",
u"success"_ustr, aValue);
// tdf#142391 - method exceeds 0xffff offset for methods
executeMacro(
u"vnd.sun.Star.script:MyLibrary.BigModule.farBigMethod?language=Basic&location=document"_ustr);
aValue = pDoc->GetString(2, 0, 0);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Far Method script did not change the value of Sheet1.C1",
u"success"_ustr, aValue);
}
executeMacro(u"vnd.sun.Star.script:Standard.Module1.Macro1?language=Basic&location=document"_ustr); double aValue = pDoc->GetValue(0,0,0);
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("script did not change the value of Sheet1.A1",2.0, aValue, 0.00001);
}
CPPUNIT_ASSERT_EQUAL(u"TRUE"_ustr, pDoc->GetString(ScAddress(1,0,0))); // Without the fix in place, this test would have failed with // - Expected: FALSE // - Actual : TRUE
CPPUNIT_ASSERT_EQUAL(u"FALSE"_ustr, pDoc->GetString(ScAddress(1,1,0)));
}
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testMacroButtonFormControlXlsxExport)
{ // Given a button form control with an associated macro:
createScDoc("macro-button-form-control.xlsm");
// When exporting to XLSM:
save(u"Calc MS Excel 2007 VBA XML"_ustr);
// Then make sure that the macro is associated with the control:
xmlDocUniquePtr pSheetDoc = parseExport(u"xl/worksheets/sheet1.xml"_ustr);
CPPUNIT_ASSERT(pSheetDoc); // Without the fix in place, this test would have failed with: // - XPath '//x:controlPr' no attribute 'macro' exist // i.e. the macro was lost on export.
assertXPath(pSheetDoc, "//x:controlPr", "macro", u"Module1.Button1_Click");
// Then also make sure that there is no defined name for the macro, which is only needed for // XLS:
xmlDocUniquePtr pWorkbookDoc = parseExport(u"xl/workbook.xml"_ustr);
CPPUNIT_ASSERT(pWorkbookDoc);
assertXPath(pWorkbookDoc, "//x:workbook/definedNames", 0);
}
// Export to ODS
saveAndReload(u"calc8"_ustr);
ScDocument* pDoc = getScDoc();
CPPUNIT_ASSERT_EQUAL(u"string no newlines"_ustr, pDoc->GetString(ScAddress(0, 0, 0)));
// Without the fix in place, this test would have failed with // - Expected: string with // newlines // - Actual : string withnewlines
CPPUNIT_ASSERT_EQUAL(OUString(u"string with" + OUStringChar(u'\xA') + u"newlines"), pDoc->GetString(ScAddress(0, 1, 0)));
}
// Add and delete the chart a few times // Without the fix in place, this test would have crashed here for (size_t i = 0; i < 5; ++i)
{
executeMacro(u"vnd.sun.Star.script:Standard.Module1.DrawGraph?language=Basic&location=document"n>_ustr);
// Export to ODS
saveAndReload(u"calc8"_ustr);
ScDocument* pDoc = getScDoc();
CPPUNIT_ASSERT_EQUAL(u"string no newlines"_ustr, pDoc->GetString(ScAddress(0,0,0)));
CPPUNIT_ASSERT_EQUAL(u"string no newlines"_ustr, pDoc->GetString(ScAddress(0,1,0)));
// Without the fix in place, this test would have failed with // - Expected: string with // newlines // - Actual : string withnewlines
CPPUNIT_ASSERT_EQUAL(OUString(u"string with" + OUStringChar(u'\xA') + u"newlines"), pDoc->GetString(ScAddress(1,0,0)));
CPPUNIT_ASSERT_EQUAL(OUString(u"string with" + OUStringChar(u'\xA') + u"newlines"), pDoc->GetString(ScAddress(1,1,0)));
}
// Without the fix in place, this test would have failed here with // - Expression: xmlXPathNodeSetGetLength(pXmlNodes) > 0
assertXPathContent(pContentXml, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[1]/table:table-cell[1]/text:p[2]",
u"cc dd");
}
// Unlock and load the library, to regenerate the image on save
css::uno::Reference<css::document::XEmbeddedScripts> xES(mxComponent, UNO_QUERY_THROW);
css::uno::Reference<css::script::XLibraryContainer> xLC(xES->getBasicLibraries(),
UNO_QUERY_THROW);
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(xLC, UNO_QUERY_THROW);
CPPUNIT_ASSERT(xPasswd->isLibraryPasswordProtected(sLibName));
CPPUNIT_ASSERT(!xPasswd->isLibraryPasswordVerified(sLibName));
CPPUNIT_ASSERT(xPasswd->verifyLibraryPassword(sLibName, u"password"_ustr));
xLC->loadLibrary(sLibName);
CPPUNIT_ASSERT(xLC->isLibraryLoaded(sLibName));
// Now check that saving stores Unicode data correctly in image's string pool
saveAndReload(u"calc8"_ustr);
// Unlock and load the library, to regenerate the image on save
css::uno::Reference<css::document::XEmbeddedScripts> xES(mxComponent, UNO_QUERY_THROW);
css::uno::Reference<css::script::XLibraryContainer> xLC(xES->getBasicLibraries(),
UNO_QUERY_THROW);
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(xLC, UNO_QUERY_THROW);
CPPUNIT_ASSERT(xPasswd->isLibraryPasswordProtected(sLibName));
CPPUNIT_ASSERT(!xPasswd->isLibraryPasswordVerified(sLibName));
CPPUNIT_ASSERT(xPasswd->verifyLibraryPassword(sLibName, u"password"_ustr));
xLC->loadLibrary(sLibName);
CPPUNIT_ASSERT(xLC->isLibraryLoaded(sLibName));
// Now check that saving stores array bounds correctly
saveAndReload(u"calc8"_ustr);
// Without the fix in place, it would have crashed here
executeMacro(u"vnd.sun.Star.script:Standard.Module1.DeletingFrame?language=Basic&location=document"</span>_ustr);
{
uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, uno::UNO_QUERY_THROW);
uno::Reference<container::XIndexAccess> xIndex(xDoc->getSheets(), uno::UNO_QUERY_THROW);
uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
OUString sCodeName;
uno::Reference<beans::XPropertySet> xProps(xSheet, uno::UNO_QUERY_THROW); // Without the fix in place the codename would not have been saved
xProps->getPropertyValue(u"CodeName"_ustr) >>= sCodeName;
CPPUNIT_ASSERT_EQUAL(u"NewCodeName"_ustr, sCodeName);
}
}
// Without the fix in place, the values of the specified cells won't be changed
pDoc->SetValue(ScAddress(0, 0, 0), 2);
CPPUNIT_ASSERT_EQUAL(3.0, pDoc->GetValue(ScAddress(1, 0, 0)));
CPPUNIT_ASSERT_EQUAL(4.0, pDoc->GetValue(ScAddress(2, 0, 0)));
}
// A1 contains formula with user-defined function, and the function is defined in VBA.
CPPUNIT_ASSERT_EQUAL(u"проба"_ustr, pDoc->GetString(ScAddress(0, 0, 0)));
}
saveAndReload(u"Calc MS Excel 2007 VBA XML"_ustr);
{
ScDocument* pDoc = getScDoc();
pDoc->CalcAll();
// Without the accompanying fix in place, this test would have failed with: // - Expected: проба (sample) // - Actual : ?????
CPPUNIT_ASSERT_EQUAL(u"проба"_ustr, pDoc->GetString(ScAddress(0, 0, 0)));
}
}
Any aRet = executeMacro(u"vnd.sun.Star.script:Standard.Module1.TestScriptInvoke?language=Basic&location=document"_ustr);
OUString aReturnValue;
aRet >>= aReturnValue;
// Without the fix in place, this test would have failed with // - Expected: Test6 // - Actual : TeTest8
CPPUNIT_ASSERT_EQUAL(u"Test6"_ustr, aReturnValue);
}
Any aRet = executeMacro(u"vnd.sun.Star.script:Standard.Module1.TestScriptInvoke?language=Basic&location=document"_ustr);
OUString aReturnValue;
aRet >>= aReturnValue;
// Without the fix in place, this test would have failed with // - Expected: $Sheet1.$B$5:$E$17 // - Actual : $Sheet1.$B$5:$C$10
CPPUNIT_ASSERT_EQUAL(u"$Sheet1.$B$5:$E$17"_ustr, aReturnValue);
}
// Without the fix in place, this test would have failed with // - Expression: false // - Unexpected dialog: Error: Inadmissible value or data type. Index out of defined range.
Any aRet = executeMacro(u"vnd.sun.Star.script:Standard.cf.doItForThisSheetindexThisRange?language=Basic&location=document"_ustr);
// Without the fix in place, this test would have failed with // - Expression: false // - Unexpected dialog: Error: BASIC runtime error. // An exception occurred // Type: com.sun.star.lang.IllegalArgumentException
executeMacro(u"vnd.sun.Star.script:Standard.Module1.Main?language=Basic&location=document"_ustr);
// Without the fix in place, changing the grammar from GRAM_NATIVE to either GRAM_NATIVE_XL_A1 // or GRAM_NATIVE_XL_R1C1 would cause a Basic exception/error in the following script.
pDoc->SetGrammar(formula::FormulaGrammar::Grammar::GRAM_NATIVE_XL_R1C1);
// Without the fix in place, this test would have failed with // - Expected: 5.5 // - Actual : 0
CPPUNIT_ASSERT_EQUAL(5.5, pDoc->GetValue(ScAddress(0, 0, 0)));
}
// Without the fix in place, this test would have crashed
executeMacro(u"vnd.sun.Star.script:TestLibrary.TestModule.Main?language=Basic&location=document"an>_ustr);
ScDocument* pDoc = getScDoc();
//Check the autoformat has been applied for (SCCOL i = 0; i < 5; ++i)
{ const ScPatternAttr* pAttr = pDoc->GetPattern(i, 0, 0); const SfxPoolItem& rItem = pAttr->GetItem(ATTR_BACKGROUND); const SvxBrushItem& rBackground = static_cast<const SvxBrushItem&>(rItem); const Color& rColor = rBackground.GetColor();
CPPUNIT_ASSERT_EQUAL(COL_BLUE, rColor);
}
for (SCROW i = 1; i < 13; ++i)
{ const ScPatternAttr* pAttr = pDoc->GetPattern(0, i, 0); const SfxPoolItem& rItem = pAttr->GetItem(ATTR_BACKGROUND); const SvxBrushItem& rBackground = static_cast<const SvxBrushItem&>(rItem); const Color& rColor = rBackground.GetColor();
// insert initial library
css::uno::Reference<css::document::XEmbeddedScripts> xDocScr(mxComponent, UNO_QUERY_THROW); auto xLibs = xDocScr->getBasicLibraries(); auto xLibrary = xLibs->createLibrary(u"TestLibrary"_ustr);
xLibrary->insertByName(
u"TestModule"_ustr,
uno::Any(
u"Function TestLayerID\n" " xShape = thisComponent.createInstance(\"com.sun.star.drawing.TextShape\")\n" " thisComponent.DrawPages(0).Add(xShape)\n" " origID = xShape.LayerID\n" " On Error Goto handler\n" " xShape.LayerID = 257 ' 1 if wrongly converted to unsigned 8-bit type\n" " TestLayerID = origID & \" \" & xShape.LayerID ' Should not happen\n" " Exit Function\n" "handler:\n" " ' This is expected to happen\n" " TestLayerID = origID & \" Expected runtime error happened\"\n" "End Function\n"_ustr));
Any aRet = executeMacro(u"vnd.sun.Star.script:TestLibrary.TestModule.TestLayerID?language=Basic&location=document"_ustr); // Without the fix in place, this test would have failed in non-debug builds with // - Expected : <Any: (string) 0 Expected runtime error happened> // - Actual : <Any: (string) 0 1> // In debug builds, it would crash on assertion inside strong_int ctor. // The LayerID property of com.sun.star.drawing.Shape service has 'short' IDL type. // The expected run-time error is because there are only 5 layers there.
CPPUNIT_ASSERT_EQUAL(Any(u"0 Expected runtime error happened"_ustr), aRet);
}
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testFunctionAccessIndirect)
{
OUString aFileName = loadFromFile(u"tdf120161.ods"); // just some document with known values in cells
// tdf#148040: without the fix in place, this would have failed with: // An uncaught exception of type com.sun.star.lang.IllegalArgumentException // because of disallowed external link update (needed to obtain the cell value).
css::uno::Any aResult = xFunc->callFunction(u"INDIRECT"_ustr, {css::uno::Any(aReference)});
CPPUNIT_ASSERT_EQUAL(css::uno::Any(u"a1"_ustr), aResult);
}
css::uno::Reference<css::document::XEmbeddedScripts> xDocScr(mxComponent, UNO_QUERY_THROW); auto xLibs = xDocScr->getBasicLibraries(); auto xLibrary = xLibs->createLibrary(u"TestLibrary"_ustr);
xLibrary->insertByName(
u"TestModule"_ustr,
uno::Any(
u"Function TestMergedSelection\n" // Insert test string into cell A1 " oActiveSheet = ThisComponent.CurrentController.ActiveSheet\n" " oActiveCell = oActiveSheet.getCellRangeByName(\"A1\")\n" " oActiveCell.setString(\"This is a test\")\n" // Merge A1:B2 cell range and return the content of the merged range " oRange = oActiveSheet.getCellRangeByName(\"A1:B2\")\n" " ThisComponent.getCurrentController.Select(oRange)\n" " oActiveCell = ThisComponent.CurrentSelection\n" " oActiveCell.Merge(True)\n" " TestMergedSelection = ThisComponent.getCurrentSelection().getString()\n" "End Function\n"_ustr));
Any aRet = executeMacro(u"vnd.sun.Star.script:TestLibrary.TestModule.TestMergedSelection?" "language=Basic&location=document"_ustr); // Without the fix in place, this test would have failed with // - Expression: false // - Unexpected dialog: Error: BASIC runtime error. // Property or method not found: getString.
CPPUNIT_ASSERT_EQUAL(Any(u"This is a test"_ustr), aRet);
}
css::uno::Reference<css::document::XEmbeddedScripts> xDocScr(mxComponent, UNO_QUERY_THROW); auto xLibs = xDocScr->getBasicLibraries(); auto xLibrary = xLibs->createLibrary(u"TestLibrary"_ustr);
xLibrary->insertByName(
u"TestModule"_ustr,
uno::Any(
u"Function TestExtendedMergedSelection\n" // Merge A1:B2 cell range " oActiveSheet = ThisComponent.CurrentController.ActiveSheet\n" " oRange = oActiveSheet.getCellRangeByName(\"A1:B2\")\n" " ThisComponent.getCurrentController.Select(oRange)\n" " oActiveCell = ThisComponent.CurrentSelection\n" " oActiveCell.Merge(True)\n" // Select A1:B3 range and check for its implementation name " oRange = oActiveSheet.getCellRangeByName(\"A1:B3\")\n" " ThisComponent.getCurrentController.Select(oRange)\n" " TestExtendedMergedSelection = ThisComponent.CurrentSelection.ImplementationName\n" "End Function\n"_ustr));
Any aRet = executeMacro(u"vnd.sun.Star.script:TestLibrary.TestModule.TestExtendedMergedSelection?" "language=Basic&location=document"_ustr); // Without the fix in place, this test would have failed with // - Expected : ScCellRangeObj // - Actual : ScCellObj // i.e. the selection was interpreted as a single cell instead of a range
CPPUNIT_ASSERT_EQUAL(Any(u"ScCellRangeObj"_ustr), aRet);
}
css::uno::Reference<css::document::XEmbeddedScripts> xDocScr(mxComponent, UNO_QUERY_THROW); auto xLibs = xDocScr->getBasicLibraries(); auto xLibrary = xLibs->createLibrary(u"TestLibrary"_ustr);
xLibrary->insertByName(
u"TestModule"_ustr,
uno::Any(u"Function TestClearContents\n" // Insert test string into cell A1 " oActiveSheet = ThisComponent.CurrentController.ActiveSheet\n" " oActiveCell = oActiveSheet.getCellRangeByName(\"A1\")\n" " oActiveCell.setString(\"Italic Test\")\n" // Create a text cursor and change the first letter to italic " oCursor = oActiveCell.Text.createTextCursor()\n" " oCursor.gotoStart(False)\n" " oCursor.goRight(1, True)\n" " oCursor.CharPosture = com.sun.star.awt.FontSlant.ITALIC\n" // Clear contents using EDITATTR cell flag to clear the italic char posture " oActiveCell.clearContents(com.sun.star.sheet.CellFlags.EDITATTR)\n" // Check the char posture of the first letter " oCursor.gotoStart(False)\n" " oCursor.goRight(1, True)\n" " TestClearContents = oCursor.CharPosture <> com.sun.star.awt.FontSlant.ITALIC\n" "End Function\n"_ustr));
Any aRet = executeMacro(u"vnd.sun.Star.script:TestLibrary.TestModule.TestClearContents?" "language=Basic&location=document"_ustr); // Without the fix in place, this test would have failed with // - Expected : true // - Actual : false // i.e. the formatting within parts of the cell contents (EDITATTR) were not deleted
CPPUNIT_ASSERT_EQUAL(Any(true), aRet);
}
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf159412)
{ // Run a macro, that itself calls two other functions using invoke, // passing a small integer value to arguments of types Long and Double
createScDoc("tdf159412.fods");
// Without the fix in place, this test would have failed with // - Expected: 1 Long/2 Double // - Actual : 0 Long/0 Double // i.e., the passed 1 and 2 values were lost.
auto currentRange = xSheetAddressable->getRangeAddress();
CPPUNIT_ASSERT_EQUAL(origSheetRange.Sheet, currentRange.Sheet);
CPPUNIT_ASSERT_EQUAL(origSheetRange.StartColumn, currentRange.StartColumn);
CPPUNIT_ASSERT_EQUAL(origSheetRange.StartRow, currentRange.StartRow);
CPPUNIT_ASSERT_EQUAL(origSheetRange.EndColumn, currentRange.EndColumn); // Without the fix, this would fail with // - Expected: 1048575 // - Actual : 0
CPPUNIT_ASSERT_EQUAL(origSheetRange.EndRow, currentRange.EndRow);
currentRange = xColAddressable->getRangeAddress();
CPPUNIT_ASSERT_EQUAL(origColRange.Sheet, currentRange.Sheet);
CPPUNIT_ASSERT_EQUAL(origColRange.StartColumn, currentRange.StartColumn); // Without the fix, this would fail with // - Expected: 0 // - Actual : 2
CPPUNIT_ASSERT_EQUAL(origColRange.StartRow, currentRange.StartRow);
CPPUNIT_ASSERT_EQUAL(origColRange.EndColumn, currentRange.EndColumn);
CPPUNIT_ASSERT_EQUAL(origColRange.EndRow, currentRange.EndRow);
currentRange = xRowAddressable->getRangeAddress();
CPPUNIT_ASSERT_EQUAL(origRowRange.Sheet, currentRange.Sheet); // Without the fix, this would fail with // - Expected: 0 // - Actual : 2
CPPUNIT_ASSERT_EQUAL(origRowRange.StartColumn, currentRange.StartColumn);
CPPUNIT_ASSERT_EQUAL(origRowRange.StartRow, currentRange.StartRow);
CPPUNIT_ASSERT_EQUAL(origRowRange.EndColumn, currentRange.EndColumn);
CPPUNIT_ASSERT_EQUAL(origRowRange.EndRow, currentRange.EndRow);
// tdf#167178: make sure that adding a sheet before the current one keeps the addressables // pointing to the correct sheet
// Without the fix, these were 0.
CPPUNIT_ASSERT_EQUAL(SCTAB(1), xSheetAddressable->getRangeAddress().Sheet);
CPPUNIT_ASSERT_EQUAL(SCTAB(1), xColAddressable->getRangeAddress().Sheet);
CPPUNIT_ASSERT_EQUAL(SCTAB(1), xRowAddressable->getRangeAddress().Sheet);
}
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf81003_DateCellToVbaUDF)
{ // The document contains a formula in B1 with a user-defined spreadsheet function from a // VBA-compatibility module, taking a date from A1. // Without the fix, this failed with // - Expression: xComponent.is() // - loading failed: file://.../vba-date.fods // because there was a failure evaluating the function at the loading time, and loading failed. // The reason was that the variable representing the cell as a VBA-compatibility object, with a // css::bridge::oleautomation::Date as its value, didn't convert to Basic's Date when passed to // the user-defined function:
createScDoc("vba-date.fods");
ScDocument* pDoc = getScDoc(); // Check value of B1. The serial date for 2025-08-29 is 45898.
CPPUNIT_ASSERT_EQUAL(45898.0, pDoc->GetValue(1, 0, 0));
}
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf168750)
{ // A class module's global names must not be visible without instantiated object
createScDoc("udf_plus_class_module.ods");
ScDocument* pDoc = getScDoc();
// B1 must have "FALSE", i.e. no errors happened during the load time. // Without the fix, this would fail with // - Unexpected dialog: Error: BASIC runtime error. Argument is not optional. // Which indicates, that the class module function was unexpectedly called.
CPPUNIT_ASSERT_EQUAL(u"FALSE"_ustr, pDoc->GetString(ScAddress(1, 0, 0)));
}
#ifdefined(_WIN32) // DDE calls work only on Windows currently
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testDdePoke)
{ // Get a document with a text in A1, and use its Basic macro to send that text into the // same document's B2 using DDEPoke call:
createScDoc("DdePoke.fods");
ScDocument* pDoc = getScDoc(); // A1 has a text:
CPPUNIT_ASSERT_EQUAL(u"Hello from Sender"_ustr, pDoc->GetString(ScAddress(0, 0, 0))); // B2 is empty initially:
CPPUNIT_ASSERT(pDoc->GetString(ScAddress(1, 1, 0)).isEmpty());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.