Публикация

Прикрепить отчет на деталь "Файлы" сразу после генерации Word отчета

Добрый день!

Предлагаю ко вниманию реализацию автоматического добавления сгенерированного Word отчета для записи раздела на деталь "Файлы".
Для этого необходимо внести следующие изменения в функцию function ShowWordReport(UserReportData, WorkspaceRecordIDs, WorkspaceWindow) скрипта scr_UserReportCommon:

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;
Dataset.Values('Revision') = 1;
var FileSize = GetFileSize(FileName);
if (FileSize > 0)
{
     Dataset.Values('FileSize') = FileSize;
}                                              
SaveFileToDataset(FileName, Dataset, DataFieldName);
Dataset.Post();                                
var FileID = ID;
var IsertQueryLinkUSI = 'iq_FileIn';
var Temp = WorkspaceWindow.USI.split('_');             
var count = 0;
for(var i = 0; i Temp[1].length; i++)
{
        if(Temp[1].charAt(i) == 'W' && Temp[1].charAt(i+1) == 'o')
        {
                count = i - 1;
                break;
        }
}  
IsertQueryLinkUSI = IsertQueryLinkUSI + Temp[1].substring(0, count);
var InsertQuery = Services.GetNewItemByUSI(IsertQueryLinkUSI);        
var ColumnsValues = InsertQuery.ColumnsValues;
ColumnsValues.Items(1).Value = FileID;
ColumnsValues.Items(2).Value = WorkspaceRecordIDs[0];
var IDs = Connector.GenGUID();
ColumnsValues.Items(0).Value = IDs;
InsertQuery.Execute();

Добавить приведенный выше код необходимо перед строкой

return Document;

в конце функции.

Приятной работы с Terrasoft.

Нравится

Поделиться

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

Здравствуйте!
Пытался использовать ваш код в конфигурации. Но возникла проблема, решение которой я так и не нашел. Суть проблемы здесь.

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

Добрый день!
Я так понимаю, что решение было предоставлено тут

Добрый день.Поставил ваш скрип и вроде все нормально работает,но у меня задание немного другое и что бы его сделать нужно немного переделать код,а для этого нужно в нем детально разобраться.Не понятно к чему относится и откуда берется iq_FileIn,где задается Temp[1].length и зачем нам цикл:
for(var i = 0; i < Temp[1].length; i++)
{
if(Temp[1].charAt(i) == 'W' && Temp[1].charAt(i+1) == 'o')
{
count = i - 1;
break;
}
}

Дмитрий не могли бы вы написать не большие коменты в коду?Я просто только начинаю писать на JScripte и некоторые моменты не понятны-на С++ немного не так все))

Здравствуйте, Егор!

Код с комментариями ниже. Если будут дополнительные вопросы - обращайтесь.

//необходимо сохранить документ, чтобы на деталь сохранялся не шаблон, а заполненный отчет.
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;
Dataset.Values('Revision') = 1;
var FileSize = GetFileSize(FileName);
if (FileSize > 0)
{
     Dataset.Values('FileSize') = FileSize;
}                                           
SaveFileToDataset(FileName, Dataset, DataFieldName);
Dataset.Post();
//далее нужно привязать этот файл к той сущности для которой был вызван отчет и поместить его на деталь "файлы"                                
var FileID = ID;
//в базовой конфигурации есть готовые insert query запросы. Они имеют вид iq_FileIn[WorkspaceName]. Нам нужно узнать с какого раздела мы запустили данный отчет, и получить ссылку на этот сервис insert query. Заполнить необходимые параметры для него, и выполнить.
//получаем первую часть имени сервиса (константа)
var IsertQueryLinkUSI = 'iq_FileIn';
//получаем USI раздела. к примеру wnd_DocumentsWorkspace. режем его по "_", и далее обрезаем, чтобы получить только Documents
var Temp = WorkspaceWindow.USI.split('_');              
var count = 0;
for(var i = 0; i < Temp[1].length; i++)
{
        if(Temp[1].charAt(i) == 'W' && Temp[1].charAt(i+1) == 'o')
        {
                count = i - 1;
                break;
        }
}   
//получили Documents, теперь формируем полное имя сервиса insert query
IsertQueryLinkUSI = IsertQueryLinkUSI + Temp[1].substring(0, count);
//и получаем экземпляр данного сервиса
var InsertQuery = Services.GetNewItemByUSI(IsertQueryLinkUSI);
//заполняем параметры запроса        
var ColumnsValues = InsertQuery.ColumnsValues;
ColumnsValues.Items(1).Value = FileID;
ColumnsValues.Items(2).Value = WorkspaceRecordIDs[0];
var IDs = Connector.GenGUID();
ColumnsValues.Items(0).Value = IDs;
//выполняем
InsertQuery.Execute();

Дмитрий у меня к вам появился следующий вопрос к этой же теме: задача не сложная-нужно сформировать отчет по определенным опросникам и этот отчет прикрепить в деталь "файлы"...отчет сформированный у меня делается но вот как его прикрепить я не знаю...я так понимаю что нужно по вашему примеру переделывать?или можно пойти каким либо иным путем?
вот мой код

var Dataset = dlData.Dataset;
Dataset.Open();
var Resume = Dataset('Resume');
var ContactName = Dataset('Name');
var ID = Dataset('ID');
var ContactTypeID = Dataset('ContactTypeID');
if (ContactTypeID == '{3D51B409-B691-4F77-9723-359C65399AB4}') {
var Word = new ActiveXObject('Word.Application');
Word.Visible = false;
Word.Documents.Add();
Word.ActiveDocument.SaveAs(ContactName);
Word.ActiveDocument.Content.Text = Resume;
Word.ActiveDocument.Close();
}

Здравствуйте, Егор Андреевич.

Да, Вам и переделывать ничего не нужно. Просто скопируйте приведенный на 2 поста выше код в функцию function ShowWordReport(UserReportData, WorkspaceRecordIDs, WorkspaceWindow) скрипта scr_UserReportCommon. Единственный момент, нужно чтобы был создан отчет в разделе "Отчеты" меню "Инструменты", и данный отчет отображался в меню "Отчеты" раздела "Опросы".

Если же у Вас отчета нету, а строите Вы его динамически из кода, то в зависимости от того в каком из скриптов Вы стоите Word документ, нужно подключить туда скрипт scr_FileUtils, а также вместо объекта Document использовать имя Вашего word-объекта (Word).

Кстати, есть такое дополнение.
Мы его с Дмитрием как раз и делали.
Чтобы файл не только сохранялся на деталь, но и обновлялся при изменении, так, как будто вы его открыли с детали файлов - с запросом "Сохранить измененный файл в базу данных? Да\Нет", но только сразу после формирования отчета - без необходимости закрывания\открывания :wink:

"Олейник Дмитрий" написал:
необходимо в функцию, где у Вас автоматически сохраняется запись на деталь файлы, подписаться на этот файл:

var InsertQuery = Services.GetNewItemByUSI(IsertQueryLinkUSI);
//заполняем параметры запроса        
var ColumnsValues = InsertQuery.ColumnsValues;
ColumnsValues.Items(1).Value = FileID;
ColumnsValues.Items(2).Value = '{EF3C7392-8A38-459E-AB36-94565FD62464}';
var IDs = Connector.GenGUID();
ColumnsValues.Items(0).Value = IDs;
//выполняем
InsertQuery.Execute(); 
var Self = Services.GetNewItemByUSI('wnd_FilesDetailGridArea');
var fnFiles = Self.ComponentsByName('fnFiles');
fnFiles.UnsubscribeFileEvents(FileID);
fnFiles.SubscribeFileEvents(FileName, FileID);
return Document;

Но, т.к. подписались мы не из детали «Файлы», необходимо модифицировать функцию SetFileIsChanged скрипта scr_FilesDetailGriaArea:

function SetFileIsChanged(FileChangeNotifier, FileName, FileID) { 
         var Dataset = FilesDetailGridArea.ChangedFilesDataset;
         if (Dataset == undefined)
            {
                        var Dataset = Services.GetNewItemByUSI('mds_DictionaryTemplate');
                        if (IsCanSaveChangeFile(FileID)) {                   
                        Dataset.Append();
                        Dataset.ValAsGUID('ID') = FileID;
                        Dataset.ValAsStr('Name') = FileName;
                        Dataset.Post();                   
                        if (ShowConfirmationDialog(DoYouWantToSaveChangedFileToDatabase) ==
                                   mrYes) {
                                   SaveFileInDataBase(FileID, FileName);
                                   dlData.Dataset.RefreshRecord(FileID, false);
                                   Dataset.Delete();                           
                        }
                        return;                       
            }
         }
         if (IsCanSaveChangeFile(FileID)) {
                   Dataset.DisableEvents();
                   Dataset.Append();
                   Dataset.ValAsGUID('ID') = FileID;
                   Dataset.ValAsStr('Name') = FileName;
                   Dataset.Post();
                   RefreshGrid();
                   if (ShowConfirmationDialog(DoYouWantToSaveChangedFileToDatabase) ==
                            mrYes) {
                            SaveFileInDataBase(FileID, FileName);
                            dlData.Dataset.RefreshRecord(FileID, false);
                            Dataset.Delete();
                            RefreshGrid();
                   }
                   Dataset.EnableEvents();
         }
}

ПС. Я пробовал

var Self = Services.GetNewItemByUSI('wnd_FilesDetailGridArea');
var fnFiles = Self.ComponentsByName('fnFiles');
fnFiles.UnsubscribeFileEvents(FileID);
fnFiles.SubscribeFileEvents(FileName, FileID);

вынести в отдельную функцию - не прокатывает, терра зависает (видимо связано с особенностями установки триггеров для функций)

кстати, раздел Продаж называется wnd_OpportunitiesWorkspace, а не wnd_OpportunityWorkspace из-за чего данный код там не срабатывает
надо

var Temp = WorkspaceWindow.USI.split('_');              
var count = 0;
for(var i = 0; i < Temp[1].length; i++)
{
        if(Temp[1].charAt(i) == 'W' && Temp[1].charAt(i+1) == 'o')
        {
                count = i - 1;
                break;
        }
}  
IsertQueryLinkUSI = IsertQueryLinkUSI + Temp[1].substring(0, count);

заменить на

var Temp = WorkspaceWindow.USI.split('_');              
	var count = 0;
	if (Temp[1] == 'OpportunitiesWorkspace') {
		InsertQueryLinkUSI = 'iq_FileInOpportunity';
	} else {
		for(var i = 0; i < Temp[1].length; i++)	{
		        if(Temp[1].charAt(i) == 'W' && Temp[1].charAt(i+1) == 'o')
		        {
		                count = i - 1;
						break;
				}
		}   
		InsertQueryLinkUSI = InsertQueryLinkUSI + Temp[1].substring(0, count);
	}

Да, Вы правы, спасибо за исправление.

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