zoukankan      html  css  js  c++  java
  • datatable.compute计算表达式实现运输费用公式计算

    运输费用公式定义:
     
    支持iif()函数,向上取整函数
    提供对外计算方法
    用到,winform控件,datatable.compute,string字符串操作。
    界面如下
    using Genersoft.Drp.Common;
    using Genersoft.Drp.LS.Control;
    using Genersoft.Drp.TP.Client;
    
    using Genersoft.GS.Public.Biz.Client;
    using Genersoft.GS.Public.Biz.Control;
    using Genersoft.GS.Public.Focus.GuiControl;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    
    namespace Genersoft.Drp.TP.Control.BaseData
    {
        public partial class TspExpenseformulaForm : Form
        {
            //计算表达式参数名称显示
            public string vsCostsFormulaName = "";
            //计算表达式参数编号显示
            public string vsCostsFormula = "";
            public TspExpenseformulaForm()
            {
                PubFunctionControlLS.InitForm(this, InitializeComponent);
                PubFunctionControlLS.AdjustSkin(this, true);
            }
    
            private Dictionary<string, string> dictParams = new Dictionary<string, string>();
            private void TspExpenseformulaForm_Load(object sender, EventArgs e)
            {
    
                this.txtFormula.Text = vsCostsFormulaName;
                //设置行变色
                this.dgvParams.RowsDefaultCellStyle.BackColor = Color.Bisque;
                this.dgvParams.AlternatingRowsDefaultCellStyle.BackColor = Color.Beige;
    
                this.dgvFunc.RowsDefaultCellStyle.BackColor = Color.Bisque;
                this.dgvFunc.AlternatingRowsDefaultCellStyle.BackColor = Color.Beige;
    
                this.dgvFunc.AllowUserToAddRows = false;
    
                this.FormBorderStyle = FormBorderStyle.FixedDialog;
                //this.dgvParams.AllowUserToAddRows = false;去掉最后一行空白行
                //this.dgvParams.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;设置自适应列宽
                //加载函数
                DgvFuncLoad();
                //加载参数
                DgvParamsLoad();
    
            }
    
            private void DgvParamsLoad()
            {
                //取自定义项
                //DataSet dsDisplay = TspCostsFormulaClient.Current.GetTspTaskBillsCustomFields("TspTaskBills", "TspTaskBills");//统计依据表头表体自定义项部分
    
                DataTable dtcus = PubFunctionClient.GetService(null).GetCustomFieldInfo("TspTaskBills", "TspTaskBills", " IsDeleted='0' ");
                this.dgvParams.Columns.Add("ParamCode", "字段语义化");
                this.dgvParams.Columns.Add("ParamName","参数名称");
                this.dgvParams.Columns["ParamCode"].Visible = false;
                this.dgvParams.Rows.Add("TspTaskBills.BaseTspCost", "基本运费");
                this.dgvParams.Rows.Add("TspTaskBills.BaseTspPrice", "基本单价");
                this.dgvParams.Rows.Add("TspTaskBills.TotalQuantity", "运输任务总数量");
                this.dgvParams.Rows.Add("TspTaskBills.TotalTransGrWeight", "运输任务总重量");
                this.dgvParams.Rows.Add("TspTaskBills.TotalTransVolume", "运输任务总体积");
                dictParams.Add("基本运费", "TspTaskBills.BaseTspCost");
                dictParams.Add("基本单价", "TspTaskBills.BaseTspPrice");
                dictParams.Add("运输任务总数量", "TspTaskBills.TotalQuantity");
                dictParams.Add("运输任务总重量", "TspTaskBills.TotalTransGrWeight");
                dictParams.Add("运输任务总体积", "TspTaskBills.TotalTransVolume");
    
                foreach (DataRow dr in dtcus.Rows)
                {
                    this.dgvParams.Rows.Add(string.Format("TspTaskBills.{0}", dr["FieldName"]), string.Format(@"运输任务{0}", dr["DisplayName"]));
    
                    dictParams.Add(string.Format(@"运输任务{0}", dr["DisplayName"]), string.Format("TspTaskBills.{0}", dr["FieldName"]));
                }
    
    
    
    
    
            }
    
            private void DgvFuncLoad()
            {
                this.dgvFunc.Columns.Add("FuncName", "名称");
                this.dgvFunc.Rows.Add("IIF( , , )");
                this.dgvFunc.Rows.Add("向上取整{ }");
                //this.dgvFunc.Rows.Add("Sum( , )");
                //this.dgvFunc.Rows.Add("Avg( )");
                //this.dgvFunc.Rows.Add("Min( )");
                //this.dgvFunc.Rows.Add("Max( )");
    
    
            }
            private void ClearToolStripMenuItem_Click(object sender, EventArgs e)
            {
                
                this.txtFormula.Clear();
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void BtnMath_Click(object sender, EventArgs e)
            {
                
                Button btn = (Button)sender;
                txtFormula.SelectedText=btn.Text;
                //txtFormula.Text = this.txtFormula.Text.Insert();
    
            }
    
            /// <summary>
            /// 确定
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void SureToolStripMenuItem_Click(object sender, EventArgs e)
            {
              
                ReplaceParams();
                //替换参数
                string checkResult = this.CheckCostFormula();
                if(checkResult=="1")
                {
                    DialogResult = DialogResult.OK;
                    this.Close();
                }
            }
            private void ReplaceParams()
            {
                this.vsCostsFormula = this.txtFormula.Text;
                this.vsCostsFormulaName = this.txtFormula.Text;
                //string all = @"这是一段测试数据[我们100]这是一段测试数据[你们200]这是一段测试数据[他们100 谁们300]";
                Regex reg = new Regex(@"[(.+?)]");
          
                foreach (Match m in reg.Matches(this.vsCostsFormula))
                {
    
                    if (dictParams.Keys.Contains(m.Groups[1].ToString()))
                    {
                        this.vsCostsFormula = this.vsCostsFormula.Replace(m.Groups[1].ToString(), dictParams[m.Groups[1].ToString()]);
                    }
                }
    
                this.vsCostsFormula = this.vsCostsFormula.Replace("编号", "");
                this.vsCostsFormula = this.vsCostsFormula.Replace("内码", "");
                this.vsCostsFormula = this.vsCostsFormula.ToUpper();
                //获取[]中的参数名称
    
    
    
            }
    
    
            private void DgvParams_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
            {
                
               txtFormula.SelectedText =string.Format(@"[{0}]", Convert.ToString(this.dgvParams.Rows[e.RowIndex].Cells["ParamName"].Value)); 
            }
    
            private void DgvFunc_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
            {
    
                txtFormula.SelectedText =Convert.ToString(this.dgvFunc.Rows[e.RowIndex].Cells["FuncName"].Value);
    
    
            }
    
            private void CheckToolStripMenuItem_Click(object sender, EventArgs e)
            {
                this.ReplaceParams();
    
                this.CheckCostFormula();
    
    
    
            }
           /// <summary>
           /// 校验
           /// </summary>
           /// <returns></returns>
            private string CheckCostFormula()
            {
                string strExpress = "";
                //服务端校验
                //this.GetTspCostsFormulaResult();
    
                try
                {
                    strExpress = Convert.ToString(this.vsCostsFormula);
              
    
    
                    if (PubFunctionDrp.IsStringEmpty(strExpress))
                    {
                        this.txtFormula.Focus();
                        MessageBoxEx.Show("计算表达式不能为空!");
                        return "0";
                    }
                  
                    if (strExpress.Contains("]["))
                    {
                        MessageBox.Show("存在相邻的数据列之间没有运算符,请检查!");
                        return "0";
                    }
                    //先赋值
                    List<string> listParams = dictParams.Values.ToList();
    
                    foreach (string strParam in listParams)
                    {
                        strExpress = strExpress.Replace(strParam.ToUpper(), "1.33");
                    }
    
                    if (strExpress.Contains("向上取整"))
                    {
                        //拿出向上取整的整个表达式
    
                        strExpress= this.CellingFuncCompute(strExpress);
    
    
                    }            
     
                    #region
                    //如果表达式中包含聚合函数,则替换为ID和Value列,验证聚合函数是否正确
                    //if (strExpress.Contains("SUM") || strExpress.Contains("COUNT") || strExpress.Contains("MIN")
                    //        || strExpress.Contains("MAX") || strExpress.Contains("AVG") || strExpress.Contains("ROUND")
                    //        || strExpress.Contains("POWER"))
                    //    {
                    //        dt.Columns.Add("ID", typeof(string));
                    //        dt.Columns.Add("Value", typeof(decimal));
    
                    //        strExpress = strExpress.Replace("SUM('1')", "Sum(ID)");
                    //        strExpress = strExpress.Replace("COUNT('1')", "Count(ID)");
                    //        strExpress = strExpress.Replace("MIN('1')", "Min(ID)");
                    //        strExpress = strExpress.Replace("MAX('1')", "Max(ID)");
                    //        strExpress = strExpress.Replace("AVG('1')", "Avg(ID)");
                    //        strExpress = strExpress.Replace("ROUND('1')", "Round(ID)");
    
                    //        strExpress = strExpress.Replace("SUM(1)", "Sum(Value)");
                    //        strExpress = strExpress.Replace("COUNT(1)", "Count(Value)");
                    //        strExpress = strExpress.Replace("MIN(1)", "Min(Value)");
                    //        strExpress = strExpress.Replace("MAX(1)", "Max(Value)");
                    //        strExpress = strExpress.Replace("AVG(1)", "Avg(Value)");
                    //        strExpress = strExpress.Replace("ROUND('1')", "Round(Value)");
    
    
                    //        if (strExpress.Contains("IIF"))
                    //        {
                    //            strExpress = strExpress.Replace("SUM(ID)", "'1'");
                    //            strExpress = strExpress.Replace("COUNT(ID)", "'1'");
                    //            strExpress = strExpress.Replace("MIN(ID)", "'1'");
                    //            strExpress = strExpress.Replace("MAX(ID)", "'1'");
                    //            strExpress = strExpress.Replace("AVG(ID)", "'1'");
                    //            strExpress = strExpress.Replace("ROUND(ID)", "'1'");
    
                    //            strExpress = strExpress.Replace("SUM(Value)", "1");
                    //            strExpress = strExpress.Replace("COUNT(Value)", "1");
                    //            strExpress = strExpress.Replace("MIN(Value)", "1");
                    //            strExpress = strExpress.Replace("MAX(Value)", "1");
                    //            strExpress = strExpress.Replace("AVG(Value)", "1");
                    //            strExpress = strExpress.Replace("ROUND(Value)", "1");
                    //        }
                    //    }
                    //int MaxCount = 0;
                    //while (strExpress.Contains("ROUND"))
                    //{
                    //    var mx = Regex.Matches(strExpress, "ROUND\([0-9]+[.]?[0-9]*,[0-9]+[.]?[0-9]*\)", RegexOptions.IgnoreCase);
                    //    if (mx != null && mx.Count > 0)
                    //    {
                    //        strExpress = strExpress.Replace(mx[0].Value, "1");
                    //    }
                    //    else
                    //    {
                    //        MaxCount++;
                    //    }
                    //    if (MaxCount >= 50)
                    //    {
                    //        MessageBoxEx.Show("Round函数校验不通过,请检查!");
                    //    return;
                    //    }
                    //}
                    //MaxCount = 0;
                    //while (strExpress.Contains("POWER"))
                    //{
                    //    var mx = Regex.Matches(strExpress, "POWER\([0-9]+[.]?[0-9]*,[0-9]+[.]?[0-9]*\)", RegexOptions.IgnoreCase);
                    //    if (mx != null && mx.Count > 0)
                    //    {
                    //        strExpress = strExpress.Replace(mx[0].Value, "1");
                    //    }
                    //    else
                    //    {
                    //        MaxCount++;
                    //    }
                    //    if (MaxCount >= 50)
                    //    {
                    //        MessageBoxEx.Show("Power函数校验不通过,请检查!");
                    //    }
                    //}
                    #endregion
                    //如果抛出异常,则计算表达式验证失败,否则验证成功
    
                    DatableComputeFunc(strExpress);
    
                    MessageBoxEx.Show("校验成功!");
                    //MessageBoxEx.Show("校验成功!");
    
                    return "1";
    
                }
          
                catch (Exception ex)
                {
                    MessageBoxEx.Show("校验失败"+ex);
                    return "0";
                }
            }
    
    //向上取整函数的嵌套实现
           private string CellingFuncCompute(string strExpress)
            {
                int idxStart = 0;//开始位置索引
                int idxEnd = 0;//结束位置索引
                string strMathCelling = "";//向上取整表达式
                int count = Regex.Matches(strExpress, "向上取整").Count;
                int count1 = 0;
                for (int i = 0; i < count; i++)
                {

                    idxStart = strExpress.IndexOf("向上取整");
                    if (idxStart == -1)
                    {
                        break;
                    }

                    idxEnd = strExpress.IndexOf("}", idxStart);
                    strMathCelling = strExpress.Substring(idxStart, idxEnd - idxStart + 1);
                    count1 = Regex.Matches(strMathCelling, "向上取整").Count-1;
                    if (count1 > 0)
                    {

                        for (int j = count1; j > 0; j--)
                        {
                            idxStart = strMathCelling.IndexOf("{");
                            if (idxStart == -1)
                            {
                                break;
                            }
                            idxStart = strMathCelling.IndexOf("向上取整", idxStart);

                            idxEnd = strMathCelling.IndexOf("}", idxStart);
                            strMathCelling = strMathCelling.Substring(idxStart, idxEnd - idxStart+1);
                            continue;
                        }



                    }
                    //strExpress = strExpress.Replace(strCelling, "向上取整i");

                    string result = DatableComputeFunc(strMathCelling.Replace("向上取整", ""));

                    strExpress = strExpress.Replace(strMathCelling, Convert.ToString(Math.Ceiling(Convert.ToDecimal(result))));
                    //计算



                }

                return strExpress;

            }
    private string DatableComputeFunc(string strExpress) { //如果表达式中包含聚合函数,则判断使用聚合函数的数据列,是否是本表单的 if (strExpress.Contains("IIF") || strExpress.Contains("Sum") || strExpress.Contains("Count") || strExpress.Contains("Min") || strExpress.Contains("Max") || strExpress.Contains("Avg") || strExpress.Contains("Power") || strExpress.Contains("Round")) { strExpress = strExpress.Replace("{", ""); strExpress = strExpress.Replace("}", ""); strExpress = strExpress.Replace("@", ""); string[] computeS = new string[] { "IIF", "Sum", "Count", "Min", "Max", "Avg", "Power", "Round" }; string strTemp = strExpress; for (int i = 0; i < computeS.Length; i++) { if (strExpress.Contains(computeS[i].ToString())) { strTemp = strTemp.Replace(computeS[i].ToString(), "#"); } } string[] tempSS = strTemp.Split('#'); for (int i = 1; i < tempSS.Length; i++) { strTemp = tempSS[i]; Match match = Regex.Match(strTemp, "\[[^\]]*\]"); //匹配字段 string tableName = match.Value.ToString(); //校验列 } } DataTable dt = new DataTable(); //如果包含多个'',替换为'。如果包含%',替换为%。 if (strExpress.Contains("''")) { strExpress = strExpress.Replace("''", "'"); } if (strExpress.Contains("%'")) { strExpress = strExpress.Replace("%'", "%"); } if (strExpress.Contains("{")) { strExpress = strExpress.Replace("{", ""); } if (strExpress.Contains("}")) { strExpress = strExpress.Replace("}", ""); } if (strExpress.Contains("[")) { strExpress = strExpress.Replace("[", ""); } if (strExpress.Contains("]")) { strExpress = strExpress.Replace("]", ""); } strExpress = strExpress.ToUpper(); object test = dt.Compute(strExpress, ""); return Convert.ToString(test); } private void GetTspCostsFormulaResult() { DataSet dataSet = new DataSet(); DataTable dataTable = new DataTable(); dataTable.TableName = "TspTaskBills"; dataTable.Columns.Add("TspOrgID"); dataTable.Columns.Add("VendorID"); dataTable.Columns.Add("TspTypeID"); dataTable.Columns.Add("CostsID"); dataTable.Columns.Add("TotalQuantity"); dataTable.Columns.Add("TotalTransGrWeight"); dataTable.Columns.Add("TotalTransVolume"); dataTable.Columns.Add("BaseTspCost"); dataTable.Columns.Add("VendorCode"); dataTable.Columns.Add("TspTypeCode"); dataTable.Columns["TotalTransGrWeight"].DefaultValue = "200";//默认值放前面 DataRow dataRow = dataTable.NewRow(); dataRow["TspOrgID"] = "00000000000000000015"; dataRow["VendorID"] = "0001"; dataRow["VendorCode"] = "0001"; dataRow["TspTypeID"] = "1"; dataRow["TspTypeCode"] = "1"; dataRow["CostsID"] = "00000000000000008251"; dataRow["TotalQuantity"] = "3"; dataRow["TotalTransGrWeight"] = "2"; dataRow["TotalTransVolume"] = "1"; dataRow["BaseTspCost"] = "7"; dataTable.Rows.Add(dataRow); DataRow dataRow1 = dataTable.NewRow(); dataRow1["TspOrgID"] = "00000000000000000015"; dataRow1["VendorID"] = "0001"; dataRow1["VendorCode"] = "0001"; dataRow1["TspTypeID"] = "1"; dataRow1["TspTypeCode"] = "1"; dataRow1["CostsID"] = "00000000000000008251"; dataRow1["TotalQuantity"] = "5"; dataRow1["TotalTransGrWeight"] = "6"; dataRow1["TotalTransVolume"] = "7"; dataRow1["BaseTspCost"] = "8"; dataTable.Rows.Add(dataRow1); DataRow dataRow2 = dataTable.NewRow(); dataRow2["TspOrgID"] = "00000000000000000015"; dataRow2["VendorID"] = "0000007"; dataRow2["VendorCode"] = "0000007"; dataRow2["TspTypeID"] = "1"; dataRow2["TspTypeCode"] = "1"; dataRow2["CostsID"] = "00000000000000004615"; dataRow2["TotalQuantity"] = "5"; //dataRow2["TotalTransGrWeight"] = "6"; dataRow2["TotalTransVolume"] = "7"; dataRow2["BaseTspCost"] = "8"; dataTable.Rows.Add(dataRow2); foreach (DataRow dr in dataTable.Rows) { dr["BaseTspCost"] = 100; } dataSet.Tables.Add(dataTable); DataSet dataSetResult = new DataSet(); dataSetResult = TspCostsFormulaClient.Current.GetTspCostsFormulaResult(dataSet); } private void CancelToolStripMenuItem_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; this.Close(); } private void CloseToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } } }

    代码如上

    对于对外计算接口,定义一个webservice,传入值datatable包含参数对应值的数据源,计算写法与校验的一样就可以。

  • 相关阅读:
    php header
    How to Share a Theme With All Users in a Windows 7 Computer?
    240多个jQuery插件
    Delphi读写UTF8、Unicode格式文本文件
    虚拟网关解决ARP批处理版
    从煎蛋网上抓取妹子图
    在【批处理】中过滤特殊字符
    反序列化(临时)
    python发邮件实例
    反序列化(临时)
  • 原文地址:https://www.cnblogs.com/liuyudong0825/p/11971582.html
Copyright © 2011-2022 走看看