/// <summary> /// This either adds the new value to an already existing composite (list of several values), /// or it changes the current non composite variable to be a composite, /// by adding the current value as the first member to the list, and then adding the new value; /// ToString will concatenate the values, but ToDecimal, ToBoolean etc will only convert the first value in the composite /// /// </summary> /// <returns>void</returns> public void Add(TVariant value, String AFormatString, Boolean AConcatenateStrings) { TVariant lastValue; value.ApplyFormatString(AFormatString); if (TypeVariant == eVariantTypes.eComposite) { if ((value.TypeVariant == eVariantTypes.eComposite) && (value.CompositeValue.Count == 1)) { // if there is only one element in the other composite, reduce to the element value = (TVariant)value.CompositeValue[0]; } // try to concatenate strings if ((AConcatenateStrings == true) && (value.TypeVariant == eVariantTypes.eString) && (CompositeValue.Count > 0)) { lastValue = (TVariant)CompositeValue[CompositeValue.Count - 1]; if (lastValue.TypeVariant == eVariantTypes.eString) { // don't create a new value in the list, but add the string to the last element lastValue.StringValue = lastValue.StringValue + value.StringValue; } else { CompositeValue.Add(value); } } else { CompositeValue.Add(value); } } else { if ((!IsNil())) { if ((AConcatenateStrings == true) && (value.TypeVariant == eVariantTypes.eString) && (this.TypeVariant == eVariantTypes.eString)) { // don't create a new value in the list, but add the string to the last element this.StringValue = this.StringValue + value.StringValue; } else { CompositeValue = new ArrayList(); // if this has already a value, then move the value over into the arraylist CompositeValue.Add(new TVariant(this)); TypeVariant = eVariantTypes.eComposite; Add(value, AFormatString, AConcatenateStrings); // recursive call so that we only need to code once for adding the strings directly } } else { // don't create a list at the moment, just copy the value this.Assign(value); } } }
/// <summary> /// copy the value to the current object instance /// </summary> /// <param name="value">value to be copied</param> public void Assign(TVariant value) { TypeVariant = value.TypeVariant; EmptyValue = value.EmptyValue; DateValue = value.DateValue; DecimalValue = value.DecimalValue; FormatString = value.FormatString; IntegerValue = value.IntegerValue; Int64Value = value.Int64Value; StringValue = value.StringValue; BooleanValue = value.BooleanValue; CompositeValue = new ArrayList(); if (value.CompositeValue != null) { foreach (TVariant v in value.CompositeValue) { CompositeValue.Add(new TVariant(v)); } } }
/// <summary> /// constructor for string /// if you want the content to be kept as a string, and not converted to int (e.g. cost centre: 0200) /// </summary> /// <param name="value"></param> /// <param name="ExplicitString"></param> public TVariant(String value, bool ExplicitString) : this(value, "") { if (ExplicitString) { TypeVariant = eVariantTypes.eString; StringValue = value; FormatString = "text"; } }
/// <summary> /// constructor for boolean /// </summary> /// <param name="value">boolean value</param> public TVariant(bool value) { TypeVariant = eVariantTypes.eBoolean; BooleanValue = value; FormatString = ""; }
/// <summary> /// constructor for long integer /// </summary> /// <param name="value">long integer value</param> public TVariant(System.Int64 value) { if (value < System.Int32.MaxValue) { TypeVariant = eVariantTypes.eInteger; IntegerValue = (int)value; } else { TypeVariant = eVariantTypes.eInt64; Int64Value = value; } FormatString = ""; }
/// <summary> /// constructor for string /// will look at the content of the string and generate a typed representation /// if you want to force a string value, use the other overloaded constructor below /// </summary> /// <param name="value">string value</param> /// <param name="AFormat">requested format</param> public TVariant(String value, String AFormat) { FormatString = AFormat; if (value == null) { TypeVariant = eVariantTypes.eEmpty; return; } TypeVariant = eVariantTypes.eString; StringValue = value; if (this.ToBool().ToString() == StringValue) { BooleanValue = this.ToBool(); TypeVariant = eVariantTypes.eBoolean; } if (this.ToDate() != DateTime.MinValue) { // this is needed for SQLite, which returns date values as a string DateValue = this.ToDate(); TypeVariant = eVariantTypes.eDateTime; } else if ((value.Length > 0) && ((value[0] == '-') || ((value[0] >= '0') && (value[0] <= '9'))) && (((this.ToInt64() == StringHelper.TryStrToInt(StringValue, -1)) && (this.ToInt64() != -1) && (this.ToInt64() == 0)) || (this.ToInt64().ToString() == StringValue))) { // prevent unnecessary Exceptions from TryStrToInt // we cannot do the following (convert in both directions to catch numbers with leading zeros, e.g. Partnerkey) // this would cause trouble with eg. Account codes that should start with 0 // I will limit it to just zeros, which would catch an empty partner key to become a zero // will create Int32 if the value is small enough Int64Value = this.ToInt64(); IntegerValue = this.ToInt(); TypeVariant = eVariantTypes.eInt64; if (Int64Value == IntegerValue) { TypeVariant = eVariantTypes.eInteger; } } else if (this.ToDecimal().ToString() == StripDecimalAndZeros(StringValue)) { // has to work for 0.0 as well! DecimalValue = this.ToDecimal(); TypeVariant = eVariantTypes.eDecimal; } else if ((StringValue.Length == 10) && (StringValue[0] == '#') && (StringValue[9] == '#')) { DateValue = new DateTime(Convert.ToInt32(StringValue.Substring(1, 4)), Convert.ToInt32(StringValue.Substring(5, 2)), Convert.ToInt32(StringValue.Substring(7, 2))); TypeVariant = eVariantTypes.eDateTime; } }
/// <summary> /// constructor for double (will be converted to decimal) /// </summary> /// <param name="value">double value</param> public TVariant(double value) { TypeVariant = eVariantTypes.eDecimal; DecimalValue = (decimal)value; FormatString = ""; }
/// <summary> /// constructor for integer /// </summary> /// <param name="value">integer value</param> public TVariant(System.Int32 value) { TypeVariant = eVariantTypes.eInteger; IntegerValue = value; FormatString = ""; }
/// <summary> /// constructor for decimal /// </summary> /// <param name="value">decimal value</param> /// <param name="AFormat">requested format</param> public TVariant(decimal value, String AFormat) { TypeVariant = eVariantTypes.eCurrency; DecimalValue = value; FormatString = AFormat; }
/// <summary> /// constructor for dates /// </summary> /// <param name="value">date time value</param> /// <param name="AFormat">can be dayofyear (for birthdays)</param> /// <returns>void</returns> /// public TVariant(System.DateTime value, String AFormat) { TypeVariant = eVariantTypes.eDateTime; DateValue = value; FormatString = AFormat; }
/// <summary> /// copy constructor /// </summary> /// <param name="value"></param> public TVariant(TVariant value) { if (value != null) { Assign(value); } else { TypeVariant = eVariantTypes.eEmpty; EmptyValue = null; FormatString = ""; } }
/// <summary> /// default constructor /// </summary> public TVariant() { TypeVariant = eVariantTypes.eEmpty; EmptyValue = null; FormatString = ""; }
/// <summary> /// apply the string format to the current variable /// </summary> /// <param name="AFormatString">format to be used</param> public void ApplyFormatString(String AFormatString) { String columnformat; int Counter; columnformat = AFormatString.ToLower();; if (columnformat.IndexOf("csvlistslash") == 0) { StringHelper.GetNextCSV(ref columnformat, ":"); // this will leave the last element in columnFormat // if there is only one element in the list, we don't want to overwrite the format of that element // but we need to apply the format to each member of the list if (this.TypeVariant == eVariantTypes.eComposite) { FormatString = "csvlistslash"; for (Counter = 0; Counter <= this.CompositeValue.Count - 1; Counter += 1) { ((TVariant) this.CompositeValue[Counter]).ApplyFormatString(columnformat); } // don't proceed, it might only cause trouble, e.g. with partnerkey being assigned to the composite return; } } else if (columnformat.IndexOf("quotes") == 0) { // apply the quotes immediately this.StringValue = "'" + this.ToFormattedString() + "'"; this.TypeVariant = eVariantTypes.eString; this.FormatString = "text"; } if (this.ToFormattedString(columnformat).Length == 0) { // e.g. empty partnerkey should print 0000000000 this.TypeVariant = eVariantTypes.eEmpty; if (columnformat != "") { this.FormatString = columnformat; } } else { if (columnformat == "partnerkey") { // this value comes from the database as a decimal, and therefore is treated like a currency; // that is not good for csv file export; so we convert it to Int64 this.Int64Value = ToInt64(); this.TypeVariant = eVariantTypes.eInt64; this.FormatString = columnformat; } else if (columnformat == "text") { // this value comes from the database as some type, but should really be treated as a text string, without formatting // so we convert it to String this.StringValue = ToString(); this.TypeVariant = eVariantTypes.eString; this.FormatString = columnformat; } else if (columnformat.StartsWith("numberformat")) { this.StringValue = this.DecimalValue.ToString(columnformat.Substring(12)); this.TypeVariant = eVariantTypes.eString; this.FormatString = columnformat; } else if (StringHelper.GetFormatString(columnformat, "").Length > 0) { // this should filter out 'row', etc. this.FormatString = columnformat; } } }