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

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

function ExecuteScriptMethod(ScriptName, MethodName) {
        var Script = GetSingleItemByCode(ScriptName);
        var CodeObject = Script.ScriptControl.CodeObject;
        var Arg;
        var Args = new Array();
        var Code = 'return CodeObject.'+MethodName+'(';
        for (var i = 2; i arguments.length; i++) {
                if (i > 2) {
                        Code += ',';
                }
                Args.push(arguments[i]);
                Code += 'Args['+(Args.length-1)+']';
        }
        Code += ');';
        var CustomFunction = new Function('CodeObject', 'Args', Code);
        return CustomFunction(CodeObject, Args);
}

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

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

Пример использования:

var CurrencyID = Dataset('CurrencyID');
var RateDate = GetLocalDateTime();
RateDate = ExtractDate(RateDate);
var Rate = ExecuteScriptMethod('scr_CurrencyUtils', 'GetRate',  CurrencyID, TodayDate, 1, true);

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

Например, можно вынести каждое отдельное действие раздела в отдельный скрипт и использовать этот скрипт только при необходимости.

Нравится

Поделиться

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

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

А можно просто возвращать ссылку на функцию, которую потом многократно использовать как обычную?

return CustomFunction;

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

"Зверев Александр" написал:А можно просто возвращать ссылку на функцию, которую потом многократно использовать как обычную?

Можно это сделать так:

function ExecuteScriptMethod(ScriptName, MethodName) {
	var Script = GetSingleItemByCode(ScriptName);
	var CodeObject = Script.ScriptControl.CodeObject;
	var Arg;
	var Args = new Array();
	var FuncDict;
	var CustomFunction;
	if (Assigned(Connector.Attributes('FuncDict'))) {
		FuncDict = Connector.Attributes('FuncDict');
	} else {
		FuncDict = GetNewDictionary();
	}
	if (FuncDict.Exists(ScriptName+'_'+MethodName)) {
		CustomFunction = FuncDict(ScriptName+'_'+MethodName);
		for (var i = 2; i < arguments.length; i++) {
			Args.push(arguments[i]);
		}
	} else {
		var Code = 'return CodeObject.'+MethodName+'(';
		for (var i = 2; i < arguments.length; i++) {
			if (i > 2) {
				Code += ',';
			}
			Args.push(arguments[i]);
			Code += 'Args['+(Args.length-1)+']';
		}
		Code += ');';
		CustomFunction = new Function('CodeObject', 'Args', Code);
		FuncDict(ScriptName+'_'+MethodName) = CustomFunction;
		Connector.Attributes('FuncDict') = FuncDict;
	}
	return CustomFunction(CodeObject, Args);
}
Показать все комментарии

Для виконання одної із фукції "SearchFor" вибраного вікна SelectWindow не можу виконати метод ExecuteScriptMethod. Пише "Несоответствие типа".
Parameters повинен мати тип SAFEARRAY

var Parameters = new GetNewDictionary();
SelectWindow.ExecuteScriptMethod("SearchFor", Parameters);

дана конструкція не проходить. (

Підскажіть, хто знає вихід.

Нравится

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

Ніколи не використовував цей метод.
А SelectWindow.ScriptControl.Run(ім'я_функції, параметри, через, кому) Вам часом не підійде?

Нажаль, не підішло. (
Спробував:

SelectWindow.ScriptControl.Run("SearchFor");
і
var Parameters = new GetNewDictionary();
SelectWindow.ScriptControl.Run("SearchFor", Parameters);

Відповідь однакова: "объект не поддерживает данное свойство или метод".
Мається на увазі Run(). Хоча я пройшовся по дереву параметрів об'єкта і Run()там був.
Думаю, що Parameters для метода Run() повинен бути таким же як і для ExecuteScriptMethod()

Для ScriptControl.Run непотрібно створювати масив параметрів.
Натомість потрібно після назви метода через кому передати всі параметри.
Наприклад:

SelectWindow.ScriptControl.Run(ім'я_функції, параметр1, параметр2, параметр3)

.

Скрипт сервісу вікна точно має метод SearchFor?

Якщо має, то можливо під час виконання методу виникала помилка. Ви не намагались на вході в метод ставити

debugger;

і продебажити ?

Віталій, дякую запрацювало за вашою порадою.

SelectWindow.ScriptControl.Run(ім'я_функції);

Моя помилка дійсно в назві функції.

Нема за що.
Був радий допомогти.
:smile:

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