白峯のソース

IT なことのメモなど

OpenOffice.org Calc JavaScript マクロ

f:id:hakuhou-src:20200518115615p:plain
OpenOffice.org Calc をもう10年以上使い続けている。
もちろん Microsoft Excelも使うし、なんでも無料が良いというわけではないが、気軽に Windows にも Mac にもインストールして実行できるのはツールとして優れている。

個人的な使い方の中心は、ゲームのアイテムやら敵やらのデータ作成ツールがメイン。
そこでは、マクロが欠かせない。
しかし、OpenOffice.orgJavaScript マクロは特殊性が強い。
ネット上の情報も少なく、Apache のリファレンスとの睨めっこの時間が長くかかる。
また、JavaScript マクロといいながらも、どちらかというと Java な Uno も癖が強い。(JavaScript の常識が通用しない。)
「Macroの杜(JavaScript編) 」さんにはお世話になりっぱなしである。

…ということで、ある程度は情報が溜まってきたので、いっちょ小さなサンプルプログラムを提供。

このマクロは、セルの背景色を文字列化する(赤→ff0000みたいな感じ)。
セルのテキストを書き換えるので、実行の際は各セルには背景色だけ設定してテキストは空にしておくこと。
ただし、実行終了行と列には # を入れておかないと、延々と処理を進めてしまう。

機能面は、
・現在のシートを取得
・セルの文字を取得・設定
・背景色を取得・設定
・外枠の幅、色を取得・設定
・簡易 CSV 出力
な感じなので、色々参考になるんじゃないかと。

importClass(Packages.com.sun.star.beans.XPropertySet);
importClass(Packages.com.sun.star.frame.XModel);
importClass(Packages.com.sun.star.io.XActiveDataSource);
importClass(Packages.com.sun.star.io.XOutputStream);
importClass(Packages.com.sun.star.io.XTextOutputStream);
importClass(Packages.com.sun.star.sheet.XSheetCellRange);
importClass(Packages.com.sun.star.sheet.XSpreadsheetView);
importClass(Packages.com.sun.star.table.XCellCursor);
importClass(Packages.com.sun.star.ucb.XSimpleFileAccess);
importClass(Packages.com.sun.star.uno.AnyConverter);
importClass(Packages.com.sun.star.uno.UnoRuntime);

////////////////////////////////////////////////////////////////////////////

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Constant definition.

TERM = "#";
SAFE_COUNTER = 999;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Acquire system object.

oDoc = UnoRuntime.queryInterface(XModel, XSCRIPTCONTEXT.getInvocationContext());
if(!oDoc){ oDoc = XSCRIPTCONTEXT.getDocument(); }

// Acquire Current Sheet.
xSheetComponent = XSCRIPTCONTEXT.getDocument();
xModel = UnoRuntime.queryInterface(XModel, xSheetComponent);
xController = xModel.getCurrentController();
xSpreadsheetView = UnoRuntime.queryInterface(XSpreadsheetView, xController);
xSpreadsheet = xSpreadsheetView.getActiveSheet();
xSheet = xSpreadsheet.getSpreadsheet();

// Acquire File Access.
xContext = XSCRIPTCONTEXT.getComponentContext();
xMCF = xContext.getServiceManager();
oFileAccess = xMCF.createInstanceWithContext("com.sun.star.ucb.SimpleFileAccess", xContext);
xFileAccess = UnoRuntime.queryInterface(XSimpleFileAccess, oFileAccess);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function definition.

// Get specific cell cursor.
function getCellCursor(xSheet, oCellName)
{
	xCellRange = xSheet.getCellRangeByName(oCellName);
	xSheetCellRange = UnoRuntime.queryInterface(XSheetCellRange, xCellRange);
	xSheetCellCursor = xSheet.createCursorByRange(xSheetCellRange);
	xCursor = UnoRuntime.queryInterface(XCellCursor, xSheetCellCursor);
	return xCursor;
}

// Get cell name.
function getCellName(oCol, oRow)
{
	oColStr = '';
	while(oCol > 0)
	{
		oColStr = String.fromCharCode(0x41 + ((oCol - 1) % 26)) + oColStr;
		oCol = Math.floor((oCol - 1) / 26);
	}
	return oColStr + oRow;
}

// Get cell string.
function getCellString(oCol, oRow)
{
	xCell = xSheet.getCellByPosition(oCol - 1, oRow - 1);
	return xCell.getFormula();
}

// Set cell string.
function setCellString(oCol, oRow, oTxt)
{
	xCell = xSheet.getCellByPosition(oCol - 1, oRow - 1);
	xCell.setFormula(oTxt);
}

// Get cell color.
function getCellColor(oCol, oRow)
{
	xCell = xSheet.getCellByPosition(oCol - 1, oRow - 1);
	xProps = UnoRuntime.queryInterface(XPropertySet, xCell);
	oColor = xProps.getPropertyValue("CellBackColor");
	return oColor; 	
}

// Set cell color.
function setCellColor(oCol, oRow, oColor)
{
	xCell = xSheet.getCellByPosition(oCol - 1, oRow - 1);
	xProps = UnoRuntime.queryInterface(XPropertySet, xCell);
	xProps.setPropertyValue("CellBackColor", oColor);
}

// Get cell table boder.
function getCellTableBorder(oCol, oRow)
{
	xCell = xSheet.getCellByPosition(oCol - 1, oRow - 1);
	xProps = UnoRuntime.queryInterface(XPropertySet, xCell);
	oTableBorder = xProps.getPropertyValue("TableBorder");
	return oTableBorder;
}

// Set cell table boder.
function setCellTableBorder(oCol, oRow, oTableBorder)
{
	xCell = xSheet.getCellByPosition(oCol - 1, oRow - 1);
	xProps = UnoRuntime.queryInterface(XPropertySet, xCell);
	xProps.setPropertyValue("TableBorder", oTableBorder);
}

// Output text file.
function outputTextFile(oFilePath, oStr, oOverwrite)
{
	oTextOutputStm = xMCF.createInstanceWithContext("com.sun.star.io.TextOutputStream", xContext);
	xTextOutputStm = UnoRuntime.queryInterface(XTextOutputStream, oTextOutputStm);
	xActiveTextSource = UnoRuntime.queryInterface(XActiveDataSource, oTextOutputStm);
	xTextOutputStm.setEncoding("utf8");	// Set UTF-8 encoding.

	sUrl = oDoc.getURL();
	sUrl = sUrl.substring(0, sUrl.lastIndexOf('/')) + '/' + oFilePath;

	if(!oOverwrite)
	{
		// Clear exists file.
		if(xFileAccess.exists(sUrl))
		{
			xFileAccess.kill(sUrl);
		}
	}

	oFile = xFileAccess.openFileWrite(sUrl);
	xFile = UnoRuntime.queryInterface(XOutputStream, oFile);
	xActiveTextSource.setOutputStream(xFile);

	xTextOutputStm.writeString(oStr);
	
	xFile.closeOutput();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Execute.

oY = 1;	// 1
oOutputText = "";

while(oY < SAFE_COUNTER)
{
	oX = 1;	// A

	if(getCellString(oX, oY) == TERM)
	{
		break;
	}
	
	while(oX < SAFE_COUNTER)
	{
		if(getCellString(oX, oY) == TERM)
		{
			break;
		}

		oCellColor = getCellColor(oX, oY);
		oCellText = oCellColor.toHexString(oCellColor);
		setCellString(oX, oY, oCellText);
		oOutputText += (oX > 1 ? "," : "") + oCellText;
		
		oX++;
	}
	
	oY++;
	oOutputText += "\n";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Done.

oX = 2;
setCellString(oX, oY, "done!");
setCellColor(oX, oY,  new java.lang.Integer(0x7777cc));
oTmp = getCellTableBorder(oX, oY);
oTmp.BottomLine.OuterLineWidth = 141;	// 4.0pt
oTmp.BottomLine.Color = new java.lang.Integer(0x0000ff);
setCellTableBorder(oX, oY, oTmp);
outputTextFile("colors.csv", oOutputText, false);

誰かの役に立つと良いですな。

参考:
https://www.openoffice.org/api/docs/common/ref/com/sun/star/table/module-ix.html
http://openoffice-docj.osdn.jp/tr/translated/DevelopersGuide/FirstSteps/FirstSteps.htm
http://openoffice3.web.fc2.com/JavaScript_Macro.html