Calling table functions from Microsoft Excel

This article explains how the table functions of the non-commercial .net library finaquant® protos can be called from within Microsoft Excel using VBA macros.

Calling .NET from Excel

Two possible integration options are presented here:

1) Calling a .net method from an Excel macro
Once called from a macro, the .net method reads the input tables from the given excel worksheets before executing the table functions to obtain output tables. The output tables are in turn written into the desired excel sheets.

Note that names of the worksheets are passed from the macro to the .net method as parameters for selecting the input tables. Each worksheet contains a single input table.

This integration option can be useful for demonstrations that are executed directly from excel. See the code examples below:

Excel VBA macro calling .net method: CalculatePrices()
' Calculate price table with given cost and margin tables
' 1) Read input tables: Costs, Margins, MetaData
' 2) Calculate price table
' 3) Write resultant price table into a sheet
Private Sub CalculatePrices()
Dim pxl As New ProtosExcelFunc
Dim CostTableSheet, MarginTableSheet, MetaDataSheet, PriceTableSheet As String
 
CostTableSheet = "CostTable"
MetaDataSheet = "MetaData"
 
MarginTableSheet = "MarginTable1"
PriceTableSheet = "PriceTable1"
 
'MarginTableSheet = "MarginTable2"
'PriceTableSheet = "PriceTable2"
 
' call .net method
MsgBox pxl.CalculatePrices(Application.ActiveWorkbook.FullName, CostTableSheet, _
    MarginTableSheet, MetaDataSheet, PriceTableSheet)
End Sub
.net method called by Excel macro: CalculatePrices()
/// <summary>
/// Calculate price table for given cost and margin tables
/// </summary>
/// <param name="ExcelFilePath">Full file path of excel file</param>
/// <param name="CostTableSheet">Name of worksheet for reading cost table (input table)</param>
/// <param name="MarginTableSheet">Name of worksheet for reading margin table (input table)</param>
/// <param name="MetaDataSheet">Name of worksheet for reading field names and types (input table)</param>
/// <param name="PriceTableSheet">Name of target worksheet for writing price table (output table)</param>
/// <returns>Message to calling function</returns>
public string CalculatePrices(string ExcelFilePath, string CostTableSheet, string MarginTableSheet,
	string MetaDataSheet, string PriceTableSheet)
{
	try
	{
		// read meta data
		DataTable MetaTbl = ExcelFunc.ReadTableFromExcelSheet_ODBC(ExcelFilePath, MetaDataSheet);
		MetaData md = MetaData.ReadFieldsFromDataTable(MetaTbl);
 
		// read input tables
		DataTable CostTbl = ExcelFunc.ReadTableFromExcelSheet_ODBC(ExcelFilePath, CostTableSheet);
		DataTable MarginTbl = ExcelFunc.ReadTableFromExcelSheet_ODBC(ExcelFilePath, MarginTableSheet);
 
		// convert DataTable to MatrixTable
		MatrixTable CostTable = MatrixTable.Import_from_DataTable(CostTbl, md);
		MatrixTable MarginTable = MatrixTable.Import_from_DataTable(MarginTbl, md);
 
		// Calculate price table with table function 'MultiplySelectedKeyFigures'
		MatrixTable PriceTable = MatrixTable.MultiplySelectedKeyFigures(CostTable, (MarginTable + 1),
		InputKeyFigTbl1: "costs", InputKeyFigTbl2: "margin", OutputKeyFig: "price",
		JokerMatchesAllvalues: true);
 
		// convert MatrixTable to DataTable
		DataTable PriceTbl = MatrixTable.Export_To_DataTable(PriceTable);
 
		// write price table into excel sheet
		ExcelFunc.WriteTableToExcelSheet(PriceTbl, ExcelFilePath, SheetName: PriceTableSheet, SaveWorkbook: false);
 
		// return affirmative message to caller
		return "Price table is calculated successfully!";
	}
	catch (Exception ex)
	{
		return "CalculatePrices: An error has occured! " + ex.Message;
	}
}

2) Directly executing the .net method
… which reads input tables from the given excel file before making the required table calculations.

In this option, an excel sheets are used solely as a database to store input and output tables; no additional VBA code (Excel macro) is needed. See the code example below:

.net code for calculating prices: CalculatePriceTable()
/// <summary>
/// Calculate price table with given cost and margin tables
/// </summary>
public static void CalculatePriceTable()
{
	// Get full file path
	string filepath = System.IO.Path.GetFullPath(@"Resources\DotNetIntegration.xlsm");
 
	// call table function
	ProtosExcelFunc pxl = new ProtosExcelFunc();
	string msg = pxl.CalculatePrices(filepath, CostTableSheet: "CostTable", MarginTableSheet: "MarginTable1",
		MetaDataSheet: "MetaData", PriceTableSheet: "PriceTable1");
 
	System.Diagnostics.Debug.WriteLine("Message from CalculatePrices: " + msg);
}

All the example codes above and others can be found in MS Visual Studio File ProtosExcelIntegration (2981 downloads) . Continue reading

Digiprove sealCopyright secured by Digiprove © 2013 Tunc Ali Kütükcüoglu
Posted in Calculation engine | Tagged , , , | 1 Comment

Importing and Exporting a DataTable from/to an Excel file

As explained in the related article, a MatrixTable of finaquant can easily be converted to or from a DataTable of the .net framework (ADO.net).

Data integration of excel with .net framework

That is, importing or exporting a MatrixTable from/to an excel sheet can be accomplished in two steps:

Import: (1) From Excel to DataTable (2) From DataTable to MatrixTable

Export: (1) From MatrixTable to DataTable (2) From DataTable to Excel

Data integration of .net with excel

Tables and values can be exchanged between .net and excel by using the methods in C# listed below.

The requirements for debugging and running these methods:

1) Microsoft Office and Excel must be installed
2) Following excel-related COM assemblies must be referenced:
Microsoft Office XX.0 Object Library
Microsoft Excel XX.0 Object Library
3) Following namespaces must be included in reference list in the code:
using System.Data;
using Excel = Microsoft.Office.Interop.Excel;

Feel free to use the code wherever you want provided that you leave any copyright information for Finaquant Analytics intact. We would appreciate any comment for possible corrections and improvements in the code. Continue reading

Digiprove sealCopyright secured by Digiprove © 2013 Tunc Ali Kütükcüoglu
Posted in Calculation engine | Tagged , , | 5 Comments

Converting a MatrixTable to a DataTable, and vice versa

MatrixTable is a type (class) for in-memory representation of data tables just like DataTable of the .net framework (ADO.net). MatrixTable has but a much simplified data structure compared to DataTable with primary focus on mathematical (or analytical) table functions rather than typical sql-based data operations like inserts and updates.

DataTable to or from MatrixTable

With the following methods of the MatrixTable class, a DataTable can easily be converted into a MatrixTable, and vice versa:

// From DataTable to MatrixTable
public static MatrixTable Import_from_DataTable(DataTable dtable, MetaData md,
   string TextReplaceNull = "NULL", int NumReplaceNull = 0, double KeyFigReplaceNull = 0)
 
// From MatrixTable to DataTable
public static DataTable Export_To_DataTable(MatrixTable tbl)

Continue reading

Digiprove sealCopyright secured by Digiprove © 2013 Tunc Ali Kütükcüoglu
Posted in Calculation engine | Tagged , , | 1 Comment

Persistent Table Array

PersistentTableArray and DataStore are new classes of the non-commercial .net library finaquant® protos (starting from release 1.04) that enable connection to relational databases like MySQL and Microsoft SQL in order to read/write complete tables from/to a database together with their instance information.

Each table instance is an element of a persistent table array. Following C# code example illustrates how separate cost tables for each country and year can be stored in a MySQL database with a persistent table array:

Cost tables for different countries and years

using FinaquantProtos;
using System.Data.Odbc;
 
// Connection string for MySQL database: 
// Replace it with your own valid connection string on your computer
string ConnStr = @"Driver={MySQL ODBC 5.2w Driver};Server=127.0.0.1;Database=testdb;uid=root;pwd=";
 
// Data provider
// You need to install ODBC driver for MySQL on your computer (win 32 bit version)
// see: http://dev.mysql.com/downloads/connector/odbc/
string DataProvider = "System.Data.Odbc";
 
// initiate DataStore object for database connection
DataStore datstore = new DataStore(Provider: DataProvider); 
 
// open database connection
datstore.OpenConnection(ConnStr);
 
// initiate "persistent table array" objects
PersistentTableArray PTblCost = new PersistentTableArray(TableName: "costs", dstore: datstore);
 
// Create TableRow objects as instance keys for tables
TableRow trow1 = TableRow.CreateTableRowWithElements(InstanceRowFields, "Peru", 2008);
TableRow trow2 = TableRow.CreateTableRowWithElements(InstanceRowFields, "Peru", 2012);
TableRow trow3 = TableRow.CreateTableRowWithElements(InstanceRowFields, "Bolivia", 2010);
 
// store each table instance separately into database (yes, just by assigning!)
PTblCost[trow1] = CostTblPeru2008;      // store CostTblPeru2008 with instance information in trow1
PTblCost[trow2] = CostTblPeru2012;
PTblCost[trow3] = CostTblBolivia2010;

Note that CostTblPeru2008, CostTblPeru2012 and CostTblBolivia2010 are different instances of in-memory cost tables (of type MatrixTable) with the same field structure. Continue reading

Digiprove sealCopyright secured by Digiprove © 2013 Tunc Ali Kütükcüoglu
Posted in Calculation engine | Tagged , , | Leave a comment