3.1.1 Data Access from Worksheet
Version Info
Minimum Origin Version Required: Origin 8 SR0
Remark
This section introduced access numeric data, text, Julian date/time data from Origin worksheet window.
More related details please reference to the following Origin C Reference sections:
WorksheetPage class
Worksheet class
Column class
DataRange class
vectorbase class
vector class
Numeric
Get Numeric Dataset
void GetNumericDataset()
{
Worksheet wks = Project.ActiveLayer();
if( wks ) // if active layer is Worksheet
{
foreach(Column col in wks.Columns)
{
vectorbase& vec = col.GetDataObject(); // use vectorbase here since data in column can be any numeric data type, for example, double, int, complex.
double dSum;
vec.Sum(dSum);
printf("The sum of the %dth column is %f\n", col.GetIndex()+1, dSum); // GetIndex return index with 0 offset
}
}
}
Modify Numeric Dataset
void ModifyNumericDataset()
{
Worksheet wks = Project.ActiveLayer();
if( wks && wks.GetNumCols() >= 2 ) //to make sure active window is Worksheet and at least exist two columns
{
DataRange dr;
dr.Add(wks, 0, "X");
dr.Add(wks, 1, "X");
vector vA, vB;
dr.GetData(&vA, 0);
dr.GetData(&vB, 1);
// sort the whole worksheet by column A with ascending
vector<uint> vnIndices;
vA.Sort(SORT_ASCENDING, TRUE, vnIndices); // sort column A and returned order indices
vB.Reorder(vnIndices); // reorder column B by column A indices
dr.SetData(vA, false, 0);
dr.SetData(vB, false, 1);
}
}
Access One Numeric Cell
void AccessNumericData(int nRow = 0, int nCol = 0)
{
Worksheet wks = Project.ActiveLayer();
if( !wks )
return;
double dd = wks.Cell(nRow, nCol);
out_double("The original data is ", dd);
dd = 100;
wks.SetCell(nRow, nCol, dd);
out_double("The modified data is ", dd);
}
Put Large Dataset to Worksheet
In order to keep Origin C function more efficient on putting the large dataset to worksheet, for example 5000 columns, need to do like the steps below.
- Prepare the columns and rows before put into data to worksheet.
- Use Worksheet::SetSize, not use Worksheet::AddCol to set size.
- Set size on an empty worksheet, means no column, since need to check the short name of the existed columns to avoid duplicate name when add new column. This check may cost many times. Can use while( wks.DeleteCol(0) ); to remove all columns.
- Put data to worksheet column by buffer, DataObject::GetInternalDataBuffer.
- Keep Code Builder close when running function to set size and put back data to worksheet.
See following example codes:
void PutLargeDataset(int rows = 100, int cols = 500)
{
// prepare worksheet size
Worksheet wks;
wks.Create("Origin");
while( wks.DeleteCol(0) );
wks.SetSize(rows, cols);
// put dataset to worksheet column one by one
foreach(Column col in wks.Columns)
{
col.SetFormat(OKCOLTYPE_NUMERIC);
col.SetInternalData(FSI_SHORT);
col.SetUpperBound(rows-1);//index of last row, 0 offset
int nElementSize;
uint nNum;
LPVOID pData = col.GetInternalDataBuffer(&nElementSize, &nNum);
short* psBuff = (short*)pData;
// OC loop is still slow, but you might pass this pointer to your DLL
// for much faster manipulation, here we just show that the pointer works
for(int ii = 0; ii < rows; ii++, psBuff++)
{
*psBuff = (ii+1) * (col.GetIndex()+1);
}
col.ReleaseBuffer(); // do NOT remember to call this
}
}
String
Get/Put String Array
void AccessStringArray()
{
Worksheet wks = Project.ActiveLayer();
if( wks )
{
foreach(Column col in wks.Columns)
{
int nFormat = col.GetFormat();
if( OKCOLTYPE_TEXT == nFormat || OKCOLTYPE_TEXT_NUMERIC == nFormat )
{
vector<string> vstr;
col.GetStringArray(vstr);
DWORD dwOptions = SORT_ASCENDING | SORT_CASE_SENSITIVE;
vstr.Sort(dwOptions); // ascending sort with case sensitive
col.PutStringArray(vstr); // put back sorted string array to column
}
}
}
}
Access One String Cell
void AccessString(int nRow = 0, int nCol = 0)
{
Worksheet wks;
wks.Create("Origin");
string strVal;
wks.GetCell(nRow, nCol, strVal);
out_str(strVal);
strVal = "This is an example!";
wks.SetCell(nRow, nCol, strVal);
out_str(strVal);
Column col = wks.Columns(nCol);
col.SetWidth(-1); // -1 to set the width to the largest cell in the column.
}
Date and Time
void AccessDateTimeData(int nColIndex)
{
Worksheet wks = Project.ActiveLayer();
if( !wks )
return;
Column col(wks, nColIndex);
if( !col )
return;
// find out the smallest date
if( OKCOLTYPE_DATE == col.GetFormat() || OKCOLTYPE_TIME == col.GetFormat() )
{
vector& vec = col.GetDataObject(); // return the Julian date value
if( vec.GetSize() != 0 )
{
vec.Sort();
printf("The smallest date is %s\n", get_date_str(vec[0], LDF_LONG));
}
}
}
Missing Value
void fill_with_missing()
{
Worksheet wks = Project.ActiveLayer(); // get active worksheet
if(!wks)
{
out_str("The active worksheet not exist!");
return;
}
DataRange dr;
dr.Add("X", wks, 0, 0, -1, -1); // the whole worksheet
dr.Replace(0, NANUM, WKSREPL_TEST_EQUAL); // replace by missing, missing=NANUM
Dataset ds(wks, 0); // dataset attached to column 1
ds = NANUM; // clear column 1
}
|