Экспорт отчета в деталь "Файлы"

Хотелось бы узнать о возможности реализации такого действия как сохранение отчета в деталь "Файлы".

При этом действии формировался бы отчет (Fast Report, Word или Excel), который сохраняется в файл (pdf, rtf или другой), и вставляется в деталь "Файлы". Причем, промежуточные варианты не очень интересуют - в итоге интересует именно наличие присоединенного файла.

Нравится

17 комментариев

Добрый день, Владимир!

Подробное описание всего механизма, с учетом всех типов отчета и текстом скриптов займет достаточно много времени и относится к проектным решениям.

Постараюсь в общих чертах изобразить суть решения.
1. Реализация действия, которое выполнит формирование отчета (вызов функции наподобие ReportMenuItemExecute() в скрипте scr_ReportUtils).
2. Сохранение отчета в файл. Реализация для FastReport - предварительная конвертация в формат pdf/rtf/html (возможно, с выбором формата пользователем) и сохранение полученного файла во временную папку. Реализация для Word/Excel - просто сохранение файла отчета во временную папку.
3. Загрузка файла из временной папки - программное выполнение действий, аналогичных нажатию кнопки "Добавить файлы" детали Файлы. Предусмотреть возможность работы действия в различных разделах системы (т.к. деталь "Файлы" есть в нескольких разделах).
4. Удаление временного файла отчета. Вывод сообщения пользователю об успешном окончании процесса.

Желаю успехов!

Спасибо!
А если такое решение было когда-нибудь реализовано (или как может быть теоретически), то насколько хорошим получается быстродействие?

Насколько мне известно, такая функциональность еще не была реализована. Но могу предположить, что время выполнения операции будет составлять сумму времени формирования отчета (зависит от сложности отчета), времени конвертации отчета в выбранный формат и времени загрузки файла на деталь "Файлы" (зависит от размера файла, скорости сети и мощности сервера).

Доброго времени суток!
Мне нужно сохранять отчет Word на деталь файлы. Сделал так, как это описано здесь
Но дебаг ругается на строку:

ColumnsValues.Items(2).Value = WorkspaceRecordIDs[0];

В целом я разобрался как работает эта функция, но причину ошибки так и не выяснил, может быть кто-нибудь подскажет, в чем может быть дело?

В первую очередь, значительно упрощает понимание ошибок текст этих ошибок - если Вы его предоставите, то ответ найдется значительно быстрее.
Отлаживайтесь построчно, выясните, чему равна в Вашем случае переменная IsertQueryLinkUSI, проверьте, чтобы структура сервиса с таким кодом была правильной. Проверьте, что массив WorkspaceRecordIDs не пуст и содержит один элемент.
Ну и задавайте вопросы автору кода, если находите в нем ошибки.

1) А что имеется ввиду под "текст ошибки"? Дебагер не показывается ничего, кроме строки, в которой происходит ошибка.
2) InsertQueryLinkUSI имеет верное значение. Структура сервиса тоже правильная.
3) Подскажите как проверить пуст ли массив и его элементы? Пробовал так:

IsertQueryLinkUSI = IsertQueryLinkUSI + Temp[1].substring(0, count);
var InsertQuery = Services.GetNewItemByUSI(IsertQueryLinkUSI);        
var ColumnsValues = InsertQuery.ColumnsValues;
var IDs = Connector.GenGUID();
ColumnsValues.Items(0).Value = IDs;
ColumnsValues.Items(1).Value = FileID;
Log.Write(1, WorkspaceRecordIDs[0]);
//ColumnsValues.Items(2).Value = WorkspaceRecordIDs[0];
InsertQuery.Execute();
return Document;

Но это приводит к ошибке.

При выполнении этой функции вылетает ошибка OLE Error 80020102 (если это имелось ввиду под текстом ошибки)

Проверил массив WorkspaceRecordIDs, массив действительно пустой. С чем это может быть связано?

Здравствуйте, Дмитрий!

Возможно отчет был запущен в то время когда в реестре записей раздела нету ни одной записи?
Если нет - проверьте в функции

function ReportMenuItemExecute(ActionMenuItem, GridDataset, DataGrid,	WorkspaceName)

заполняется ли массив здесь:

var SelectedIDs = GetArrayByCollection(DataGrid.SelectedIDs);

Спасибо за ответ!
Проверял и на пустом реестре, и когда 3 записи, результат один. Проверил SelectedIDs, в данном случае массив не пуст, и данные туда заносятся правильно.

В scr_ReportUtils в функции ReportMenuItemExecute(ActionMenuItem, GridDataset, DataGrid, WorkspaceName) поменял код:

default:
       if (SourceTypeID == rstExcel) {
              ProcessPrepareExcelReport(QueryID, WorkspaceWindow);
       } else 
       if (SourceTypeID == rstWord) {
             ProcessPrepareWordReport(ID, QueryID, WorkspaceWindow, false);

На:

default:
       if (SourceTypeID == rstExcel) {
              ProcessPrepareExcelReport(QueryID, WorkspaceWindow);
       } else 
       if (SourceTypeID == rstWord) {
              ProcessPrepareWordReport(ID, QueryID, WorkspaceWindow, false, SelectedIDs);

Теперь он начал сохранять в файлы, но не то что нужно. Сохраняется шаблон отчета, а не сам отчет. Причем в количестве 2-х едениц.

Проблему с дублем решил, осталась проблема с выводом шаблона а не самого отчета.

Дмитрий, видимо проблема в том что у Вас сохраняется отчет на деталь файлы еще до того, как он был сформирован (т.е сохраняется сам шаблон без подстановки данных).
Причина - скорей всего Вы вставили код сохранения отчета на деталь файлов не в том месте.
Убедитесь что код идет после строчки

ProcessWordReportDataFill(Document, RootSection, Sections, IsPreview, WorkspaceRecordIDs, WorkspaceWindow);

в функции

ShowWordReport(UserReportData, WorkspaceRecordIDs, WorkspaceWindow)

P.S.: вообще представленный мною код нужно вставить в самый конец функции, перед строчкой

return Document;

Дмитрий, пробовал вставлять этот код чуть ли не после каждой строки функции:) Изначально стоял перед

return Document;

как Вы и писали. Результат везде тот же.

Дмитрий, данная ошибка происходит из-за того, что в коде динамически создается документ Word, на основе шаблона, далее в уже созданный и открытый документ Word, на основе шаблона подставляются данные. Когда Вы добавили код, сохраняется документ, но изменения, которые были внесены после открытия файла (а именно подстановка данных вместо макросов в шаблоне) не были сохранены, соответственно на деталь "Файлы" сохраняется просто шаблон.
Решение: добавьте Document.Save(); самой первой в коде, который Вы добавили:

Document.Save();
 
var ID = Connector.GenGUID();
var FileName = BuildFilePath(Document.Path, Document.Name);
var Dataset = Services.GetNewItemByUSI('ds_Files');
var DataFieldName = 'FileData';
Dataset.Append();
Dataset.Values('ID') = ID;
Dataset.Values('ItemTypeID') = '{39A5B367-4A7A-473E-8F74-26977CB6DB67}';
Dataset.Values('Link') = Document.Name;
//..и т.д.

Код вставьте в конец функции, перед

return Document; 

Дмитрий, спасибо большое!
Теперь все работает.

В продолжение темы про Экспорт отчета FastReport в деталь Файлы в формате PDF для выделенных записей в реестре можно почитать тут

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