2017-05-28

23: To Read from and Write to Spread Sheet Cells, Part One

<The previous article in this series | The table of contents of this series | The next article in this series>

Main Body START

How to Get Access to an Arbitrary Spread Sheet Cell from Java or Basic Macro Programs Is Explained

About: UNO (Universal Network Objects)

About: LibreOffice

About: Apache OpenOffice

About: Java Programming Language

A Note

This series is about developing UNO extensions that consist of Java UNO components, but most of its descriptions also apply to using UNO in external Java programs or Basic macros (handling spread sheets is inevitably using UNO because spread sheets are UNO objects). The only difference for using UNO in external Java programs is how to get the component context, and the difference is dealt with in the series, 'How to Use UNO (Handle LibreOffice or Apache OpenOffice Documents) in External Java Programs'. As for using UNO in Basic macros, in addition to how to get the component context, there are some other differences, and those differences are dealt with in the series, 'Notes About Using UNO (Handling LibreOffice or Apache OpenOffice Documents) in Basic Macros'.

Reading from or Writing to Spread Sheet Cells Is Handling UNO Objects

-Hypothesizer

Now, we know how to develop UNO extensions. However, we will probably want to interact with LibreOffice documents.

-Rebutter

Or as we wanted to interact with LibreOffice documents, we began to learn how to develop UNO extensions.

-Hypothesizer

. . . Yes. That's the correct order. Especially, we have wanted to read from and write to spread sheet cells.

-Rebutter

Well, I understand that that is a typical concern when handling spread sheets is concerned.

-Hypothesizer

As spread sheets documents are composed of instances of specific UNO components, we have to learn what those UNO components are and how to handle instances of those UNO components.

-Rebutter

Although someone who isn't familiar with the term, UNO, might think, "UNO? What's UNO? I'm not interested in such a thing; I just want to read from and write to spread sheet cells.", . . .

-Hypothesizer

As spread sheet cells are UNO objects and handling spread sheet cells is inevitably using UNO, he or she is certainly interested in UNO.

What Is the Spread Sheets Document? What Is the Spread Sheet? What Is the Spread Sheet Cell?

-Rebutter

First, we will have to clarify our usage of terms.

-Hypothesizer

What terms?

-Rebutter

For example, 'spread sheet'.

-Hypothesizer

Isn't what 'spread sheet' means obvious?

-Rebutter

I sometimes don't know whether a 'spread sheet' means a spread sheet, a spread sheets document, or a spread sheets document file.

-Hypothesizer

Ah, when we mention a 'spread sheet', it's definitely a spread sheet, not a spread sheets document nor a spread sheets document file. You know, our major principle is to state things as unambiguously as possible while using a term for multiple meanings is a major cause of ambiguity.

-Rebutter

So, what is the spread sheets document?

-Hypothesizer

The spread sheets document is a UNO object that bundles multiple spread sheets (although there are cases in which only one spread sheet is bundled).

-Rebutter

We also distinguish 'spread sheets document file' from 'spread sheets document', don't we?

-Hypothesizer

Yes, we do. The spread sheets document file is a file that is a bits array that is the result of the serialization of a spread sheets document.

-Rebutter

So, the spread sheets document file is not a UNO object.

-Hypothesizer

No, it isn't.

Anyway, in UNO programming, It's important for us to know what UNO interfaces a UNO component implements: unless we know them, we can't call methods of the UNO component. So, we will list the UNO interfaces that the spread sheets document component implements . . .

-Rebutter

We don't have to know all the UNO interfaces just in order to read from and write to spread sheet cells, do we?

-Hypothesizer

Certainly, not: we will use just a few UNO interfaces for that purpose. However, this list will be useful in the future when we want to do more things.

-Rebutter

So, we don't need to peruse this list right now, but we can come back here when necessary.

-Hypothesizer

Yes. The spread sheets document component implements these UNO interfaces.

  • com.sun.star.container.XChild
  • com.sun.star.document.XDocumentPropertiesSupplier
  • com.sun.star.document.XCmisDocument
  • com.sun.star.rdf.XDocumentMetadataAccess
  • com.sun.star.document.XDocumentRecovery
  • com.sun.star.document.XUndoManagerSupplier
  • com.sun.star.document.XEventBroadcaster
  • com.sun.star.document.XDocumentEventBroadcaster
  • com.sun.star.lang.XEventListener
  • com.sun.star.document.XEventsSupplier
  • com.sun.star.document.XEmbeddedScripts
  • com.sun.star.document.XScriptInvocationContext
  • com.sun.star.frame.XModel2
  • com.sun.star.util.XModifiable2
  • com.sun.star.view.XPrintable
  • com.sun.star.view.XPrintJobBroadcaster
  • com.sun.star.frame.XStorable2
  • com.sun.star.frame.XLoadable
  • com.sun.star.script.XStarBasicAccess
  • com.sun.star.document.XViewDataSupplier
  • com.sun.star.util.XCloseable
  • com.sun.star.datatransfer.XTransferable
  • com.sun.star.document.XDocumentSubStorageSupplier
  • com.sun.star.document.XStorageBasedDocument
  • com.sun.star.script.provider.XScriptProviderSupplier
  • com.sun.star.ui.XUIConfigurationManagerSupplier
  • com.sun.star.embed.XVisualObject
  • com.sun.star.lang.XUnoTunnel
  • com.sun.star.frame.XModule
  • com.sun.star.frame.XTitle
  • com.sun.star.frame.XTitleChangeBroadcaster
  • com.sun.star.frame.XUntitledNumbers
  • com.sun.star.lang.XTypeProvider
  • com.sun.star.uno.XWeak
  • com.sun.star.sheet.XSpreadsheetDocument
  • com.sun.star.document.XActionLockable
  • com.sun.star.sheet.XCalculatable
  • com.sun.star.util.XProtectable
  • com.sun.star.drawing.XDrawPagesSupplier
  • com.sun.star.sheet.XGoalSeek
  • com.sun.star.sheet.XConsolidatable
  • com.sun.star.sheet.XDocumentAuditing
  • com.sun.star.style.XStyleFamiliesSupplier
  • com.sun.star.view.XRenderable
  • com.sun.star.document.XLinkTargetSupplier
  • com.sun.star.beans.XPropertySet
  • com.sun.star.lang.XMultiServiceFactory
  • com.sun.star.lang.XServiceInfo
  • com.sun.star.util.XChangesNotifier
  • com.sun.star.sheet.opencl.XOpenCLSelection
  • com.sun.star.util.XNumberFormatsSupplier
  • com.sun.star.lang.XUnoTunnel
  • com.sun.star.lang.XTypeProvider
  • com.sun.star.uno.XWeak
  • com.sun.star.uno.XAggregation
-Rebutter

Well, it implements many UNO interfaces . . .

Then, what is the spread sheet?

-Hypothesizer

The spread sheet is a UNO object that bundles spread sheet cells. As is well-known, on the display, a tab on an arbitrary spread sheets document frame represents a spread sheet.

The spread sheet component implements these UNO interfaces.

  • com.sun.star.beans.XPropertySet
  • com.sun.star.beans.XMultiPropertySet
  • com.sun.star.beans.XPropertyState
  • com.sun.star.sheet.XSheetOperation
  • com.sun.star.chart.XChartDataArray
  • com.sun.star.util.XIndent
  • com.sun.star.sheet.XCellRangesQuery
  • com.sun.star.sheet.XFormulaQuery
  • com.sun.star.util.XReplaceable
  • com.sun.star.util.XModifyBroadcaster
  • com.sun.star.lang.XServiceInfo
  • com.sun.star.lang.XUnoTunnel
  • com.sun.star.lang.XTypeProvider
  • com.sun.star.sheet.XCellRangeAddressable
  • com.sun.star.sheet.XSheetCellRange
  • com.sun.star.sheet.XArrayFormulaRange
  • com.sun.star.sheet.XArrayFormulaTokens
  • com.sun.star.sheet.XCellRangeData
  • com.sun.star.sheet.XCellRangeFormula
  • com.sun.star.sheet.XMultipleOperation
  • com.sun.star.util.XMergeable
  • com.sun.star.sheet.XCellSeries
  • com.sun.star.table.XAutoFormattable
  • com.sun.star.util.XSortable
  • com.sun.star.sheet.XSheetFilterableEx
  • com.sun.star.sheet.XSubTotalCalculatable
  • com.sun.star.table.XColumnRowRange
  • com.sun.star.util.XImportable
  • com.sun.star.sheet.XCellFormatRangesSupplier
  • com.sun.star.sheet.XUniqueCellFormatRangesSupplier
  • com.sun.star.sheet.XSpreadsheet
  • com.sun.star.container.XNamed
  • com.sun.star.sheet.XSheetPageBreak
  • com.sun.star.sheet.XCellRangeMovement
  • com.sun.star.table.XTableChartsSupplier
  • com.sun.star.sheet.XDataPilotTablesSupplier
  • com.sun.star.sheet.XScenariosSupplier
  • com.sun.star.sheet.XSheetAnnotationsSupplier
  • com.sun.star.drawing.XDrawPageSupplier
  • com.sun.star.sheet.XPrintAreas
  • com.sun.star.sheet.XSheetAuditing
  • com.sun.star.sheet.XSheetOutline
  • com.sun.star.util.XProtectable
  • com.sun.star.sheet.XScenario
  • com.sun.star.sheet.XScenarioEnhanced
  • com.sun.star.sheet.XSheetLinkable
  • com.sun.star.sheet.XExternalSheetName
  • com.sun.star.document.XEventsSupplier
-Rebutter

What is the spread sheet cell?

-Hypothesizer

The spread sheet cell is a UNO object that represents one of cells that are placed on the grid on a spread sheet.

-Rebutter

Well, we can merge a rectangle of cells, can't we?

-Hypothesizer

Yes, . . . and?

-Rebutter

And do we call the rectangle a cell?

-Hypothesizer

Well, I wonder. . . . From the viewpoint of UNO programming, the rectangle isn't a cell, in the meaning that the rectangle doesn't implement the UNO interface, 'com.sun.star.table.XCell'. However, from the viewpoint of us as users, the rectangle is a cell: we handle the rectangle as though it is a normal cell. . . . In our discussions, not calling the rectangle a cell would be inconvenient, for when we talk of cells, such rectangles of merged cells are included in our intention, in most cases.

-Rebutter

However, we will sometimes have to talk specifically about cells in the UNO programming sense.

-Hypothesizer

Yes. . . . We will call them 'atomic cells'.

-Rebutter

Is a merged cell, meaning a cell in a rectangle of merged cells, an atomic cell?

-Hypothesizer

Yes. Any atomic cell always keeps to be an atomic cell whether it has become a merged cell or remains an independent cell, as any atom doesn't cease to be an atom by being included in a molecule.

So, in our terminology, the 'atomic cell' is an indivisible cell whether it is an unmerged cell or a member of a rectangle of merged cells; the 'compound cell' is a rectangle of merged cells; the 'cell' is an atomic cell or a compound cell. . . . And we will call the top leftmost atomic cell of any compound cell the 'representative cell' of the compound cell, and the unmerged cell will be the representative cell of itself.

-Rebutter

We need the last term because . . .

-Hypothesizer

Because we handle the top leftmost atomic cell when we read from and write to any compound cell.

-Rebutter

So, we can say, "When we read from or write to an arbitrary cell, we handle the representative cell of the cell".

-Hypothesizer

Yes.

. . . Well, I can guess that such an attempt at exact distinctions are vexatious for many people, but that's necessary in order to be accurate . . .

-Rebutter

Can you?

-Hypothesizer

Certainly, but to be less accurate to be less vexatious isn't our option.

-Rebutter

Of course.

-Hypothesizer

Anyway, the spread sheet atomic cell component implements these UNO interfaces.

  • com.sun.star.beans.XPropertySet
  • com.sun.star.beans.XMultiPropertySet
  • com.sun.star.beans.XPropertyState
  • com.sun.star.sheet.XSheetOperation
  • com.sun.star.chart.XChartDataArray
  • com.sun.star.util.XIndent
  • com.sun.star.sheet.XCellRangesQuery
  • com.sun.star.sheet.XFormulaQuery
  • com.sun.star.util.XReplaceable
  • com.sun.star.util.XModifyBroadcaster
  • com.sun.star.lang.XServiceInfo
  • com.sun.star.lang.XUnoTunnel
  • com.sun.star.lang.XTypeProvider
  • com.sun.star.sheet.XCellRangeAddressable
  • com.sun.star.sheet.XSheetCellRange
  • com.sun.star.sheet.XArrayFormulaRange
  • com.sun.star.sheet.XArrayFormulaTokens
  • com.sun.star.sheet.XCellRangeData
  • com.sun.star.sheet.XCellRangeFormula
  • com.sun.star.sheet.XMultipleOperation
  • com.sun.star.util.XMergeable
  • com.sun.star.sheet.XCellSeries
  • com.sun.star.table.XAutoFormattable
  • com.sun.star.util.XSortable
  • com.sun.star.sheet.XSheetFilterableEx
  • com.sun.star.sheet.XSubTotalCalculatable
  • com.sun.star.table.XColumnRowRange
  • com.sun.star.util.XImportable
  • com.sun.star.sheet.XCellFormatRangesSupplier
  • com.sun.star.sheet.XUniqueCellFormatRangesSupplier
  • com.sun.star.table.XCell
  • com.sun.star.sheet.XCellAddressable
  • com.sun.star.text.XText
  • com.sun.star.container.XEnumerationAccess
  • com.sun.star.sheet.XSheetAnnotationAnchor
  • com.sun.star.text.XTextFieldsSupplier
  • com.sun.star.document.XActionLockable
  • com.sun.star.sheet.XFormulaTokens
  • com.sun.star.table.XCell2

How Can We Get the Current Spread Sheet?

-Hypothesizer

Although we now know what UNO interfaces those UNO components implement, first, we have to get references to UNO objects.

-Rebutter

Of course.

-Hypothesizer

A typical use case will be to get a reference to the current spread sheet.

-Rebutter

By 'current', you mean the spread sheet that has the focus right now?

-Hypothesizer

Yes. We can do that like this, where 'i_componentContextInXComponentContext' is the component context (how to get it in an arbitrary UNO extension is described here; how we get it in an arbitrary external UNO program is described here; how to get it in an arbitrary Basic macro is described here).

@Java Source Code
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XModel;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetView;
import thebiasplanet.coreutilities.messaging.Publisher;

  XDesktop l_unoDesktopInXDesktop = null;
  try {
   l_unoDesktopInXDesktop = (XDesktop) UnoRuntime.queryInterface (XDesktop.class, i_componentContextInXComponentContext.getServiceManager ().createInstanceWithContext ("com.sun.star.frame.Desktop", i_componentContextInXComponentContext));
  }
  catch (com.sun.star.uno.Exception l_exception) {
   Publisher.show (l_exception.toString ());
  }
  
  // Gets the current spread sheets document START
  XSpreadsheetDocument l_currentSpreadSheetsDocumentInXSpreadsheetDocument = (XSpreadsheetDocument) UnoRuntime.queryInterface (XSpreadsheetDocument.class, l_unoDesktopInXDesktop.getCurrentComponent ());
  if (l_currentSpreadSheetsDocumentInXSpreadsheetDocument != null) {
   Publisher.show (l_currentSpreadSheetsDocumentInXSpreadsheetDocument.toString ());
  }
  else {
   Publisher.show ("No spread sheets document is current.");
   return "No spread sheets document is current.";
  }
  // Gets the current spread sheets document END
  
  // Gets the current spread sheet START
  XModel l_currentSpreadSheetsDocumentModelInXModel = (XModel) UnoRuntime.queryInterface (XModel.class, l_currentSpreadSheetsDocumentInXSpreadsheetDocument);
  XSpreadsheetView  l_currentSpreadSheetsDocumentViewInXSpreadsheetView = (XSpreadsheetView) UnoRuntime.queryInterface (XSpreadsheetView.class, l_currentSpreadSheetsDocumentModelInXModel.getCurrentController ());
  XSpreadsheet l_currentSpreadSheetInXSpreadsheet  = l_currentSpreadSheetsDocumentViewInXSpreadsheetView.getActiveSheet ();
  Publisher.show (l_currentSpreadSheetInXSpreadsheet.toString ());
  // Gets the current spread sheet END

-Hypothesizer

If you don't understand what 'UnoRuntime.queryInterface' does, you will have to look back at here; 'i_componentContextInXComponentContext.getServiceManager ().createInstanceWithContext' creates a UNO object from the global UNO services manager.

-Rebutter

I understand the code all right. 'l_currentSpreadSheetInXSpreadsheet' is the current spread sheet, and the current spread sheet document is already gotten as 'l_currentSpreadSheetsDocumentInXSpreadsheetDocument'.

Anyway, it's cumbersome just to get the current spread sheet.

-Hypothesizer

Basically, handling UNO objects is cumbersome because a UNO object implements many UNO interfaces, and we have to get a UNO proxy for each UNO interface we intend to use. As it's cumbersome, we will later create utility classes and wrapper classes for our convenience.

-Rebutter

All right.

By the way, it looks like we have created an instance of the service, 'com.sun.star.frame.Desktop'. Isn't that service a singleton? I mean, the desktop should be one and already exist. It seems odd to create multiple desktops.

-Hypothesizer

Well, it seems a singleton. So, the 'createInstanceWithContext' method doesn't seem to necessarily create an instance, regardless of the name.

-Rebutter

How can the 'createInstanceWithContext' method return a singleton? I mean, in the way we developed our first and second sample UNO extensions, we can't make the 'createInstanceWithContext' method return a singleton.

-Hypothesizer

I don't know. I can't find any explanation about that in the reference documents. We created a singleton, but not in a way in which we can get the singleton instance from the global UNO service manager.

-Rebutter

Well, we may have to investigate it in the future.

How Can We Get an Arbitrary Spread Sheet of an Arbitrary Spread Sheets Document?

-Hypothesizer

If we want to get a reference to another spread sheet of the spread sheets document, we can get it like this.

@Java Source Code
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.lang.WrappedTargetException;

  // Gets another spread sheet START
  XSpreadsheets l_currentSpreadSheetsInXSpreadsheets = l_currentSpreadSheetsDocumentInXSpreadsheetDocument.getSheets ();
  XSpreadsheet l_anotherSpreadSheetInXSpreadsheet = null;
  try {
   l_anotherSpreadSheetInXSpreadsheet = (XSpreadsheet) UnoRuntime.queryInterface(XSpreadsheet.class, l_currentSpreadSheetsInXSpreadsheets.getByName ("Sheet2"));
   Publisher.show (l_anotherSpreadSheetInXSpreadsheet.toString ());
  }
  catch (NoSuchElementException | WrappedTargetException l_exception) {
   Publisher.show (l_exception.toString ());
  }
  // Gets another spread sheet END

-Rebutter

We can get it by the spread sheet name.

-Hypothesizer

Yes. Although we don't show here, we can also get it by the index of the spread sheet in the spread sheets contained in the spread sheets document.

-Rebutter

Although we used the current spread sheets document here, the spread sheets document can be any spread sheets document if we get a reference to it?

-Hypothesizer

Of course.

How Can We Get an Arbitrary Atomic Cell of an Arbitrary Spread Sheet?

-Hypothesizer

If we want to get a reference to an arbitrary spread sheet atomic cell on the spread sheet, we can get it like this, where 2 is the column index and 0 is the row index.

@Java Source Code
import com.sun.star.table.XCell;

  // Gets a spread sheet cell START
  XCell l_spreadSheetCellInXCell = null;
  try {
   l_spreadSheetCellInXCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (2, 0);
   Publisher.show (l_spreadSheetCellInXCell.toString ());
  }
  catch (com.sun.star.lang.IndexOutOfBoundsException l_exception) {
   Publisher.show (l_exception.toString ());
  }
  // Gets a spread sheet cell END

-Rebutter

Column indexes and row indexes start from 0.

-Hypothesizer

Yes.

-Rebutter

Again, the spread sheet can be any spread sheet?

-Hypothesizer

Yes.

How Can We Get the Representative Cell of the Current Spread Sheet Cell?

Postscript:
To be more accurate, what we get here is the first selected atomic cell (the first atomic cell among the selected cells), not necessarily the representative cell of the current cell. The difference between the current cell and the selected cells is described here. At the time of writing this article, we weren't concerned with the difference. In cases in which we use only single cell selections, the first selected atomic cell is identical with the representative cell of the current cell.

-Hypothesizer

We can get the reference to any spread sheet atomic cell on the spread sheet, by the spread sheet atomic cell column index and row index, but sometimes we will want to get the reference to the representative cell of the current spread sheet cell.

-Rebutter

That is a possibility.

-Hypothesizer

We can get it like this.

@Java Source Code
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.XInterface;
import com.sun.star.sheet.XSheetCellRange;
import com.sun.star.sheet.XSheetCellRangeContainer;
  
  // Gets the current spread sheet cell START
  XInterface l_currentSelectionInXInterface = (XInterface) UnoRuntime.queryInterface (XInterface.class, l_currentSpreadSheetsDocumentInXModel.getCurrentSelection ());
  XSheetCellRange l_currentCellsInXSheetCellRange = (XSheetCellRange) UnoRuntime.queryInterface (XSheetCellRange.class, l_currentSelectionInXInterface);
  if (l_currentCellsInXSheetCellRange == null) {
   XSheetCellRangeContainer l_currentCellsInXSheetCellRangeContainer = (XSheetCellRangeContainer) UnoRuntime.queryInterface (XSheetCellRangeContainer.class, l_currentSelectionInXInterface);
   if (l_currentCellsInXSheetCellRangeContainer != null) {
    try {
     l_currentCellsInXSheetCellRange = (XSheetCellRange) AnyConverter.toObject (XSheetCellRange.class , l_currentCellsInXSheetCellRangeContainer.getByIndex (0));
    }
    catch (com.sun.star.lang.IndexOutOfBoundsException | WrappedTargetException l_exception) {
     Publisher.show (l_exception.toString ());
    }
   }
   else {
   }
  }
  XCell l_currentSpreadSheetCellInXCell = null;
  if (l_currentCellsInXSheetCellRange != null) {
   try {
    l_currentSpreadSheetCellInXCell = l_currentCellsInXSheetCellRange.getCellByPosition (0, 0);
    Publisher.show (l_currentSpreadSheetCellInXCell.toString ());
   }
   catch (com.sun.star.lang.IndexOutOfBoundsException l_exception) {
    Publisher.show (l_exception.toString ());
   }
  }
  else {
   Publisher.show ("No cell seems to be selected.");
  }
  // Gets the current spread sheet cell END

How Can We Open an Arbitrary Spread Sheets Document File?

-Rebutter

So far, we have talked on the precondition that the spread sheets document to be accessed is already loaded into LibreOffice and current. How can we open an arbitrary spread sheets document file?

-Hypothesizer

We can open an arbitrary spread sheets document file like this.

@Java Source Code
import com.sun.star.util.XCloseable;
import com.sun.star.util.CloseVetoException;
import com.sun.star.frame.FrameSearchFlag;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable2;
import com.sun.star.beans.PropertyValue;

  // Opens and closes a spread sheets document file START
  XStorable2 l_currentSpreadSheetsDocumentInXStorable2 = (XStorable2) UnoRuntime.queryInterface (XStorable2.class, l_currentSpreadSheetsDocumentInXSpreadsheetDocument);
  String l_currentDocumentUrl = l_currentSpreadSheetsDocumentInXStorable2.getLocation ();
  String l_openedDocumentUrl = String.format ("%s%s", l_currentDocumentUrl.substring (0, l_currentDocumentUrl.lastIndexOf ("/") + 1), "TestSpreadSheetsDocument1.ods");
  XComponentLoader l_unoDesktopInXComponentLoader = (XComponentLoader) UnoRuntime.queryInterface (XComponentLoader.class, l_unoDesktopInXDesktop);
  PropertyValue [] l_loadPropertiesArray = new PropertyValue [2];
  PropertyValue l_loadProperty = null;
  l_loadProperty = new PropertyValue ();
  l_loadProperty.Name = "ReadOnly";
  l_loadProperty.Value = Boolean.valueOf (false);
  l_loadPropertiesArray [0] = l_loadProperty;
  l_loadProperty = new PropertyValue ();
  l_loadProperty.Name = "Hidden";
  l_loadProperty.Value = Boolean.valueOf (false);
  l_loadPropertiesArray [1] = l_loadProperty;
  XSpreadsheetDocument l_openedSpreadSheetsDocumentInXSpreadsheetDocument = null;
  try {
   l_openedSpreadSheetsDocumentInXSpreadsheetDocument = UnoRuntime.queryInterface (XSpreadsheetDocument.class, l_unoDesktopInXComponentLoader.loadComponentFromURL (l_openedDocumentUrl.replaceAll ("\\\\", "/"), "_blank", FrameSearchFlag.CREATE, l_loadPropertiesArray));
   Publisher.show (l_openedSpreadSheetsDocumentInXSpreadsheetDocument.toString ());
   XCloseable l_openedSpreadSheetsDocumentInXSpreadsheetDocumentInXCloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, l_openedSpreadSheetsDocumentInXSpreadsheetDocument);
   l_openedSpreadSheetsDocumentInXSpreadsheetDocumentInXCloseable.close (false); 
  }
  catch (com.sun.star.io.IOException | CloseVetoException l_exception) {
   Publisher.show (l_exception.toString ());
  }
  // Opens and closes a spread sheets document file END

-Rebutter

Um? What are we doing using 'XStorable2'?

-Hypothesizer

We are on the premise that the spread sheets document file, 'TestSpreadSheetsDocument1.ods', is in the same directory with the file of the current spread sheets document, and are getting the URL of 'TestSpreadSheetsDocument1.ods' using the URL of the current spread sheets document file. If we want to directly specify the URL of the opened file, we don't have to do such a thing.

-Rebutter

I see.

-Hypothesizer

Our test code (in fact, it also includes the logics described in some following articles) is here. To test, we have to build the projects (how to build projects is described here); import a Basic library, 'UnoExtensionsTests', which is in the 'execution' directory of the 'testUnoExtensionToDisclose' project (how to import a Basic library is described here); open 'TestSpreadSheetsDocumentForExecutingTests.ods' in the 'execution' directory; push the 'Test1' button on the 'Tests' spread sheet.

-Rebutter

Isn't it dangerous to import a Basic library and execute a Macro program as we are told?

-Hypothesizer

Ah, of course, we should never do such a thing blindly. After we imported the library (just importing won't do any harm), peruse the contents of the library, and only if we happen to be satisfied that it's safe, we should push the button.

-Rebutter

What if we are worried about just importing?

-Hypothesizer

Then, open the files in the 'UnoExtensionsTests' directory, in a text editor: we can see the contents in the text editor.

Main Body END

<The previous article in this series | The table of contents of this series | The next article in this series>