Как оказалось, в целом, идея решения правильная, но есть небольшая неточность. В системе Axapta отчет может быть запущен через пункт меню двумя способами:
- В пункте меню указывается класс-наследник от RunBaseReport, который в свойстве lastValueElementName() ссылается на нужный отчет
- В пункте меню напрямую указывается отчет
Так вот, если отчет явным образом "обернут" в класс-наследник от RunBaseReport, то приведенное решение корректно работает. Однако если отчет вызывается напрямую, то снова имеет старую проблему. Точнее, имеем "сломанный" стандартный код
Для решения проблемы необходимо, если отчет вызывается по первому варианту выполнить указанные действия, а если отчет вызывается по второму варианту, то ничего не делать. Оставить стандартный код.
Поскольку, если отчет напрямую указывается в пункте меню, то он автоматически "оборачивается" в класс-наследник от RunBaseReportStd, то код модифицируется следующим образом
X++:
static void main(Args args)
{
RunBaseReportDialog reportDialog = new RunBaseReportDialog(args.caller());
RunBaseReport runBaseReport = args.caller().runbase();
ReportRun reportRun = runBaseReport.reportRun();
Report report = reportRun.report();
boolean oldInteractive;
boolean res;
Dialog dialog;
// 31.03.2011, Maksi -->
PrintJobSettings printJobSettingsRunBase;
PrintJobSettings printJobSettingsReportRun;
// 31.03.2011, Maksi <--
;
// We must invoke the SysPrintForm via the report object so that we honor an prompt overrides.
oldInteractive = report.interactive();
report.interactive(true);
res = reportRun.prompt();
report.interactive(oldInteractive);
if (!res)
return;
// 31.03.2011, Maksi -->
// Если вызов произошел из класса или наследника RunbaseReportStd, то это означает прямой вызов отчета
// без "обертки" в виде RunBaseReport
// В этом случае ничего менять в коде не надо !
// В противном случае необходимо передать сделанный выбор из ReportRun в RunBaseReport
if (! SysDictClass::isEqualOrSuperclass(classIdGet(runBaseReport),classnum(RunBaseReportStd)))
{
printJobSettingsReportRun = reportRun.printJobSettings();
printJobSettingsRunBase = runBaseReport.printJobSettings();
printJobSettingsRunBase.unpackPrintJobSettings(printJobSettingsReportRun.packPrintJobSettings());
}
// 31.03.2011, Maksi <--
dialog = Dialog::getDialogFromCaller(args.caller());
if (dialog)
{
dialog.updateServer();
}
runBaseReport.dialogUpdatePrinterSettings(dialog);
reportDialog.run();
}
Правда, следует заметить, что в связи с такой "двухпалубной" системой настроек, исходная неопределенность сохраняется. Т.е. по прежнему возможна рассинхронизация настроек для отчета и для класса RunBaseReport. Но уже не в такой критической форме
Если выполнить следующие действия
- Вызывать отчет, чтобы появилась форма настроек параметров отчета
- Через кнопку "Параметры" изменить настройки вывода отчета
- Сам отчет не запускать и нажать кнопку "Отмена"
- Снова вызывать отчет, чтобы появилась форма настроек параметров отчета
Как и положено, раз отчет предварительно не запускался, цель вывода отчета осталась старая. Какая и была при первоначальном запуске. Однако если нажать кнопку "Параметры", то увидим, что настройки, сделанные для отчета сохранились!
Собственно, так и должно быть. Ведь кеш отчета был сохранен сразу же по закрытии формы "Параметры" еще до того, как было принято решение не печатать отчет.
В принципе, ничего страшного, ведь при печати будут использованы настройки RunBaseReport, а не самого отчета. Проблемы могут быть только если один и тот же отчет может печататься разными способами. Как напрямую, так и через "обертку" RunBaseReport.
Но в данном случае - это не настолько критично, поскольку настройки кеша самого отчета в данной связке выступают в подчиненной роли.