Формирование печатных форм Excel по шаблону. Для версии ТС 3.4

В этой теме детально расписано, как реализовать такое. Но, как показала практика, -- это для версии 3.3.2. Поскольку версии Террасофт разные, то, соответственно, у них и функционал различный -- значит, "тупо" загружать сервисы из той темы не стоит -- отладчик будет ругаться (и не только отладчик) :smile: В общем, пришлось покопаться в этих сервисах, выяснить доработки и загружать только изменения. Делюсь опытом -- может, кому-то тоже пригодится.

В этой теме детально расписано, как реализовать такое. Но. Как показала практика, -- это для версии 3.3.2. Поскольку версии Террасофт разные, то, соответственно, у них и функционал различный -- значит, "тупо" загружать сервисы из той темы не стоит -- отладчик будет ругаться (и не только отладчик) :smile: В общем, пришлось покопаться в этих сервисах, выяснить доработки и загружать только изменения. Делюсь опытом -- может, кому-то тоже пригодится.

Алгоритм такой:
0. Настоятельно рекомендуется сделать бекап базы.
1. Добавить поле в таблицу tbl_Report IsExcelReportByTemplate, булевское.
2. Добавить это поле в запрос sq_Report +галочка "всегда выбирать в запросе". Добавить в датасет ds_Report. Заголовок -- "Отчет по шаблону".
3. В скрипт scr_UserReportCommon добавить след.функции:

/* s.t.a.s - Show Excel report by Template */
function ShowExcelReportByQueryID(QueryID, Workbook, RecordIDs) {
        var QueryObj = CreateUserQueryObject(QueryID);
        var Sections = QueryObj.Data.Sections;
        var RootSection = QueryObj.RootSection;
        var RootDataset = GetDatasetBySectionAndSetupDatasetLink(QueryObj.RootSection, Sections);      
        var DontApplyIDsFilter = false;
        AddIDsIncludeFilter(RootDataset.SelectQuery);
        ApplyDatasetIncludeFilter(RootDataset, 'IDs', RecordIDs, true);
        RootDataset.Open();
        if (RootDataset.IsEmptyPage) {
                return;
        }
        var ChildSectionsArray = GetChildSectionsArray(RootSection, Sections);
        var ChildDatasetsArray = GetChildDatasetsArray(ChildSectionsArray, Sections);  
function ReplaceTag(DatasetCaption, Dataset, Section) {
                var DatasetCaption = Dataset.Caption;
                while((Res) && (!IsEmptyValue(Res))) {
                        var Cell = ExcelActiveSheet.Cells(Res.Row, Res.Column);
                        if (Cell) {
                                var Value = Cell.Value;
                                if (!IsEmptyValue(Value)) {
                                        var TextArray = Value.split('#' + DatasetCaption +  '>.');
                                        for (var i = 0; i TextArray.length; i++) {
                                                if (TextArray[i].indexOf('') == -1) {
                                                        delete TextArray[i];
                                                } else {
                                                        var Start = TextArray[i].indexOf('');
                                                        var End = TextArray[i].indexOf('>');
                                                        TextArray[i] = TextArray[i].substring(Start + 1, End - Start);
                                                }
                                        }
                                        var Columns = Section.Columns;
                                        var Keys = new VBArray(Columns.Keys()).toArray();
                                        var Length = Keys.length;
                                        for (var k = 0; k Length; k++) {
                                                var Column = Columns(Keys[k]);
                                                FieldCaption = Column.Caption;
                                                if (IsStringInArray(FieldCaption, TextArray)) {
                                                        DataField = GetDataFieldByCaption(Dataset, FieldCaption);
                                                        if (!DataField) continue;
                                                        if (DataField.FieldType == dftDateTime) {
                                                                if (!IsEmptyValue(DataField.Value)){
                                                                        DataFieldValue =
                                                                                DateToStr(DataField.Value);
                                                                } else {
                                                                        DataFieldValue = '';
                                                                }
                                                        } else {
                                                                DataFieldValue = DataField.Value;
                                                        }
                                                        if (IsEmptyValue(DataFieldValue)){
                                                                DataFieldValue = '―';
                                                        }
                                                        Value = Value.replace('#' + DatasetCaption +
                                                                '>.' + FieldCaption + '>', DataFieldValue);
                                                }
                                        }
                                        Cell.Value = Value;
                                }
                        }
                        Res = ExcelActiveSheet.Cells.Find('#' + DatasetCaption +  '>.');
                }
        }      
        var ExcelActiveSheet = Workbook.ActiveSheet;
        while (!RootDataset.IsEOF) {
                SetChildSectionsFilter(ChildSectionsArray, Sections);
            OpenChildDatasets(ChildSectionsArray);
                var Res = ExcelActiveSheet.Cells.Find('#' + RootDataset.Caption +  '>.');
            if (Res) {
                ReplaceTag(RootDataset.Caption, RootDataset, RootSection);
            }
            for (var j = 0; j ChildSectionsArray.length; j++) {
                        var Res = ExcelActiveSheet.Cells.Find('#' +
                                ChildSectionsArray[j].DatasetLink.Dataset.Caption +  '>.');
                        if (Res) {
                        ReplaceTag(ChildSectionsArray[j].DatasetLink.Dataset.Caption,
                                        ChildSectionsArray[j].DatasetLink.Dataset, ChildSectionsArray[j]);
                        }
                }
                RootDataset.GotoNext();
        }
        RootDataset.Close();
        if (Workbook) {
                Workbook.Application.Visible = true;
        }
}
function OpenChildDatasets(ChildSectionsArray) {
        var Section;
        for (var i = 0; i ChildSectionsArray.length; i++) {
                Section = ChildSectionsArray[i];
                Section.DatasetLink.Dataset.Open();
        }
}

+ подключить скрипт scr_UserQueryUtils.
4. В скрипте в функции ReportMenuItemExecute в блоке
switch (FilteringTypeID) {
  case rftSelectedRecords:
        if (SourceTypeID == rstExcel) { //...

заменить строчку
ProcessPrepareExcelReport(QueryID, WorkspaceWindow, SelectedIDs);

на блок (авторские права сохранены:smile:):
if (!Dataset('IsExcelReportByTemplate')) {
/* s.t.a.s - Base product implementation */
  ProcessPrepareExcelReport(QueryID, WorkspaceWindow, SelectedIDs);
} else {
/* s.t.a.s - Project implementation */
  var QueryID = Dataset.Values('QueryID');
  PrepareExcelReportByTemplate(QueryID, ID, SelectedIDs);
}

+ подключить скрипт scr_MSExcelLibrary.
еще была заменена строчка ProcessPrepareExcelReport(QueryID, WorkspaceWindow); в блоке default (на блок, написанный выше), на всякий случай.
5. Остальные сервисы из темы-источниказагрузить без изменений.

Все переделанные сервисы прикреплены к теме.
excel_reports_by_template_ts_3_4.rar

Нравится

Поделиться

4 комментария

кстати, если нужен функционал для отображений отчетов в определенном разделе+для определенных значений, то нужно в загруженном скрипте wnd_ExcelReportEditScript подкорректировать функцию ShowControlsForExcel():

function ShowControlsForExcel() {
	try {
		Self.BeginUpdate();
		var Dataset = dlData.Dataset;
		var IsVisible = !!Dataset('IsExcelReportByTemplate');
		//fgFilter.IsVisible = fgFiltering.IsVisible = frmValues.IsVisible = 
		//	fgValues.IsVisible = !IsVisible;
		btnLoadTemplate.IsVisible = IsVisible;
		Dataset.DataFields('QueryID').IsRequired = IsVisible;
		//Self.Height = (!IsVisible) ? 422 : 160;
	} finally {
		Self.EndUpdate();
	}
}

Ольга, здравствуйте.
Не совсем понял как это функция ReplaceTag объявляется внутри другой функции ShowExcelReportByQueryID. Разве оно так работать будет? С какой целью так написано?

"Кошкаров Андрей" написал:Не совсем понял как это функция ReplaceTag объявляется внутри другой функции ShowExcelReportByQueryID. Разве оно так работать будет? С какой целью так написано?

интересно, я не заметила этого... эта часть кода не моя.. наверное, нужно уточнять у автора))

"Кошкаров Андрей" написал:

Ольга, здравствуйте.

Не совсем понял как это функция ReplaceTag объявляется внутри другой функции ShowExcelReportByQueryID. Разве оно так работать будет? С какой целью так написано?

http://javascript.ru/basic/closure

Показать все комментарии