# 2.3.2.1 Range Notation

## Introduction to Range

Inside your Origin Project, data exists in four primary places: in the columns of a worksheet, in a matrix, in a loose dataset, or in a graph. In any of these forms, the range data type allows you to access your data easily in a standard way.

Once a range variable is created, you can work with the range data directly; reading and writing to the range. Examples below demonstrate the creation and use of many types of range variables.

Before Origin Version 8.0, data were accessed via datasets as well as cell(), col(), and wcol() functions. The cell(), col(), and wcol() functions are still very effective for data access, provided that you are working with the active sheet in the active book. The Range notation essentially expanded upon these functions to provide general access to any book, sheet, or plot inside an Origin Project.

Note : Not all X-Functions can handle complexities of ranges such as multiple columns or noncontiguous data. Where logic or documentation does not indicate support, a little experimentation is in order.

Note : Data inside a graph are in the form of Data Plots and they are essentially references to columns, matrix or loose datasets. There is no actual data stored in graphs.

### Declaration and Syntax

Similar to other data types, you can declare a Range variable using the following syntax:

range [-option] RangeName = RangeString

The left-hand side of the range assignment is uniform for all types of range assignments. Note that the square brackets indicate that the option switch is an optional parameter and for different data type the available option switches are different, please view the Types of Range Data section for details. Range names follow Origin variable naming rules; please note that system variable names should be avoided.

The right-hand side of the range assignment, RangeString, changes depending on what type of object the range points to. Individual Range Strings are defined in the sections below on Types of Range Data. Range notation is used exclusively to define range variables. It cannot be used as a general notation for data access on either side of an expression.

### Accessing Origin Objects

A range variable can be assigned to the following types of Origin Objects:

Once assigned, the range will represent that object so that you can access the object properties and methods using the range variable.

range rA = [Book1]Sheet1!Col(A);
rA.name$=; rA.lname$=;
rA.unit$=; rA.index=; rA.nRows=; To determine which object properties and methods are accessible, open the Script Window and type the following: rangeVariable.=; ... where rangeVariable is the name of your range variable. A range may consist of some subset or some combination of standard Origin Objects. Examples include: ## Types of Range Data ### Worksheet Data For worksheet data, RangeString takes the form: [WorkBookName]SheetNameOrIndex!ColumnNameOrIndex[CellIndex]  Note: The WorkBookName andSheetName above used their corresponding Short Name since Short Name is the default programming name. To use Long Name in range notation for workbook or worksheet, you have to put Long Name in double quotes such as ["MyBook"]"MySheet"!; whereas ColumnName can be either the Long Name or the Short Name of the column. In any RangeString, a span of continuous sheets, columns, or rows can be specified by providing pairs of sheet, column, or row indices (respectively), separated by a colon, as in index1:index2. The keyword end can replace index2 to indicate that Origin should pick up all of the indicated objects. For example: range rs = [Book1]4:end! // Get sheets 4 through last range rd = [Book2]Sheet3!5:10; // Get columns 5 through 10 range rr = ["MyBook"]Sheet1!A; // Get column A in sheet 1 with workbook Long Name // as MyBook In the case of rows the indices must be surrounded by square brackets, so a full range assignment statement for several rows of a worksheet column looks like: range rc1 = [Book1]Sheet2!Col(3)[10:end]; // Get rows 10 through last range rc2 = [Book1]Sheet2!Col(3)[10:20]; // Get rows 10 through 20 The old way of accessing cell contents, via the Cell function is still supported. If you wish to access column label rows using range, please see Accessing Metadata and the Column Label Row Reference Table. #### Column When declaring a range variable for a column on the active worksheet, the book and sheet part can be dropped, such as: range rc = Col(3) You can further simplify the notation, as long as the actual column can be identified, as shown below: range aa=1; // col(1) of the active worksheet range bb=B; // col(B) of the active worksheet range cc="Test A"; // col with Long Name ("Test A"), active worksheet Note: the quotation mark used in the range string expression always refers to long name, even though the long name is identical to an expression of worksheet (e.g. 1!), the range string "1!" refers to the column with long name 1!. This behavior could be turned off by using the system variable @RPQ, for details please refer to this table. Multiple range variables can be declared on the same line, separated by comma. The above example could also have been written as: range aa = 1, bb = B, cc = "Test A"; Or if you need to refer to a different book sheet, and all in the same sheet, then the book sheet portion can be combined as follows: range ["MyBook"]Sheet3 aa=1, bb=B, cc="Test A"; //Book Long Name is MyBook Because Origin does not force a column's Long Name to be unique (i.e., multiple columns in a worksheet can have the same Long Name), the Short Name and Long Name may be specified together to be more precise: range dd = D"Test 4"; // Assign Col(D), Long Name 'Test 4', to a range Once you have a column range, use it to access and change the parameters of a column: range rColumn = [Book1]1!2; // Range is a Column rColumn.digitMode = 1; // Use Set Decimal Places for display rColumn.digits = 2; // Use 2 decimal places Or perform computations: // Point to column 1 of sheets 1, 2, and 3 of the active workbook: range aa = 1!col(1); range bb = 2!col(1); range cc = 3!col(1); cc = aa+bb; When performing arithmetic on data in different sheets, you need to use range variables. Direct references to range strings are not yet supported. For example, the script Sheet3!col(1) = Sheet1!col(1) + Sheet2!col(1); will not work! If you really need to write in a single line without having to declare range variables, then use Dataset Substitution. #### Page and Sheet Besides a single column of data, a range can be used to access any portion of a page object: Use a range variable to access an entire workbook: // 'rPage' points to the workbook named 'Book1' range rPage = [Book1]; // Set the Long Name of 'Book1' to "My Analysis Worksheets" rPage.LongName$ = My Analysis Worksheets;

Use a range variable to access a worksheet:

range rSheet = ["MyBook"]"MySheet"!;      // Range is a Worksheet (WKS object) with
// book Long Name MyBook, sheet Long Name
// MySheet
rSheet.name$= "Statistics"; // Rename Sheet1 to "Statistics". page.xlcolname = 0; //Turn off Spreadsheet Cell Notation firstly rSheet.AddCol(StdDev); // Add a column named StdDev For the Spreadsheet Cell Notation in the workbook, please see FAQ-849 for more information. #### Column Subrange Use a range variable to address a column subrange, such as // A subrange of col(a) in MyBook (Long Name) sheet2 range cc = ["MyBook"]sheet2!col(a)[3:10]; Or if the desired workbook and worksheet are active, the shortened notation can be used: // A subrange of col(a) in book1 sheet2 range cc = col(a)[3:10]; Using range variables, you can perform computation or other operations on part of a column. For example: range r1=1[5:10]; range r2=2[1:6]; r1 = r2; // copy values in row 1 to 6 of column 2 to rows 5 to 10 of column 1 r1=; // this should output value in row 5 of column 1, which equates to row 1 of column 2 #### Block of Cells Use a range to access a single cell or block of cells (may span many rows and columns) as in: range aa = 1; // cell(2,1), row2 of col(1) range bb = 1:3; // cell(1,1) to cell(10,3) Note: A range variable representing a block of cells can be used as an X-Function argument only, direct calculations are not supported. #### Option Switch -v Minimum Origin Version: 9.1 SR0 For worksheet data, you can use the -v switch to define a single block as a range and store its values in a temporary vector, so that the data assignment between blocks with same size but different block shape is possible (e.g. assign values from a row to a column would be possible). The following examples scales all entries in a particular row of columns in the workshet: // Scale 1st element of all columns except the last column, by a factor range -v r=1:$(wks.ncols-1);
r*=10;
// Scale 1st element of all columns
range -v r=1:end;
r*=10;

The following example illustrates how this option switch can be used.

//Import a sample data into a new book
fname$=system.path.program$ + "\Samples\Statistics\automobile.dat";
newbook;
impasc;
//Define a block as column B to C,all rows
range -v r1 = B:C[end];
// Create a new sheet
newsheet;
//Define a block as column A to B sized
range -v r2 = 1:2[r1.GetSize()/2]; // size of block is 2 columns x rows
//Assign the values in the first block to the second block
r2 = r1;

The vector stores data in column order and fills the destination block regardless of the 'shape':

// Import sample data into a new book
fname$=system.path.program$ + "\Samples\Statistics\abrasion_raw.dat";
newbook;
impasc;
// Define a block as column A & B, all rows
range -v ra1 = 1:2[end];
// Create a new sheet
newsheet;
// Define a block as one column, using the ra1 block size
range -v ra2 = 1[1:ra1.GetSize()];
// Assign the values in the first block to the second block
ra2 = ra1;
col(1)[L]$= Combined; Note: The columns defined by the target block must exist before the assignment is made. ### Matrix Data For matrix data, the RangeString is [MatrixBookName]MatrixSheetNameOrIndex!MatrixObject  Note: The MatrixBookName andMatrixSheetName above used their corresponding Short Name since Short Name is the default programming name. To use Long Name in range notation for matrixbook or matrixsheet, you have to put Long Name in double quotes such as ["MyMatrixBook"]"MyMatrixSheet"!. Variable assignment can be made using the follow syntax: // Second matrix object on MBook1, MSheet1 range mm = [MBook1]MSheet1!2; // Matrix object with Long Name MatObject1 on matrix sheet MatSheet1 (Long Name) // on matrix book MatBook1 (Long Name) range mo = ["MatBook1"]"MatSheet1"!Mat("MatObject1"); Access the cell contents of a matrix range using the notation RangeName[row, col]. For example: range mm=[MBook1]1!1; mm[2,3]=10; If the matrix contains complex numbers, the string representing the complex number can be accessed as below: string str$;
str$= mm[3,4]$;

### Graph Data

For graph data, the RangeString is

[GraphWindowName]LayerNameOrIndex!DataPlot

An example assignment looks like

range ll = [Graph1]Layer1!2;       // Second curve on Graph1, Layer1

#### Option Switches -w, -wx, -wy and -wz

For graph windows, you can use range -w and range -wx, range -wy, range -wz options to get the worksheet column range of a plotted dataset.

range -w always gets the worksheet range of the most dependent variable - which is the Y value for 2D plots and the Z value or matrix object for 3D plots. And since Origin 9.0 SR0, multiple ranges are supported for range -w.

range -wx, range -wy, and range -wz will get the worksheet range of the corresponding X, Y and Z values, respectively.

range -wx, range -wz Require Version: 9.0 SR0

// Make a graph window the active window ...
// Get the worksheet range of the Y values of first dataplot:
range -w rW = 1;

// Get the worksheet range of the corresponding X-values:
range -wx rWx = 1;

//Get the worksheet range of the corresponding Y-values:
range -wy rWy = 1;

//Get the worksheet range of the corresponding Z-values:
range -wz rWz = 1;

// Get the graph range of the first dataplot:
range rG = 1;

// Get the current selection (%C); will resolve data between markers.
range -w rC = %C;

Note that in the script above, rW = [Book1]Sheet1!B while rG = [Graph1]1!1.

#### Data Selector Ranges on a Graph

You can use the Data Selector tool to select one or more ranges on a graph and to refer to them from LabTalk. For a single selected range, you can use the MKS1, MKS2 system variables. Starting with version 8.0 SR6, a new X-Function, get_plot_sel, has been added to get the selected ranges into a string that you can then parse. The following example shows how to select each range on the current graph:

string strRange;
get_plot_sel str:=strRange;
StringArray sa;
sa.Append(strRange$,"|"); // Tokenize it int nNumRanges = sa.GetSize(); if(nNumRanges == 0) { type "there is nothing selected"; return; } type "Total of$(nNumRanges) ranges selected for %C";
for(int ii = 1; ii <= nNumRanges; ii++)
{
range -w xy = sa.GetAt(ii)$; string strWks$ = "Temp$(ii)"; create %(strWks$) -wdn 10 aa bb;
range fitxy = [??]!(%(strWks$)_aa, %(strWks$)_bb);
fitlr iy:=xy oy:=fitxy;
plotxy fitxy p:=200 o:=<active> c:=color(red) rescale:=0 legend:=0;
type "%(xy) fit linear gives slope=$(fitlr.b)"; } // clear all the data markers when done mark -r; Additional documentation is available for the the Create (Command) (for creating loose datasets), the [??] range notation (for creating a range from a loose dataset), the fitlr X-Function, and the StringArray (Object) (specifically, the Append method, which was introduced in Origin 8.0 SR6). ### Specifying Subrange Using X Values When working with an XY range, you can specify a subrange using the X values. The syntax is as follows: 1. From Worksheet [WorkBookName]SheetNameOrIndex!YColumnNameOrIndex[xX1:X2] Example: // Using Columns 1 and 2 for X and Y, specify subrange from x=0.15 to 0.2 range rxy = (1, 2)[x0.15:0.2]; 1. From Graph [GraphWindowName]LayerNameOrIndex!DataPlot[xX1:X2] Example: // XY subrange of the 2nd curve on Graph1, Layer1 range rxy2 = [Graph1]Layer1!2[x5:20]; The following example uses the plotxy X-Function to plot a graph, and then the smooth X-Function to smooth a subrange of the data. // Import data into a new book newbook; fname$ = system.path.program$+ "\Samples\Signal Processing\EMG Recording.dat"; impasc; // Define XY subrange, X from 5 to 5.5, and from 9.3 to 9.8 range rxy1 = (1, 2)[x5:5.5]; range rxy2 = 2[x9.3:9.8]; plotxy rxy1 plot:=200; // Plot line for the 1st XY subrange smooth -r 2 rxy2 method:=le; // Smooth the 2nd XY subrange by Loess method When specifying a subrange based on X values, the X data needs to be monotonic. ### Loose Dataset Loose Datasets are similar to columns in a worksheet but they don't have the overhead of the book-sheet-column organization. They are typically created with the create command, or automatically created from an assignment statement without Dataset declaration. The RangeString for a loose dataset is: [??]!LooseDatasetName Assignment can be performed using the syntax: range xx = [??]!tmpdata_a; // Loose dataset 'tmpdata_a' To show how this works, we use the plotxy X-Function to plot a graph of a loose dataset. // Create 2 loose datasets create tmpdata -wd 50 a b; tmpdata_a=data(50,1,-1); tmpdata_b=normal(50); // Declare the range and explicitly point to the loose dataset range aa=[??]!(tmpdata_a, tmpdata_b); // Make a scatter graph with it: plotxy aa; Loose datasets belong to a project, so they are different from a Dataset variable, which is declared, and has either session or local scope. Dataset variables are also internally loose datasets but they are limited to use in calculations only; they cannot be used in making plots, for example. ## Methods of Range Once a range variable is created, the following methods can be used by this range Method Description range.getSize() Return the size of the range. This method works for a dataset range, such as column, matrix object, graph plot, block of cells, loose dataset, etc. Note that, for a block of cells, it only returns the size of the first sub column specified in the range declaration. range.setSize() Set the size of the range. This method works for a dataset range, such as column, matrix object, graph plot, block of cells, loose dataset, etc. If the range is block of cells, it only set the size for the first sub column specified in the range declaration. range.getLayer() If the range has an attached layer (graph layer, worksheet, or matrix layer), this method will return the uid of the layer, to get the name of the layer, you need the$ sign after the method, such as "rng.getLayer()$= ". range.getPage() If the range has an attached page (graph page, workbook, or matrixbook), this method will return the uid of the page, to get the name of the page, you need the$ sign after the method, such as "rng.getPage()$= ". range.getop() If the range is a column in a worksheet or plot in a graph, this method will return the uid of the operation attached to the range. If the range is a worksheet (including hierarchical sheet), it will return the first operation's uid attached to this sheet range. range.sub(name/index) This method is used to get a subrange from a data range by either specifying a name or index. This method is only useful for virtual matrix. For example, with a virtual matrix named as ztitle, you could use such expression ztitle.sub(y);(by name) or ztitle.sub(1); (by index) to return a dataset for the Y values, in addition, you may use such expression ztitle.sub(y)=; or ztitle.sub(y)$=; to return the 3rd value in this dataset.
range.reverse() This method works for a dataset range, such as column, matrix object, graph plot, block of cells, loose dataset, etc. It will reverse the data order of the range. If the range is block of cells, it only reverses the data order of the first sub column specified in the range declaration. The X-Function, colReverse, will do the same thing.
range.empty() This method works for the label area and the data area, such as column, matrix object, block of cells, label rows, etc. It would clear the data and label in the range. If the range is data area, the data in this range will be set to the missing value. In GUI, you can also right click on the selected range and then select Clear in the context menu.

## Unique Uses of Range

### Manipulating Range Data

A column range can be used to manipulate data directly. One major advantage of using a range rather than the direct column name, is that you do not need to be concerned with which page or layer is active.

For example:

// Declare two range variables, v1 and v2:
range [Book1]Sheet1 r1=Col(A), r2=Col(B);

// Same as col(A)=data(1,30) if [book1]sheet1 is active:
r1 = data(1,30);
r2 = uniform(30);

// Plot creates new window so [Book1]Sheet1 is NOT active:
plotxy 2;
sec -p 1.5;            // Delay
r2/=4;                 // But our range still works; col(A)/=4 does NOT!
sec -p 1.5;            // Delay
r2+=.4;
sec -p 1.5;            // Delay
r1=10+r1/3;

Direct calculations on a column range variable that addresses a range of cells is supported. For example:

range aa = Col(A)[10:19]; // Row 10 to 19 of column A
aa += 10;                 // All elements in aa increase by 10

Support for sub ranges in a column has expanded.

// Range consisting of column 1, rows 7 to 13 and column 2, rows 3 to 4
// Note use of parentheses and comma separator:
range rs = (1[7:13], 2[3:4]);
del rs; // Supported since 8.0 SR6

// Copying between sub ranges
range r1 = 1[85:100];
range r2 = 2;
// Copy r1 to top of column 2
r2 = r1; // Supported in 8.1
// 8.1 also complete or incomplete copying to sub range
range r2 = 2[17:22];
r2 = r1; // Only copies 6 values from r1
range r2 = 3[50:200];
r2 = r1; // Copies only up to row 65 since source has only 16 values

### Dynamic Range Assignment

Sometimes it is beneficial to be able to create a new range in an automated way, at runtime, using a variable column number, or the name of another range variable.

#### Define a New Range Using an Expression for Column Index

The wcol() function is used to allow runtime resolution of actual column index, as in

int nn = 2;
range aa=wcol(2*nn +1);

#### Define a New Range Using an Existing Range

The following lines of script demonstrate how to create one range based on another using the %( ) substitution notation and wks (object) methods. When the %( ) substitution is used on a range variable, it always resolves it to a [Book]Sheet! string, regardless of the type:

range rwks = sheet3!;
range r1= %(rwks)col(a);

in this case, the new range r1 will resolve to Sheet3!Col(A).

This method of constructing new range based on existing range is very useful because it allows code centralization to first declare a worksheet range and then to use it to declare column ranges. Lets now use the rwks variable to add a column to Sheet 3:

rwks.addcol();

And now define another range that resolves to the last (rightmost) column of range rwks; that is, it will point to the newly made column:

range r2 = %(rwks)wcol( %(rwks)wks.ncols );

With the range assignments in place it is easy to perform calculations and assignments, such as:

r2=r1/10;

which divides the data in range r1 by 10 and places the result in the column associated with range r2.

### X-Function Argument

Many X-functions use ranges as arguments. For example, the stats X-Function takes a vector as input and calculates descriptive statistics on the specified range. So you can type:

stats [Book1]Sheet2!(1:end); // stats on the second sheet of book1
stats Col(2);                // stats on column 2 of active worksheet

// stats on block of cells, col 1-2, row 5-10
stats 1:2;

Or you can use a range variable to do the same type of operation:

/* Defines a range variable for col(2) of 1st and 2nd sheet,
rows 3-5, and runs the stats XF on that range: */
range aa = (1,2)!col(2)[3:5]; stats aa;

The input vector argument for this X-Function is then specified by a range variable.

Some X-Functions use a special type of range called XYRange, which is essentially a composite range containing X and Y as well as error bar ranges.
The general syntax for an XYRange is

(rangeX, rangeY)

but you can also skip the rangeX portion and use the standard range notation to specify an XYRange, in which case the default X data is assumed.
The following two notations are identical for XYRange,

(, rangeY)
rangeY

For example, the integ1 X-Function takes both input and output XYRange,

// integrate col(1) as X and col(2) as Y,
// and put integral curve into columns 3 as X and 4 as Y
integ1 iy:=(1,2) oy:=(3,4);

// same as above except result integral curve output to col(3) as Y,
// and sharing input's X of col(1):
integ1 iy:=2 oy:=3;

## Listing, Deleting, and Converting Range Variables

### Listing Range Variables

Use the list LabTalk command to print a list of names and their defined bodies of all session variables including the range variables. For example:

list a; // List all session variables

If you issue this command in the Command Window, it prints a list such as:

Session:
1       MYRANGE   [book1]sheet1!col(b)
2         MYSTR  "abc"
3            PI   3.1415926535898

As of Origin 8.1, more switches have been added (given below) to list particular session variables:

Option What Gets Listed Option What Gets Listed
a All session variables aa String arrays (session)
ac Constants (session) af Local Function (session)
afc Local Function Full Content (session) afp Local Function Prototype (session)
ag Graphic objects (session) ar Range variables (session)
as String variables (session) at Tree variables (session)
av Numeric variables (session) -- --

### Deleting Range Variables

To delete a range variable, use the del LabTalk command with the -ra switch. For example:

range aa=1;  // aa = Col(1) of the active worksheet
range ab=2;  // ab = Col(2) of the active worksheet
range ac=3;  // ac = Col(3) of the active worksheet
range bb=4;  // bb = Col(4) of the active worksheet
list a;      // list all session variables; will include aa, ab, ac, bb
del -ra a*;  // delete all range variables beginning with the letter "a"

// The last command will delete aa, ab, and ac.

The table below lists options for deleting variables.

Option What Gets Deleted/Cleared Option What Gets Deleted/Cleared
ra Any Local/Session variable al same as -ra
rar Range variable ras String variable
rav Numeric variable rac Constant
rat Tree variable raa String array
rag Graphic object raf Local/Session Function

### Converting Range to UID

Each Origin Object has a short name, long name, and universal identifier (UID). You can convert between range variables and their UIDs as well as obtain the names of pages and layers using the functions range2uid, uid2name, and uid2range. See LabTalk Objects for examples of use.

## Special Notations for Range

### Specifying Multiple Sheets

When referring to multiple sheets, use the general form of the worksheet data range string, combined with commas and colons to specify the range.

[Workbook](SheetA,SheetN:SheetM)!colBegin[rowIndex]:colEnd[rowIndex]

// Basic combination of three ranges:
(range1, range2, range3)

// Common column ranges from multiple sheets:
(sheet1,sheet2,sheet3)!range1
(sheet1,sheet3:5)!range1

// Common column ranges from a range of sheets
(sheet1:sheetn)!range1

For example:

// plot A(X)B(Y) from two sheets into the same graph.
plotxy (1:2)!(1,2);

// Activate workbook again and add more sheets and fill them with data.
// Plot A(X)B(Y) from all sheets between row2 and row10:
plotxy (1:end)!(1,2)[2:10];
// Appends every worksheet in the active workbook into a new sheet in the book.
wappend irng:=(1:end)!;

A more general discussion of Composite Range is given below.

### XY and XYZ Range

Designed as inputs to particular X-Functions, an XY Range is an ordered pair designating two worksheet columns as XY data. And the XY subrange is able to be specified by using X values. Similarly, an (XYZ Range) is an ordered triple containing three worksheet columns representing XYZ data.

For instance, the fitpoly X-Function takes an XY range for both input and output:

// Fit a 2nd order polynomial to the XY data in columns 1 and 2;
// Put the coefficients into column 3 and the XY fit data in cols 4 and 5:
fitpoly iy:=(1,2) polyorder:=2 coef:=3 oy:=(4,5);

### XY Range using # and ? for X

There are two special characters '?' and '#' introduced in (8.0 SR3) for range as an X-Function argument. '?' indicates that the range is forced to use worksheet designation, and will fail if the range designation does not satisfy the requirement. '#' means that the range ignores designations and uses row number as the X designation. However, if the Y column has even sampling information, that sampling information will be used to provide X.

For example:

plotxy (?, 5);        // if col(5) happens to be X column call fails
plotxy (#, 3);        // plot col(3) as Y and use row number as X

These notations are particularly handy in the plotxy X-Function, as demonstrated here:

// Plot all columns in worksheet using their column designations:
plotxy (?,1:end);

### Tag Notations in Range Output

Many X-Functions have an output range that can be modified with tags, including template, name, and index. Here is an example that can be used by the Discrete Frequency X-Function, discfreqs

discfreqs irng:=1 freq:=1 rd:="[Result]<new template:=table.otw index:=3>";

The output is directed to a Workbook named Result by loading a template named TABLE.OTW as the third sheet in the Result book.

Support of tag notation depends on the particular X-Function, so verify tag notation is supported before including in production code.

### Composite Range

A Composite Range is a range consisting of multiple subranges. You can construct composite ranges using the following syntax:

// Basic combination of three ranges:
(range1, range2, range3)

// Common column ranges from multiple sheets:
(sheet1,sheet2,sheet3)!range1

// Common column ranges from a range of sheets
(sheet1:sheetn)!range1

To show how this works, we will use the wcellcolor X-Function to show range and plotxy to show XYRange. Assuming we are working on the active book/sheet, with at least four columns filled with numeric data:

// color several different blocks with blue color
wcellcolor (1:2, 1:2, 2) color(blue);

// set font color as red on some of them
wcellcolor (1:4, 2:3) color(red) font;

To try plotxy, we will put some numbers into the first sheet, add a new sheet, and put more numbers into the second sheet.

// plot A(X)B(Y) from both sheets into the same graph.
plotxy (1:2)!(1,2);

// Activate workbook again and add more sheets and fill them with data.
// Plot A(X)B(Y) from all sheets between row2 and row10:
plotxy (1:end)!(1,2)[2:10];

Note: There exists an inherent ambiguity between a composite range, composed of ranges r1 and r2 as in (r1,r2), and an XY range composed of columns named r1 and r2, i.e., (r1,r2). Therefore, it is important that one keep in mind what type of object is assigned to a given range variable!