public WithParamsHeaderWriter(ThisReportParams ps) { if (ps == null) { throw new ArgumentNullException("ps"); } this.ps = ps; }
/// <summary> /// Построение отчета /// </summary> /// <param name="data">Контекст</param> protected override void buildReport(ReportLayoutData data) { XslFOProfileWriter foWriter = data.RepGen; ThisReportParams ps = new ThisReportParams(data.Params); ps.FolderName = data.DataProvider.GetValue("Header", null) as string; OverallData report = null; // получим данные using (IDataReader reader = data.DataProvider.GetDataReader("Main", null)) { if (reader.Read()) { IOverallDeserializer deserializer = new OverallDeserializer( new DepartmentDataDeserializer( new DepartmentDetailDataDeserializer() ) ); report = deserializer.Deserialize(new DataReaderWrapper(reader)); } else { report = new OverallData(new List <DepartmentData>()); } } // сконфигурируем компонент, отвечающий за формирование отчета IReportWriter writer = new ReportWriter( ps.ShowRestrictions ? new WithParamsHeaderWriter(ps) as IHeaderWriter : new SimpleHeaderWriter() as IHeaderWriter, new BodyWriter( new BaseDataWriter( new SimpleIntIndexGenerator(1, 1), ps.TimeMeasureUnits == TimeMeasureUnits.Days ? new DHMCostsFormatter() as ICostsFormatter : new HourCostsFormatter() as ICostsFormatter ), report, ps.ShowDetalization ? new DetailReportSerializer() as IReportSerializer : new MainReportSerializer() as IReportSerializer ) ) as IReportWriter; writer.Write(foWriter); }
/// <summary> /// Метод, формирующий отчет; вызывается подсистемой ReportService /// </summary> protected override void buildReport(Croc.XmlFramework.ReportService.Layouts.ReportLayoutData reportData) { // Получаем все данные для постоения отчета: ThisReportData data = new ThisReportData(reportData); reportData.RepGen.WriteLayoutMaster(); reportData.RepGen.StartPageSequence(); reportData.RepGen.StartPageBody(); reportData.RepGen.Header(String.Format("Кассовые транзакции сотрудника - {0}", xmlEncode((String)reportData.Params.GetParam("EmpName").Value))); // Получаем все данные для постоения отчета: ThisReportParams Params = new ThisReportParams(reportData.Params); Params.WriteParamsInHeader(reportData.RepGen, reportData.DataProvider); writeMainData(reportData.RepGen, data); reportData.RepGen.EndPageBody(); reportData.RepGen.EndPageSequence(); }
/// <summary> /// Построение отчета /// </summary> /// <param name="data">Контекст</param> protected override void buildReport(ReportLayoutData data) { XslFOProfileWriter foWriter = data.RepGen; ThisReportParams ps = new ThisReportParams(data.Params); string name = data.DataProvider.GetValue("Header", null) as string; List <BaseData> report = null; // получим данные using (IDataReader reader = data.DataProvider.GetDataReader("Main", null)) { if (reader.Read()) { IDataDeserializer deserializer = new DataDeserializer( new SnapDataDeserializer(), new StatusDataDeserializer() ); report = new List <BaseData>(deserializer.Deserialize(new DataReaderWrapper(reader))); } else { report = new List <BaseData>(); } } // сконфигурируем компонент, отвечающий за формирование отчета IReportWriter writer = new ReportWriter( new HeaderWriter(name), new BodyWriter( new BaseDataWriter( new SimpleIntIndexGenerator(1, 1)), report, new ReportSerializer() ) ) as IReportWriter; writer.Write(foWriter); }
// Метод, формирующий отчет; вызывается подсистемой ReportService protected override void buildReport(Croc.XmlFramework.ReportService.Layouts.ReportLayoutData reportData) { // Получаем все данные для постоения отчета: ThisReportData data = new ThisReportData(reportData); reportData.RepGen.WriteLayoutMaster(); reportData.RepGen.StartPageSequence(); reportData.RepGen.StartPageBody(); reportData.RepGen.Header(xmlEncode("Сальдо ДС по сотрудникам")); // Получаем все данные для постоения отчета: ThisReportParams Params = new ThisReportParams(reportData.Params); //Формируем и выводим подзаголовок StringBuilder sbBlock = new StringBuilder(); string sParamValue; if (Params.IsSpecifiedIntervalBegin) { sParamValue = ((DateTime)Params.IntervalBegin).ToString("dd.MM.yyyy"); } else { sParamValue = "не задана"; } sbBlock.Append(_GetParamValueAsFoBlock("Дата начала отчетного периода", sParamValue)); if (Params.IsSpecifiedIntervalEnd) { sParamValue = ((DateTime)Params.IntervalEnd).ToString("dd.MM.yyyy"); } else { sParamValue = "не задана"; } sbBlock.Append(_GetParamValueAsFoBlock("Дата окончания отчетного периода", sParamValue)); reportData.RepGen.AddSubHeader(_MakeSubHeader(sbBlock)); writeMainData(reportData.RepGen, data, Params); reportData.RepGen.EndPageBody(); reportData.RepGen.EndPageSequence(); }
/// <summary> /// Метод формирования отчета. Вызывается из ReportService /// </summary> /// <param name="foWriter"></param> /// <param name="Params"></param> /// <param name="Provider"></param> /// <param name="cn"></param> /// <param name="CustomData"></param> protected void buildThisReport(XslFOProfileWriter foWriter, ReportParams Params, IReportDataProvider Provider, object CustomData) { // Получим параметры: m_oParams = new ThisReportParams(Params, Provider); // ФОРМИРОВАНИЕ ОТЧЕТА foWriter.WriteLayoutMaster(); foWriter.StartPageSequence(); foWriter.StartPageBody(); // ЗАГОЛОВОК foWriter.Header("Баланс списаний сотрудника"); // Параметры отчета в заголовке? if (m_oParams.ShowRestrictions) { m_oParams.WriteParamsInHeader(foWriter); } writeBody(foWriter, Provider); foWriter.EndPageBody(); foWriter.EndPageSequence(); }
/// <summary> /// Метод формирования отчета. Вызывается из ReportService /// </summary> /// <param name="foWriter"></param> /// <param name="Params"></param> /// <param name="Provider"></param> /// <param name="cn"></param> /// <param name="CustomData"></param> protected void buildThisReport(XslFOProfileWriter foWriter, ReportParams Params, IReportDataProvider Provider, object CustomData) { // Получим параметры: ThisReportParams oParams = new ThisReportParams(Params); // ФОРМИРОВАНИЕ ОТЧЕТА foWriter.WriteLayoutMaster(); foWriter.StartPageSequence(); foWriter.StartPageBody(); // ЗАГОЛОВОК foWriter.Header("Затраты в разрезе направлений"); // Параметры отчета в заголовке? if (oParams.ShowRestrictions) { oParams.WriteParamsInHeader(foWriter, Provider); } writeBody(foWriter, oParams, Provider); foWriter.EndPageBody(); foWriter.EndPageSequence(); }
/// <summary> /// Фомрирование "тела" отчета /// </summary> /// <param name="foWriter"></param> /// <param name="oParams"></param> /// <param name="cn"></param> private void writeBody(XslFOProfileWriter foWriter, ThisReportParams oParams, IReportDataProvider Provider) { using (IDataReader reader = Provider.GetDataReader("dsMain", oParams)) { // Вне зависимости от параметров в результате первым идет рекордсет с // результатами анализа допустимости анализа - это будет или одна строка // с текстом "несоответствий не обрнаружено" или массированный рекордсет // с перечнем активностей, для которых обнаружены баги. // NB! Если рекордсет пришел пустой - это ошибка! if (!reader.Read()) { throw new ApplicationException("Ошибка получения данных отчета: запрос процедуры вернул пустой результирующий набор!"); } // ... проверим набор с данными первого рекордсета: если это строка // в один столбец, то это хороший результат; иначе - это набор с перечнем // активностей, в которых найдены несоответствия IDictionary rowData = _GetDataFromDataRow(reader); if (1 != rowData.Count) { #region Отображение данных с ошибками // Обнаружены случаи недопустимости выполнения анализа. // В рекордсете идут: // - CustomerID - идентификатор организации, Guid // - CustomerName - наименование организации // - FolderID - иденетификатор активности, в котором обнаружена проблема // - FullName - полное наименование (путь) проекта // - ErrorType - "тип" проблемы, здесь: // 1 - нет направлений, // 2 - не заданы доли, // 3 - нарушения в задании направлений для подчиненных активностей/каталогов, // 4 - что-то еще (ошибка в определении типа проблемы, по идее так быть не должно) // #1: Служебное сообщение об обнаружении ошибок foWriter.TStart(false, "WARNING_MESSAGE_TABLE", false); foWriter.TAddColumn("Сообщение"); foWriter.TRStart(); foWriter.TRAddCell( "Внимание! Выполнение анализа затрат невозможно: обнаружены ошибки определения направлений для активностей!", null, 1, 1, "WARNING_MESSAGE"); foWriter.TREnd(); foWriter.TEnd(); // #2: Заголовок таблицы с перечнем активностей, в которых обнаружены нарушения foWriter.TStart(true, "TABLE", false); foWriter.TAddColumn("Активность", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, null, String.Empty, align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); foWriter.TAddColumn("Ошибка определения", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, null, String.Empty, align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); // ... данные сгруппированы по организации-Клиенту: string sCustomerName = rowData["CustomerName"].ToString(); bool bIsNextCusomerData = true; for (bool bMoreRows = true; bMoreRows;) { // ...если при последнем чтении строки обнаружено условие перехода // к данным следующей организации-Клиента, то выводим заголовок // группы - наименование Клиента: if (bIsNextCusomerData) { foWriter.TRStart(); foWriter.TRAddCell(xmlEncode(sCustomerName), null, 2, 1, "GROUP_HEADER"); foWriter.TREnd(); } // Текстовое представление "типа" нарушения: string sErrorDescription; switch ((int)rowData["ErrorType"]) { case 1: sErrorDescription = "(ТИП-1) Для активности не заданы направления"; break; case 2: sErrorDescription = "(ТИП-2) Для направления активности не заданы доли затрат"; break; case 3: sErrorDescription = "(ТИП-3) Для подчиненной активности / каталога указано направление, отличное от направлений, заданных для активности"; break; default: sErrorDescription = "(Ошибка определения типа несоответствия)"; break; } // Выводим данные по одной активности; при этом наименование активности // оформляется как анкер, при клике на который будет отображаться всплывающее // меню с доступными операциями - просмотр, редактирование, отчеты и т.д. foWriter.TRStart(); foWriter.TRAddCell(_GetFolderAnchor(rowData["FullName"], (Guid)rowData["FolderID"], true), null, 1, 1, "TABLE_CELL"); foWriter.TRAddCell(sErrorDescription, null, 1, 1, "TABLE_CELL"); foWriter.TREnd(); // Читаем след. строку (если данные еще есть); при этом определяем // условие перехода к следующей грппе данных, по след. Клиенту: bMoreRows = reader.Read(); if (bMoreRows) { rowData = _GetDataFromDataRow(reader); } bIsNextCusomerData = (sCustomerName != rowData["CustomerName"].ToString()); if (bIsNextCusomerData) { sCustomerName = rowData["CustomerName"].ToString(); } } foWriter.TEnd(); #endregion // На этом отчет заканчивается! return; } // Несоответствий нет - выводим данные: if (!reader.NextResult()) { throw new ApplicationException("Отсутствует основной результирующий набор! Текст запроса: "); } // ЗАГОЛОВОК ОСНОВНОЙ ТАБЛИЦЫ string sDirsColumnName; bool bWithActivityQnt = (ThisReportParams.AnalysisDirectionEnum.ByActivity != oParams.AnalysisDirection); if (ThisReportParams.AnalysisDirectionEnum.ByCustomer_AllCustomners == oParams.AnalysisDirection && oParams.ShowDetails) { sDirsColumnName = "Направления / организации"; } else if (ThisReportParams.AnalysisDirectionEnum.ByActivity == oParams.AnalysisDirection && oParams.ShowDetails) { sDirsColumnName = "Направления / активности"; } else { sDirsColumnName = "Направления"; } foWriter.TStart(true, "TABLE", false); foWriter.TAddColumn("№", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, null, "5%", align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); foWriter.TAddColumn(sDirsColumnName, align.ALIGN_LEFT, valign.VALIGN_MIDDLE, null, (bWithActivityQnt ? "40%" : "55%"), align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); if (bWithActivityQnt) { foWriter.TAddColumn("Количество активностей", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "15%", align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); } foWriter.TAddColumn("Затраты", (TimeMeasureUnits.Days == oParams.TimeMeasure ? align.ALIGN_LEFT : align.ALIGN_RIGHT), valign.VALIGN_MIDDLE, null, "20%", align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); //foWriter.TAddColumn("Сумма затрат", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "20%", align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_HEADER"); // ПОКА - КОНСТАНТА! TODO! int nWorkDayDuration = 600; if (oParams.ShowDetails) { #region ДАННЫЕ С ДЕТАЛИЗАЦИЕЙ // - DirectionName - Наименование направления; // - DetailID - Идентификатор детализирующей сущности (Организация / Активность) // - DetailName - Наименование детализируюшей сущности // - ActivityQnt - Количество активностей // - ExpensesSum - Сумма затрат string sDirectionName = null; int nSubTotalTime = 0; // промежуточный итог по сумме затраченного времени int nTotalTime = 0; // общий итог по сумме затраченного времени int nSubTotalQnt = 0; // промежуточный итог по количеству активностей (по направлению) int nTotalQnt = 0; // общий итог по количеству активностей int nRowNum = 0; // сквозная нумерация строк детализации // Признак, что наименование детализирующей сущности есть гиперссылка: // Сейчас это единственный случай - при направлении анализа "Организации..", // в случае указания конкретной организации - когда в кач. детализации // выводятся активности. Для них и формляем анкер с всплывающим меню операций: bool bIsDetailNameAsHref = (ThisReportParams.AnalysisDirectionEnum.ByCustomer_TargetCustomer == oParams.AnalysisDirection); while (reader.Read()) { IDictionary rec = _GetDataFromDataRow(reader); // Если очередная рассматриваемая строка относится уже к другой группе, // то сформируем строку отчета с данными подытога if (null == sDirectionName || sDirectionName != rec["DirectionName"].ToString()) { if (null != sDirectionName) { foWriter.TRStart(); foWriter.TRAddCell("Итого по направлению", "string", 2, 1, "GROUP_FOOTER"); if (bWithActivityQnt) { foWriter.TRAddCell(nSubTotalQnt, "i4", 1, 1, "GROUP_FOOTER"); } if (TimeMeasureUnits.Days == oParams.TimeMeasure) { foWriter.TRAddCell(_FormatTimeStringAtServer(nSubTotalTime, nWorkDayDuration), "string", 1, 1, "GROUP_FOOTER"); } else { foWriter.TRAddCell(string.Format("{0:0.##}", nSubTotalTime / 60.0), "r8", 1, 1, "GROUP_FOOTER"); } //foWriter.TRAddCell( (nSubTotalSum / 100.0).ToString("F2"), "fixed.14.4", 1, 1, "GROUP_FOOTER" ); foWriter.TREnd(); } sDirectionName = rec["DirectionName"].ToString(); nSubTotalTime = 0; nSubTotalQnt = 0; // Текст с "заголовком" следующей группы: foWriter.TRStart(); foWriter.TRAddCell(xmlEncode(sDirectionName), "string", (bWithActivityQnt ? 5 : 4), 1, "GROUP_HEADER"); foWriter.TREnd(); } // Зачитываем данные int nTime = Int32.Parse(rec["ExpensesTime"].ToString()); nSubTotalTime += nTime; nTotalTime += nTime; /*int nSum = Int32.Parse( rec["ExpensesSum"].ToString() ); * nSubTotalSum += nSum; * nTotalSum += nSum;*/ int nQnt = Int32.Parse(rec["ActivityQnt"].ToString()); nSubTotalQnt += nQnt; nTotalQnt += nQnt; nRowNum += 1; // Формируем соответствующую строку отчета: foWriter.TRStart(); foWriter.TRAddCell(nRowNum, "i4", 1, 1, "TABLE_CELL_ROWNUM"); if (bIsDetailNameAsHref) { foWriter.TRAddCell(_GetFolderAnchor(rec["DetailName"].ToString(), (Guid)rec["DetailID"], true), "string", 1, 1, "TABLE_CELL"); } else { foWriter.TRAddCell(xmlEncode(rec["DetailName"]), "string", 1, 1, "TABLE_CELL"); } if (bWithActivityQnt) { foWriter.TRAddCell(nQnt, "i4", 1, 1, "TABLE_CELL"); } if (TimeMeasureUnits.Days == oParams.TimeMeasure) { foWriter.TRAddCell(_FormatTimeStringAtServer(nTime, nWorkDayDuration), "string", 1, 1, "TABLE_CELL"); } else { foWriter.TRAddCell(string.Format("{0:0.##}", nTime / 60.0), "r8", 1, 1, "TABLE_CELL"); } //foWriter.TRAddCell( (nSum / 100.0).ToString("F2"), "fixed.14.4", 1, 1, "TABLE_CELL" ); foWriter.TREnd(); } // Строка с последним накопленным подитогом (если такой был) if (null != sDirectionName) { foWriter.TRStart(); foWriter.TRAddCell("Итого по направлению", "string", 2, 1, "GROUP_FOOTER"); if (bWithActivityQnt) { foWriter.TRAddCell(nSubTotalQnt, "i4", 1, 1, "GROUP_FOOTER"); } if (TimeMeasureUnits.Days == oParams.TimeMeasure) { foWriter.TRAddCell(_FormatTimeStringAtServer(nSubTotalTime, nWorkDayDuration), "string", 1, 1, "GROUP_FOOTER"); } else { foWriter.TRAddCell(string.Format("{0:0.##}", nSubTotalTime / 60.0), "r8", 1, 1, "GROUP_FOOTER"); } //foWriter.TRAddCell( (nSubTotalSum / 100.0).ToString("F2"), "fixed.14.4", 1, 1, "GROUP_FOOTER" ); foWriter.TREnd(); } // Строка с общим итогом по всему отчету foWriter.TRStart(); foWriter.TRAddCell("Итого", "string", 2, 1, "TABLE_FOOTER"); if (bWithActivityQnt) { foWriter.TRAddCell(nTotalQnt, "i4", 1, 1, "TABLE_FOOTER"); } if (TimeMeasureUnits.Days == oParams.TimeMeasure) { foWriter.TRAddCell(_FormatTimeStringAtServer(nTotalTime, nWorkDayDuration), "string", 1, 1, "TABLE_FOOTER"); } else { foWriter.TRAddCell(string.Format("{0:0.##}", nTotalTime / 60.0), "r8", 1, 1, "TABLE_FOOTER"); } //foWriter.TRAddCell( (nTotalSum / 100.0).ToString("F2"), "fixed.14.4", 1, 1, "TABLE_FOOTER" ); foWriter.TREnd(); #endregion } else { #region ДАННЫЕ БЕЗ ДЕТАЛИЗАЦИИ // - DirectionName - Наименование направления; // - ActivityQnt - Количество активностей // - ExpensesSum - Сумма затрат int nTotalTime = 0; int nTotalQnt = 0; int nRowNum = 0; while (reader.Read()) { // Зачитываем значения текущей строки: IDictionary rec = _GetDataFromDataRow(reader); int nTime = Int32.Parse(rec["ExpensesTime"].ToString()); nTotalTime += nTime; /* Убираем Фин данные из отчета * int nSum = Int32.Parse( rec["ExpensesSum"].ToString() ); * nTotalSum += nSum;*/ int nQnt = Int32.Parse(rec["ActivityQnt"].ToString()); nTotalQnt += nQnt; nRowNum += 1; // Формируем представление строки в XSL-FO: foWriter.TRStart(); foWriter.TRAddCell(nRowNum, "i4", 1, 1, "TABLE_CELL"); foWriter.TRAddCell(xmlEncode(rec["DirectionName"]), "string", 1, 1, "TABLE_CELL"); if (bWithActivityQnt) { foWriter.TRAddCell(nQnt, "i4", 1, 1, "TABLE_CELL"); } if (TimeMeasureUnits.Days == oParams.TimeMeasure) { foWriter.TRAddCell(_FormatTimeStringAtServer(nTime, nWorkDayDuration), "string", 1, 1, "TABLE_CELL"); } else { foWriter.TRAddCell(string.Format("{0:0.##}", nTime / 60.0), "r8", 1, 1, "TABLE_CELL"); } //foWriter.TRAddCell( (nSum / 100.0).ToString("F2"), "fixed.14.4", 1, 1, "TABLE_CELL" ); foWriter.TREnd(); } foWriter.TRStart(); foWriter.TRAddCell("Итого", "string", 2, 1, "TABLE_FOOTER"); if (bWithActivityQnt) { foWriter.TRAddCell(nTotalQnt, "i4", 1, 1, "TABLE_FOOTER"); } if (TimeMeasureUnits.Days == oParams.TimeMeasure) { foWriter.TRAddCell(_FormatTimeStringAtServer(nTotalTime, nWorkDayDuration), "string", 1, 1, "TABLE_FOOTER"); } else { foWriter.TRAddCell(string.Format("{0:0.##}", nTotalTime / 60.0), "r8", 1, 1, "TABLE_FOOTER"); } //foWriter.TRAddCell( (nTotalSum / 100.0).ToString("F2"), "fixed.14.4", 1, 1, "TABLE_FOOTER" ); foWriter.TREnd(); #endregion } foWriter.TEnd(); } #region ДОПОЛНИТЕЛНЫЕ ДАННЫЕ // Если направление анализа - "Активность-Направления" и задан признак отображения // данных о последнем изменении определения направления для активности: if (ThisReportParams.AnalysisDirectionEnum.ByActivity == oParams.AnalysisDirection && oParams.ShowHistoryInfo) { // Получение исторической информации - когда и кто последний раз изменил определение направлений object oScalar = Provider.GetValue("dsHistory", oParams); string sNoteText = String.Format( "<fo:inline>Последнее изменение определения направлений: </fo:inline><fo:inline font-weight=\"bold\">{0}</fo:inline>", (null != oScalar? xmlEncode(oScalar.ToString()) : "(нет данных") ); // Формируем таблицу с "исторической справкой": // NB! Заголовок здесь НЕ ОТОБРАЖАЕТСЯ! foWriter.TStart(false, "TABLE_NOTE", false); foWriter.TAddColumn("Замечание", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, null, "100%", align.ALIGN_NONE, valign.VALIGN_NONE, "TABLE_NOTE_HEADER"); foWriter.TRStart(); foWriter.TRAddCell(sNoteText, null, 1, 1, "TABLE_NOTE_CELL"); foWriter.TREnd(); foWriter.TEnd(); } #endregion }
// Отображение в отчете основных свойств лота и тендера private void writeMainData(XslFOProfileWriter fo, ThisReportData data, ThisReportParams Params) { #region #1: Основные данные // ...разделитель _TableSeparator(fo); fo.TStart(true, ITRepStyles.TABLE, false); fo.TAddColumn("Сотрудник", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, null, "13%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Балланс ДС", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Балланс ДС на начало", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Балланс ДС за период", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Получено в кассе", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Сдано по АО", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Возвращено в кассу", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Получено от сотрудников", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); fo.TAddColumn("Передано сотрудникам", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, null, "10%", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, ITRepStyles.TABLE_HEADER); foreach (IDictionary EmpDS in data.Main) { fo.TRStart(); _WriteCell(fo, xmlEncode(EmpDS["EmpName"])); _WriteCell(fo, xmlEncode(EmpDS["EmpSaldoTotal"])); _WriteCell(fo, xmlEncode(EmpDS["EmpSaldoDSBegin"])); StringBuilder sbLotHRef = new StringBuilder(); //если существуют кассовые транзакции за данный период по сотруднику if ((Int32)EmpDS["IsExistsEmpKassTrans"] == 1) { //... то сальдо ДС выводим с сылкой на отчет о детализации кассовых транзакций _StartReportURL(sbLotHRef, "r-EmployeeKassTrans"); _AppendParamURL(sbLotHRef, "EmpID", (Guid)EmpDS["EmpID"]); _AppendParamURL(sbLotHRef, "EmpName", EmpDS["EmpName"]); if (Params.IsSpecifiedIntervalBegin) { _AppendParamURL(sbLotHRef, "IntervalBegin", ((DateTime)Params.IntervalBegin).ToString("yyyy-MM-dd")); } if (Params.IsSpecifiedIntervalEnd) { _AppendParamURL(sbLotHRef, "IntervalEnd", ((DateTime)Params.IntervalEnd).ToString("yyyy-MM-dd")); } _EndReportURL(sbLotHRef, "Детализация кассовых транзакций", EmpDS["EmpSaldoDS"]); } else { sbLotHRef.Append(xmlEncode(EmpDS["EmpSaldoDS"])); } _WriteCell(fo, sbLotHRef, "string", ITRepStyles.TABLE_CELL_BOLD); _WriteCell(fo, xmlEncode(EmpDS["KassRecieved"])); _WriteCell(fo, xmlEncode(EmpDS["AOSended"])); _WriteCell(fo, xmlEncode(EmpDS["KassReturned"])); _WriteCell(fo, xmlEncode(EmpDS["EmpRecieved"])); _WriteCell(fo, xmlEncode(EmpDS["EmpSended"])); fo.TREnd(); } fo.TEnd(); #endregion }