/// <summary> /// Match a string value to conditional formatting & return the first matching item /// Handles dates converted to normalized string values also (yyyymmdd) /// </summary> /// <param name="rules"></param> /// <param name="value"></param> /// <returns></returns> public static CondFormatRule Match( CondFormat condFormat, string stringValue) { double v, v1, v2; int ri; object o; CondFormatRules rules = condFormat.Rules; CondFormatRule rule = null; DateTime dtValue = DateTime.MinValue, dt2; if (condFormat.ColumnType == MetaColumnType.CompoundId) { return(Match(condFormat, new CompoundId(stringValue))); } if (String.IsNullOrEmpty(stringValue)) { return(MatchNull(condFormat)); } int lowerLimitRule = -1; int upperLimitRule = -1; for (ri = 0; ri < rules.Count; ri++) { rule = rules[ri]; if (!String.IsNullOrEmpty(stringValue)) { // check where we have a value string value = rule.Value; if (rule.ValueNormalized != null) { value = rule.ValueNormalized; } string value2 = rule.Value2; if (rule.Value2Normalized != null) { value2 = rule.Value2Normalized; } if (rule.OpCode == CondFormatOpCode.Within) // check date range { dtValue = DateTimeMx.NormalizedToDateTime(stringValue); // convert to a DateTime double withinValue = rule.ValueNumber; if (Lex.Contains(value2, "Day")) { dt2 = dtValue.AddDays(withinValue); } else if (Lex.Contains(value2, "Week")) { dt2 = dtValue.AddDays(withinValue * 7); } else if (Lex.Contains(value2, "Month")) { dt2 = dtValue.AddMonths((int)withinValue); // note must be integer months } else if (Lex.Contains(value2, "Year")) { dt2 = dtValue.AddYears((int)withinValue); // note must be integer years } else { throw new Exception("Unexpected date unit: " + value2); } dt2 = dt2.AddDays(1); // add one day to dt2 since it's time is 12:00 AM and the Now date includes the hours passed so far today if (DateTime.Compare(dt2, DateTime.Now) >= 0) { break; // if stored date/time + within value is >= current date/time then condition passes } else { continue; } } if (rule.OpCode == CondFormatOpCode.Between && value2 != null && value != null) { if (Lex.Gt(value, value2)) { string s1 = value; value = value2; value2 = s1; } if (Lex.Ge(stringValue, value) && Lex.Le(stringValue, value2)) { break; } } else if (rule.OpCode == CondFormatOpCode.NotBetween && value2 != null && value != null) { if (Lex.Gt(value, value2)) { string s1 = value; value = value2; value2 = s1; } if (Lex.Lt(stringValue, value) || Lex.Gt(stringValue, value2)) { break; } } else if (rule.OpCode == CondFormatOpCode.Eq && Lex.Eq(stringValue, value)) { break; } else if (rule.OpCode == CondFormatOpCode.NotEq && Lex.Ne(stringValue, value)) { break; } else if (rule.OpCode == CondFormatOpCode.Gt && Lex.Gt(stringValue, value)) { break; } else if (rule.OpCode == CondFormatOpCode.Lt && Lex.Lt(stringValue, value)) { break; } else if (rule.OpCode == CondFormatOpCode.Ge && Lex.Ge(stringValue, value)) { if (rules.ColoringStyle == CondFormatStyle.ColorScale || ri > rules.Count - 1) { break; } else { lowerLimitRule = ri; } } else if (rule.OpCode == CondFormatOpCode.Le && Lex.Le(stringValue, value)) { upperLimitRule = ri; break; } else if (rule.OpCode == CondFormatOpCode.Substring && stringValue.ToLower().IndexOf(value.ToLower()) >= 0) { break; } else if (rule.OpCode == CondFormatOpCode.NotNull || rule.OpCode == CondFormatOpCode.Exists) // value is not null or exists { break; } else if (rule.OpCode == CondFormatOpCode.Unknown && // treat unknown as equal Lex.Eq(stringValue, value)) { break; } } else if (rule.OpCode == CondFormatOpCode.Null || rule.OpCode == CondFormatOpCode.NotExists) { break; // null value & null conditional format operator } } //DebugLog.Message(stringValue + " " + ri); // debug if (ri >= rules.Count) { return(null); // return null if no rule matches } // Matches a rule associated with a particular color if (rules.ColoringStyle == CondFormatStyle.ColorSet) { return(rule); } // Calculate a linear gradient between the two color limits else if (rules.ColoringStyle == CondFormatStyle.ColorScale && rule.OpCode == CondFormatOpCode.Between) { // newer single color scale rule ConvertDateValuesToDoubles(condFormat, stringValue, rule.ValueNormalized, rule.Value2Normalized, out v, out v1, out v2); rule.ValueNumber = v1; rule.Value2Number = v2; rule = BuildColorRuleForColorScale(v, rule); return(rule); } else if (rules.ColoringStyle == CondFormatStyle.ColorScale && lowerLimitRule >= 0 && upperLimitRule >= lowerLimitRule) { // older two-rule, double color scale rules CondFormatRule r1 = rules[lowerLimitRule]; CondFormatRule r2 = rules[upperLimitRule]; ConvertDateValuesToDoubles(condFormat, stringValue, r1.ValueNormalized, r2.ValueNormalized, out v, out v1, out v2); rule.ValueNumber = v1; rule.Value2Number = v2; rule = BuildColorRuleForGradientValue(v, v1, v2, r1.BackColor1, r2.BackColor1); return(rule); } // Calculate a percentage for a data bar for a value between the two color limits else if (rules.ColoringStyle == CondFormatStyle.DataBar) { ConvertDateValuesToDoubles(condFormat, stringValue, rule.ValueNormalized, rule.Value2Normalized, out v, out v1, out v2); rule.ValueNumber = v1; rule.Value2Number = v2; rule = BuildPercentageRuleForDataBarValue(v, rule); return(rule); } else if (rules.ColoringStyle == CondFormatStyle.IconSet) { rule = BuildImageRuleForIconSetValue(rule); return(rule); // image name should be included in rule } else { return(rule); // shouldn't happen } }