Задача:
Реализовать корректную печать для раздела проекты для выделенного в реестре проекта
Подробнее о проблеме описано тут
Для построения выборки нам потребуется рекурсивный запрос, с помощью базовых компонентов SQ Terrasoft'a у меня такой придумать не получилось так как синтаксис CTE начинается со слова with. Решение - создать ADO Dataset, где можно написать любой запрос
1. Создаем ADO Dataset, пишем Connection string, задаем сам запрос :
AS
(
SELECT tbl_Project.*, 0 AS Level
FROM tbl_Project
WHERE ID = :ID
UNION ALL
SELECT p.*, Level+1
FROM tbl_Project p
INNER JOIN MyProject AS mp
ON p.ParentID = mp.id
)
SELECT
MyProject.ID,
MyProject.ParentID,
MyProject.Name,
MyProject.EstimatedStartDate,
MyProject.EstimatedDueDate,
ContactOwner.Name AS OwnerName,
ProjectState.Name AS StateName,
Level
FROM
MyProject,
tbl_Contact AS ContactOwner,
tbl_ProjectState AS ProjectState
WHERE MyProject.OwnerID = ContactOwner.ID
AND ProjectState.ID = MyProject.StateID
ORDER BY MyProject.SortOrder
Колонки которые вынесены в последнем запросе нужно создать руками, также необходимо создать параметр ID с типом уникального идентификатора
Настройки Dataset'a следующие
2. Кнопка в реестре раздела [Проекты], передача параметра ID записи в отчет:
var SelectedIDs = GetProjectSelectedIDsArray();
var Dataset = Services.GetNewItemByUSI('adods_PrintProject');
var Report = Services.GetNewItemByUSI('fr_PrintProject');
if (!IsEmptyValue(SelectedIDs[0]))
{
SetAttribute(Report,'ProjectIDtoPrint',SelectedIDs[0]);
ShowReport(Report);
}
else
MessageBox('Не выбран ни один проект');
}
ShowReport c скрипта scr_ReportUtils
3. Сама печатная форма
Получение параметров
var DatasetNameStr = "adods_PrintProject"; //датасет в котором мы хотим делать фильтрацию (необходимо помнить о том, что у отчета может быть несколько датасетов)
var str = ReportPreviewer.DatasetUSIList.CommaText; //в строчке ReportPreviewer.DatasetUSIList.CommaText передаются USI датасетов, через запятую
var ReportDatasetUSI = str.substr(str.indexOf(DatasetNameStr), DatasetNameStr.length);
var Dataset = ReportPreviewer.DatasetByUSI(ReportDatasetUSI);
var ProjectIDtoPrint = GetAttribute(ReportPreviewer.Report,'ProjectIDtoPrint');
Dataset.Parameters.ItemsByName('ID').Value = ProjectIDtoPrint;
}
К параметру ID в ADO Dataset получаем доступ так:
3. Сам отчет
oldCurXBand: Extended;
oldBandWidth: Extended;
procedure ProjectNameOnBeforePrint(Sender: TfrxComponent);
begin
oldCurXBand := ProjectName.Left;
oldBandWidth := ProjectName.Width;
ProjectName.Left := ProjectName.Left + 20 * Project.Value('Level');
ProjectName.Width := ProjectName.Width - 20 * Project.Value('Level');
end;
procedure ProjectNameOnAfterPrint(Sender: TfrxComponent);
begin
ProjectName.Left := oldCurXBand;
ProjectName.Width := oldBandWidth;
end;
begin
end.
Идея отступа взята с FastReport. Отчёты с деревьями, все остальное в статье у меня не заработало, даже на тестовых таблицах с совпадающими типами + в статье есть ошибки. Реализовано лучше с Документации по методам FR берем
Left (Integer) - Координата Х левого верхнего угла объекта.
Width (Integer) - Ширина объекта.
Отступаем по x нужную длину и кушаем это число с ширины бэнда. Выходит более красивее чем прыгающий бэнд.
Результат :
p.s Пожелания по улучшению:
1.Использовать текущие данные подключения для получения данных с ADO Dataset