Доброго времени суток, коллеги!
Возникла хотелка сохранять файлы из соответствующей детали не поштучно, а кучей - все выделенные. Вариант 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 на сервере.
Что-то вроде (покажет все файлы для контрагента горсовет)
SELECT ItemTypeID from tbl_Files where FileID in (select FileID from tbl_FileInAccount where AccountID in (select ID from tbl_Account where Name = 'ОАО Горсовет'))
А 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');
И счастье получил. Но ведь это не правильно. При сохранении файлов из задачи или ещё откуда-то косяк будет.
Андрей, в более новых версиях уже есть массовое сохранение. Вот коробочная функция:
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; }
Дмитрий, это был суперский вариант!
Не понятыми остались строки
Message = FormatStr(FilesSavedMessage, SavedFilesCount, SelectedIDs.Count); ShowInformationDialog(Message);
на них вылетало в дебагер. Прикрыл эти строчки и всё работает!
В этих строках просто выводится сообщение пользователю сколько файлов сохранено. Можете заменить эти 2 строки на:
ShowInformationDialog('Операция завершена. Файлов сохранено: ' + SavedFilesCount);
Да, без завершающего окошка как-то скучно.
В общем, спасибо всем, вопрос изначальный можно считать решенным.
И всё-таки интересно, жесткая привязка tbl_FileInAccount в общей выборке sq_FileInItem - это ошибка, или так задумано?
Так задумано. Она действительно меняется "на лету" в зависимости от раздела, но в инструкции, на которую вы дали ссылку, этот момент не учтен.