最近剛好有數據分析的需求

想在Calc上寫個程式來加快我的數據分析的前置工作

(弄些自動改格式、儲存格上色、儲存格取值作判斷等的小動作)

因為要重複做同樣的事

所以想說寫個巨集來把上述的動作自動化

不過我只寫過C,沒碰過VB這類的語言

想說網路上是不是有新手教程可以看

結果一搜發現:資料還真是少!?

 

只看到這篇

其他中文網頁有可以直接套用的文章就很少了

對岸的CSDN上是有一些教程,不過下載還要點數,有點麻煩

所以我就開始自己搞了~

 

我一開始是直接用CALC的巨集直接錄下我在CALC上的動作

然後去看程式碼,把程式碼拆解成可用的小方塊來使用

這樣我就可以在不花太多時間去研究Basic的語法的情況下

實作出我想要的功能

不過目前LibreOffice(7.2.2版)的錄製巨集功能好像還很陽春

好像在CALC上只能錄製對儲存格的操作

所以這招還是有些限制的

 

後來我又研究了一段時間,找英文的資料

發現其實官網是有快速上手的指令參考的

官網的參考文件頁面是這個

PDF連結

用上面那個文件,基本上就可以很快地拼出你想要的基礎功能

 

====

下面寫寫我在網路上看了幾篇文章的小結論,可以參考參考:

 

在網路上搜尋『Porting Excel/VBA to Calc/StarBasic』(2004) 連結

裡面有寫到:LibreOffice Basic的語法跟VB應該是完全相通的

差別在於Calc 跟 Excel的架構:Calc是完全的物件導向,Excel則不是

Excel少了繼承這個部分

 

我又看到另一篇文章『OOP In VBA?

在講Excel不是完全的物件導向設計,會有什麼問題

作者的結論是:其實也不一定完全是缺點

反正好用就好了,呵呵

 

像CALC是完全的物件導向,可是code就是超級長一串

對新手(像我就是)來說其實也不是很友善

 

總之,如果你就是剛好需要使用CALC(譬如不想用盜版MS Office or 其他)

那就只好接受CALC的設計,想辦法去讓code動起來

 

以下分享一些前面講的用巨集弄出來的code

給大家參考參考,基本上組一組就可以用了

底色是灰色的是code,說明加在code後面

至於官網的參考文件,我研究研究有什麼心得再PO上來吧~

======

1. 常用code功能區塊

 <<宣告物件>>

dim document   as object
dim dispatcher as object

document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

 

說明:給完全沒碰過VB的人的解釋一下基礎語法

dim = dimensions,是Basic語言中的宣告的意思(這有些典故,欲知詳情請查英文資料)

rem => 註解 ,另外『`』也是註解

document , dispatcher 都宣告成物件,當作Handle

這兩個物件在後面每個模塊要設定的時候都會用到

基本上複製貼上就好了

 

<<選擇範圍>>

dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$A$1:$N$36"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

 

 

<<修改格子內的文字顏色>>

dim args5(0) as new com.sun.star.beans.PropertyValue
args5(0).Name = "Color"
args5(0).Value = 0

dispatcher.executeDispatch(document, ".uno:Color", "", 0, args5())

說明:

0=黑色

不同顏色請上網查RGB色碼表

例如黃色等於(0xFFFF00)

 

<<修改字型為粗體>>

dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Bold"
args2(0).Value = true

dispatcher.executeDispatch(document, ".uno:Bold", "", 0, args2())

 

<<修改字型大小>>

dim args4(2) as new com.sun.star.beans.PropertyValue
args4(0).Name = "FontHeight.Height"
args4(0).Value = 12
args4(1).Name = "FontHeight.Prop"
args4(1).Value = 100
args4(2).Name = "FontHeight.Diff"
args4(2).Value = 0

dispatcher.executeDispatch(document, ".uno:FontHeight", "", 0, args4())

說明:上面是錄製巨集自動產生的code

有沒有能刪掉的,我也不確定

可以自己實驗看看

懶的實驗就整個貼上去用

 

2. Code

下面的code建議可以直接貼到CALC的巨集中,直接執行看看

在那邊看半天其實效率不太好(對外行人來說)

PS: 下面的code基本上很不簡潔,基本上就是把不同模塊拼湊起來而已

功能有達到就好,VB專業的勿鞭XD",我也是外行人

 

<<設定一個範圍的顏色 >>

REM  *****  BASIC  *****

Sub Main

    dim document   as object
    dim dispatcher as object
    dim szRange
    rem ----------------------------------------------------------------------
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
    

    szRange=MakeRangeString("R", 10, "R", 25)
    msgbox (szRange)
    SelectRange_ChangeColor(document, dispatcher, szRange)
    

End Sub


sub SelectRange_ChangeColor(document as object, dispatcher as object, szRange as string)

    dim args2(0) as new com.sun.star.beans.PropertyValue
    args2(0).Name = "ToPoint"
'    args2(0).Value = "$O$10:$O$25"
    args2(0).Value = szRange
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args2())

    rem ----------------------------------------------------------------------
    dim args3(0) as new com.sun.star.beans.PropertyValue
    args3(0).Name = "BackgroundColor"
    args3(0).Value = 16776960
    dispatcher.executeDispatch(document, ".uno:BackgroundColor", "", 0, args3())
end sub

 

function MakeRangeString(szStartCol as String,  _
                         dStartRow as Integer, _
                         szEndCol as String,    _
                         dEndRow as Integer) as String

    MakeRangeString="$" & szStartCol & "$" & CStr(dStartRow) & ":$" & szEndCol & "$" & CStr(dEndRow)

end function

 

給Basic語言新手的說明:

Basic有兩種函式宣告

Sub是沒有回傳值的

Function是有回傳值的,回傳值是用函數名稱傳出去

rem後面是註解,只是排版用的,不要理他

另外,CALC中字串拼接可以使用"&"

 

另外document  跟 dispatcher 其實可以宣告成全域變數,拉到Main外面去就好了

function宣告後面那個『_』是換行的符號

這樣就可以不用寫一長串擠在一行裡,很不好看

 

<<改特定行的顏色 & 設置Filter>>

 

REM  *****  BASIC  *****
rem ==== color table ====
const clrYELLOW_DARK          = &hF9F900
const clrYELLOW             = &hFFFF00
const clrYELLOW_LIGHTER    = &hFFFFAA
const clrYELLOW_LIGHT         = &hFFFFDF


const clrGOLD_DARK        = &hEAC100
const clrGOLD              = &hFFDC35
const clrGOLD_LIGHTER  = &hFFED97
const clrGOLD_LIGHT       = &hFFF8D7

const clrORANGE               = &hFFA042
const clrORANGE_LIGHTER  = &hFFBB77
const clrORANGE_LIGHT       = &hFFDCB9

const clrGREEN_DARK   = &h73BF00
const clrGREEN               = &h8CEA00
const clrGREEN_LIGHTER  = &hA8FF24
const clrGREEN_LIGHT       = &hD3FF93

rem =====================
Sub Main

    dim document   as object
    dim dispatcher as object
    dim szRange
    rem ----------------------------------------------------------------------
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
    
    
    rem === set color for interested item ===
    szRange=MakeRangeString("C", 2, "C", 1000)
    SelectRange_ChangeColor(document, dispatcher, szRange, clrGREEN_DARK)
    
    szRange=MakeRangeString("E", 2, "E", 1000)
    SelectRange_ChangeColor(document, dispatcher, szRange, clrGREEN_DARK)
    
    szRange=MakeRangeString("G", 2, "G", 1000)
    SelectRange_ChangeColor(document, dispatcher, szRange, clrGREEN_DARK)
    
    
    rem === set color for parameters ====
    szRange=MakeRangeString("K", 2, "K", 1000)
    SelectRange_ChangeColor(document, dispatcher, szRange, clrGOLD_LIGHT)
    
    szRange=MakeRangeString("L", 2, "L", 1000)
    SelectRange_ChangeColor(document, dispatcher, szRange, clrGOLD_LIGHT)
    
    szRange=MakeRangeString("M", 2, "M", 1000)
    SelectRange_ChangeColor(document, dispatcher, szRange, clrGOLD_LIGHT)
    
    SetFilter(document, dispatcher)
    

End Sub

 


Sub SelectRange_ChangeColor(document as object, dispatcher as object, _
                            szRange as string, dColor as long)

    dim args(0) as new com.sun.star.beans.PropertyValue
    args(0).Name = "ToPoint"
    args(0).Value = szRange
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args())

    rem ----------------------------------------------------------------------
    args(0).Name = "BackgroundColor"
    args(0).Value = dColor
    dispatcher.executeDispatch(document, ".uno:BackgroundColor", "", 0, args())
    
End sub

 

Function MakeRangeString(szStartCol as String,  _
                         dStartRow as Integer,  _
                         szEndCol as String,    _
                         dEndRow as Integer)     _
                         as String

    MakeRangeString="$" & szStartCol & "$" & CStr(dStartRow) & ":$" & szEndCol & "$" & CStr(dEndRow)

End Function


Rem: Go to A1 and set filter
Sub SetFilter(document as object, dispatcher as object)

    dim args(0) as new com.sun.star.beans.PropertyValue
    args(0).Name = "ToPoint"
    args(0).Value = "$A$1"
    
    dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args())
    
    rem ----------------------------------------------------------------------
    dispatcher.executeDispatch(document, ".uno:DataFilterAutoFilter", "", 0, Array())


End Sub

 

=====

後面有什麼心得再來補上吧~

謝謝觀賞~

arrow
arrow
    文章標籤
    libreOffice basic calc
    全站熱搜

    迷途工程師 發表在 痞客邦 留言(0) 人氣()