Data Tips

Deriving Cell Ordinals and Axis Coordinates

The following code enables you to determine the column or row coordinate given the labels for a column or row:

/* Find the column ( Axis(0) ) that contains these labels */
String labels[] = { "CANADA", "Actual Sales", "Sum" };
int columnCoordinate = mi.getAxis(0).getAxisCoordinate(labels); 

The following code enables you to determine the labels at a coordinate given an axis coordinate:

/* Retrieve the labels of the first column of the table */
int columnCoordinate = 0;
AxisLabelInterface labels[] = mi.getAxis(0).getLabels(columnCoordinate);

The following code enables you to determine the cell ordinal at a crossing given a column axis coordinate and a row axis coordinate:

/* Find the cell ordinal that corresponds to column 3, row 4 (0 based indexing) */
int axisCoordinates[] = {2, 3};
int cellOrdinal = mi.getCellOrdinal(axisCoordinates);

The following code enables you to determine the column and row axis coordinates given a cell ordinal:

/* Determine the column and row coordinates for the last cell */
int cellOrdinal = mi.getCellCount() -1;
int axisCoordinates[] = mi.getAxisCoordinates(cellOrdinal);

Retrieving Cell Values for a Particular Column, Row, or Block of Cells

To retrieve the cell values for a given row or column:

/* Retrieve all the cell values in the first column (0 based) */
int columnCoordinate = 0;

/* Determine the cell ordinal of the first value in the column */
int firstOrdinal = 0;

/* Determine the cell ordinal of the last value in the column */
int lastRowCoordinate = mi.getAxis(1).getMagnitude()-1;
int axisCoordinates[] = {columnCoordinate, lastRowCoordinate};
int lastOrdinal = mi.getCellOrdinal(axisCoordinates);

/* Retrieve the block of values from the first ordinal to the last ordinal */
Object values[] = mi.getCells(firstOrdinal, lastOrdinal);

To retrieve the cell values for a block (rectangle) of cells:

/* Retrieve all the formatted cell values from column 2 row 1 to column 4 row 3 */
/* The first ordinal should reflect the upper left ordinal of the block of values */

int axisCoordinates[] = {1, 0};
int firstOrdinal = mi.getCellOrdinal(axisCoordinates);

/* The last ordinal should reflect the lower right ordinal of the block of values */
axisCoordinates[0] = 3;
axisCoordinates[1] = 2;
int lastOrdinal = mi.getCellOrdinal(axisCoordinates);
String formattedCells[] = mi.getFormattedCells(firstOrdinal, lastOrdinal);

Filtering Data

The following applet finds all the years between a certain range and subsets the data to include only those years:

/* Copyright (c) 2000 by SAS Institute Inc., Cary, NC 27513 */

import com.sas.sasserver.mdtable.MultidimensionalTableV2Interface;
import com.sas.mdtable.MemberInterface;
import com.sas.sasserver.mdtable.Level;
import com.sas.rmi.Rocf;
import com.sas.rmi.Connection;
import com.sas.collection.StringCollection;
import com.sas.collection.Dictionary;
import com.sas.table.TableException;

class RangeSubsetting
{
static MultidimensionalTableV2Interface mi;
  public static void main(String[] argv)
{
try 
{
setup();

String levelName = "YEAR";
Dictionary levels = mi.getAllLevels();

//assuming it will be found should check before getting
Level level = (Level)levels.get(levelName);
String start = "1995";
String end = "1999";
String values[] = getRangeValues( level, start, end);

if ( values != null )
{
level.setSubset(values);

// synchronize the server with the new subsets
mi.setSubsets();
} 
}

catch (Exception e)
{
e.printStackTrace();
}
}

public static void setup()
{
try{
Rocf rocf = new Rocf();
Connection con = new Connection();
con.setHost("localhost");

//con.setLogTrap(true);
mi = (MultidimensionalTableV2Interface)rocf.newInstance(MultidimensionalTableV2Interface.class, con);

mi.setMetabase("SASHELP");
mi.setDatabase("SASHELP.PRDMDDB");
String col[] = {"Geographic"};
String row[] = {"Time"};
String measure[] = {"ACTUAL", "PREDICT"};
String stat[] = {"SUM"};
mi.setColumnAxis(col);
mi.setRowAxis(row);
mi.setSelectedMeasures(measure);
mi.setSelectedStatistics(stat);
mi.initializeTable();
}
catch ( Exception except ) {Thread.dumpStack();};
}

public static String[] getRangeValues(Level level, String startRange, String endRange)
{
try{
System.out.println("Level " + level);

// again assumption about order that should be validated
mi.sort(level, SortInterface.ASCENDING);
System.out.println("Sort succeeded");
int startMember = mi.findMember(level.getName(), startRange, false);
System.out.println("startMember " + startMember);

if ( startMember >= 0 )
{

//should make sure there are not subsequent members with same name
int endMember = mi.findNextMember(level.getName(), endRange, false, startMember+1);
System.out.println("endMember " + endMember);

if ( endMember > startMember )
{

MemberInterface members[] = level.getMembers(startMember, endMember-startMember+1);

String values[] = new String[members.length];
for ( int i = 0; i < members.length; ++i )
values[i] = members[i].getLabel();

System.out.println("Values for " + level + ": " + new StringCollection(values));
return values;
}
}
}
catch (Exception except) {Thread.dumpStack(); return null;};

return null;
}
}

The following example filters the data to include only members where the Actual Sales exceed $245,000. For simplicity, assume only YEAR on the row and Actual Sales/Sum on the column. The goal is to subset the model to include only years where the actual sales exceed $245,000.

/* First sort Actual Sales/Sum descending. Since our simple example has only one column we sort column 0 */
/* For examples of sorting based on a particular set of labels see SortInterface */

mi.sort(0, SortInterface.DESCENDING);

/* Retrieve the cell values for the column. Since this is the only column we get all the cells */
/* Retrieving Cell Values for a Particular Column, Row or Block of Cells 
*/

Object values[] = mi.getCells(0, mi.getCellCount()-1);

/* Iterate through the cell values until you reach one that falls below the target value */
Double targetValue = new Double(245000.00);
int idx = 0;

for ( ; idx < values.length; ++idx)
{

if ( ((Double)values[idx]).doubleValue() < targetValue.doubleValue())
   break;
}

/* The previous cell value will be the last row to include */
--idx;

/* Get the labels for the rows that you wish to include */
/* Get the member values from these labels */
/* This example is simplified to only include one level */
/* on the row. When multiple levels are present each */
/* level will need to be subset accordingly. */

String subsets[] = new String[idx+1];
Axis rowAxis = (Axis)mi.getAxis(1);

for ( int row = 0; row <= idx; ++row)
{
AxisLabelInterface labels[] = rowAxis.getLabels(row);
subsets[row] = labels[0].getLabel();
}

/* Subset the level to only include these member values */
/* Get the level that is on the row. Here again we assume one level on the row */
/* So we get the first level on the row Axis */
LevelInterface levels[] = rowAxis.getLevels();
((Level)levels[0]).setSubset(subsets);
mi.setSubsets();