// 汇总价格 // 货币单位不同的,互相独立 // parameters: // prices 若干单一价格字符串构成的数组。并未进行过排序 // return: // -1 error // 0 succeed public static int TotalPrice(List <string> prices, out List <string> results, out string strError) { strError = ""; results = new List <string>(); List <CurrencyItem> items = new List <CurrencyItem>(); // 变换为PriceItem // for (int i = 0; i < prices.Count; i++) foreach (string price in prices) { // string strText = prices[i].Trim(); if (price == null) { continue; } string strText = price.Trim(); if (String.IsNullOrEmpty(strText) == true) { continue; } #if NO string strLeft = ""; string strRight = ""; string strOperator = ""; // 先处理乘除号 // return: // -1 出错 // 0 没有发现乘号、除号 // 1 发现乘号或者除号 int nRet = ParseMultipcation(strText, out strLeft, out strRight, out strOperator, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { Debug.Assert(strOperator.Length == 1, ""); if (String.IsNullOrEmpty(strLeft) == true || String.IsNullOrEmpty(strRight) == true) { strError = "金额字符串格式错误 '" + strText + "'。乘号或除号的两边必须都有内容"; return(-1); } } string strPrice = ""; string strMultiper = ""; if (nRet == 0) { Debug.Assert(String.IsNullOrEmpty(strLeft) == true, ""); Debug.Assert(String.IsNullOrEmpty(strRight) == true, ""); Debug.Assert(String.IsNullOrEmpty(strOperator) == true, ""); strPrice = strText.Trim(); } else { Debug.Assert(nRet == 1, ""); if (StringUtil.IsDouble(strLeft) == false && StringUtil.IsDouble(strRight) == false) { strError = "金额字符串格式错误 '" + strText + "'。乘号或除号的两边必须至少有一边是纯数字"; return(-1); } if (StringUtil.IsDouble(strLeft) == false) { strPrice = strLeft; strMultiper = strRight; } else if (StringUtil.IsDouble(strRight) == false) { strPrice = strRight; strMultiper = strLeft; if (strOperator == "/") { strError = "金额字符串格式错误 '" + strText + "'。除号的右边才能是纯数字"; return(-1); } } else { // 默认左边是价格,右边是倍率 strPrice = strLeft; strMultiper = strRight; } } string strPrefix = ""; string strValue = ""; string strPostfix = ""; nRet = ParsePriceUnit(strPrice, out strPrefix, out strValue, out strPostfix, out strError); if (nRet == -1) { return(-1); } // 2012/1/5 if (string.IsNullOrEmpty(strValue) == true) { strError = "单个金额字符串 '" + strPrice + "' 中没有包含数字部分"; return(-1); } decimal value = 0; try { value = Convert.ToDecimal(strValue); } catch { strError = "单个金额字符串 '" + strPrice + "' 中, 数字部分 '" + strValue + "' 格式不正确"; return(-1); } if (String.IsNullOrEmpty(strOperator) == false) { double multiper = 0; try { multiper = Convert.ToDouble(strMultiper); } catch { strError = "数字 '" + strMultiper + "' 格式不正确"; return(-1); } if (strOperator == "*") { value = (decimal)((double)value * multiper); } else { Debug.Assert(strOperator == "/", ""); if (multiper == 0) { strError = "金额字符串格式错误 '" + strText + "'。除法运算中,除数不能为0"; return(-1); } value = (decimal)((double)value / multiper); } } PriceItem item = new PriceItem(); item.Prefix = strPrefix.ToUpper(); item.Postfix = strPostfix.ToUpper(); item.Value = value; // 缺省货币为人民币 if (item.Prefix == "" && item.Postfix == "") { item.Prefix = "CNY"; } #endif CurrencyItem item = null; int nRet = ParseSinglePrice(strText, out item, out strError); if (nRet == -1) { return(-1); } items.Add(item); } // 汇总 for (int i = 0; i < items.Count; i++) { CurrencyItem item = items[i]; for (int j = i + 1; j < items.Count; j++) { CurrencyItem current_item = items[j]; if (current_item.Prefix == item.Prefix && current_item.Postfix == item.Postfix) { item.Value += current_item.Value; items.RemoveAt(j); j--; } /* * else * break; * */ // 这里是一个BUG。没有排序,并不知道后面还有没有重复的事项呢,不能break。2009/10/10 changed } } // 输出 for (int i = 0; i < items.Count; i++) { CurrencyItem item = items[i]; decimal value = item.Value; string fmt = "0.00"; // #.## // 负号要放在最前面 if (value < 0) { results.Add("-" + item.Prefix + (-value).ToString(fmt) + item.Postfix); } else { results.Add(item.Prefix + value.ToString(fmt) + item.Postfix); } } // 注: value.ToString("#.##") 采用的是四舍五入的方法 return(0); }
// 能够处理乘号或者除号了 public static string GetPurePrice(string strText) { string strError = ""; string strLeft = ""; string strRight = ""; string strOperator = ""; // 先处理乘除号 // return: // -1 出错 // 0 没有发现乘号、除号 // 1 发现乘号或者除号 int nRet = ParseMultipcation(strText, out strLeft, out strRight, out strOperator, out strError); if (nRet == -1) { throw new Exception(strError); } if (nRet == 0) { return(OldGetPurePrice(strText)); } Debug.Assert(nRet == 1, ""); string strMultiper = ""; string strPrice = ""; if (StringUtil.IsDouble(strLeft) == false && StringUtil.IsDouble(strRight) == false) { strError = "金额字符串格式错误 '" + strText + "'。乘号或除号的两边必须至少有一边是纯数字"; throw new Exception(strError); } if (StringUtil.IsDouble(strLeft) == false) { strPrice = strLeft; strMultiper = strRight; } else if (StringUtil.IsDouble(strRight) == false) { strPrice = strRight; strMultiper = strLeft; if (strOperator == "/") { strError = "金额字符串 '" + strText + "' 格式错误。除号的右边才能是纯数字"; throw new Exception(strError); } } else { // 默认左边是价格,右边是倍率 strPrice = strLeft; strMultiper = strRight; } string strValue = OldGetPurePrice(strPrice); decimal value = 0; try { value = Convert.ToDecimal(strValue); } catch { strError = "单个金额字符串 '" + strPrice + "' 中, 数字部分 '" + strValue + "' 格式不正确"; throw new Exception(strError); } if (String.IsNullOrEmpty(strOperator) == false) { double multiper = 0; try { multiper = Convert.ToDouble(strMultiper); } catch { strError = "数字 '" + strMultiper + "' 格式不正确"; throw new Exception(strError); } if (strOperator == "*") { value = (decimal)((double)value * multiper); } else { Debug.Assert(strOperator == "/", ""); if (multiper == 0) { strError = "金额字符串格式错误 '" + strText + "'。除法运算中,除数不能为0"; throw new Exception(strError); } value = (decimal)((double)value / multiper); } return(value.ToString()); } return(strValue); }
// 解析单个金额字符串。例如 CNY10.00 或 -CNY100.00/7 public static int ParseSinglePrice(string strText, out CurrencyItem item, out string strError) { strError = ""; item = new CurrencyItem(); if (string.IsNullOrEmpty(strText) == true) { return(0); } strText = strText.Trim(); if (String.IsNullOrEmpty(strText) == true) { return(0); } string strLeft = ""; string strRight = ""; string strOperator = ""; // 先处理乘除号 // return: // -1 出错 // 0 没有发现乘号、除号 // 1 发现乘号或者除号 int nRet = ParseMultipcation(strText, out strLeft, out strRight, out strOperator, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { Debug.Assert(strOperator.Length == 1, ""); if (String.IsNullOrEmpty(strLeft) == true || String.IsNullOrEmpty(strRight) == true) { strError = "金额字符串格式错误 '" + strText + "'。乘号或除号的两边必须都有内容"; return(-1); } } string strPrice = ""; string strMultiper = ""; if (nRet == 0) { Debug.Assert(String.IsNullOrEmpty(strLeft) == true, ""); Debug.Assert(String.IsNullOrEmpty(strRight) == true, ""); Debug.Assert(String.IsNullOrEmpty(strOperator) == true, ""); strPrice = strText.Trim(); } else { Debug.Assert(nRet == 1, ""); if (StringUtil.IsDouble(strLeft) == false && StringUtil.IsDouble(strRight) == false) { strError = "金额字符串格式错误 '" + strText + "'。乘号或除号的两边必须至少有一边是纯数字"; return(-1); } if (StringUtil.IsDouble(strLeft) == false) { strPrice = strLeft; strMultiper = strRight; } else if (StringUtil.IsDouble(strRight) == false) { strPrice = strRight; strMultiper = strLeft; if (strOperator == "/") { strError = "金额字符串格式错误 '" + strText + "'。除号的右边才能是纯数字"; return(-1); } } else { // 默认左边是价格,右边是倍率 strPrice = strLeft; strMultiper = strRight; } } string strPrefix = ""; string strValue = ""; string strPostfix = ""; nRet = ParsePriceUnit(strPrice, out strPrefix, out strValue, out strPostfix, out strError); if (nRet == -1) { return(-1); } if (string.IsNullOrEmpty(strValue) == true) { strError = "金额字符串 '" + strPrice + "' 中没有包含数字部分"; return(-1); } decimal value = 0; try { value = Convert.ToDecimal(strValue); } catch { strError = "金额字符串 '" + strPrice + "' 中, 数字部分 '" + strValue + "' 格式不正确"; return(-1); } if (String.IsNullOrEmpty(strOperator) == false) { double multiper = 0; try { multiper = Convert.ToDouble(strMultiper); } catch { strError = "数字 '" + strMultiper + "' 格式不正确"; return(-1); } if (strOperator == "*") { value = (decimal)((double)value * multiper); } else { Debug.Assert(strOperator == "/", ""); if (multiper == 0) { strError = "金额字符串格式错误 '" + strText + "'。除法运算中,除数不能为0"; return(-1); } // value = (decimal)((double)value / multiper); value = Convert.ToDecimal((double)value / multiper); } } item.Prefix = strPrefix.ToUpper(); item.Postfix = strPostfix.ToUpper(); item.Value = value; // 缺省货币为人民币 if (item.Prefix == "" && item.Postfix == "") { item.Prefix = "CNY"; } return(0); }