Доброго времени суток, коллеги!
Возникла хотелка сохранять файлы из соответствующей детали не поштучно, а кучей - все выделенные. Вариант https://community.terrasoft.ru/forum/topic/7719 не помог, видимо из-за разницы в платформах.
Как правильно реализовать на ServiceDesk 3.х?
Нравится
Должно работать на SD 3.x.
Почему у вас не получилось? Какие то ошибки? Предоставьте, пожалуйста, более подробную информацию.
Никаких ошибок, но и действий никаких не происходит. Оно должно отработать на Файлы - Операции - Сохранить в файл?
По идее да. Но нужно выделить через Ctrl несколько файлов на детали. Если будет выделен один - один и сохранится.
Выяснил, что не проходит проверка
if (Dat('ItemTypeID') != ft_File) {
continue;
}
и оно улетает на следующий круг цикла
Это проверка необходима, т.к. на детали файлы могут хранится не только файлы, но и ссылки.
Возможно у вас были какие либо доработки? Посмотрите в отладчике что у вас здесь
Dat('ItemTypeID')
при сохранении именно файла, и если это значение не совпадает с ft_File - замените.
Не пойму, как заполучить Dat('ItemTypeID'). Инструкция Log.Write(1, Dat('ItemTypeID')) падает на ошибке типов
Боюсь, что никакого, потому и ковыряю через запись в лог :-) Или что-то подтянулось при установке ServiceDesk, но не знаю как это запустить.
Есть возможность поставить Visual Studio? Думаю, все ровно пригодится, если будете дорабатывать конфигурацию в будущем.
Если поставите, то перед строкой
if (Dat('ItemTypeID') != ft_File) {
наберите
debugger;
и посмотрите что же все таки в Dat('ItemTypeID').
пс: перед этим не забудьте включить в реестре отладчик:
HKEY_CURRENT_USER\Software\Microsoft\Windows Script\Settings
JitDebug = 1
переустановил SreviceDesk с предлагаемыми дебаггерами. Теперь на точке "debugger;" открывается microsoft script debugger. Как в нём значение переменной посмотреть?
Здравствуйте.
Посмотрите, пожалуйста, рекомендации по использованию "debugger", перейдя по ссылке: file:///C:/Windows/help/debug/SDbug.htm
Александр, спасибо за подсказку!
Dat('ItemTypeID')=null после Dat.Open()!
Почему? IDs[i] не пуст и вполне реальный.
Андрей, Dataset.RecordsCount возвращает 1?
Если да - значит либо колонка как-то по другому называется, либо действительно у вас в колонке "Тип файла" пусто. Может вы их как-то нестандартно заливали?
пс: чтобы наверняка, выполните SELECT на сервере.
Что-то вроде (покажет все файлы для контрагента горсовет)
[sql]
SELECT ItemTypeID from tbl_Files
where FileID in (select FileID from tbl_FileInAccount where AccountID in (select ID from tbl_Account where Name = 'ОАО Горсовет'))
[/sql]
А null там потому, что Dat открывается пустым. А пустой он потому, что в sq_FileInItem есть связка
INNER JOIN
[dbo].[tbl_FileInAccount] AS [FileInItem] ON [FileInItem].[FileID] = [tbl_Files].[ID]
На каком-то этапе [dbo].[tbl_FileInAccount] должно было подмениться на [dbo].[tbl_FileInIncident]?
Собственно, по тексту заменил
var Dat = Services.GetNewItemByUSI('ds_FileInItem');
на
var Dat = Services.GetNewItemByUSI('ds_FileInIncident');
И счастье получил. Но ведь это не правильно. При сохранении файлов из задачи или ещё откуда-то косяк будет.
Андрей, в более новых версиях уже есть массовое сохранение. Вот коробочная функция:
[javascript]
function SaveToFile(){
var Dataset = FilesDetailGridArea.Dataset;
var SelectedIDs = grdData.SelectedIDs;
if (SelectedIDs.Count == 0) {
return;
}
var Message;
var InitialDir = EmptyStr;
var FileName = System.CreateObject('TSObjectLibrary.Value');
if (SelectedIDs.Count > 1) {
var WindowCaption = "Сохранить файлы";
var DirectoryName = System.CreateObject('TSObjectLibrary.Value');
if (!(System.SelectDirectory(WindowCaption, InitialDir,
DirectoryName))) {
return;
}
var SavedFilesCount = 0;
Dataset.DisableEvents();
for (var i = 0; i < SelectedIDs.Count; i++) {
var RecordID = SelectedIDs(i);
Dataset.Locate('ID', RecordID);
var FileType = GetFieldValueFromDisabledField(Dataset, 'ItemTypeID');
FileName.Value =
GetFieldValueFromDisabledField(Dataset, 'Link');
if (!SaveToFileByFileType(Dataset, RecordID, FileName,
DirectoryName.Value, FileType)) {
continue;
}
SavedFilesCount++;
}
Dataset.EnableEvents();
Message = FormatStr(FilesSavedMessage, SavedFilesCount,
SelectedIDs.Count);
ShowInformationDialog(Message);
} else {
FileName.Value =
GetFieldValueFromDisabledField(Dataset, 'Link');
if (!SaveToFileByFileType(Dataset, FilesDetailGridArea.RecordID,
FileName, '', FilesDetailGridArea.FileType)) {
return;
}
if (FilesDetailGridArea.FileType != ft_File) {
return;
}
Message = FormatStr(OpenFileForEditMessage, FileName.Value);
if (ShowConfirmationDialog(Message) == mrYes) {
if (!OpenFileWithFullAccess(FileName.Value, true, ft_File)) {
return;
}
}
}
}
function SaveToFileByFileType(Dataset, RecordID, FileName, FilePath, FileType) {
if (!FilePath) {
FilePath = '';
}
switch(FileType) {
case ft_File:
var FileExtension = '.' + ExtractFileExtension(FileName.Value);
var FileFilterValue = '*' + FileExtension;
FileFilterValue = FileFilterValue + '|' + FileFilterValue;
var WindowCaption = "Сохранить файл";
var InitialDir = EmptyStr;
var IsSaving = true;
if (FileName.Value == EmptyStr) {
return false;
}
if (FilePath != '') {
FileName.Value = FilePath + '\\' + FileName.Value;
} else
if (!(System.PromptForFileName(FileName,
FileFilterValue, FileExtension, WindowCaption,
InitialDir, IsSaving))) {
return false;
}
var File = LoadFileFromDatabase(RecordID,
FileName.Value, false);
if (!File) {
return false;
}
break;
case ft_Link:
case ft_FolderLink:
var FileExtension = 'lnk';
var FileFilterValue = '*lnk';
FileFilterValue = FileFilterValue + '|' + FileFilterValue;
var WindowCaption = "Сохранить файл";
var InitialDir = EmptyStr;
var IsSaving = true;
if (FileName.Value == EmptyStr) {
return false;
}
var DestinationFileName = FileName.Value;
FileName.Value = ExtractFileNameWithoutExtension(FileName.Value);
if (FilePath != '') {
FileName.Value += '.' + FileExtension;
FileName.Value = FilePath + '\\' + FileName.Value;
} else
if (!(System.PromptForFileName(FileName,
FileFilterValue, FileExtension, WindowCaption,
InitialDir, IsSaving))) {
return false;
}
var LinkCaption = ExtractFileNameWithoutExtension(FileName.Value);
System.CreateFileLink(DestinationFileName, '',
LinkCaption, ExtractFilePath(FileName.Value));
break;
case ft_URL:
var FileExtension = 'url';
var FileFilterValue = '*url';
FileFilterValue = FileFilterValue + '|' + FileFilterValue;
var WindowCaption = "Сохранить файл";
var InitialDir = EmptyStr;
var IsSaving = true;
if (FileName.Value == EmptyStr) {
return false;
}
var URLPath = new String(FileName.Value);
var Index = URLPath.indexOf('://') == -1 ? 0 :
URLPath.indexOf('://') + 3;
var URLFileName = URLPath.substr(Index, URLPath.length);
Index = URLFileName.indexOf('/') == -1 ? URLFileName.length :
URLFileName.indexOf('/');
URLFileName = new String(URLFileName.substr(0, Index));
FileName.Value = URLFileName;
if (FilePath != '') {
FileName.Value += '.' + FileExtension;
FileName.Value = FilePath + '\\' + FileName.Value;
} else
if (!(System.PromptForFileName(FileName,
FileFilterValue, FileExtension, WindowCaption,
InitialDir, IsSaving))) {
return false;
}
var URLFileStream = new ActiveXObject('ADODB.Stream');
URLFileStream.Type = 2;
URLFileStream.Mode = 3;
URLFileStream.Open();
URLFileStream.WriteText("[InternetShortcut]",1);
URLFileStream.WriteText("URL=" + URLPath,1);
URLFileStream.Position = 0;
URLFileStream.SaveToFile(FileName.Value, 2);
URLFileStream.Close();
URLFileStream = null;
break;
}
return true;
}
[/javascript]
Дмитрий, это был суперский вариант!
Не понятыми остались строки
[javascript]
Message = FormatStr(FilesSavedMessage, SavedFilesCount,
SelectedIDs.Count);
ShowInformationDialog(Message);
[/javascript]
на них вылетало в дебагер. Прикрыл эти строчки и всё работает!
В этих строках просто выводится сообщение пользователю сколько файлов сохранено. Можете заменить эти 2 строки на:
[javascript]
ShowInformationDialog('Операция завершена. Файлов сохранено: ' + SavedFilesCount);
[/javascript]
Да, без завершающего окошка как-то скучно.
В общем, спасибо всем, вопрос изначальный можно считать решенным.
И всё-таки интересно, жесткая привязка tbl_FileInAccount в общей выборке sq_FileInItem - это ошибка, или так задумано?
Так задумано. Она действительно меняется "на лету" в зависимости от раздела, но в инструкции, на которую вы дали ссылку, этот момент не учтен.