2017-06-18

26: To Read from and Write to Spread Sheet Cells, Part Four

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

Main Body START

How to Manipulate the String of an Arbitrary String Type 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'.

How Can We Manipulate the String of an Arbitrary String Type Spread Sheet Cell?

-Hypothesizer

Previously, we set an arbitrary string to an arbitrary spread sheet cell by erasing the existing string and setting the new string.

-Rebutter

So we did.

-Hypothesizer

We can also insert an arbitrary string in any position of the existing string, replace any area of the existing string with an arbitrary string, or erase any area of the existing string.

-Rebutter

We can also do so by getting the existing string, manipulating the gotten string in Java, erasing the existing string, and setting the manipulated string. Which is more efficient?

-Hypothesizer

When the existing string is very long, the latter is far more efficient. I don't know why, but manipulating the existing long string in the former way takes uncannily much CPU resource.

-Rebutter

What degree of length are you talking about?

-Hypothesizer

Thousands of characters. In our extremely low-speed computer, it takes about 20 seconds just to add one character.

-Rebutter

I know that the computer is extremely, extremely low-speed, but isn't the inner algorithm somehow inappropriate?

-Hypothesizer

I guess, such long strings aren't supposed to be set in spread sheet cells. I think, there should be a better algorithm if long strings are taken in consideration.

-Rebutter

What if the existing string isn't so long?

-Hypothesizer

I haven't measured precise performances in such cases. If we aren't processing large amount of data, there would be no noticeable difference.

-Rebutter

Well, we can judge it when we encounter the necessity. Anyway, is there any necessity for us to manipulate cell strings in the former way?

-Hypothesizer

Ah, there is a case which requires the former way. If parts of the existing string are formatted differently, we can't just replace the whole string.

-Rebutter

You mean, for example only a word in the string is italic?

-Hypothesizer

Yes. Of course we can replace the whole string and set the format again, but that may be cumbersome to do: we will have to acquire the existing formatting information of the whole string and reapply the format.

-Rebutter

Hmm, I don't know whether it's really cumbersome or not, but it seems natural to manipulate the existing string in the former way if the string isn't so long.

-Hypothesizer

If we want to apply formats part by part in a long cell string, we will have to contrive something.

-Rebutter

As we aren't handling a word processor, we don't seem to need intricate formats, but we may want to have markers to indicate certain words in the string.

-Hypothesizer

Ah, we may, but we won't delve into it right now.

-Rebutter

OK.

-Hypothesizer

As we did in the previous article, we get a 'com.sun.star.text.XTextCursor' instance from the representative cell UNO object using the 'com.sun.star.text.XText' UNO interface. The UNO interface, 'com.sun.star.text.XTextCursor', is a sub interface of 'com.sun.star.text.XTextRange', and represents a selected area of the string of the cell.

-Rebutter

So, the 'com.sun.star.text.XTextCursor' instance isn't just a single point cursor.

-Hypothesizer

When the selected area shrinks so that no character is selected, the 'com.sun.star.text.XTextCursor' instance becomes a single point cursor.

-Rebutter

I see.

-Hypothesizer

If we get a 'com.sun.star.text.XTextCursor' instance by the method, 'createTextCursor', the whole string is initially selected. By using the method, 'createTextCursorByRange', we can get a 'com.sun.star.text.XTextCursor' instance in which the cursor is placed at the beginning or at the end of the string.

-Rebutter

Oh.

-Hypothesizer

The cursor can be moved to right or left by the method 'goRight' or 'goLeft', respectively. In those methods, we can specify by how many characters the cursor should be moved.

The cursor can be moved to the beginning or to the end of the string by the method 'gotoStart' or 'gotoEnd', respectively.

-Rebutter

How can we select an arbitrary area of the string?

-Hypothesizer

Those four methods have an argument in which we specify whether the selected area should be expanded.

-Rebutter

Hmm, I guess, if we want to select an arbitrary area, we can move the cursor to the left border of the area with the argument off, and then, move the cursor to the right border of the area with the argument on.

-Hypothesizer

Yes. Of course, we can do it backward, placing the cursor to the right border of the area and expanding to left.

-Rebutter

I see.

-Hypothesizer

After we adjusted the state of the cursor, we insert an arbitrary string by calling the 'insertString' method of the 'com.sun.star.text.XText' UNO interface. We pass the 'com.sun.star.text.XTextCursor' instance and the string to be inserted as the first and the second arguments, respectively. The third argument specifies whether the selected area should be replaced. If not, the new string will be inserted in front of the selected area.

-Rebutter

After the string is inserted, what will be the state of the cursor?

-Hypothesizer

Whether the selected area is replaced or not, the cursor is placed after the inserted string as a single point cursor.

-Rebutter

Ah-ha.

-Hypothesizer

If we want to erase the selected area, we can call the method, 'insertString' with the empty string replacing the area.

-Rebutter

I see.

-Hypothesizer

After all, I have written this code after the code of the previous article.

@Java Source Code
   // Manipulates the string of a spread sheet cell START
   // Sets the spread sheet cell, H1, with a string value, '0123456789', as the preparation START
   try {
    l_spreadSheetCellInXCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (7, 0);
   }
   catch (com.sun.star.lang.IndexOutOfBoundsException l_exception) {
    Publisher.show (l_exception.toString ());
   }
   XPropertySet l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCellInXCell);
   l_spreadSheetCellInXPropertySet.setPropertyValue ("NumberFormat", new Integer (l_stringExpressionFormatKey));
   l_spreadSheetCellInXCell.setFormula ("");
   XText l_spreadSheetCellInXText = (XText) UnoRuntime.queryInterface (XText.class, l_spreadSheetCellInXCell);
   XTextCursor l_textCursorInXTextCursor = l_spreadSheetCellInXText.createTextCursor ();
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "0123456789", true);
   // Sets a spread sheet cell with a string value as the preparation END
   l_textCursorInXTextCursor = l_spreadSheetCellInXText.createTextCursorByRange (l_spreadSheetCellInXText.getEnd ());
   l_textCursorInXTextCursor.gotoStart (false);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "A", true);
   l_textCursorInXTextCursor.goRight ( (short) 1,false);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "B", true);
   l_textCursorInXTextCursor.goRight ( (short) 1, false);
   l_textCursorInXTextCursor.goRight ( (short) 1, true);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "C", true);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "D", true);
   l_textCursorInXTextCursor.gotoEnd (false);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "E", true);
   l_textCursorInXTextCursor.goLeft ( (short) 2, false);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "F", true);
   l_textCursorInXTextCursor.goLeft ( (short) 2, false);
   l_textCursorInXTextCursor.goLeft ( (short) 1, true);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "G", true);
   l_textCursorInXTextCursor.goLeft ( (short) 2, false);
   l_textCursorInXTextCursor.goLeft ( (short) 1, true);
   l_spreadSheetCellInXText.insertString (l_textCursorInXTextCursor, "", true);
   // Manipulates the string of a spread sheet cell END

-Rebutter

We have first forcefully set the spread sheet cell, 'H1', with a string value, '0123456789', and then, manipulated the string value.

-Hypothesizer

Yes. As we need an existing string value cell as the preparation, we did that preparation at the beginning of the code.

-Rebutter

We have gotten the cursor initially placed at the end of the existing string, and moved it to the beginning of the string.

-Hypothesizer

Yes. Of course, we can get the cursor initially placed at the beginning of the existing string. We have done as we did, in order to demonstrate calling the 'gotoStart' method.

-Rebutter

I know.

-Hypothesizer

The final cell string must be "A0B1CD346G8F9E".

In fact, we have implemented the above code into the test project included in the zip file cited in a previous article. How to use the zip file is described in the article.

Main Body END

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