Skip to content

Instantly share code, notes, and snippets.

@mndrake
Last active December 21, 2015 23:19
Show Gist options
  • Save mndrake/6381857 to your computer and use it in GitHub Desktop.
Save mndrake/6381857 to your computer and use it in GitHub Desktop.
A C# wrapper class for the Excel4/Excel12 methods contained in Excel-DNA to mimic basic methods of the COM object model
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
namespace Excel4
{
using System;
using System.Collections.Specialized;
using System.Linq;
using ExcelDna.Integration;
public class Application
{
public Workbook ActiveWorkbook()
{
var name = XlCall.Excel(XlCall.xlfGetWorkbook, 16).ToString();
return new Workbook(name);
}
public Worksheet SelectedSheet()
{
var sheetRef = (ExcelReference)XlCall.Excel(XlCall.xlfSelection);
return new Worksheet(sheetRef.SheetId);
}
public Range Selection()
{
var selectionRef = (ExcelReference)XlCall.Excel(XlCall.xlfSelection);
return new Range(selectionRef);
}
}
public class Sheets
{
private Workbook parent;
private OrderedDictionary sheets = new OrderedDictionary();
internal Sheets(Workbook parent)
{
this.parent = parent;
var sheetNames =
((object[,])XlCall.Excel(XlCall.xlfGetWorkbook, 1, parent.Name))
.Cast<object>()
.ToArray()
.Select(x => x.ToString().Split(']').LastOrDefault());
foreach (var s in sheetNames)
{
this.sheets.Add(s, new Worksheet(s));
}
}
public Worksheet this[int index]
{
get { return (Worksheet)sheets[index]; }
set { sheets[index] = value; }
}
public Worksheet this[string name]
{
get { return (Worksheet)sheets[name]; }
set { sheets[name] = value; }
}
}
public class Workbook
{
private string name;
private Sheets sheets;
public Workbook(string name)
{
this.name = name;
this.sheets = new Sheets(this);
}
public Sheets Sheets
{
get
{
return this.sheets;
}
}
public string Name
{
get
{
return this.name;
}
}
}
public class Worksheet
{
private ExcelReference sheetRef;
public Worksheet(string name)
{
this.sheetRef = (ExcelReference)XlCall.Excel(XlCall.xlSheetId, name);
}
public Worksheet(IntPtr id)
{
this.sheetRef = new ExcelReference(0, 0, 0, 0, id);
}
internal string FullName
{
get { return XlCall.Excel(XlCall.xlSheetNm, this.sheetRef).ToString(); }
}
public string Name
{
get { return this.FullName.Split(']').LastOrDefault(); }
}
public Workbook Parent
{
get
{
var workbookName = this.FullName.Split(']').FirstOrDefault().Split('[').LastOrDefault();
return new Workbook(workbookName);
}
}
internal IntPtr SheetId
{
get
{
return this.sheetRef.SheetId;
}
}
public void Activate()
{
XlCall.Excel(XlCall.xlcWorkbookActivate, this.FullName);
}
public Range UsedRange
{
get
{
var lastRow = Convert.ToInt32(XlCall.Excel(XlCall.xlfGetDocument, 10, this.sheetRef.SheetId));
var lastCol = Convert.ToInt32(XlCall.Excel(XlCall.xlfGetDocument, 12, this.sheetRef.SheetId));
var rangeRef = new ExcelReference(0, lastRow, 0, lastCol, this.sheetRef.SheetId);
return new Range(rangeRef);
}
}
public Range Cells
{
get
{
return this.UsedRange;
}
}
public Range Range(Range begRange, Range endRange)
{
return new Range(begRange, endRange);
}
public Range Range(string rangeName)
{
return new Range(this.FullName + "!" + rangeName);
}
public void Select()
{
XlCall.Excel(XlCall.xlcWorkbookSelect, this.FullName);
}
}
public class Range
{
private ExcelReference rangeRef;
public Range(Range begRange, Range endRange)
{
if (begRange == null) { throw new ArgumentNullException("begRange"); }
if (endRange == null) { throw new ArgumentNullException("endRange"); }
if (begRange.Parent.SheetId != endRange.Parent.SheetId)
{
throw new ArgumentException("parent sheet not the same as begRange", "endRange");
}
this.rangeRef =
new ExcelReference(
begRange.Row - 1,
endRange.Row - 1,
begRange.Column - 1,
endRange.Column - 1,
begRange.Parent.SheetId);
}
public Range Cells
{
get
{
return this;
}
}
public Range this[int row, int column]
{
get
{
if (this.ColumnCount - 1 < column)
{
throw new IndexOutOfRangeException("column");
}
if (this.RowCount - 1 < row)
{
throw new IndexOutOfRangeException("row");
}
var cellRow = this.rangeRef.RowFirst + row;
var cellCol = this.rangeRef.ColumnFirst + column;
var cellRef = new ExcelReference(cellRow - 1, cellRow - 1, cellCol - 1, cellCol - 1, this.rangeRef.SheetId);
return new Range(cellRef);
}
}
public int Column
{
get
{
return this.rangeRef.ColumnFirst + 1;
}
}
public int Row
{
get
{
return this.rangeRef.RowFirst + 1;
}
}
public Range(string rangeName)
{
var rangeRef = (ExcelReference)XlCall.Excel(XlCall.xlfEvaluate, rangeName);
new Range(rangeRef);
}
internal Range(ExcelReference rangeRef)
{
this.rangeRef = rangeRef;
}
private int ColumnCount
{
get
{
return this.rangeRef.ColumnLast - this.rangeRef.ColumnFirst + 1;
}
}
public Range[] Columns
{
get
{
var columns = new Range[this.ColumnCount];
for (int i = 0; i < this.ColumnCount; i++)
{
columns[i] = new Range(this.Cells[i, 0], this.Cells[i, this.RowCount - 1]);
}
return columns;
}
}
private int RowCount
{
get
{
return this.rangeRef.RowLast - this.rangeRef.RowFirst + 1;
}
}
public Range[] Rows
{
get
{
var rows = new Range[this.RowCount];
for (int i = 0; i < this.RowCount; i++)
{
rows[i] = new Range(this.Cells[0, i], this.Cells[this.ColumnCount - 1, i]);
}
return rows;
}
}
public Worksheet Parent
{
get
{
return new Worksheet(this.rangeRef.SheetId);
}
}
public object Value
{
get
{
return this.rangeRef.GetValue();
}
set
{
if (this.rangeRef.SetValue(value) == false)
{
throw new ArgumentException("could not set value to range", "value");
}
}
}
public Range Offset(int offsetRows, int offsetColumns)
{
var offsetRef = new ExcelReference(
this.rangeRef.RowFirst + offsetRows,
this.rangeRef.RowLast + offsetRows,
this.rangeRef.ColumnFirst + offsetColumns,
this.rangeRef.ColumnLast + offsetColumns,
this.rangeRef.SheetId);
return new Range(offsetRef);
}
public Range Offset(int offsetRows, int offsetColumns, int rows, int columns)
{
var offsetRef = new ExcelReference(
this.rangeRef.RowFirst + offsetRows,
this.rangeRef.RowFirst + offsetRows + rows - 1,
this.rangeRef.ColumnFirst + offsetColumns,
this.rangeRef.ColumnFirst + offsetColumns + columns - 1);
return new Range(offsetRef);
}
public void Select()
{
this.Parent.Select();
XlCall.Excel(XlCall.xlcFormulaGoto, this.rangeRef);
}
public void ClearContents()
{
this.Value = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment