<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>setDataArray &#8211; tutolibro.org</title>
	<atom:link href="https://tutolibro.org/tag/setdataarray/feed/" rel="self" type="application/rss+xml" />
	<link>https://tutolibro.org</link>
	<description>Free online tutorials</description>
	<lastBuildDate>Tue, 18 Nov 2025 22:58:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://tutolibro.org/wp-content/uploads/2020/02/cropped-logo_mini-32x32.png</url>
	<title>setDataArray &#8211; tutolibro.org</title>
	<link>https://tutolibro.org</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">173775150</site>	<item>
		<title>LibreOffice Calc &#038; Python: part 9 &#8211; Reverse the order of cells content from a cell range</title>
		<link>https://tutolibro.org/2021/05/07/python-libreoffice-reverse-the-order-of-cells-content-from-a-cell-range/</link>
					<comments>https://tutolibro.org/2021/05/07/python-libreoffice-reverse-the-order-of-cells-content-from-a-cell-range/#comments</comments>
		
		<dc:creator><![CDATA[gweno]]></dc:creator>
		<pubDate>Fri, 07 May 2021 18:27:08 +0000</pubDate>
				<category><![CDATA[Calc]]></category>
		<category><![CDATA[LibreOffice]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[calc]]></category>
		<category><![CDATA[cell type]]></category>
		<category><![CDATA[libreoffice]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setDataArray]]></category>
		<guid isPermaLink="false">https://tutolibro.tech/?p=1070</guid>

					<description><![CDATA[Using the code created in part 8, in this part 9 we are going to manipulate the data with functions getDataArray, setDataArray and Python Tuples. In this first example we are going to reverse the order of data within a...<br /><a class="read-more-button" href="https://tutolibro.org/2021/05/07/python-libreoffice-reverse-the-order-of-cells-content-from-a-cell-range/">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p>Using the code created in <a href="https://tutolibro.org/2020/07/10/libreoffice-calc-python-programming-part-7-from-cells-range-to-python-tuple/">part 8</a>, in this part 9 we are going to manipulate the data with functions getDataArray, setDataArray and Python Tuples. In this first example we are going to reverse the order of data within a cell range.</p>



<p class="has-small-font-size"><em>edit 30/09/2021: Thanks to karolus for pointing out a few mistakes and for suggesting improvements for this tutorial.</em></p>



<h4 class="wp-block-heading">Here is the plan for this tutorial:</h4>



<ul class="wp-block-list"><li><strong>Prepare your file</strong></li><li><strong>Some useful functions</strong></li><li><strong>How to increment a tuple</strong></li><li><strong>Try in the console</strong></li><li><strong>Increment tuple step by step</strong></li><li><strong>Use built-in functions &#8216;tuple&#8217; and &#8216;reversed&#8217; together</strong></li><li><strong>Full ReverseRange.py file</strong></li><li><strong>Walk through the code</strong></li><li><strong>Test the code</strong></li></ul>



<h4 class="wp-block-heading">Prepare your file</h4>



<p>We start with creating a new folder, I named mine &#8216;part 9&#8217;, in the python scripts folder for LibreOffice. Depending on your OS, it will be at a specific location in your user folder. Within that location you can organise your python scripts the way you want and each folder will be seen as a module within the LibreOffice Python Script manager.<br>This part 9 will re-use some of the code from <a href="https://tutolibro.org/2020/07/17/libreoffice-calc-python-programming-part-8-from-python-tuple-to-cells-range/">part 8</a>  (also available on <a rel="noreferrer noopener" href="https://github.com/Gweno/tutolibro.tech/tree/master/lopy/part8" target="_blank">my gitHub repository</a>).</p>



<p>I named the file for this tutorial  &#8216;ReverseRange.py&#8217;.</p>



<p>Check my tutorial <a href="https://tutolibro.org/2019/08/16/libreoffice-calc-python-programming-part-2-hello-world/">hello world</a> if you need help to get started with python scripts for LibreOffice.</p>



<p>I usually assign a button or a keyboard shortcut to the main() program of my new python file. This is explained in <a href="https://tutolibro.org/2020/03/11/libreoffice-calc-python-programming-annex-1-assign-a-python-macro-to-a-key/">tutorial Annex 1</a>.</p>



<p>If you are starting from <a href="https://tutolibro.org/2020/07/17/libreoffice-calc-python-programming-part-8-from-python-tuple-to-cells-range/">part 8</a> code,  I am not using a <strong>context()</strong> function anymore to define the global variable needed for pyUNO, but instead I declare them at the global scope straight away. This make things easier and avoid repeating calling context in every function that need the global variables.</p>



<p>So this code below:</p>



<pre class="wp-block-code"><code>def context():
    
    # set global variables for context
    
    global desktop
    global model
    global active_sheet
    
    # get the doc from the scripting context 
    # which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    
    # access the active sheet
    active_sheet = model.CurrentController.ActiveSheet</code></pre>



<p><strong>Is replaced by:</strong></p>



<pre class="wp-block-code"><code># set global variables for context
    
# get the doc from the scripting context 
# which is made available to all scripts
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()

# access the active sheet
active_sheet = model.CurrentController.ActiveSheet</code></pre>



<h4 class="wp-block-heading">Some useful functions</h4>



<p>I also replaced the section that is calculating Cell addresses from the current Range selection, by a simpler function returning a new range with horizontal and vertical offset as arguments. These two arguments having a default value  of 0.</p>



<pre class="wp-block-code"><code>def getSelectionAddresses(horizontalOffset = 0 , verticalOffset = 0):
    # get the range of addresses from selection
    oSelection = model.getCurrentSelection()
    oArea = oSelection.getRangeAddress()
    return oArea.StartColumn + horizontalOffset, oArea.StartRow + verticalOffset, oArea.EndColumn + horizontalOffset, oArea.EndRow + verticalOffset</code></pre>



<p>This function returns a tuple(a list you cannot change, also called immutable, see further for more details) with 4 elements. You can indeed create a tuple without using parenthesis.<br>If you are not convinced, try this in a python console:</p>



<pre class="wp-block-code"><code>&gt;&gt;&gt; fruits = "oranges","bananas","apples"
&gt;&gt;&gt; fruits
('oranges', 'bananas', 'apples')
&gt;&gt;&gt; type(fruits)
&lt;class 'tuple'&gt;</code></pre>



<p><em>(Don&#8217;t type the  &#8216;&gt;&gt;&gt;&#8217;, it&#8217;s python key prompt!)</em></p>



<p>The python built-in method <strong>type()</strong> tells you that you have defined the object &#8216;<strong>fruits</strong>&#8216; as an instance of class &#8216;<strong>tuple</strong>&#8216;.</p>



<h4 class="wp-block-heading">How to increment a tuple</h4>



<p>A tuple in python is a special type of array of data to store any type of data. Once a tuple has been created you cannot change its elements individually. A common solution to build a tuple is to use a &#8216;<strong>for loop</strong>&#8216; and to recreate the entire tuple with the same name at each loop iteration. It will look exactly like incrementing a variable, with each loop&#8217;s iteration looking like this:</p>



<pre class="wp-block-code"><code>myTuple = myTuple + (newElement,)</code></pre>



<p>The comma at the end within the parenthesis is important, if you don&#8217;t have it, the (newElement) is not a tuple but just a single element of whatever the type of newElement is.</p>



<h4 class="wp-block-heading">Try in the console</h4>



<p>So let&#8217;s open an APSO console (see <a href="https://tutolibro.org/2019/07/26/libreoffice-calc-python-programming-part-1-requirements/">part 1</a> if you need help), or if any other python console  like the Python Idle, or even your terminal after starting python3.</p>



<p>Then in the python console of your choice just create two new tuples like this:</p>



<pre class="wp-block-code"><code>source = (1,2,3)
target = ()</code></pre>



<p>You can do a quick print of your two tuple if you want to make sure your 2 tuples are good:</p>



<pre class="wp-block-code"><code>&gt;&gt;&gt; source
(1, 2, 3)
&gt;&gt;&gt; target = ()
&gt;&gt;&gt; ()
()
&gt;&gt;&gt; type(target)
&lt;class 'tuple'&gt;</code></pre>



<pre class="wp-block-verse">Note: as you can see you can create an empty tuple simply with empty parenthesis.</pre>



<h4 class="wp-block-heading">Increment tuple step by step</h4>



<p>To have our &#8216;<strong>target</strong>&#8216; tuple elements in the exact reverse order than the elements from the &#8216;<strong>source</strong>&#8216; tuple we need to do the following steps:</p>



<ol class="wp-block-list"><li>define target tuple equal to target tuple (which is empty at this step) + last element of source tuple (3)</li><li>define target tuple equal to target tuple(as it is) + second last element of source tuple (2)</li><li>define target tuple equal to target tuple(as it is) + first element of source tuple (1)</li></ol>



<p>In the console, it looks like this:</p>



<pre class="wp-block-code"><code>&gt;&gt;&gt; target = target + (source&#91;-1],)
&gt;&gt;&gt; target
(3,)
&gt;&gt;&gt; target = target + (source&#91;-2],)
&gt;&gt;&gt; target
(3, 2)
&gt;&gt;&gt; target = target + (source&#91;-3],)
&gt;&gt;&gt; target
(3, 2, 1)</code></pre>



<h4 class="wp-block-heading">Use the reversed() function</h4>



<p>Using a for loop and the <strong>reversed()</strong> function, we can now define a new function that takes a a tuple as argument and returns the reversed tuple, I called mine <strong>reverseTuple()</strong>:</p>



<pre class="wp-block-code"><code>def reverseTuple(aTuple):
    oReversedSource = ()
    for t in reversed(aTuple): 
        oReversedSource = oReversedSource + (t,)
    return oReversedSource</code></pre>



<h4 class="wp-block-heading">Use built-in functions &#8216;tuple()&#8217; and &#8216;reversed()&#8217; together.</h4>



<p>A nicer and more &#8216;pythonic&#8217; way of doing it, is to use the function <strong>tuple()</strong> and building the elements using what is called &#8216;tuple comprehension&#8217; with a loop on the reversed source tuple. This is done in one line only. So in the console it would look like this:</p>



<pre class="wp-block-code"><code>&gt;&gt;&gt; source = (1,2,3)
&gt;&gt;&gt; target = tuple(reversed(source))
&gt;&gt;&gt; target
(3, 2, 1)
&gt;&gt;&gt; </code></pre>



<p>So let&#8217;s create a <strong>reverse</strong> function. Now we have two functions doing the same job, just to show you that most of the time there are many ways to do the same thing in python and in programming in general. What counts is how readable the code is for you and other people that will read your code. </p>



<pre class="wp-block-code"><code>def reverse(aTuple):
    return tuple(reversed(aTuple))</code></pre>



<pre class="wp-block-verse">Note that you could do without this function and use the tuple comprehension directly where you need to reverse your tuple.</pre>



<p>For our final code we&#8217;ll keep the <strong>reverse</strong> function instead of the <strong>ReverseTuple</strong>, it&#8217;ll make people reading your code thinking, &#8220;That person knows python!&#8221;.</p>



<p>Now that we know how to reverse a tuple with python, we can apply it to a selected range of data within LibreOffice Calc.</p>



<h4 class="wp-block-heading">Full ReverseRange.py file</h4>



<pre class="wp-block-code"><code># Created by Gwenole Capp 05/05/2021
# For tutolibro.tech
# Public Domain, feel free to copy, modify, use in your own scripts
# 
# email: gwenole.capp@gmail.com
   
# set global variables for context
    
# get the doc from the scripting context 
# which is made available to all scripts
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()

# access the active sheet
active_sheet = model.CurrentController.ActiveSheet

# define useful functions

def getSelectionAddresses(horizontalOffset = 0 , verticalOffset = 0):
    # get the range of addresses from selection
    oSelection = model.getCurrentSelection()
    oArea = oSelection.getRangeAddress()
    return oArea.StartColumn + horizontalOffset, oArea.StartRow + verticalOffset, oArea.EndColumn + horizontalOffset, oArea.EndRow + verticalOffset
    
def reverse(aTuple):
    return tuple(reversed(aTuple))

# main function
def main():
       
    # get the Cell Range
    # use tuple unpacking of getSelectionAddresses returned tuple as parameter of getCellRangeByPosition
    oRangeSource = active_sheet.getCellRangeByPosition(*getSelectionAddresses())
    
    # get data from the Range of cells and store in a tuple
    oDataSource = oRangeSource.getDataArray()
    
    # print to console
    print(oDataSource)
    
    # create a new range of cells
    # from current selection using function getSelectionAddresses with offset
    # you can use the kwarg (keyword argument) horizontalOffset in parameter
    oRangeTarget = active_sheet.getCellRangeByPosition(*getSelectionAddresses(horizontalOffset = 3))
    
    # Reverse the data 
    oReversedSource = reverse(oDataSource)
    # Then set data for the target range using the 'reversed' data from the source range.
    oRangeTarget.setDataArray(oReversedSource)
</code></pre>



<h4 class="wp-block-heading">Walk through the code</h4>



<p>The global variables at the start are what allow us to manipulate LibreOffice Objects like the spreadsheet and its cells.<br>Then the function <strong>getSelectionAddresses()</strong>, as we have seen earlier is to get the addresses of the selected cells on LibreOffice.<br>The function <strong>reverse()</strong> is returning a reversed version of a tuple.</p>



<p> Let&#8217;s focus on the <strong>main</strong>() function.<br>In the main function, The function<strong> getCellRangeByPosition()</strong> to get the cells coordinates of the range of cells, takes 4 arguments, and not a tuple with 4 elements. But our function <strong>getSelectionAddresses</strong>() returns a tuple of 4 elements.  So that is why the argument <strong>getSelectionAddresses</strong>() is preceded with a &#8216;*&#8217; (asterisk). This mean that we are &#8216;<span style="text-decoration: underline;">unpacking</span>&#8216; the tuple returned by the function <strong>getSelectionAddresses</strong>() into a sequence of for single elements.<br>When you create a tuple, you are &#8216;packing&#8217; it with elements. You can &#8216;unpack&#8217; it to access all its elements at once. And the asterisk can do it for you!</p>



<pre class="wp-block-code"><code>    # get the Cell Range
    # use tuple unpacking of getSelectionAddresses returned tuple as parameter of getCellRangeByPosition
    oRangeSource = active_sheet.getCellRangeByPosition(*getSelectionAddresses())
</code></pre>



<p id="block-0425428d-2de8-4591-a39f-ebf88292e19e">Then we are using <strong>getDataArray()</strong> to get the data within the selected range, we are printing the tuple to the console.</p>



<pre id="block-3dd6bda9-e0ff-4d88-a8e5-58c6dcad86be" class="wp-block-code"><code>    # get data from the Range of cells and store in a tuple
    oDataSource = oRangeSource.getDataArray()
    
    # print to console
    print(oDataSource)</code></pre>



<p>Next, we create a new range of cells, using again the &#8216;unpacked&#8217; version of <strong>getSelectionAddresses()</strong> preceded with an asterix, but this time with the argument  &#8216;<strong>horizontalOffset = 3</strong>&#8216;, we don&#8217;t need to specify the <strong>verticalOffset</strong> if we want to use its default vaue set to 0 in the function definition. But we have to use the kwarg (the keyword argument) <strong>horizontalOffset</strong> to make sure we are passing the wanted value to the correct argument.<br>So in this case I have an offset of 3 cells horizontally, the reversed range of data will be displayed 3 cells on the right of the selected data.<br>If you wanted to reverse the range &#8216;in place&#8217; and overwrite the source data, you just need to put no arguments in the code for function <strong>getSelectionAddresses()</strong>.</p>



<pre id="block-3dd6bda9-e0ff-4d88-a8e5-58c6dcad86be" class="wp-block-code"><code>    # create a new range of cells
    # from current selection using function getSelectionAddresses with offset
    # you can use the kwarg (keyword argument) horizontalOffset in parameter
    oRangeTarget = active_sheet.getCellRangeByPosition(*getSelectionAddresses(horizontalOffset = 3))</code></pre>



<pre class="wp-block-verse">Note: there is no exception handling, no safeguard, to check if the offset your enter makes the range being 'out of range'. That could be a further improvement of this program. Another improvement could be to have the offset defined in a cell, or defined using a small control form with a text input.</pre>



<p>Finally, we reverse the tuple of data and store it in our new range of Cell addresses in the LibreOffice Calc sheet.</p>



<pre class="wp-block-code"><code>    # Reverse the data 
    oReversedSource = reverse(oDataSource)
    # Then set data for the target range using the 'reversed' data from the source range.
    oRangeTarget.setDataArray(oReversedSource)</code></pre>



<p>You can also find the file with the full code on <a href="https://github.com/Gweno/tutolibro.tech/tree/master/lopy/part9" target="_blank" rel="noreferrer noopener">this gitHub rep</a>.</p>



<h4 class="wp-block-heading">Test the code</h4>



<p>Now it&#8217;s time to create a range of data, select that rage and run the python macro!</p>



<figure class="wp-block-image size-large"><img decoding="async" width="500" height="89" src="https://tutolibro.org/wp-content/uploads/2021/05/tutolibro_part9.gif" alt="" class="wp-image-1104"/><figcaption>The selected range is reversed!</figcaption></figure>



<p>You can a look at <a href="https://tutolibro.org/2020/03/11/libreoffice-calc-python-programming-annex-1-assign-a-python-macro-to-a-key/">tutorial Annex 1</a> to map a combination of key to this macro (I use CTRL + 0).<br>I hope this tutorial helped you understand a bit more about using python to control LibreOffice Calc. Please leave a comment to let me know!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tutolibro.org/2021/05/07/python-libreoffice-reverse-the-order-of-cells-content-from-a-cell-range/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1070</post-id>	</item>
		<item>
		<title>LibreOffice Calc &#038; Python Programming: part 8 – From Python Tuple to Cells Range</title>
		<link>https://tutolibro.org/2020/07/17/libreoffice-calc-python-programming-part-8-from-python-tuple-to-cells-range/</link>
					<comments>https://tutolibro.org/2020/07/17/libreoffice-calc-python-programming-part-8-from-python-tuple-to-cells-range/#comments</comments>
		
		<dc:creator><![CDATA[gweno]]></dc:creator>
		<pubDate>Fri, 17 Jul 2020 20:28:03 +0000</pubDate>
				<category><![CDATA[Calc]]></category>
		<category><![CDATA[LibreOffice]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[calc]]></category>
		<category><![CDATA[cell type]]></category>
		<category><![CDATA[libreoffice]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setDataArray]]></category>
		<guid isPermaLink="false">https://tutolibro.tech/?p=1017</guid>

					<description><![CDATA[This time we are going to create a new Range of Cells and fill it with the data stored in our tuple created in part 7. Here is the plan for this tutorial: Start with code from the previous chapter...<br /><a class="read-more-button" href="https://tutolibro.org/2020/07/17/libreoffice-calc-python-programming-part-8-from-python-tuple-to-cells-range/">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p>This time we are going to create a new Range of Cells and fill it with the data stored in our tuple created in <a href="https://tutolibro.org/2020/07/10/libreoffice-calc-python-programming-part-7-from-cells-range-to-python-tuple/">part 7</a>.</p>



<h4 class="wp-block-heading">Here is the plan for this tutorial:</h4>



<ul class="wp-block-list">
<li>Start with code from the previous chapter</li>



<li>Set the top-left and bottom-right Cells addresses</li>



<li>Set the Target Range</li>



<li>Create a new Array of data</li>
</ul>



<h4 class="wp-block-heading">Start with code from the previous chapter</h4>



<p>Starting with the code from the previous episode of this series LibreOffice Calc &amp; Python Programming from its corresponding <a rel="noreferrer noopener" href="https://github.com/Gweno/tutolibro.tech/tree/master/lopy/part7" target="_blank">gitHub rep</a>, or a copy paste here:</p>



<pre class="wp-block-code"><code>def context():
    
    # set global variables for context
    
    global desktop
    global model
    global active_sheet
    
    # get the doc from the scripting context 
    # which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    
    # access the active sheet
    active_sheet = model.CurrentController.ActiveSheet
    
def main():
    
    # call function context()
    context()
    
    # get the range of addresses from selection
    oSelection = model.getCurrentSelection()
    oArea = oSelection.getRangeAddress()

    # store the attribute of CellRangeAddress 
    nLeft = oArea.StartColumn
    nTop = oArea.StartRow
    nRight = oArea.EndColumn
    nBottom = oArea.EndRow
    #(note: could the attribute directly instead of using intermediary variable)
    
    # get the Cell Range 
    oRangeSource = active_sheet.getCellRangeByPosition(nLeft, nTop, nRight, nBottom)
    
    # example by name:
    # ~ oRangeSource = active_sheet.getCellRangeByName('A1:C10')
    
    # get data from the Range of cells and store in a tuple
    oDataSource = oRangeSource.getDataArray()
    
    # print to console
    print(oDataSource)
</code></pre>



<h4 class="wp-block-heading">Set  the top-left and bottom-right Cells addresses</h4>



<p>This step is to calculate the addresses for our target range of cells, by defining the columns and rows for the top-left and bottom-right cells or our target range, the range where we are going to transfer the data from the selected area.<br>To avoid having python to throw an error, we need to make sure that our target area is exactly the same size than our source area.<br>We also don&#8217;t want to overlap our source area with our target area.<br>In this example, let&#8217;s define an area starting two columns to the right of our selected area. So the addresses of the cells in the new range will depend on the addresses of cells within the source range.<br>We can set an offset value that will define how many columns to the right of our selected range will our target range will be.</p>



<p>For example:<br><strong>offset = 2</strong></p>



<p>Then we set the leftmost column of our new range to be like this:<br><strong>tLeft = nRight + offset</strong><br>With <strong>nRight</strong> being the right column of our range of selected cells.<br>So here we are simply adding the offset (=2) to the end column of the source range.</p>



<p>Then we need to know the number of columns in the source area:<br><strong>nbCol = nRight &#8211; nLeft + 1</strong><br>This is the difference between the address of the right column of the source area and the address of the left column area, to which we add 1.<br>Check the illustration below to understand:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="769" height="73" src="https://tutolibro.org/wp-content/uploads/2020/07/lopy-part8_0.png" alt="" class="wp-image-1055" srcset="https://tutolibro.org/wp-content/uploads/2020/07/lopy-part8_0.png 769w, https://tutolibro.org/wp-content/uploads/2020/07/lopy-part8_0-300x28.png 300w" sizes="(max-width: 769px) 100vw, 769px" /><figcaption class="wp-element-caption">There are 3 three columns in the yellow range starting at number 2, ending at number 4:<br>(4-2)+1 = 2 + 1 = 3</figcaption></figure>



<p>To remember that logic I always use a metaphor about number of holidays: if I start my holidays the 2nd of the month and my last day of holidays is the 4th of the month, I know I had 3 days of holidays, the 2nd, the 3rd and the 4th. And first day subtracted to last day makes <strong>4 -2 = 2</strong> , and I need to <strong>add 1</strong> day to have the right count: 3 days from the 2nd to the 4th.<br>In the illustration above, the column 2 is the day 2 of the month, the column 4, the day 4&#8230;</p>



<p>To set the address of the last column of our target range we do the following:<br><strong>tRight = nRight + nbCol &#8211; 1 + offset</strong><br>Starting from the last column of the source area, you add the number of columns in that source area, subtract 1, and then add the same offset that you used for the starting column of this new range.<br>To use the same number of holidays example, to know what are the starting date and ending date of my holidays knowing that I have 3 days off next week, I need to add the number of days off to the starting date and take away 1: 2+3=5, 5-1 = 4 -&gt; the 4th.</p>



<p>We can keep the same rows than the source area for the target area:<br><strong>tTop = nTop<br>tBottom = nBottom</strong></p>



<p>Altogether the snippet for setting the columns and rows of our new range is:</p>



<pre class="wp-block-code"><code>    # set the target columns and rows
    # relative to the selected area
    offset = 2
    tLeft = nRight + offset
    nbCol = nRight - nLeft + 1
    tRight = nRight + nbCol - 1 + offset
    tTop = nTop
    tBottom = nBottom

    print(tLeft,tTop,tRight,tBottom)</code></pre>



<p>A simplified version, of <strong>tRight</strong>, if you replace nbCol by its value, would be:<br><strong>tRight = 2*nRight &#8211; nLeft + offset</strong><br>In which case you don&#8217;t need the nbCol variable anymore, but to make the explanation easier I am keeping it.</p>



<p>As usual, to help with testing, I added a print statement. It will print the value you calculated in the console. You can read my tutorial <a href="https://tutolibro.org/2020/02/24/libreoffice-calc-python-programming-part-4-using-apso-console-to-print-text/">about the APSO console</a> if you haven&#8217;t yet. Also to make testing easier, I usually assign the program to a combination of key, like CTRL + 0. Check <a href="https://tutolibro.org/2020/03/11/libreoffice-calc-python-programming-annex-1-assign-a-python-macro-to-a-key/">my post</a> that explains how to do that easily.</p>



<h4 class="wp-block-heading">Set the Target range</h4>



<p>We are going to use <strong>getCellRangeByPosition</strong> again to create a range of cells, but this time we are not going to use the addresses of the area defined by the mouse selection. We are now going to use the variables that we created in the previous step <strong>tLeft, tTop, tRight, tBottom</strong>.</p>



<pre class="wp-block-code"><code>    # create target Range
    oRangeTarget = active_sheet.getCellRangeByPosition(tLeft, tTop, tRight, tBottom)</code></pre>



<p>Now that we have define a cell range, we can assign data to it.</p>



<h4 class="wp-block-heading">Create a new Array of data</h4>



<p>In the <a href="https://tutolibro.org/2020/07/10/libreoffice-calc-python-programming-part-7-from-cells-range-to-python-tuple/">last tutorial</a> we used the function getDataArray() to create a python tuple that we named oDataSource from the data stored in the source range of cells. This time we are going to use the function setDataArray() with the existing tuple of data oDataSource as parameter.</p>



<p>This will store the data from the tuple oDataSource to the target Range of Cells that we defined earlier, and hopefully display the data in the cells on the LibreOffice current spreadsheet.</p>



<pre class="wp-block-code"><code>    # set data for the target range using datafrom the source range.
    oRangeTarget.setDataArray(oDataSource)</code></pre>



<p>Here is what I get with a bit of data, including the APSO console:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="500" height="353" src="https://tutolibro.org/wp-content/uploads/2020/07/lopy-part8_1.gif" alt="" class="wp-image-1061"/><figcaption class="wp-element-caption">Simple example</figcaption></figure>



<p>This is the full code:</p>



<pre class="wp-block-code"><code>def context():
    
    # set global variables for context
    
    global desktop
    global model
    global active_sheet
    
    # get the doc from the scripting context 
    # which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    
    # access the active sheet
    active_sheet = model.CurrentController.ActiveSheet
    
def main():
    
    # call function context()
    context()
    
    # get the range of addresses from selection
    oSelection = model.getCurrentSelection()
    oArea = oSelection.getRangeAddress()

    # store the attribute of CellRangeAddress 
    nLeft = oArea.StartColumn
    nTop = oArea.StartRow
    nRight = oArea.EndColumn
    nBottom = oArea.EndRow
    #(note: could the attribute directly instead of using intermediary variable)
    
    # get the Cell Range 
    oRangeSource = active_sheet.getCellRangeByPosition(nLeft, nTop, nRight, nBottom)
    
    # example by name:
    # ~ oRangeSource = active_sheet.getCellRangeByName('A1:C10')
    
    # get data from the Range of cells and store in a tuple
    oDataSource = oRangeSource.getDataArray()
    
    # print to console
    print(oDataSource)
    
    # set the target columns and rows
    # relative to the selected area
    offset = 2
    tLeft = nRight + offset
    nbCol = nRight - nLeft + 1
    tRight = nRight + nbCol - 1 + offset
    tTop = nTop
    tBottom = nBottom
    
    print(tLeft,tTop,tRight,tBottom)
    
    # create target Range
    oRangeTarget = active_sheet.getCellRangeByPosition(tLeft, tTop, tRight, tBottom)
    
    # set data for the target range using data from the source range.
    oRangeTarget.setDataArray(oDataSource)</code></pre>



<p>You can also find this code on <a href="https://github.com/Gweno/tutolibro.tech/tree/master/lopy/part8" target="_blank" rel="noreferrer noopener">this gitHub rep</a>.</p>



<p>The getDataArray() function creates a tuple of tuples. Tuples are immutable objects, so you cannot change them once you have created them.<br>So if you want to change the data that you stored from a range of cells, you will need to create a new tuple, while looping on the source tuple element by element.<br>In the next episode of this series of Tutorials about LibreOffice Calc and Python Programming, I will show you some examples on how to work with these tuples of tuples to work on the data.</p>



<p>If you like this tutorial, you could <a href="https://buymeacoffee.com/tutolibro" data-type="link" data-id="https://buymeacoffee/tutolibro" target="_blank" rel="noreferrer noopener">buy me a coffee</a> to help me continue writing add-free tutorials.</p>



<p>Thank you!</p>



<div class="wp-block-group is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-0dfbf163 wp-block-group-is-layout-flex">

</div>
]]></content:encoded>
					
					<wfw:commentRss>https://tutolibro.org/2020/07/17/libreoffice-calc-python-programming-part-8-from-python-tuple-to-cells-range/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1017</post-id>	</item>
	</channel>
</rss>
