private void ReplaceFunctionVariables(ref TVariant v) { String s; TVariant testS; TVariant[] ops = new TVariant[ReportingConsts.MAX_FUNCTION_PARAMETER + 1 - 0 + 1]; Int32 counter; if (v.TypeVariant == eVariantTypes.eString) { s = v.ToString().Trim(); s = s.Replace("{{lineId}}", StringHelper.IntToStr(LineId)); s = s.Replace("{{column}}", StringHelper.IntToStr(column)); s = s.Replace("{{level}}", StringHelper.IntToStr(Depth)); // make sure that e.g. HasChildRows is evaluated for (counter = 1; counter <= ReportingConsts.MAX_FUNCTION_PARAMETER; counter += 1) { ops[counter] = null; } testS = FunctionSelector(s, ops); if (testS != null) { s = testS.ToString(); } TRptFormatQuery query = new TRptFormatQuery(s, null, Parameters, column, Depth); query.ReplaceVariables(); v = query.VariantValue; } }
/// <summary> /// this is only called when we know for sure that we need to know the value of this operand /// </summary> /// <returns>void</returns> private TVariant EvaluateOperand(TVariant op) { int after; if (op != null) { if (op.ToString().IndexOf("SUBCALL:") == 0) { after = -1; op = EvaluateOperator(op.ToString().Substring(8), 0, out after); } ReplaceFunctionVariables(ref op); } return(op); }
/// <summary> /// Reads the selected values from the controls, /// and stores them into the parameter system of FCalculator /// /// </summary> /// <param name="ACalculator"></param> /// <param name="AReportAction"></param> /// <returns>void</returns> public void ReadControls(TRptCalculator ACalculator, TReportActionEnum AReportAction) { System.Int32 MaxDisplayColumns; MaxDisplayColumns = TUC_ColumnHelper.ReadControls(ref FColumnParameters, ref ACalculator); FPetraUtilsObject.FMaxDisplayColumns = MaxDisplayColumns; for (int Counter = 0; Counter <= FColumnParameters.Get("MaxDisplayColumns").ToInt() - 1; Counter += 1) { String SelectedLedgers = FColumnParameters.Get("param_selected_ledgers", Counter).ToString(false); if (SelectedLedgers.Length != 0) { ACalculator.AddColumnFunctionLedgers(Counter, "add", StringHelper.StrSplit(SelectedLedgers, ","), FColumnParameters.Get("param_calculation", Counter).ToString(), FColumnParameters.Get("param_ytd", Counter).ToBool()); } } // set the global param_ytd; that is needed for formatting the header of some reports String ytdMixed = ""; for (int Counter = 0; Counter <= FColumnParameters.Get("MaxDisplayColumns").ToInt() - 1; ++Counter) { TVariant ParamYtd = FColumnParameters.Get("param_ytd", Counter); if (!ParamYtd.IsZeroOrNull()) { if (ytdMixed.Length == 0) { ytdMixed = ParamYtd.ToString(); } if (ParamYtd.ToString() != ytdMixed) { ytdMixed = "mixed"; } } } if (ytdMixed.Length != 0) { ACalculator.AddParameter("param_ytd", ytdMixed); } }
/// <summary> /// add an odbc parameter, and replace the placeholders /// </summary> public void AddOdbcParameters(string APrefix, string AName, string APostfix, TVariant AValue) { if (IsVariant) { this.FSQLStmt = this.FVariantValue.ToString(); } int pos = 0; int parampos = 0; int parameterIndex = 0; int wherePos = this.FSQLStmt.ToUpper().IndexOf(" WHERE "); pos = this.FSQLStmt.IndexOf(APrefix + AName + APostfix, pos); if (pos == -1) { return; } if (wherePos > pos) { TLogging.Log(this.FSQLStmt); throw new Exception("AddOdbcParameters: do not replace table names with odbc parameters"); } while ((pos = this.FSQLStmt.IndexOf(APrefix + AName + APostfix, pos)) != -1) { while ((parampos != -1) && (parampos <= pos)) { parampos = this.FSQLStmt.IndexOf("PARAMETER?", parampos + 1); if ((parampos != -1) && (parampos <= pos)) { parameterIndex++; } } pos++; parampos = pos; if (APrefix == "{") { // force a string. needed for example for cost centre codes AValue = new TVariant(AValue.ToString(), true); } this.FOdbcParameters.Insert(parameterIndex, AValue.ToOdbcParameter(AName)); // we have added now a parameter, so this needs to be counted. // this is important if there are multiple occurances for the same parameter parameterIndex++; } this.FSQLStmt = this.FSQLStmt.Replace(APrefix + AName + APostfix, "PARAMETER?"); }
/// <summary> /// print one value, into the given column /// </summary> /// <param name="columnNr"></param> /// <param name="level"></param> /// <param name="column"></param> /// <returns></returns> protected override bool PrintColumn(Int32 columnNr, Int32 level, TVariant column) { String s; float position; float width; bool linePrinted; linePrinted = false; position = GetPosition(columnNr, level, 0); width = GetWidth(columnNr, level, 0); s = column.ToString(); if (s.Length != 0) { linePrinted = true; if (FParameters.Get("LineAbove", columnNr, level, eParameterFit.eAllColumnFit).ToBool() == true) { FPrinter.DrawLine(position, position + width, eLinePosition.eAbove, eFont.eDefaultFont); } if (FWrapColumn) { FPrinter.PrintStringWrap(s, eFont.eDefaultFont, position, width, GetAlignment(columnNr, level, eAlignment.eRight)); } else { FPrinter.PrintString(s, eFont.eDefaultFont, position, width, GetAlignment(columnNr, level, eAlignment.eRight)); } if (FParameters.Get("LineBelow", columnNr, level, eParameterFit.eAllColumnFit).ToBool() == true) { FPrinter.DrawLine(position, position + width, eLinePosition.eBelow, eFont.eDefaultFont); } FPrinter.LineFeed(eFont.eDefaultFont); } return(linePrinted); }
/// <summary> /// This formats the caption of a column, into up to 3 rows /// /// </summary> /// <returns>void</returns> protected void FormatCaption(String AParameterName, TVariant ACaption, System.Int32 AColumn) { int br; String caption; // v, newValue: TVariant; // Counter: integer; // TODO: client side formatting of column captions? e.g. month names should be localised // problems: there can be \n inside strings; // need to split strings by the \n caption = ACaption.ToString(); br = caption.IndexOf("\\n"); if (br != -1) { Parameters.Add(AParameterName, new TVariant(caption.Substring(0, br), true), AColumn); // Tlogging.Log(parameters.Get(AParameterName).EncodeToString()); caption = caption.Substring(br + 2, caption.Length - br - 2); br = caption.IndexOf("\\n"); if (br != -1) { Parameters.Add(AParameterName + '2', new TVariant(caption.Substring(0, br), true), AColumn); // Tlogging.Log(parameters.Get(AParameterName+'2').EncodeToString()); caption = caption.Substring(br + 2, caption.Length - br - 2); Parameters.Add(AParameterName + '3', new TVariant(caption, true), AColumn); } else { Parameters.Add(AParameterName + '2', new TVariant(caption, true), AColumn); } } else { Parameters.Add(AParameterName, new TVariant(caption, true), AColumn); } }
/// <summary> /// format a date in a form that will be adjusted /// for each database in FormatQueryRDBMSSpecific; /// (correct order of month/day etc) /// </summary> /// <param name="value"></param> /// <returns></returns> public static TVariant FormatDate(TVariant value) { String list; String day; String month; String year; String resultString; if (value.TypeVariant == eVariantTypes.eDateTime) { resultString = "#" + value.DateToString("yyyy/MM/dd") + "#"; // it seems, the separators (e.g. , /, .) are not considered resultString = resultString.Replace(value.DateToString("yyyy/MM/dd")[4], '-'); } else { list = value.ToString(); // try all available separators, defined in Ict.Common.StringHelper day = StringHelper.GetNextCSV(ref list, ".", true); if (list.Length == 0) { throw new Exception("Ict.Petra.Server.MReporting.FormatQuery: Cannot decode date " + value.ToString()); } month = StringHelper.GetNextCSV(ref list, ".", true); year = StringHelper.GetNextCSV(ref list, ".", true); resultString = String.Format("#{0:4}-{1:2}-{2:2}#", year, month, day); } return(new TVariant(resultString, true)); // explicit string }
/// <summary> /// todoComment /// </summary> /// <param name="orig"></param> /// <param name="searchOpen"></param> /// <param name="searchClose"></param> /// <param name="newOpen"></param> /// <param name="newClose"></param> /// <param name="convert"></param> /// <returns></returns> protected TVariant ReplaceVariablesPattern(TVariant orig, String searchOpen, String searchClose, String newOpen, String newClose, TConvertProc convert) { int position = 0; String resultString = orig.ToString(); TVariant ReturnValue = null; int bracket = resultString.IndexOf(searchOpen, position); if (bracket == -1) { // no brackets, therefore use the original TVariant, so that the type information is not lost ReturnValue = orig; } while (bracket != -1) { int firstRealChar = bracket + searchOpen.Length; int paramEndIdx = resultString.IndexOf(searchClose, firstRealChar); if (paramEndIdx <= 0) { // missing closing bracket; can happen with e.g. #testdate; should be #testdate# if (resultString.Length > bracket + 20) { throw new Exception("Cannot find closing bracket " + searchClose + " for " + resultString.Substring(bracket, 20)); } else { throw new Exception("Cannot find closing bracket " + searchClose + " for " + resultString.Substring(bracket)); } } String parameter = resultString.Substring(firstRealChar, paramEndIdx - firstRealChar); bool ParameterExists = false; TVariant newvalue; if (parameters != null) { if (parameter.IndexOf("GLOBAL:") == 0) { newvalue = parameters.Get(parameter.Substring(7), -1, -1, eParameterFit.eExact); } else if (parameter.IndexOf("ALLLEVELS:") == 0) { newvalue = parameters.Get(parameter.Substring(10), -1, depth, eParameterFit.eBestFitEvenLowerLevel); } else { newvalue = parameters.Get(parameter, column, depth, eParameterFit.eBestFitEvenLowerLevel); } ParameterExists = (newvalue.TypeVariant != eVariantTypes.eEmpty); } else { newvalue = new TVariant(); } if (!ParameterExists) { // if date is given, use the parameter itself if ((parameter[0] >= '0') && (parameter[0] <= '9')) { newvalue = new TVariant(parameter); } else { int CountWarning = 1; // do not print warning too many times for the same variable if (!VariablesNotFound.ContainsKey(parameter)) { VariablesNotFound.Add(parameter, 1); } else { VariablesNotFound[parameter] = VariablesNotFound[parameter] + 1; CountWarning = VariablesNotFound[parameter]; } if (CountWarning < 5) { // this can be alright, for empty values; for example method of giving can be empty; for report GiftTransactions TLogging.Log( "Variable " + parameter + " empty or not found (column: " + column.ToString() + "; level: " + depth.ToString() + "). " + resultString); } else if (CountWarning % 20 == 0) { TLogging.Log("20 times: Variable " + parameter + " empty or not found."); } } } try { if (resultString.Length == (searchOpen + parameter + searchClose).Length) { // replace the whole value, return as a TVariant ReturnValue = convert(newvalue); } resultString = resultString.Replace(searchOpen + parameter + searchClose, newOpen + convert(newvalue).ToString() + newClose); } catch (Exception e) { throw new Exception( "While trying to format parameter " + parameter + ", there was a problem with formatting." + Environment.NewLine + e.Message); } bracket = resultString.IndexOf(searchOpen, position); } // while if (ReturnValue == null) { // there has not been just a single value ReturnValue = new TVariant(resultString, true); // explicit string } return(ReturnValue); }
/// <summary> /// todoComment /// </summary> /// <param name="precalculatedColumns"></param> /// <returns></returns> public TVariant Precalculate(TVariant[] precalculatedColumns) { TVariant ReturnValue; String strCalculation; TRptDataCalcCalculation rptDataCalcCalculation; TRptCalculation rptCalculation; DataTable tab; ReturnValue = new TVariant(); // calculation is used for display in the GUI, formula is used for adding ledgers if ((!GetParameters().Exists("param_calculation", column, Depth))) { return(ReturnValue); } if (GetParameters().Exists("param_formula", column, Depth)) { strCalculation = GetParameters().Get("param_formula", column, Depth).ToString(); } else { strCalculation = GetParameters().Get("param_calculation", column, Depth).ToString(); } rptCalculation = ReportStore.GetCalculation(CurrentReport, strCalculation); if (rptCalculation == null) { ReturnValue = EvaluateFunctionCalculation(strCalculation, precalculatedColumns); } else { rptDataCalcCalculation = new TRptDataCalcCalculation(this); if (!rptDataCalcCalculation.EvaluateCalculationFunction(rptCalculation.rptGrpQuery, ref precalculatedColumns, ref ReturnValue)) { ReturnValue = rptDataCalcCalculation.EvaluateCalculationAll(rptCalculation, null, rptCalculation.rptGrpTemplate, rptCalculation.rptGrpQuery); if (ReturnValue.IsZeroOrNull()) { ReturnValue.ApplyFormatString(rptCalculation.strReturnsFormat); return(ReturnValue); } int SelectPos = ReturnValue.ToString().ToUpper().IndexOf("SELECT"); if ((SelectPos >= 0) && (SelectPos <= 3)) { // this is an sql statement and not a function result tab = DatabaseConnection.SelectDT(ReturnValue.ToString(), "", DatabaseConnection.Transaction); if (tab.Rows.Count > 0) { if (tab.Rows[0][0].GetType() == typeof(String)) { ReturnValue = new TVariant(Convert.ToString(tab.Rows[0][0])); } else { ReturnValue = new TVariant(tab.Rows[0][0]); } } } } ReturnValue.ApplyFormatString(rptCalculation.strReturnsFormat); } return(ReturnValue); }