(因みに「マクロの一歩」で記す文法はExcelのVBAとほぼ同じです。LibreOffice Basic初心者は必見です。)
Cell操作
[ 取得・代入 ]
Sub EnetrCell()
Dim oDoc as Object
Dim oSheet as Object
oDoc = ThisComponent
oSheet = oDoc.getSheets().getByIndex(0)
oSheet.getCellByPosition(0,0).value=1
oSheet.getCellByPosition(0,1).String="test"
oSheet.getCellByPosition(0,2).Formula="=A1*10"
msgbox "Success", 0, "LO7.0.4.2"
End Sub
ThisComponentは本file。Excel風に言うとWorkBooks(1)。
.getSheets().getByIndex(0)はSheet1の事( 省略系はSheets(0) )。
Excel風に言うとWorkSheets(1)。
oSheet.getCellByPosition(0,0).value=1は
Sheet1のセルA1に数値データ(value)型の1が入力されるという事。
Excel風に言うとWorkbooks(1).Worksheets(1).cells(1,1).Value = 1。
oSheet.getCellByPosition(0,1).String="test"は
セルA2に文字列型データ(String)の"test"が入力される。
oSheet.getCellByPosition(0,1).Formula="=A1*10"は
セルA3に数式(Formula)の"=A1*10"が入力される。
ここで、VBAではcells(行,列)であるが、
LibreOffice BasicではgetCellByPosition(列,行)である事に注意。
また、VBAでは 1 から始めるが、LibreOffice Basicでは 0 から始まる
つまり、上記をExcel VBAにて表すと以下の様になる。
[Excel VBAでの記述]
Sub mainVBA()
Workbooks(1).Worksheets(1).Cells(1, 1).Value = 1
Workbooks(1).Worksheets(1).Cells(2, 1).Value = "test"
Workbooks(1).Worksheets(1).Cells(3, 1).Formula = "=A1*10"
End Sub
Sub CalcBasic()
Dim oDoc as Object, oSheet as Object
Dim oCell1 as Object, oCell2 as Object, oCell3 as Object
oDoc = ThisComponent
'
oSheet = oDoc.getSheets().getByName("Sheet1")
'
oCell1 = oSheet.getCellRangeByName("A1")
oCell2 = oSheet.getCellRangeByName("A3")
oCell3 = oSheet.getCellRangeByName("A5")
'
oCell1.String = "Test1"
oCell2.Value = 10
oCell3.Formula = "=A3*5 "
msgbox "Success", 0, "Cellに入力"
End Sub
VBAでSheet名で指定する時は
WorkSheets("Sheet1")であるが、
Calcの場合は
getSheets().getByName("Sheet1")となる。
VBAでA1形式で指定する時は
.Range("A1") ですが、
LibreOffice Basic では
.getCellRangeByName("A1")
Sub SampleCode()
GlobalScope.BasicLibraries.LoadLibrary("ScriptForge")
Dim oDoc as Object
Dim oSheet as Object
Set oDoc = CreateScriptService("Calc", ThisComponent)
oDoc.SetValue("Sheet1.A1:A2", Array(100,"ScriptForge"))
oDoc.SetFormula("Sheet1.A3", "=A1/2")
'oSheet.getCellByPosition(0,1).String="test"
'oSheet.getCellByPosition(0,2).Formula="=A1*10"
msgbox "Success", 0, "LO7.5.2.2"
End Sub
ScriptForge を利用したコードです。
本コードでの利点は、Value と Stringを意識することなく、代入できることです。(VBAと同じになります)
ScriptForgeを使わない場合、形式を区別する必要があります。
以下のコードでは、A1には Test でなく 0 が入力されます。
Sub ExamleCode()
Dim oDoc as Object, oSheet as Object
Dim oCell1 as Object, oCell2 as Object, oCell3 as Object
oDoc = ThisComponent
oSheet = oDoc.getSheets().getByName("Sheet1")
oCell = oSheet.getCellRangeByName("A1")
oCell.Value = "Test"
msgbox "Success", 0, "LO.7.5.2.2"
End Sub
一方、欠点は ScriptForge は
svc.SetValue(targetrange: str, value: any): str
で定義されているので、targetrange(Cellアドレス)をstr型に変更する必要があります。
Sub EnterCell()
Dim oDoc as Object, oCtrl as Object, oFrame as Object
Dim oDispatcher as Object
Dim oProp(0) as new com.sun.star.beans.PropertyValue
oDoc = ThisComponent
oCtrl = oDoc.getCurrentController()
oFrame = oCtrl.getFrame()
oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
'
oProp(0).Name = "ToPoint"
oProp(0).Value = "A1"
oDispatcher.executeDispatch(oFrame, ".uno:GoToCell", "", 0, oProp())
'
oProp(0).Name = "StringName"
oProp(0).Value = "1"
oDispatcher.executeDispatch(oFrame, ".uno:EnterString", "", 0, oProp())
'
oProp(0).Name = "ToPoint"
oProp(0).Value = "A2"
oDispatcher.executeDispatch(oFrame, ".uno:GoToCell", "", 0, oProp())
'
oProp(0).Name = "StringName"
oProp(0).Value = "test"
oDispatcher.executeDispatch(oFrame, ".uno:EnterString", "", 0, oProp())
'
oProp(0).Name = "ToPoint"
oProp(0).Value = "A3"
oDispatcher.executeDispatch(oFrame, ".uno:GoToCell", "", 0, oProp())
'
oProp(0).Name = "StringName"
oProp(0).Value = "=A1*10"
oDispatcher.executeDispatch(oFrame, ".uno:EnterString", "", 0, oProp())
'
msgbox "Success" & Chr$(10) & "( DispatchHelper )"
End Sub
『Cellに値(数字 & 文字列 & 式)を代入する』を「マクロの記録」のコードにしたものです。
LibreOfficeのマクロの記録は
createUnoService("com.sun.star.frame.DispatchHelper")
で実行できるものだけでそれ以外は記録されません。
従い、マクロの記録のコードの文法はシンプルです。
MS-Officeでも記録されない処置はあるので同じと言えば同じですが、記録される処置が多いです。
但しMS-Officeの「マクロの記録」のコードを理解するにはそれなりにVBAの知識が必要です。
[参考1]
MS-Officeにおいて 『「マクロ」と「VBA」は同じ(同意語)か?』について
あるサイトでは「同じ」、別のサイトでは「違う」とマクロやVBAを紹介しているサイトでも意見が割れています。
言葉の意味だけで言えば
・マクロ : 処置を再現実行すること。
・VBA : Visual Basic for Application。 つまりMS-Office用のプログラミング言語(Visual Basic:VB)。
でしょう
MS-Office以外のApplicationにもマクロという機能はありますが、それは「処置を再現実行」です。
事実、MS-ACCESSは ver2003 までマクロと言えば、各クエリ処置を連続的に実行するものでした。
そしてMS-ACCESS ver2003には マクロとは別に VBAの機能がついており、マクロと同じ処置をVBAで記述する事が出来ました。
これを見ると「マクロ」と「VBA」は別ものと言えるかもしれません。
ただ、MS-Excelの処置を細分化されたもの(マクロ)は VBAの文法で表されますので、マクロ ≒ VBA と考えても間違いではないでしょう。
結果、Excelの「マクロの記録」は「コード作成機能」という側面が強いです。(但し、かなりアバウトなコードです。。。が)
一方、LibReOfficeの「マクロの記録」は各手順毎にコードが記録されるので 「コード作成機能」ではなく、純粋に「マクロの記録」です。
また「マクロの記録」で記録されるコードは com.sun.star.frame.DispatchHelper で実行できるものだけです。
結果、マクロの記録で記されるコードは 通常のLibreOffice Basic のコードとは異なります。
従い非常に簡単で少ない処置の再現処置には有効ですが少し複雑や処理量が多いものは「マクロの記録」のコードは不向きです。
詳しくは Macroの記録 参照
形式によって入力値を取得
Sub CetCellVauleString()
Dim oDoc as Object
Dim oSheet as Object
Dim oCellType as Long
Dim oCell(3) as Variant
Dim oDisp as String
oDoc = ThisComponent
oSheet = oDoc.getSheets().getByIndex(0)
'
oDisp = "[ Cell 値取得 ]" & Chr$(10)
for i = 0 to 3
oCellType = oSheet.getCellByPosition(0, i ).getType()
Select Case oCellType
case com.sun.star.table.CellContentType.EMPTY
oCell( i ) = "空白です。"
case com.sun.star.table.CellContentType.VALUE
oCell( i ) = oSheet.getCellByPosition(0, i ).Value
case com.sun.star.table.CellContentType.TEXT
oCell( i ) = oSheet.getCellByPosition(0, i ).String
case com.sun.star.table.CellContentType.FORMULA
oCell( i ) = oSheet.getCellByPosition(0, i ).Formula
case Else
oCell( i ) = "不正な型のDataです。"
End Select
'
oDisp = oDisp & "A" & i & " Cell の値 : " & oCell( i ) & Chr$(10)
next i
msgbox(oDisp,0,"各Cellの値")
End Sub
【 解説 】
入力値の形式によって入力値を取得しています.
Excel VBA利用者が面食う違いの1つが、データの取得方法です。
VBAでは .Value でどんなもの形式のセルでも一応、値を取得することが可能です。
(VBAでも .Value と .Text のデータ取得値が違う場合もありますが。)
一方、LibreOffice Basicでは下記コードのように 入力値の形式に関わらず .Valueで取得した場合は、
文字列と空白は 0 になります。
入力形式に関係なく、値を取得したいときは .getDataArray()を使いましょう(Cellの値を高速取得 を参照)
Sub CetCellVauleString()
Dim oDoc as Object
Dim oSheet as Object
Dim oCell(3) as Variant
Dim oDisp as String
oDoc = ThisComponent
oSheet = oDoc.getSheets().getByIndex(0)
'
oDisp = "[ Cell 値取得 ]" & Chr$(10) & _
"( 全て.Valueで取得した場合 )" & Chr$(10)
for i = 0 to 3
oCell( i ) = oSheet.getCellByPosition(0, i ).Value
oDisp = oDisp & "A" & i+1 & " Cell の値 : " & oCell( i ) & Chr$(10)
next i
msgbox(oDisp,0,"各Cellの値")
End Sub