Minimum Javascript version in macros

LibreOffice includes whatever ancient language specification was implemented in Mozilla Rhino used in the project.

Specifically, that’s Rhino version 1.5R5 from 2004, so the JavaScript language is no newer than of that time. Likely that’s version 3 of ECMAScript spec.

EDIT:
yes; citing “overview.html” from the tarbal:

Rhino contains

  • All the features of JavaScript 1.5

and JavaScript 1.5 is documented to comply with ECMAScript 3.


Did you see that part of the menus? As for the bindings, it seems that the following code is legal.

importClass(Packages.com.sun.star.uno.UnoRuntime);
importClass(Packages.com.sun.star.sheet.XSpreadsheetDocument);
importClass(Packages.com.sun.star.container.XNameAccess);
importClass(Packages.com.sun.star.table.XCellRange);
importClass(Packages.com.sun.star.table.XCell);
importClass(Packages.com.sun.star.table.CellContentType);

At first: This site (or the people creating ask… didn’t like “answers” to give a some kind of continued dialogue. The mess will start, when answers are voted for etc…

Second I didn’t say you can’t use javascript. What you found is a way to organize texts as scripts an call a handler for this script. As an example: In a python-macro the first thing to do is to get something like XSCRIPTCONTEXT to have a starting point for conversation with LO. But you may also connect via sockets, if you are outside the proceds if LO… LO itself is using Python3, but you could interface from Python2…

I’m debating writing a C# tool to do what I want. There do appear to be .NET bindings.

I got the code running, but XCell.setFormula() doesn’t seem to be doing anything.

Hello,
Have not looked at this in quite some time and know little about JavaScript but this works for me:

//xSheet = xSheetsIndexAccess.getByIndex(0);
xSheet = xSheetsNameAccess.getByName("Sheet1");
//get the XCellRange interface used to access a cell
xCll = UnoRuntime.queryInterface(XCellRange,xSheet);
//get Cell A1
xCellA1 = xCll.getCellByPosition(0,0);
//get the XCell interface used to access a cell
xC = UnoRuntime.queryInterface(XCell,xCellA1);
xC.setFormula("=a2+b2");

Result:
Screenshot at 2022-05-04 18-07-47

I should note that in most cells, I need a text value. There is no overload of setValue that takes a string.

Sorry, don’t know what you are noting. Thought this was in answer to

.
Also please use comments to respond and not answers. Answers are meant to actually answer the original post. Thank You.

I was talking about that. How do you specify a text value for a cell? I only see setFormula. No overload of setValue exists for values of type string.

Again, please us comments not answers.
.

As mentioned don’t know much about this but seems it is setString using:

importClass(Packages.com.sun.star.text.XTextRange);

See XTextRange Interface Reference
.
Edit:
Yes that works:

oTextRange = UnoRuntime.queryInterface(XTextRange,xCellA1);
oTextRange.setString("Hello");

produces:
Screenshot at 2022-05-04 19-15-37

Ah. I didn’t see comment. No changes in the behavior. Still no new cell contents. Some cells will be set with setFormula (with actual formulas). Some get simple numbers and are set with setValue. Some are set with setString.

Please post your code.
.
Edit:
You can see my code above and that it worked. Found this post and thought it may help > Re: [Calc] Set value for a cell with Javascript

Note: This code is intended to merge the tables from Comparison of remote desktop software - Wikipedia. I’ve deleted some fields I don’t care about.

'use strict';

// jshint esversion: 8

importClass(Packages.com.sun.star.uno.UnoRuntime);
importClass(Packages.com.sun.star.sheet.XSpreadsheetDocument);
importClass(Packages.com.sun.star.container.XNameAccess);
importClass(Packages.com.sun.star.table.XCellRange);
importClass(Packages.com.sun.star.table.XCell);
importClass(Packages.com.sun.star.table.CellContentType);
importClass(Packages.com.sun.star.text.XTextRange)

//get the document object from the scripting context
var oDoc = XSCRIPTCONTEXT.getDocument();
//get the XSpreadsheetDocument interface from the document
var xSDoc = UnoRuntime.queryInterface(XSpreadsheetDocument, oDoc);
//get the XIndexAccess interface used to access each sheet
var xSheetsNameAccess = UnoRuntime.queryInterface(XNameAccess, xSDoc.getSheets());

var cellrangeBasic = UnoRuntime.queryInterface(XCellRange, xSheetsNameAccess.getByName("Basic"));
var cellrangeOS = UnoRuntime.queryInterface(XCellRange, xSheetsNameAccess.getByName("OS_Support"));
var cellrangeFeatures = UnoRuntime.queryInterface(XCellRange, xSheetsNameAccess.getByName("Features"));
var cellrangeResults = UnoRuntime.queryInterface(XCellRange, xSheetsNameAccess.getByName("Results"));
var cellrangeRejects = UnoRuntime.queryInterface(XCellRange, xSheetsNameAccess.getByName("Rejects"));
var cellrangeIncomplete = UnoRuntime.queryInterface(XCellRange, xSheetsNameAccess.getByName("Incomplete"));
function findProductLine(strNameToFind, cellrangeToUse)
{
	var iCurRow = 1;
	var strProductNameInCurRow = getCellAutoValByPos(cellrangeToUse, 0, iCurRow);

	while(strProductNameInCurRow != null && strProductNameInCurRow != strNameToFind)
	{
		iCurRow++;
		strProductNameInCurRow = getCellAutoValByPos(cellrangeToUse, 0, iCurRow);
	}

	return strProductNameInCurRow == null ? -1 : iCurRow;
}

function getCellByPos(cellrangeToUse, iCol, iRow)
{
	return UnoRuntime.queryInterface(XCell, cellrangeToUse.getCellByPosition(iCol, iRow));
}

function getCellAutoValByPos(cellrangeToUse, iCol, iRow)
{
	var cell = getCellByPos(cellrangeToUse, iCol, iRow);

	switch(cell.getType())
	{
		case CellContentType.EMPTY:
			return null;

		case CellContentType.VALUE:
		case CellContentType.FORMULA:
			return cell.getValue();

		case CellContentType.TEXT:
		default:
			return cell.getFormula();
	}
}

function getCellBoolValByPos(cellrangeToUse, iCol, iRow)
{
	var strValFound = getCellAutoValByPos(cellrangeToUse, iCol, iRow).toLowerCase();

	if(strValFound == "?")
		return undefined;

	if(strValFound.includes("partial"))
		return "Partial";

	if(strValFound.includes("yes"))
		return true;

	return false;
}

function getCellNumValByPos(cellrangeToUse, iCol, iRow)
{
	var strValFound = getCellAutoValByPos(cellrangeToUse, iCol, iRow).toLowerCase();

	if(strValFound == "?")
		return undefined;

	var numResult = parseFloat(strValFound);

	return numResult == NaN ? undefined : numResult;
}

function Product(strName)
{
	this.strName = strName;

	var iBasicRow = findProductLine(strName, cellrangeBasic);
	var iOsSupportRow = findProductLine(strName, cellrangeOS);
	var iFeatureRow = findProductLine(strName, cellrangeFeatures);

	if(iBasicRow > -1)
	{
		this.strProtocols = getCellAutoValByPos(cellrangeBasic, 1, iBasicRow);
		this.strCreator = getCellAutoValByPos(cellrangeBasic, 2, iBasicRow);
		this.strFirstPublicReleaseDate = getCellAutoValByPos(cellrangeBasic, 2, iBasicRow);
		this.strLatestStableRelease = getCellAutoValByPos(cellrangeBasic, 3, iBasicRow);
		this.strLicense = getCellAutoValByPos(cellrangeBasic, 4, iBasicRow);
		this.bFree = getCellBoolValByPos(cellrangeBasic, 5, iBasicRow);
	}

	if(iOsSupportRow > -1)
	{
		this.bHasServer = getCellBoolValByPos(cellrangeOS, 1, iOsSupportRow);
		this.bHasClient = getCellBoolValByPos(cellrangeOS, 2, iOsSupportRow);
	}

	if(iFeatureRow > -1)
	{
		this.strListening = getCellAutoValByPos(cellrangeFeatures, 1, iFeatureRow);
		this.builtInEncryptionOpt = getCellAutoValByPos(cellrangeFeatures, 2, iFeatureRow);
		this.bFivarransferSupported = getCellBoolValByPos(cellrangeFeatures, 3, iFeatureRow);
		this.bAudioSupport = getCellBoolValByPos(cellrangeFeatures, 4, iFeatureRow);
		this.bMultiSession = getCellBoolValByPos(cellrangeFeatures, 5, iFeatureRow);
		this.bSeamlessWnds = getCellBoolValByPos(cellrangeFeatures, 6, iFeatureRow);
		this.bRemoteAssist = getCellBoolValByPos(cellrangeFeatures, 7, iFeatureRow);
		this.bIPV6 = getCellBoolValByPos(cellrangeFeatures, 8, iFeatureRow);
		this.bDragDrop = getCellBoolValByPos(cellrangeFeatures, 9, iFeatureRow);
		this.bUsbForwarding = getCellBoolValByPos(cellrangeFeatures, 10, iFeatureRow);
		this.bH264 = getCellBoolValByPos(cellrangeFeatures, 11, iFeatureRow);
		this.bBrowserSupport = getCellBoolValByPos(cellrangeFeatures, 12, iFeatureRow);
		this.bSessionPersists = getCellBoolValByPos(cellrangeFeatures, 13, iFeatureRow);
	}

	this.bFoundBasicInfo = iBasicRow > -1;
	this.bFoundOsSupportInfo = iOsSupportRow > -1;
	this.bFoundFeatureInfo = iFeatureRow > -1;

}

var listAllProductNamesFound = [];

function addAllKnownProductsInCellRange(cellrangeToUse)
{
	var iCurRow = 1;
	var strProductNameInCurRow = getCellAutoValByPos(cellrangeToUse, 0, iCurRow);

	while(strProductNameInCurRow != null)
	{
		iCurRow++;
		strProductNameInCurRow = getCellAutoValByPos(cellrangeToUse, 0, iCurRow);
		listAllProductNamesFound.push(strProductNameInCurRow);
	}
}

addAllKnownProductsInCellRange(cellrangeBasic);
addAllKnownProductsInCellRange(cellrangeOS);
addAllKnownProductsInCellRange(cellrangeFeatures);

var listAllProductDetailsFound = [];
for(var iCurProductIndex = 0; iCurProductIndex < listAllProductNamesFound.length; iCurProductIndex++)
{
	listAllProductDetailsFound.push(new Product(listAllProductNamesFound[iCurProductIndex]));
}

var iCurResultRow = 1;
var iCurRejectRow = 1;
var iCurIncompleteRow = 1;

function setCellVal(cellrangeDataDest, iCol, iRow, val)
{
	var cell = UnoRuntime.queryInterface(XCell, cellrangeDataDest.getCellByPosition(iCol, iRow));

	if(val == null)
		return;

	if(val == undefined)
		cell.setFormula("Unknown");
	else
		switch(typeof(val))
		{
			case "number":
				cell.setValue(val);

				break;

			case "string":
				UnoRuntime.QueryInterface(XTextRange, cell).setString(val);

				break;

			case "boolean":
				cell.setFormula("=" + val.toString().toUpperCase() + "()");

				break;
		}
}

for(var iCurProductIndex = 0; iCurProductIndex < listAllProductDetailsFound.length; iCurProductIndex++)
{
	var productCur = listAllProductDetailsFound[iCurProductIndex];

	var cellrangeDataDest = cellrangeResults;

	if(!productCur.bFoundBasicInfo || !productCur.bFoundOsSupportInfo || !productCur.bFoundFeatureInfo)
		cellrangeDataDest = cellrangeIncomplete;
	else if(!productCur.bFree || !productCur.bHasServer || !productCur.bHasClient || !productCur.bHasClient)
		cellrangeDataDest = cellrangeRejects;

	var iOutputRow;

	switch(cellrangeDataDest)
	{
		case cellrangeResults:
			iOutputRow = iCurResultRow++;

			break;

		case cellrangeRejects:
			iOutputRow = iCurRejectRow++;

			break;

		case cellrangeIncomplete:
			iOutputRow = iCurIncompleteRow++;

			break;
	}

	setCellVal(cellrangeDataDest, 0, iOutputRow, productCur.strName);
	setCellVal(cellrangeDataDest, 1, iOutputRow, productCur.strProtocols);
	setCellVal(cellrangeDataDest, 2, iOutputRow, productCur.strCreator);
	setCellVal(cellrangeDataDest, 3, iOutputRow, productCur.strFirstPublicReleaseDate);
	setCellVal(cellrangeDataDest, 4, iOutputRow, productCur.strLatestStableRelease);
	setCellVal(cellrangeDataDest, 5, iOutputRow, productCur.strLicense);
	setCellVal(cellrangeDataDest, 6, iOutputRow, productCur.bFree);
	setCellVal(cellrangeDataDest, 7, iOutputRow, productCur.bHasServer);
	setCellVal(cellrangeDataDest, 8, iOutputRow, productCur.bHasClient);
	setCellVal(cellrangeDataDest, 9, iOutputRow, productCur.strListening);
	setCellVal(cellrangeDataDest, 10, iOutputRow, productCur.builtInEncryptionOpt);
	setCellVal(cellrangeDataDest, 11, iOutputRow, productCur.bFivarransferSupported);
	setCellVal(cellrangeDataDest, 12, iOutputRow, productCur.bAudioSupport);
	setCellVal(cellrangeDataDest, 13, iOutputRow, productCur.bMultiSession);
	setCellVal(cellrangeDataDest, 14, iOutputRow, productCur.bSeamlessWnds);
	setCellVal(cellrangeDataDest, 15, iOutputRow, productCur.bRemoteAssist);
	setCellVal(cellrangeDataDest, 16, iOutputRow, productCur.bIPV6);
	setCellVal(cellrangeDataDest, 17, iOutputRow, productCur.bDragDrop);
	setCellVal(cellrangeDataDest, 18, iOutputRow, productCur.bUsbForwarding);
	setCellVal(cellrangeDataDest, 19, iOutputRow, productCur.bH264);
	setCellVal(cellrangeDataDest, 20, iOutputRow, productCur.bBrowserSupport);
	setCellVal(cellrangeDataDest, 21, iOutputRow, productCur.bSeamlessWnds);
}

Remote desktop software comparison.ods (43.7 KB)
That’s my version of the table with the macro enclosed.

Looks beyond my quick look.
.
I think trying a few smaller items as I tested may get you started. Also I expect you did create parcel-descriptor.xml? Writing Office Scripts in JavaScript

I was staying within the GUI. I didn’t know of any of that.

Can’t say there is a GUI. A debugger is what I see.
.
When I look for your code & try to edit I receive the following message:
.


.
Don’t see in your file what is supposed to execute the code.
.
Again, probably beyond my knowledge in this area. I have a better chance with Python or even basic.

I was executing the code manually from Tools/Macros/Run. No idea why it’d complain about a reserved word on line 21. You saw the code listed in a previous file.

It is strange for you to use Tools>Macros>Run as these are functions requiring parameters and have return information. No where to input parameters and no place to put return data.
.
Interface seems incorrect here. Would think a function is called from a cell and data (or whatever) is returned there.
.
Edit:
Possibly a call from Basic as posted here > Solved: How to call JavaScript function from Basic

I abandoned that code entirely. The new solution uses C#. The role of Calc was replaced by JSON. I ended up not needing LibreOffice at all.