Формирование печатных форм Excel по шаблону. Для версии ТС 3.4
В этой теме детально расписано, как реализовать такое. Но, как показала практика, -- это для версии 3.3.2. Поскольку версии Террасофт разные, то, соответственно, у них и функционал различный -- значит, "тупо" загружать сервисы из той темы не стоит -- отладчик будет ругаться (и не только отладчик) В общем, пришлось покопаться в этих сервисах, выяснить доработки и загружать только изменения. Делюсь опытом -- может, кому-то тоже пригодится.
В этой теме детально расписано, как реализовать такое. Но. Как показала практика, -- это для версии 3.3.2. Поскольку версии Террасофт разные, то, соответственно, у них и функционал различный -- значит, "тупо" загружать сервисы из той темы не стоит -- отладчик будет ругаться (и не только отладчик) В общем, пришлось покопаться в этих сервисах, выяснить доработки и загружать только изменения. Делюсь опытом -- может, кому-то тоже пригодится.
Алгоритм такой:
0. Настоятельно рекомендуется сделать бекап базы.
1. Добавить поле в таблицу tbl_Report IsExcelReportByTemplate, булевское.
2. Добавить это поле в запрос sq_Report +галочка "всегда выбирать в запросе". Добавить в датасет ds_Report. Заголовок -- "Отчет по шаблону".
3. В скрипт scr_UserReportCommon добавить след.функции:
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 в блоке
case rftSelectedRecords:
if (SourceTypeID == rstExcel) { //...
заменить строчку
на блок (авторские права сохранены):
/* 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. Остальные сервисы из темы-источниказагрузить без изменений.
Все переделанные сервисы прикреплены к теме.
кстати, если нужен функционал для отображений отчетов в определенном разделе+для определенных значений, то нужно в загруженном скрипте 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. Разве оно так работать будет? С какой целью так написано?