V4 V5

CellValue is a struct holding one cell’s value. Numbers, booleans and dates are kept without being wrapped in an object, so walking a large number of cells allocates nothing.

The namespace is unvell.ReoGrid.Core.Data.

Kinds

One value is 16 bytes. An empty cell simply has the kind Empty and costs nothing extra.

Kind (CellValueKind)What it holds
Emptynothing (default)
Numbera double
Boolean0 / 1 in the double
DateTimean OLE Automation date serial
Textan id into the shared string pool
Erroran error code

Reading

using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.Data;

CellValue v = ws.GetValue(0, 0);

switch (v.Kind)
{
	case CellValueKind.Empty:
		break;
	case CellValueKind.Number:
		Console.WriteLine(v.AsNumber);
		break;
	case CellValueKind.Boolean:
		Console.WriteLine(v.AsBoolean);
		break;
	case CellValueKind.DateTime:
		Console.WriteLine(DateTime.FromOADate(v.AsDateSerial));
		break;
	case CellValueKind.Text:
	case CellValueKind.Error:
		// strings and errors are held by id, so resolve them through the Worksheet
		Console.WriteLine(ws.GetObjectValue(0, 0));
		break;
}

The accessors do not check the kind. Look at Kind first, then use the matching accessor.

AccessorValid for
AsNumberNumber
AsBooleanBoolean
AsDateSerialDateTime (convert with DateTime.FromOADate)
AsStringIdText (a pool id, not the string itself)
AsErrorCodeError

Writing

ws.SetValue(0, 0, CellValue.Number(1200));
ws.SetValue(0, 1, CellValue.Boolean(true));
ws.SetValue(0, 2, CellValue.Date(DateTime.Today.ToOADate()));

// strings always go through the Worksheet (they have to enter the shared pool)
ws.SetText(0, 3, "Notebook");

CellValue.Text(int) and CellValue.ErrorCode(int) take ids. An id only means anything once it has been registered in the sheet’s pool, so there is no reason to call them from application code. Use ws.SetText(...) for strings.

Empty cells

CellValue none = CellValue.Empty;         // = default
bool isEmpty = ws.GetValue(5, 5).IsEmpty;

CellValue.Empty is the same as default. Reading a cell that holds nothing does not throw; you get Empty back.

Which access route to use

SituationUse
You want a string to display or exportws.GetDisplayText(r, c)
You want an ordinary .NET valuews.GetObjectValue(r, c)
You are walking many cells and want to avoid allocationws.GetValue(r, c) / ws.ReadWindow(...)

GetObjectValue resolves Text to a string and DateTime to a DateTime, which makes it the easier choice most of the time. Reaching for CellValue directly pays off when you are walking tens of thousands to millions of cells.

Equality

CellValue implements IEquatable<CellValue>, comparing kind and held value. For Text that is an id comparison, so it is only meaningful between values from the same sheet’s pool.

Was this article helpful?