You are on page 1of 19

Calc Guide

Chapter Calc Macros


Automating repetitive tasks
This PDF is designed to be read onscreen, two pages at a time. If you want to print a copy, your PDF viewer should have an option for printing two pages on one sheet of paper, but you may need to start with page 2 to get it to print facing pages correctly. (Print this cover page separately.

12

Copyright
This document is !opyright 2""#$2"%" by its contributors as listed in the section titled Authors. &ou may distribute it and'or modify it under the terms of either the ()* (eneral Public +icense, version , or later, or the !reative !ommons -ttribution +icense, version ,." or later. -ll trademar.s within this guide belong to their legitimate owners.

Authors
-ndrew Pitonya. (ary /chnabl 0ean 1ollis 2eber !laire 2ood

Feedback
3aintainer4 -ndrew Pitonya. 5andrew6pitonya..org7 Please direct any comments or suggestions about this document to4 authors6documentation.openoffice.org

Publication date and software version


Published 8 0une 2"%". 9ased on :pen:ffice.org ,.2.

You can download an editable version of this document from


http://oooauthors.org/english/userguide3/published/

Contents
!opyright............................................................................................... 2 Introduction........................................................................................... ; *sing the macro recorder......................................................................; 2rite your own functions.......................................................................< *sing a macro as a function..............................................................%% Passing arguments to a macro..........................................................%; -rguments are passed as values.......................................................%# 2riting macros that act li.e built=in functions..................................%8 -ccessing cells directly........................................................................%8 /orting................................................................................................. %> !onclusion...........................................................................................%?

Calc Macros

Introduction
- macro is a saved se@uence of commands or .eystro.es that are stored for later use. -n eAample of a simple macro is one that BtypesC your address. The :pen:ffice.org (::o macro language is very fleAible, allowing automation of both simple and compleA tas.s. 3acros are especially useful to repeat a tas. the same way over and over again. This chapter briefly discusses common problems related to macro programming using !alc.

Using the macro recorder


!hapter %, of the Getting tarted guide ((etting /tarted with 3acros provides a basis for understanding the general macro capabilities in :pen:ffice.org using the macro recorder. -n eAample is shown here without the eAplanations in the Getting tarted guide. The following steps create a macro that performs paste special with multiply. % :pen a new spreadsheet. 2 Dnter numbers into a sheet.

!igure ": #nter numbers , /elect cell -,, which contains the number ,, and copy the value to the clipboard. ; /elect the range -%4!,. # *se Tools > Macros > Record Macro to start the macro recorder. The Eecord 3acro dialog is displayed with a stop recording button.

!igure $:

top recording button

Calc Macros

8 *se Edit > Paste Special to open the Paste /pecial dialog.

!igure 3: &aste

pecial dialog

> /et the operation to Multiply and clic. OK. The cells are now multiplied by ,.

!igure %: Cells multiplied b' 3 < !lic. Stop Recording to stop the macro recorder. The :pen:ffice.org 9asic 3acros dialog opens. ? /elect the current document (see Figure # . For this eAample, the current !alc document is (ntitled ". DAisting documents show a library named /tandard. This library is not created until the document is saved or the library is needed, so at this point your new document does not contain a library. &ou can create a new library to contain the macro, but this is not necessary.

(sing the macro recorder

1 My Macros OpenOffice.org Macros " Open documents $ Create new library

5 Create new module in library ! Macros in selected library # Current document % Expand/collapse list

!igure ): &arts of the *pen*ffice.org +asic Macros dialog %" !lic. New Module. If no libraries eAist, then the /tandard library is automatically created and used. In the )ew 3odule dialog, type a name for the new module or leave the name as 3odule%.

%% !lic. OK to create a new module named 3odule%. /elect the newly created 3odule%, type PasteMultiply in the Macro name boA at the upper left, and clic. Save. (/ee Figure 8.

Calc Macros

!igure ,:

elect the module and name the macro

The created macro is saved in 3odule% of the /tandard library in the (ntitled " document. +isting % shows the contents of the macro. -isting ". &aste special with multipl'.
sub PasteMultiply rem -------------------------------------------------------------rem define variables dim document as object dim dispatcher as object rem -------------------------------------------------------------rem get access to the document document = ThisComponent.CurrentController.Frame dispatcher = createUno ervice!"com.sun.star.frame.#ispatch$elper"% rem -------------------------------------------------------------dim args&!'% as ne( com.sun.star.beans.Property)alue args&!*%.+ame = "Flags" args&!*%.)alue = "," args&!&%.+ame = "FormulaCommand" args&!&%.)alue = args&!.%.+ame = " /ip0mptyCells" args&!.%.)alue = false args&!-%.+ame = "Transpose" args&!-%.)alue = false args&!1%.+ame = ",s2in/" args&!1%.)alue = false args&!'%.+ame = "MoveMode" args&!'%.)alue = 1 dispatcher.e3ecute#ispatch!document4 ".uno56nsertContents"4 ""4 *4 args&!%% end sub

(sing the macro recorder

3ore detail on recording macros is provided in !hapter %, ((etting /tarted with 3acros in the Getting tarted guideF we recommend you read it if you have not already done so. 3ore detail is also provided in the following sections, but not as related to recording macros.

&rite your own functions


!alc can call macros as !alc functions. *se the following steps to create a simple macro4 % !reate a new !alc document named CalcTestMacros.ods. 2 *se Tools > Macros > Organize Macros > OpenO ice!org "asic to open the :pen:ffice.org 9asic 3acros dialog. The Macro from boA lists available macro library containers including currently open ::o documents. M' Macros contains macros that you write or add to ::o. *pen*ffice.org Macros contains macros included with ::o and should not be changed.

!igure .: *pen*ffice.org +asic Macros dialog , !lic. Organizer to open the :pen:ffice.org 9asic 3acro :rganiGer dialog. :n the +ibraries tab, select the document to contain the macro.

Calc Macros

!igure /: *pen*ffice.org +asic Macro *rgani0er ; !lic. New to open the )ew +ibrary dialog.

!igure 1: 2ew -ibrar' dialog # Dnter a descriptive library name (such as -uthors!alc3acros and clic. OK to create the library. The new library name is shown the library list, but the dialog may show only a portion of the name.

!igure "3: 4he librar' is shown in the organi0er

5rite 'our own functions

8 /elect -uthors!alc3acros and clic. Edit to edit the library. !alc automatically creates a module named 3odule% and a macro named 3ain.

!igure "": +asic 6ntegrated 7evelopment #nvironment 867#9 > 3odify the code so that it is the same as that shown in +isting 2.The important addition is the creation of the NumberFive function, which returns the number five. The Option Explicit statement forces all variables to be declared before they are used. If :ption DAplicit is omitted, variables are automatically defined at first use as type Hariant. < /ave the modified 3odule%. -isting $. !unction that returns five.
70M 88888 9, 6C :ption 03plicit ub Main 0nd ub 88888

Function +umberFive!% +umberFive = ' 0nd Function

"3

Calc Macros

Using a macro as a function


*sing the newly created !alc document CalcTestMacros.ods, enter the formula =NumberFive() (see Figure %2 . !alc finds the macro and calls it.

!igure "$: (se the 2umber!ive89 Macro as a Calc function 'ip


Function names are not case sensitive. In Figure %2, you can enter =NumberFive() and !alc clearly shows =N M!E"F#$E().

/ave the !alc document, close it, and open it again. Depending on your settings in Tools > Options > OpenO ice!org > Security > Macro Security, !alc will dislay the warning shown in Figure %, or the one shown in Figure %;. &ou will need to clic. Ena#le Macros, or !alc will not allow any macros to be run inside the document. If you do not eApect a document to contain a macro, it is safer to clic. $isa#le Macros in case the macro is a virus.

!igure "3: **o warns 'ou that a document contains macros

5rite 'our own functions

""

!igure "%: 5arning if macros are disabled If you choose to disable macros, then when the document loads, !alc can no longer find the function.

!igure "): 4he function is gone 2hen a document is created and saved, it automatically contains a library named /tandard. The /tandard library is automatically loaded when the document is opened. )o other library is automatically loaded. !alc does not contain a function named )umberFive( , so it chec.s all opened and visible macro libraries for the function. +ibraries in *pen*ffice.org Macros, M' Macros, and the !alc document are chec.ed for an appropriately named function (see Figure > . The )umberFive( function is stored in the -uthors!alc3acros library, which is not automatically loaded when the document is opened. *se Tools > Macros > Organize Macros > OpenO ice!org "asic to open the :pen:ffice.org 9asic 3acros dialog (see Figure %8 . DApand !alcTest3acros and find -uthors!alc3acros. The icon for a loaded library is a different color from the icon for a library that is not loaded. !lic. the eApansion symbol (usually a plus or a triangle neAt to -uthors!alc3acros to load the library. The icon changes color to indicate that the library is now loaded. !lic. %lose to close the dialog. *nfortunately, the cells containing I)umberFive( are in error. !alc does not recalculate cells in error unless you edit them or somehow change them. The usual solution is to store macros used as functions in the /tandard library. If the macro is large or if there are many macros,
"$ Calc Macros

a stub with the desired name is stored in the /tandard library. The stub macro loads the library containing the implementation and then calls the implementation. % *se Tools > Macros > Organize Macros > OpenO ice!org "asic to open the :pen:ffice.org 9asic 3acros dialog. /elect the )umberFive macro and clic. Edit to open the macro for editing.

!igure ",: elect a macro and click #dit 2 !hange the name of )umberFive to )umberFiveJImplementation (see +isting , . -isting 3. Change the name of 2umber!ive to 2umber!ive:6mplementation
Function NumberFive%#mplementation() NumberFive%#mplementation() = & End Function

, In the 9asic IDD (see Figure %% , hover the mouse cursor over the toolbar buttons to display the tool tips. !lic. the Select Macro button to open the :pen:ffice.org 9asic 3acros dialog (see Figure %8 . ; /elect the /tandard library in the !alcTest3acros document and clic. New to create a new module. Dnter a meaningful name such as !alcFunctions and clic. OK. ::o automatically creates a macro named 3ain and opens the module for editing. # !reate a macro in the /tandard library that calls the implementation function (see +isting ; . The new macro loads the -uthors!alc3acros library if it is not already loaded, and then calls the implementation function.

5rite 'our own functions

"3

8 /ave, close, and reopen the !alc document. This time, the )umberFive( function wor.s. -isting %. Change the name of 2umber!ive to 2umber!ive:6mplementation.
Function +umberFive!% 6f +:T 9asic2ibraries.is2ibrary2oaded!",uthorsCalcMacros"% Then 9asic2ibraries.2oad2ibrary!",uthorsCalcMacros"% 0nd 6f +umberFive = +umberFive;6mplementation!% 0nd Function

Passing arguments to a macro


To illustrate a function that accepts arguments, we will write a macro that calculates the sum of its arguments that are positive it will ignore arguments that are less than Gero (see +isting # . -isting ). &ositive um calculates the sum of the positive arguments.
Function Positive um!:ptional 3% #im The um ,s #ouble #im i7o( ,s 6nteger #im iCol ,s 6nteger The um = *.* 6f +:T 6sMissing!3% Then 6f +:T 6s,rray!3% Then 6f 3 < * Then The um = 3 0lse For i7o( = 29ound!34 &% To U9ound!34 &% For iCol = 29ound!34 .% To U9ound!34 .% 6f 3!i7o(4 iCol% < * Then The um = The um = 3!i7o(4 iCol% +e3t +e3t 0nd 6f 0nd 6f Positive um = The um 0nd Function

The macro in +isting # demonstrates a couple of important techni@ues4 % The argument x is optional. If the argument is not optional and it is called without an argument, ::o prints a warning message every time the macro is called. If !alc calls the function many times, then the error is displayed many times. 2 #sMissin' chec.s that an argument was passed before the argument is used.
"% Calc Macros

, #s(rray chec.s to see if the argument is a single value, or an array. For eAample, =Positive)um(*) or =Positive)um((+). In the first case, the number > is passed as an argument, and in the second case, the value of cell -; is passed to the function. ; If a range is passed to the function, it is passed as a two= dimensional array of valuesF for eAample, =Positive)um((,-!&). .!ound and !ound are used to determine the array bounds that are used. -lthough the lower bound is one, it is considered safer to use .!ound in case it changes in the future.
The macro in +isting # is careful and chec.s to see if the argument is an array or a single argument. The macro does not verify that each value is numeric. &ou may be as careful as you li.e. The more things you chec., the more robust the macro is, and the slower it runs.

'ip

Passing one argument is as easy as passing two4 add another argument to the function definition (see +isting 8 . 2hen calling a function with two arguments, separate the arguments with a semicolonF for eAample, =TestMax(/& 0+). -isting ,. 4estMa; accepts two arguments and returns the larger of the two.
Function TestMa3!34 y% 6f 3 <= y Then TestMa3 = 3 0lse TestMa3 = y 0nd 6f 0nd Function

Arguments are passed as values


-rguments passed to a macro from !alc are always values. It is not possible to .now what cells, if any, are used. For eAample, =Positive)um((/) passes the value of cell -,, and Positive/um has no way of .nowing that cell -, was used. If you must .now which cells are referenced rather than the values in the cells, pass the range as a string, parse the string, and obtain the values in the referenced cells.

5rite 'our own functions

")

&riting macros that act like built(in functions


-lthough !alc finds and calls macros as normal functions, they do not really behave as built=in functions. For eAample, macros do not appear in the function lists. It is possible to write functions that behave as regular functions by writing an -dd=In. 1owever, this is an advanced topic that is not covered hereF see http4''wi.i.services.openoffice.org'wi.i'/imple!alc-ddIn.

Accessing cells directly


&ou can access the ::o internal obKects directly to manipulate a !alc document. For eAample, the macro in +isting > adds the values in cell -2 from every sheet in the current document. T1isComponent is set by /tar9asic when the macro starts to reference the current document. !alc document contains sheets4 T1isComponent.'et)1eets(). *se 'etCell!yPosition(col2 ro3) to return a cell at a specific row and column. -isting .. Add cell A$ in ever' sheet.
Function umCells,ll heets!% #im The um ,s #ouble #im i ,s integer #im o heets #im o heet #im oCell o heets = ThisComponent.get heets!% For i = * To o heets.getCount!% - & o heet = o heets.get9y6nde3!i% oCell = o heet.getCell9yPosition!*4 &% > ?etCell ,. The um = The um = oCell.get)alue!% +e3t umCells,ll heets = The um 0nd Function

'ip

- cell obKect supports the methods 'et$alue(), 'et)trin'(), and 'etFormula() to get the numerical value, the string value, or the formula used in a cell. *se the corresponding set functions to set appropriate values.

*se o)1eet.'etCell"an'e!yName(4(,4) to return a range of cells by name. If a single cell is referenced, then a cell obKect is returned. If a cell range is given, then an entire range of cells is returned (see +isting < . )otice that a cell range returns data as an array of arrays,
", Calc Macros

which is more cumbersome than treating it as an array with two dimensions as is done in +isting #. -isting /. Add cell A$:C) in ever' sheet
Function umCells,ll heets!% #im The um ,s #ouble #im i7o( ,s 6nteger4 iCol ,s 6nteger4 i ,s 6nteger #im o heets4 o heet4 oCells #im o7o(!%4 o7o(s!% o heets = ThisComponent.get heets!% For i = * To o heets.getCount!% - & o heet = o heets.get9y6nde3!i% oCells = o heet.getCell7ange9y+ame!",.5C'"% 70M get#ata,rray!% returns the data as variant so strings 70M are also returned. 70M get#ata!% returns data data as type #ouble4 so only 70M numbers are returned. o7o(s!% = oCells.get#ata!% For i7o( = 29ound!o7o(s!%% To U9ound!o7o(s!%% o7o(!% = o7o(s!i7o(% For iCol = 29ound!o7o(!%% To U9ound!o7o(!%% The um = The um = o7o(!iCol% +e3t +e3t +e3t umCells,ll heets = The um 0nd Function

'ip

2hen a macro is called as a !alc function, the macro cannot modify any value in the sheet from which the macro was called.

)orting
!onsider sorting the data in Figure %>. First, sort on column 9 descending and then column - ascending.

!igure ".:
orting

ort column + descending and column A ascending


".

The eAample in +isting ?, however, demonstrates how to sort on two columns. -isting 1. ort cells A":C) on heet ".
ub ort7ange #im o heet #im oCell7ange 70M 70M 70M 70M #im

> Calc sheet containing data to sort. > #ata range to sort.

,n array of sort fields determines the columns that are sorted. This is an array (ith t(o elements4 * and &. To sort on only one column4 use5 #im o ortFields!*% ,s +e( com.sun.star.util. ortField o ortFields!&% ,s +e( com.sun.star.util. ortField

70M The sort descriptor is an array of properties. 70M The primary property contains the sort fields. #im o ort#esc!*% ,s +e( com.sun.star.beans.Property)alue 70M ?et the sheet named " heet&" o heet = ThisComponent. heets.get9y+ame!" heet&"% 70M ?et the cell range to sort oCell7ange = o heet.getCell7ange9y+ame!",&5C'"% 70M elect the range to sort. 70M The only purpose (ould be to emphasi@e the sorted data. >ThisComponent.getCurrentController.select!oCell7ange% 70M The columns are numbered starting (ith *4 so 70M column , is *4 column 9 is &4 etc. 70M ort column 9 !column &% descending. o ortFields!*%.Field = & o ortFields!*%. ort,scending = F,2 0 70M 6f column 9 has t(o cells (ith the same value4 70M then use column , ascending to decide the order. o ortFields!&%.Field = * o ortFields!&%. ort,scending = True 70M etup the sort descriptor. o ort#esc!*%.+ame = " ortFields" o ort#esc!*%.)alue = o ortFields!% 70M ort the range. oCell7ange. ort!o ort#esc!%% 0nd ub

"/

Calc Macros

Conclusion
This chapter provides a brief overview on how to create libraries and modules, using the macro recorder, using macros as !alc functions, and writing your own macros without the macro recorder. Dach topic deserves at least one chapter, and writing your own macros for !alc could easily fill an entire boo.. In other words, this is Kust the beginning of what you can learnL

Conclusion

"1

You might also like