Добрый день!



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

Нравится

1 комментарий
Лучший ответ

Сделайте замещение базовой страницы, от которой наследуются все Вас интересующие страницы, и добавьте необходимый Вам код

Сделайте замещение базовой страницы, от которой наследуются все Вас интересующие страницы, и добавьте необходимый Вам код

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

Добрый день!



Каким образом можно подключить скрипт для пользователя?

У меня есть ссылка на скрипт, который я хочу внедрить для пользователя и передать определенный параметр.

Как это можно реализовать?

Нравится

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

Можете описать более точнее что Вы имеете ввиду под словом "скрипт"?

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

Поясните, пожалуйста, какие параметры использовать в SQL-скриптах при установке пакета?



Конкретная ситуация: на PostgreSQL необходимо изменить длину текстового поля, но это поле используется в VIEW. Соответственно, если не предпринять ничего дополнительного, то при установке получаем ошибку:



Terrasoft.Core.DB.DBMetaActionExecuteException: Error "0A000: cannot alter type of a column used by a view or rule" occurred when updating schema structure



Логично хочется перед установкой схемы объекта удалить VIEW. Но Drop view с параметром 'Before Saving Package' не сработал - всё равно в логах та же ошибка.



Как же сделать так, чтобы один скрипт срабатывал ДО установки схем, а второй - ПОСЛЕ?

 

Нравится

7 комментариев
Лучший ответ

Владимир Соколов,

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

Обходной вариант разнести их в несколько пакетов и сначала поставить пакет1 потом пакет2.

Вообще я бы не лез в исправление типа поля и создал бы новое поле с нужной длиной и использовал бы его там где надо в логике.

Кроме параметра Тип установки порядок установки sql скриптов больше никак не контролируется.

Полозюков Евгений Петрович пишет:

Кроме параметра Тип установки порядок установки sql скриптов больше никак не контролируется.

А как можно заставить их выполняться в нужный момент? 

Владимир Соколов,

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

Обходной вариант разнести их в несколько пакетов и сначала поставить пакет1 потом пакет2.

Вообще я бы не лез в исправление типа поля и создал бы новое поле с нужной длиной и использовал бы его там где надо в логике.

Полозюков Евгений Петрович,

Иногда у клиента бывает, что в стандартные 250 символов не помещается текст, и он просит увеличить до 500... Переделывать всю логику очень лень :)



Поддержка же отмалчивается.



С пакетами идея! А как пакеты объединить потом в одно "дополнение", чтобы высылать одним файлом?

Владимир Соколов,

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

В один файл можно самому сархивировать все выгруженные пакеты. Либо выделить несколько пакетов при выгрузке если это делается в интерфейсе конфигурации.

В вашем случае если вы объедините пакеты в один проблема с установкой может остаться. В таком случае перед установкой пакетов надо самостоятельно на бд удалить view, по-другому я не вижу вариантов.

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

Дополнительный вопрос к знающим людям - А скрипты выполняются всегда или только в том случае, если изменились с момента последней установки?

Владимир Соколов,

Можно это проверить самостоятельно поставив пакет несколько раз подряд и посмотрев лог установки.

Я при написании скриптов исхожу из того что скрипты выполняются всегда и поэтому пишутся дополнительные проверки чтобы одна и та же операция не выполнялась несколько раз.

К примеру если вы добавляете записи с помощью insert, перед выполнение необходимо проверить наличие записи с помощью select. Если запись есть insert не выполнять.

Примеры написания скриптов есть в базовых пакетах.

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

Пытаюсь вызывать alert('Hello') на каждой странице. Получилось пока только на конкретной странице создав замещающий клиентский модуль и наследуясь от SalesEnterpriseSoftkey_ENU. Как можно сделать этот алерт на всех страницах,  включая авторизацию и другие?

Нравится

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

Андрей, можно вообще добавить свой скрипт в системную настройку GoogleTagManagerScript («Скрипт для Google Tag Manager»), так он будет срабатывать после логина или при загрузке страницы в новой вкладке.

При помощи этого способа встроили в 7.Х голосовалку от Hotjar:

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

Добрый день!

Установил расширение, которое по таймеру показывает всплывающие изображения (https://marketplace.terrasoft.ru/app/new-year-motivation-bpmonline)

Изменил скрипт, который сейчас показывает изображения пользователю, запустившему процесс:

var sender = "ShowImageScreen";

var userConnection = Get("UserConnection");

var messageText = string.Format("\"number\":{0}", UsrNumber.ToString());

messageText = '{' + messageText + '}';

            MsgChannelUtilities.PostMessage(userConnection, sender, messageText);

return true;

Подскажите пожалуйста (как человеку неопытному в данной тематике), как переделать скрипт, чтобы изображение показывалось пользователю, указанному через параметр.

Заранее благодарю!

Нравится

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

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

В клиентском модуле необходимо подписаться на данное сообщение. Например данное сообщение необходимо выводить в карточке контакта ContactPageV2

Тогда в данном модуле необходимо прописать следующее:

 

define("ContactPageV2", [],
function() {
	return {
		entitySchemaName: "Contact",
		attributes: {},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		messages:{},
		methods: {
			init: function () {
				this.callParent(arguments);
				this.subscriptionFunction();
			},			
			subscriptionFunction: function() {
				this.callParent(arguments);
				Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
				this.onWebSocketListener, this);
			},
			onWebSocketListener: function(scope, message) {
				if (message && message.Header.Sender === "ShowImageScreen") {
					var message2 = message.Body;
					if (!this.Ext.isEmpty(message2)) {
						this.Terrasoft.showInformation(message2);
					}
					return;
				} 
			},
 
		},
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
	};
});

 

Нигрескул Алексей,

в нашем случае сообщение всплывает поверх всех открытых окон в bpm. Задача не стоит конкретно отображать сообщение в каком-либо разделе (в Вашем примере в контактах), а в самом скрипте прописать параметр, в который мы бы и задавали пользователя для отображения сообщения.

Насколько понимаю, MsgChannelUtilities.PostMessage взаимодействует только с текущим пользователем, выполняющим процесс. Ещё есть MsgChannelUtilities.PostMessageToAll(string sender, string message), см. обсуждение.

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

Добрый день!
При удалении инцидента появляется ошибка "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.

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

Доброго дня!
Столкнулся со следующей задачей:
При изменении значения поля необходимо установить свойство "обязательно для заполнения" других полей. С этим я справился.
Также мне необходимо при активации чек-бокса установить свойство "только для чтения" для других полей

case ('OfferingInOrderID'):
if ((Name == 'OfferingInOrderID') && (Value == '{42D3DE40-55D1-46F6-B5A5-AFB1EAAE181E}'))      
{
Dataset.DataFields.ItemsByName('DateOfPlacing').IsRequired = true;
Dataset.DataFields.ItemsByName('PlaningDateOfDelivery').IsRequired = true;
}
else
{
Dataset.DataFields.ItemsByName('DateOfPlacing').IsRequired = false;
Dataset.DataFields.ItemsByName('PlaningDateOfDelivery').IsRequired = false;                    
}
break;

Это на обязательность заполнения.
Функция SelfOnDatasetDataChange
Подскажите пожалуйста, как реализовать свойство "только для чтения" для этих же полей?
Пробовал и "IsVisible" и "IsEnabled" - безрезультатно
//case ('OnStock'):
//if  ((Name == 'OnStock') && (Value == 1)) //На складе
//{
//Dataset.DataFields.ItemByName('DateOfPlacing').IsEnabled = false;
//Dataset.DataFields.ItemByName('PlaningDateOfDelivery').IsEnabled = false;
//}
//else
//{
//Dataset.DataFields.ItemByName('DateOfPlacing').IsEnabled = true;
//Dataset.DataFields.ItemByName('PlaningDateOfDelivery').IsEnabled = true;
//}
//break;

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

Нравится

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

Дмитрий, Вы можете менять свойство «IsEnabled» не у поля датасета, а у контрола:

edtDateOfPlacing.IsEnabled = true;

Учтите только, что делать это можно в скрипте карточки на событии «DataChange», но не скрипте датасета.

Также см. подробнее тут.

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

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

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

Заранее благодарю за ответы!

С уважением,
Александр

Нравится

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

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

Для реализации Вашей задачи Вы можете установить требуемое значение в поле датасета прямо в элементе бизнес процесса, а именно в скрипте wa_TaskActionScript в обработчике события wa_TaskActionOnExecute.

Благодарю!
Получилось!

Спасибо.

Нам вдвойне приятно получать от клиентов такой фидбек!

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

Здравствуйте! Я в террасофте совсем новичок, только начинаю изучать. Версия ТС - 3.4.0.38. По форуму искала, вроде подходящего решения не нашла, либо не поняла что это "оно". Подскажите пожалуйста!
Была поставлена задача - по расписанию формировать файл с отчетом для Excel (есть аналог для работы пользователя в FR), выкладывать его в сеть и отправлять группе лиц.
Вроде как все решила через SQL, правда экселевский файл сформировала через spread xls на xml.
Несущественная проблема - при открытии на некоторых компьютерах ругается на несоответствие формата, с этим можно жить, но вот на телефонах этот файл не открывается в приложениях, но очень нужно.
В итоге встал вопрос о другом формате.. Возможно ли как то через sql или сам террасофт выполнить по расписанию формирование файла в формате xlsx или pdf (редактируемый)? Либо конвертацию сделать, может что-то вроде - открыть файл в sql через sp_OACreate 'Excel.Application', и сохранить его в xlsx..

Нравится

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

С помощью Terrasoft, также можно выполнить такую задачу, для этого необходимо на сервер создать задачу (Task Scheduler), которая будет запускаться по времени и вызывать Terrasoft командой TSClient.exe /wnd=wnd_ExportRep.

Где в окне wnd_ExportRep будет прописана логика экспорта.
Обратите внимание на сервисы scr_MSExcelLibrary, scr_MSExcelLibraryConsts, а также на сервис scr_UserReportCommon, в особенности на функцию GetExcelObject - которая возвращает Com объект на Excel.

Также можно изучить работу сервиса scr_ImportExcelWizardUtils, который автоматически создает отчеты в Excel, на основании его работы можете создать свой экспорт.

Хороший вариант! Спасибо! Правда мне очень много стоит изучить для реализации подобного..
А клиент терры будет открыватся на сервере или только процесс висеть? Если есть возможность подсказать подобные примеры решения буду очень признательна.

Пробовала запускать excel на террасофте через var ExcelApp = new ActiveXObject("Excel.Application");
но система выругалась на меня и клиент вылетел..

Можете взять мой пример запуска коннектора и создание Excel файла.
Алгоритм следующий:
1. Создайте файле с расширением js
2. Пропишите в нем следующий код:

function WSLog(LogText) {
	WScript.stdout.WriteLine(LogText);
}
 
function GetExcelObject() {
	var Excel = new ActiveXObject('Excel.Application');
	var Excel_wb = Excel.Workbooks.Add();
	Excel.Sheets(1).Name = "Данные";
	var SheetsCount = Excel.Sheets.Count;
	for (var i = 2; i <= SheetsCount; i++) {
		Excel.Sheets(2).Delete();
	}
	Excel.Visible = false;
	return Excel;
}
 
function Main() {
	var args = WScript.arguments;
	var ConfigurationName = "TS_3.4.1.113_XRM_SD_SoftKey_ENU_Tereshchuk";
	var AuthenticationMode = 1; //1 - DatabaseServer, 0 - Windows
	var UserName = "Supervisor";
	var UserPassword = "";
	var ExcelFileName = 'C:\\Temp\\TestExcel.xlsx';
	WSLog("Start!");
	var Connector =  new ActiveXObject('TSObjectLibrary.Connector');
	var Config;
	if (AuthenticationMode) {
		Config = Connector.OpenConfigurationByName(ConfigurationName, AuthenticationMode, UserName, UserPassword);
	} else {
		Config = Connector.OpenConfigurationByName(ConfigurationName, AuthenticationMode);
	}
	var Excel = GetExcelObject();
	Excel.Sheets(1).SaveAs(ExcelFileName);
	Excel.Visible = true;
	Connector.Logoff();
	WSLog("Finish!");
}
 
Main();

3. Создайте файл с расширением bat и пропишите в нем код:
%WinDir%/SysWOW64/cscript.exe /d D:\Projects\JS\RunTS.js

4. Запустите bat файл

Исходники: js.zip

Спасибо!
Так как задача была горящей, а 'Excel.Application' наотрез отказывается работать, временно решила через excelcnv.exe. Там правда очень много нюансов, за счет чего код получился совсем извращенным, но главное рабочим.. позже вернусь к приведению в нормальный вид ) попробую все-таки решить через террасофт по #1 предложенному ответу.

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

Доброго дня.
Столкнулся с проблемой:
Необходимо перегнать значения из строкового поля в blob поле, но при запуске скрипта выдает ошибку
"Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом"

function Main()
{  
        var TaskDataset = Services.GetNewItemByUSI('ds_Task');
        EnableDatasetFilters(TaskDataset, false);
        var ID = '{332C64BC-245B-4A08-B345-C392F4A8FCFF}';
        ApplyDatasetFilter(TaskDataset, 'ID', ID, true);
        TaskDataset.Open();
        while(!TaskDataset.IsEOF)
        {
                var Detalization = TaskDataset('Detalization');
                var Stream = new ActiveXObject('ADODB.Stream');
                Stream.CharSet = 'windows-1251';
                Stream.Mode = 3;        
                Stream.Type = 2;
                Stream.Open(Detalization);
                var Field = TaskDataset.DataFields.ItemsByName('DetalizationRich');
                Field.SetValAsBlob(Stream);
                Stream.Close();        
                TaskDataset.GotoNext();        
        }      
        TaskDataset.Post();
        TaskDataset.Close();
}

В чем может быть проблема? Заранее спасибо

Нравится

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

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

Сообщение говорит, что не правильно открываете Stream.

Пример записи значения поля [ФИО] Контакта на деталь [Описание] раздела Контакты:

	var ID = '{251FB9AC-C17E-4DF7-A0CB-D591FDB97462}';
 
	var ContactDataset = Services.GetNewItemByUSI('ds_Contact');
	EnableDatasetFilters(ContactDataset, false);    
    ApplyDatasetFilter(ContactDataset, 'ID', ID, true);
    ContactDataset.Open();
 
    var DescriptionDataset = Services.GetNewItemByUSI('ds_Description');
	ApplyDatasetFilter(ContactDataset, 'ID', ID, true);
 
	var SubjectSelectQuery = ContactDataset.SelectQuery;
	var DetailSelectQuery = DescriptionDataset.SelectQuery;
	var FromTable = SubjectSelectQuery.Items(0).FromTable;
	DetailSelectQuery.Items(0).FromTable = FromTable;
	DescriptionDataset.Open(); 
 
    var FieldName = ContactDataset.DataFields.ItemsByName('Name');
    var FieldDescription = DescriptionDataset.DataFields.ItemsByName('Description');
 
 
    var Stream = new ActiveXObject('ADODB.Stream');
	Stream.CharSet = 'windows-1251';
    Stream.Mode = 3;
    Stream.Type = 2;
	Stream.Open();
    Stream.Position = 0;
    Stream.WriteText(FieldName.Value); 
 
    DescriptionDataset.Edit();
    FieldDescription.SetValAsBlob(Stream);
    Stream.Close();
    DescriptionDataset.Post();
 
    DescriptionDataset.Close();
    ContactDataset.Close();

Результат:

Cпасибо большое!
Теперь все работает, правда если я хочу перегнать все записи, то выдает ошибку "Out of memory"
Можно с этим как то бороться?

Попробуйте вызывать функцию CollectGarbage(0.001);
Выполняйте Post() в цикле, а также создание Strem-а вне цикла.

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