如何有效地查询多个表以在 dataGrid 中生成 excel STYLE 报告

Posted

技术标签:

【中文标题】如何有效地查询多个表以在 dataGrid 中生成 excel STYLE 报告【英文标题】:How to effectively query several tables to produce an excel STYLE report in a dataGrid 【发布时间】:2011-06-08 17:25:41 【问题描述】:

我正在创建一个 C#、Windows 窗体应用程序,使用 Access 数据库作为后端。我使用数据集和表适配器将信息从 Excel 传输到数据库,然后使用 winforms 从数据库中提取我需要的记录。

我从多个表中检索信息以生成月度销售报告。 Store# 从组合框中选择的每个报告都需要:

作为一行的产品名称(来自产品表) 产品表中有一个字段 称为标记的产品分析 如果产品应该是 1 包含在分析报告中。

开始(库存)计数 (由日期选择框选择)

(开始日期,产品 购买价格)

购买的每件商品的数量。 (所以一个 产品数量总和#/商店/日期 来自交易表)

结束(库存)计数 (由日期选择框选择)

产品购买的结束日期 价格。

每个商店的库存计数都保存在一个表中,其中包含日期、商店#、countNo 和产品#。所有商店都保存到同一个表中。每次购买都与日期、购买价格、数量、商店# 和产品# 一起存储在交易表中(还有一些其他字段也与这种情况无关)。我需要这张表中购买的数量和最后购买价格的总和。

我的问题在于试图将所有这些信息放入一个查询中以生成DataGridView

我将根据所有这些信息计算一些字段。我能找到的所有信息都适用于使用 SQL Server,但我无法让这些示例适用于我的情况。我可以将它分成块并分别进行查询,但是将它们全部放在一个位置对我来说是有问题的。我尝试过的一些查询如下。

SELECT AnalysisItems.ProductName, 
       BeginningCount.CountNumber AS Beginning, 
       sum(Transactions.TransactionQty) AS SumOfTransactionQty, 
       EndingCount.CountNumber AS Ending
FROM Product 
INNER JOIN (((AnalysisItems 
INNER JOIN BeginningCount ON AnalysisItems.Pmid = BeginningCount.Pmid) 
INNER JOIN EndingCount ON BeginningCount.Pmid = EndingCount.Pmid) 
INNER JOIN Transactions ON EndingCount.Pmid = Transactions.Pmid) 
       ON (AnalysisItems.Pmid = Product.Pmid) AND (Product.Pmid = Transactions.Pmid)
WHERE (((Product.ProductAnalysis)=1))
GROUP BY AnalysisItems.ProductName, BeginningCount.CountNumber, 
         EndingCount.CountNumber;

这让我更接近,但仍然有几个相同产品的条目。我似乎无法思考如何在访问中执行此操作。

SELECT 
    AnalysisItems.ProductName,
    BeginningCount.CountNumber AS Beginning,
    Sum(Transactions.TransactionQty) AS SumOfTransactionQty,
    EndingCount.CountNumber AS Ending,
    EndingCount.StoreAccount
FROM Product 
    INNER JOIN 
    (
        AnalysisItems 
           INNER JOIN BeginningCount ON 
               AnalysisItems.Pmid = BeginningCount.Pmid
           INNER JOIN EndingCount ON
               BeginningCount.Pmid = EndingCount.Pmid
           INNER JOIN Transactions ON
               EndingCount.Pmid = Transactions.Pmid
    ) ON 
             (Product.Pmid = AnalysisItems.Pmid) AND 
             (Product.Pmid = Transactions.Pmid)
WHERE (((Product.ProductAnalysis)=1))
GROUP BY 
     AnalysisItems.ProductName,
     BeginningCount.CountNumber,
     EndingCount.CountNumber,
     EndingCount.StoreAccount;

【问题讨论】:

好的,所以我一直坚持下去,因为这个申请截止日期是明天。我所做的是使用相同的列创建两个不同的数据集。通过使用两个日期选择器组合框,它们将显示不同的信息。然后我尝试“合并”数据表。虽然 dataGridView 仍然只显示其中一个表。所以我仍然必须弄清楚这一点。然后也添加我的计算数据。 `DataTable one = new beginningDataSet.BeginningCountDataTable();数据表二 = newendingDataSet.EndingCountDataTable(); //将数据表合并为一个。 foreach (DataRow r2 in two.Rows) foreach (DataColumn dc in two.Columns) one.Columns.Add(dc); //我知道接下来的两行不正确,但我仍在努力解决。开始数据集.AcceptChanges(); dataGridView1.DataSource = beginDataSet.Tables; 【参考方案1】:

嗯,可能有一种更简单的方法可以做到这一点,但我似乎找不到它。我是一个初学者,所以有一天我会回头想想,我敢肯定:) 我所做的是..

将 3 个 DataGridView 框放到一个表单上。在屏幕加载时,我将“先前”月份数据加载到第一个数据中,将当前月份数据加载到第二个数据中。我将它们最小化并锁定在第三网格后面,因此它们无法被看到。然后我使用前两个网格中的每一行的每一行创建一个数据表。执行我需要同时进行的计算并将所有计算添加到第三个表中。

       private void btnLoad_Click(object sender, EventArgs e)
    

        //to load the first chosen months data
        this.beginningCountTableAdapter.Fill(this.beginningDataSet.BeginningCount, Convert.ToInt32(storeAccountComboBox.Text), Convert.ToDateTime(dateTimePicker1.Text));
        //to load the second chosen months data
        this.endingCountTableAdapter.Fill(this.endingDataSet.EndingCount, Convert.ToInt32(storeAccountComboBox.Text), Convert.ToDateTime(dateTimePicker2.Text));

        //Create new DataTable
        DataTable dtItems = new DataTable();

        //add columns to the dataTable
        dtItems.Columns.Add("Product", typeof(string));
        dtItems.Columns.Add("Beginning", typeof(decimal));
        dtItems.Columns.Add("Purchases", typeof(int));
        dtItems.Columns.Add("Ending", typeof(decimal));
        //Add a new Column to Calculate the Value
        dtItems.Columns.Add("Total Gone (Usage)", typeof(decimal)); 
        //add more columns for $ value
        dtItems.Columns.Add("Beginning$", typeof(decimal));
        dtItems.Columns.Add("Purchases$", typeof(decimal));
        dtItems.Columns.Add("Ending$", typeof(decimal));
        //Add a new Column to Calculate the Value
        dtItems.Columns.Add("Total Gone ($)", typeof(decimal));
        dtItems.Columns.Add("% of Sales", typeof(decimal));

        try
        
            for (int i = 0; i < dataGridView1.RowCount; i++)
            
                //first column
                string product = Convert.ToString(dataGridView1.Rows[i].Cells[0].Value);

                //calculation for TotalGone (usage)
                decimal beginning = Convert.ToDecimal(dataGridView1.Rows[i].Cells[1].Value);
                decimal purchases = Convert.ToDecimal(dataGridView2.Rows[i].Cells[0].Value);
                decimal ending = Convert.ToDecimal(dataGridView2.Rows[i].Cells[1].Value);
                decimal totalGone = ((beginning + purchases) - ending);
                //Variables for conversions for $ column math
                decimal beg = Convert.ToDecimal(dataGridView1.Rows[i].Cells[1].Value);
                decimal begPrice = Convert.ToDecimal(dataGridView1.Rows[i].Cells[2].Value);
                decimal begValue = beg * begPrice;
                decimal pur = Convert.ToDecimal(dataGridView2.Rows[i].Cells[0].Value);
                decimal purPrice = Convert.ToDecimal(dataGridView2.Rows[i].Cells[2].Value);
                decimal purValue = pur * purPrice; 
                decimal end = Convert.ToDecimal(dataGridView2.Rows[i].Cells[1].Value);
                decimal endPrice = Convert.ToDecimal(dataGridView2.Rows[i].Cells[2].Value);
                decimal endValue = end * endPrice;
                decimal totalGoneValue = ((beg * begPrice) + (pur * purPrice)) - (end * endPrice);

                totalGoneColumnTotal = totalGoneColumnTotal + totalGoneValue; //The total of all product totalGoneValues
                decimal salesPercentage = 0; //The sales percentage
                thirtyPercent = Convert.ToDecimal(txtThirtyPct.Text); //the thirty percent discount txt entry
                double chickenValue = Convert.ToDouble(dataGridView2.Rows[28].Cells[0].Value);
                chickenRebate = (chickenValue * .512);
                double steakValue = Convert.ToDouble(dataGridView2.Rows[29].Cells[0].Value);
                steakRebate = steakValue * .550; 
                totalWithRebates = (Convert.ToDouble(totalWithDiscount) - ((chickenRebate + steakRebate)));
                try
                
                    decimal sales = Convert.ToDecimal(textSales.Text); //convert the sales entry
                    salesPercentage = totalGoneValue / sales * 100; //find sales percentage
                    totalWithDiscount = totalGoneColumnTotal - thirtyPercent; //find thirtypercent discount amount
                
                catch  MessageBox.Show("The sales entry must be a number between 1 and 999999.99");
                break;
                

                //add colors to the output. 


                //Add rows to the DataTable
                dtItems.Rows.Add(product, beginning, purchases, ending, totalGone, begValue, purValue, endValue, totalGoneValue, salesPercentage);                
            //end for

            //Totals Summary Rows
            dtItems.Rows.Add("Totals", null, null, null, null, null, null, null, totalGoneColumnTotal, null);
            dtItems.Rows.Add("30% discounts",  null, null, null, null, null, null, null, thirtyPercent ,null);
            dtItems.Rows.Add("Total w/discount", null, null, null, null, null, null, null, totalWithDiscount, null);
            dtItems.Rows.Add("Chicken Rebate x * 5.12", null, null, null, null, null, null, null, chickenRebate, null);
            dtItems.Rows.Add("Steak Rebate x * 5.50", null, null, null, null, null, null, null, steakRebate, null);
            dtItems.Rows.Add("Total w/Rebates", null, null, null, null, null, null, null, totalWithRebates, null);

            //Set the DataTable as DataSource of the GridView
            dataGridView3.DataSource = dtItems;
        
        catch  MessageBox.Show("Could not determine values. There may be no data for this date range/store."); 

就像我说的那样,我确信这可能是一种非常奇怪的方法,但我无法仅使用 dataTables 来完成任何工作..

【讨论】:

以上是关于如何有效地查询多个表以在 dataGrid 中生成 excel STYLE 报告的主要内容,如果未能解决你的问题,请参考以下文章

如何高效地从多个表中查询子记录?

如何在一个 sql 查询中生成多个时间序列?

如何设置模型实例以在Django中生成确认表单

带有表变量的动态查询以循环遍历所有表以在数据库中更新

Spring data jpa 插入多个表以避免锁定表

如何在 Keras 中生成 class_labels.txt 以在 CoreML 模型中使用?