运输费用公式定义:
支持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包含参数对应值的数据源,计算写法与校验的一样就可以。