Прошу помощи у коллективного разума, т.к. официальная поддержка отклонила этот вопрос по SLA, как касающийся разработки "новой функциональности", хотя это очевидная просьба о разъяснении логики работы встроенных механизмов.

На конфигурации "A" - разрабатывался пакет в его составе предусмотрено несколько SQL-скриптов.
Они были созданы с Типом установки "После сохранения пакета".
Пакет был успешно перенесен в другую конфигурацию ("B") через SVN, т.е. установлен там из репозитория в котором из конфигурации "A" он был зафиксирован.

После установки пакета в конфигурацию "B",
И выполнения пункта действий конфигуратора "Установить для требующих обновления" - скрипты были выполнены и с них снялся признак "Требует установки в БД".

А вот в искомой конфигурации "А" (где разрабатывался пакет и откуда он фиксировался в SVN) после "Установки этих скриптов" - выполнении действия конфигуратора "Установить выбранные элементы" - признак "Требует установки в БД" - не снимается,
Что приводит к их постоянному повторному выполнению, когда кто либо в конфигурации использует "Установить для требующих установки".
Можно ли, и если да то как снять этот признак принудительно ?

Как правильно конфигурировать такие скрипты, когда их выполнение требуется только при установке пакета (регистрация разделов, деталей, справочников и т.д. и в дальнейшем даже при обновлении пакета их выполнение более не требуется ?

PS: 3 доступных значения "Тип установки",
не ясно чем они отличаются, когда и при каких условиях выполняются.
(в документации всего 2 упоминания на 97-й странице, ничего никак не разъясняющие)
Не очень понятно, что например подразумевается под типом установки "После сохранения пакета".
О каком "сохранении" идет речь ?
Т.е. они выполняются каждый раз когда пакет - что?
Фиксируется в репозитории или устанавливается из него, или при каждом обновлении пакета.

Нравится

1 комментарий

Здравствуйте!

Можно ли, и если да то как снять этот признак принудительно? - Да можно, вот простой скрипт:

update SysPackageSqlScript set NeedInstall = 0 where name = ''

Т.е. они выполняются каждый раз когда пакет - что? - когда пакет сохраняется в БД

Если будете переносить пакеты при помощи WorkspaceConsole, Вы сможете увидеть в какой момент времни происходит выполнение sql скриптов.

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

Добрый день !
Подскажите пожалуйста как посмотреть стек вызова функции при отладке ?

Нравится

2 комментария

Если используете для отладки Visual Studio, там есть окно «Call Stack». Если оно не открыто, нажмите Ctrl+Alt+C.

спасибо

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

Добрый день. В версии Terrasoft 332 создаю новый раздел с помощью мастера разделов. Все вроде бы создалось корректно, ошибок при создании не было. Но при открытии в клиентском приложении все поля карточки неактивны (серые), заполнить карточку никак нельзя. работают только поля с выпадающими списками, и то выбор в поле не появляется. в разделе доступ я установила права доступа. Проверяла все созданные элементы , используя инструкцию https://community.terrasoft.ru/developer/advice/4576, ошибок не нашла. Петесоздала раздел дважды безцспешно.
раздел делаю не в первый раз, но такая проблема впервые. как это исправить?"

Нравится

3 комментария

Виктория, причины могут быть разные.

В первую очередь проверьте, не в правах доступа ли дело, зайдите в раздел под администратором. Также дело может быть, что в карточке не вызывается или не отрабатывает на открытии логика базовой карточки. Проверить можно в отладчике, посмотрев при открытии, заходит ли в эти скрипты из сервиса scr_BaseDBEdit и сравнить с нормально работающим разделом. Также стоит проверить в дизайнере карточки, всё ли там привязано, выставлен ли нужный датасет и верно ли привязаны к нему поля.

Также раздел может быть создан некорректно из-за слишком длинного названия, которое при автоматическом создании сервисов мастером могло в некоторых местах не влезть и урезаться.

Добрый день.
Я захожу под администратором.
Логика базовой карточки действительно страдала, карточка не закрывалась. Я указала родительским окно базовое окно, проблема ушла. Но проблема неправильного открытия осталась.
В дизайнере в карточке указан правильный датасет, и все поля, в запросе и в датасете все нормально, их исполнение в дизайнере ошибок не выдает
Длинное название это сколько букв? Я создавала раздел два раза, как ServiceProject и ServiceClient. Это длинно?

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

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

Добрый день!
При удалении инцидента появляется ошибка "ParentDataset - есть null или не является объектом"
Отладчик ссылается на строчку var Dataset = DataFields.ParentDataset; скрипта ds_IncidentScript

function DataChange(DataField){
        if (DataField == null) {
                return;
        }      
        var DataFields = DataField.ParentDataFields;
        var Dataset = DataFields.ParentDataset;
        if (Dataset.Attributes('IsUpdating')) {
                return;
        }
        var Name = DataField.Name;
                            ...

При создании и редактировании инцидентов никаких ошибок не происходит, все прекрасно работает. Ошибка появляется только при удалении. Причем после закрытия ошибки запись удаляется.
Если кто-нибудь может подсказать в чем может быть проблема, буду крайне благодарен!

Нравится

2 комментария

Добрый день, Дмитрий!
Проверил указанное Вами поведение в базовой версии продукта, данная проблема не воспроизводится.
Прошу Вас, укажите детальный кейс воспроизведения, версию продукта, на котором воспроизводилась проблема и необходимо выполнить анализ произведенных доработок в системе.
Спасибо!

Если это какая-то доработка, можно добавить в скрипт дополнительные проверки на null или обернуть в try.

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

Добрый день.
Помогите пожалуйста в решении такой задачи:
На событии OnKeyUp проверяется некое условие, если оно верно, то в поле нужно вставить строку и продолжыть ввод текста с клавиатуры. Но при вставке строки, курсор оказывается в начале строки, а нужно чтобы он был в конце. Можно ли это реализовать? Можно ли вызвать событие то же событие, что выполняется при нажатии на кнопку END?
Terrasoft 3.4.0.130

Нравится

3 комментария

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

Для решения проблемы рекомендую Вам обновиться до последней версии 3.4.1.

Для того, чтобы получить файлы обновления на эту версию, обратитесь, пожалуйста, в службу поддержки Terrasoft - напишите электронное письмо на адрес: support@terrasoft.ru.

И как мне это поможет?

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

Я предположила, что в последней версии 3.4.1, данное событие отрабатывает иначе, чем в 3.4.0.130, но, к сожалению, в этой версии поведение курсора аналогичное.

Решить данную задачу можно таким образом.

Вместо контрола Edit используйте MemoControl. В обработчике OnKeyUp пропишите такой код:

function edtMemoControl1OnKeyUp(Control, Key, Shift) {
var saveValue = Control.Value;
Control.Value = "";
Control.SelectedText = "@" + saveValue;
}

Для того, чтобы в MemoControl не срабатывал переход на новую строку в свойстве WordWrap установить значение False и в обработчике события OnKeyPress написать код:

function edtMemoControl1OnKeyPress(Control, Char) {
if (Char.Value == 13) {
Char.Value = 0;
}
}

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

Хочу добавить картинку в ImageList.

ImageL = Services.GetSingleItemByUSI('il_TDpics');
var FileName = System.CreateObject('TSObjectLibrary.Value');
if (!(System.OpenDialog(FileName, '*.jpg|*.jpg', EmptyStr, EmptyStr, EmptyStr))) {
return;
}
var ImageItem = ImageL.CreateImage();
ImageItem.ImageType = 2;
ImageItem.LoadFromFile(FileName);

Выдает ошибку. См. присоединенный файл. Просьба подсказать решение.
Вручную рисунки добавляются. Такой код работает

var part1 = 'C:\\Program Files\\Terrasoft\\Res\\';
var part2 = dlData.Dataset.DataFields('DeliveryPointID').Value;
var Final_5 = part1 + part2 + '5.jpg';
if (fso.FileExists(Final_5)) {
var ImageList = Services.GetNewItemByUSI('il_CommunicationActionSmartTag');
var ImageItem = ImageList.CreateImage();
ImageItem.LoadFromFile(Final_5);

Нравится

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

Если картинка лежит где-то в файловой системе — нужно получить строку с её адресом. У Вас в работающем примере в функцию LoadFromFile передаётся строковая константа. А в первом — какой-то объект, возвращаемый из диалогового окна. Попробуйте в отладчике посмотреть, что передаётся в переменную FileName и в чём отличие от работающего примера.

Также см. пример отсюда, где для аналогичным образом полученного значения используется FileName.Value. Возможно, нужная Вам строка находится там.

Спасибо от ошибки избавился. Но завершить работу не получается. Вот код:

var ImageList = Services.GetNewItemByUSI('il_DPpics');
var FileName = System.CreateObject('TSObjectLibrary.Value');
if (!(System.OpenDialog(FileName, '*.jpg|*.jpg', EmptyStr, EmptyStr, EmptyStr))) {
return;
}
var ImageItem = ImageList.CreateImage();
ImageItem.ImageType = 2;
imgTDp1.ImageList = ImageList;
ImageItem.LoadFromFile(FileName.Value);
ImageList.Add(ImageItem);
imgTDp1.ImageList = ImageList;
imgTDp1.ImageName = dlData.Dataset.DataFields('DeliveryPointID').Value + '1';

Все вроде бы работает. В отладчике я виж, что число изображений в ImageList увеличилось с 3 до 4, вижу правильные размеры картинки. Потом уже из ImageList заполняю imgTDp1 и вижу картинку на форме. Но после того, как я закрываю карточку редактирования, введенная картинка исчезает из ImageList. Методов Open / Save для ImageList я не нашел. Как правильно все закрыть, чтобы результаты работы сохранились? Подробности в присоединенном файле.

Вы меняете объект в памяти, а GetNewItemByUSI берёт его сериализированное представление из базы, где оно хранится вместе с другими сервисами.

Для сохранения сервиса делается:

Services.SaveItem(ImageList, sdoaSave);

См. пример реализации в мастере разделов, в скрипте wnd_LoadWorkspaceIconScript.

Спасибо. Уже почти у цели (см. вложение). Может подскажете, как удалить ImageItem из ImageList
Пробовал, что пришло в голову: Remove(), Delete(), ImageList.Items(i) = ImageList.Items(i + 1)? но не вышло. Может быть, менять Name, это возможно?

Увидеть названия всех методов, которые есть у объектов ImageList и ImageItem, можно прямо в отладчике. Если таких методов нет — простым способом удалить не получится.

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

Здравствуйте!
Подскажите, как в Террасофте 3.5.1 реализовать следующий java script:

var https = require('https');
var fs = require('fs');

var file = fs.createWriteStream("file.jpg");
var request = https.get("http://test/test.jpg", function(response) {
  response.pipe(file);
});

Т.е. нужно по https ссылке сохранить файл в определенную директорию.
Как это можно сделать в Террасофт?

Нравится

1 комментарий

Что-то похожее делают тут. Там файл из Интернета сохраняют во временную папку, но код функции можно переделать под нужное место. Не уверен только по поводу HTTPS.

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

Доброго дня!
Хочу сделать возможность переноса данных из одного датасета в другой.
В гриде детали первого раздела сделал кнопку, при нажатии на которую открывается окно второго раздела с записями.

var wndContactsGridArea =  Services.GetNewItemByUSI('wnd_OfferingOrderGridArea');
wndContactsGridArea.Prepare();
var Dataset = wndContactsGridArea.ComponentsByName('dlData').Dataset;
RefreshDataset(Dataset);
WndContactsGridArea.ShowModal();

Может кто подсказать как в этом окне сделать импорт из одного раздела в другой? И можно ли вообще так сделать?
Хочется, чтобы пользователям не приходилось дублировать записи в каждом разделе.

Нравится

2 комментария

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

Теоретически возможность такого переноса данных есть, но сама реализация зависит от сложности того, что Вам нужно получить в итоге.

В Вашем случае в вызываемое по кнопке окно нужно передавать Dataset раздела, из котого Вы хотите импортировать данные и ID его записей, тогда в зависимости от этих значений реализовывать копирование нужных записей.

Можно усложнить задачу и вызывать не окно раздела, в который Вы хотите копировать данные, а реализовать своё окно именно под эту задачу, которое может быть похоже, например, на wnd_MultiSelectData.

Вот мне хотелось бы сделать следующую реализацию:
По нажатию на кнопку открывается окно с разделом, в который я хочу передать данные. В этом окне я выбираю нужную запись и после информационного сообщения "Найдено n продуктов, импортировать их?" происходила передача данных

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

Доброго времени суток!

Создал новый раздел (в нем есть и ContactID и AccountID), добавил детали, все фильтруется в зависимости от ContactID.
При добавлении детали звонков возникли кое какие вопросы:
- можно ли фильтровать деталь по разным ID при каких либо условиях? В таблице звонков есть AccountID и ContactID, а в таблице нового раздела заполнено поле ContactID или AccountID. Как можно настроить фильтрацию в детали звонков в зависимости от того, ContactID или AccountID заполнен?

Использовал подобный код:

var ContactID = GetFieldValueFromDisabledField(BaseWorkspace.GridDataset, 'ContactID');
var AccountID = GetFieldValueFromDisabledField(BaseWorkspace.GridDataset, 'AccountID');

if (IsEmptyGUID(ContactID) == false) {
RefreshCommonDetail(null, wnd_CallGridArea,
'ContactID', 'ContactID', null, null, null, null, null, ContactID);
}
else if (IsEmptyGUID(AccountID) == false ){
RefreshCommonDetail(null, wnd_CallGridArea,
'AccountID', 'AccountID', null, null, null, null, null, AccountID);
}
else {RefreshCommonDetail(null, wnd_CallGridArea,
null, null, null, null, null, null, null, null);}

При загрузке, фильтрация работает, но при переключении на другую запись фильтрация детали перестает срабатывать. Что я делаю не так?

Заранее спасибо.

Нравится

1 комментарий

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

Да, фильтрация набора данных детали по разным полям возможна.

Почему не работает Ваша реализация при переключении на другую запись, Вы сможете понять, если отладитесь.
Вероятнее всего, что по каким-то причинам не переоткрывается датасет детали.

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

Добрый день!

Возникла нужда интегрировать Terrasoft XRM Professional Services v3.3.2.292 с сервисом ExpertSender. Этот сервис имеет собственный API, который работает через POST и GET запросы.Ранее мы уже проводили интеграцию данного сервиса с BPM'online. Для этого мы создавали бизнес-процесс, который запускался как только в CRM добавлялся новый Лид. У этого Лида считывался email-адрес, после чего запускался скрипт, который отправлял на сервис ExpertSender API-запрос, в котором содержался считанный email. Таким образом, мы добавляли новых Лидов в сервис ExpertSender, который работает через API.

Теперь же нужно то же самое воссоздать в Terrasoft XRM. Мы смогли создать новый процесс, в нем создали скрипт, который отправляет POST-запрос на ExpertSender. Но вот как сделать, чтобы процесс запускался автоматически, когда добавляется новый Лид, и как у конкретно этого нового Лида считать email - разобраться так и не удалось. Возможно, кто-то здесь подскажет, что можно сделать?

Нравится

1 комментарий

Здравствуйте, Александр Николаевич!

Для решения Вашей задачи Вы можете использовать функцию WFStartByID(WorkflowID, ParamNames, ParamValues). В качестве параметров, в которую передаются WorkflowID - ID сервиса Вашего процесса, ParamNames - массив имен параметров Вашего БП, для которых Вы хотите передать начальное значение, ParamValues - массив значений параметров.

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