SQL pivot function text file database with VBA Excel

后端 未结 2 1232
醉话见心
醉话见心 2021-01-24 12:11

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

2条回答
  •  孤城傲影
    2021-01-24 12:58

    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#

提交回复
热议问题