We do not have access to SQL server at work so I have to design an app within Excel VBA and using a text file (CSV) to store the data.
I have no problem querying data, j
This might not be the best of the solution, but it did work for me. I converted my data to a list and passed it to a function called "ToDataTable" to convert into datatable first.
public DataTable ToDataTable(List items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
dataTable.Columns.Add(prop.Name , prop.PropertyType);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
object val;
val = Props[i].GetValue(item, null);
values[i] = val;
}
dataTable.Rows.Add(values);
}
return dataTable;
}
Then using GetInversedDataTable() function will convert it to the format you want.
public static DataTable GetInversedDataTable(DataTable table, string columnX,
string columnY, string columnZ, string nullValue, bool sumValues)
{
DataTable returnTable = new DataTable();
if (columnX == "")
columnX = table.Columns[0].ColumnName;
returnTable.Columns.Add(columnY);
List columnXValues = new List();
foreach (DataRow dr in table.Rows)
{
string columnXTemp = dr[columnX].ToString();
if (!columnXValues.Contains(columnXTemp))
{
returnTable.Columns.Add(columnXTemp);
}
}
//Verify if Y and Z Axis columns re provided
if (columnY != "" && columnZ != "")
{
List columnYValues = new List();
foreach (DataRow dr in table.Rows)
{
if (!columnYValues.Contains(dr[columnY].ToString()))
columnYValues.Add(dr[columnY].ToString());
}
//Loop all Column Y Distinct Value
foreach (string columnYValue in columnYValues)
{
DataRow drReturn = returnTable.NewRow();
drReturn[0] = columnYValue;
DataRow[] rows = table.Select(columnY + "='" + columnYValue + "'");
foreach (DataRow dr in rows)
{
string rowColumnTitle = dr[columnX].ToString();
foreach (DataColumn dc in returnTable.Columns)
{
if (dc.ColumnName == rowColumnTitle)
{
if (sumValues)
{
try
{
drReturn[rowColumnTitle] =
Convert.ToDecimal(drReturn[rowColumnTitle]) +
Convert.ToDecimal(dr[columnZ]);
}
catch
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
else
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
}
}
returnTable.Rows.Add(drReturn);
}
}
else
{
throw new Exception("The columns to perform inversion are not provided");
}
if (nullValue != "")
{
foreach (DataRow dr in returnTable.Rows)
{
foreach (DataColumn dc in returnTable.Columns)
{
if (dr[dc.ColumnName].ToString() == "")
dr[dc.ColumnName] = nullValue;
}
}
}
return returnTable;
}
Use it like this :
DataTable dtReturn = GetInversedDataTable(dt, "client", "emp_id",
"allocation", "0", true);
The three columns are provided and a new DataTable is returned.
The example below will use the source table and the params below to build a Pivot Table. In your case here : X axis column: "client" Y axis column: "emp_id" Z axis column: "allocation" Null value: "0"; Sum of values: true
Note that this is what I used for my problem and my code is in C#