bpm 5.4 on-site, как передать информацию в подпроцесс

например есть скрипт А и скрипт Б
как из скрипта А вызвать скрипт Б и передать в него текстовую строку?

Нравится

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

Так всё таки передать параметр в подпроцесс, или из скрипта А вызвать скрипт Б?
В подпроцесс можно передать информацию, например, с помощью параметров бизнес-процесса.
Опишите ситуацию более подробно.

из скрипта А вызвать скрипт Б

Скрипт А и скрипт Б - это 2 функции "задание-сценарий"?

Нужно сделать так, чтобы каким-то образом при выполнении скрипта А, запустилась функция Б и пошло-поехало?
Или вам просто нужно вызвать какой-то вспомогательный метод, и после этого продолжить выполнение скрипа А?

Здравствуйте, Илья!

В бизнес процессе можно добавить параметры и методы. А потом просто вызывать их из Вашего скрипта.

"Яландаев Евгений" написал:

Скрипт А и скрипт Б - это 2 функции "задание-сценарий"?

Нужно сделать так, чтобы каким-то образом при выполнении скрипта А, запустилась функция Б и пошло-поехало?

Или вам просто нужно вызвать какой-то вспомогательный метод, и после этого продолжить выполнение скрипа А?

да надо из А просто запустить скрипт Б и передать в скрипт Б параметр

"Резниченко Сергей" написал:

Здравствуйте, Илья!

В бизнес процессе можно добавить параметры и методы. А потом просто вызывать их из Вашего скрипта.

С уважением,

Резниченко Сергей

Специалист 2-й линии поддержки

я в процессах и сздал сценарий, а как создать сценарий с параметром не нашел

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

Не вижу нигде где можно создать параметр для скрипта.
вот скрин http://joxi.ru/zE7gU_3JTJD9B0uy32I
скрин

Здравствуйте, Илья!

Прочитайте, пожалуйста, внимательнее комментарий моего коллеги Максима

"Maxim Gritsenko" написал:

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


Параметры задаются на уровне всего процесса.

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

Сделал параметр
вот скрин: http://joxi.ru/LV_gU_3JTJBlZPqSF_U
скрин

присваиваю параметру значение "авто" и запускаю скрипт ScriptTask10Execute
вот скрин http://joxi.ru/a1_gU_3JTJA-CC1SJLY
скрин

а вот проверяю значение этого параметра в скрипте ScriptTask10Execute
и не срабатывает условие, значит значение параметру не передалось
вот скрин условия http://joxi.ru/NGHgU4wyTJC6Aufx0g4
скрин

Как вы определяете, что условие не выполнилось?
Советую отлаживаться, так как представленная вами конструкция должна отрабатывать. А если не отрабатывает, необходимо смотреть в другие места, например, задание-сценарий называется не ScriptTask10.

1. Я точно знаю, что ScriptTask10Execute запустился, так как у меня там выполняются еще действия.
2. Как видите условие двойное, и условие Page.TextEdit5.Text=="авиа" срабатывает
3. скрипт так и называется ScriptTask10Execute, именно по этому имени он и вызывается, как видите на скриншоте именно такое и есть название

Проверьте, не меняется ли значение до момента проверки. Выведите значение параметра в текстовый файл или в панель уведомлений непосредственно перед условием.
Лучше, конечно, пользоваться Visual Studio, это сэкономит время.

"Maxim Gritsenko" написал:

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

напомните как выводить в файл и как вывести сообщение

"Maxim Gritsenko" написал:

Лучше, конечно, пользоваться Visual Studio, это сэкономит время.


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

В файл можно вывести так:

System.IO.File.AppendAllText("C:\\debug.txt", VidPerevozkiParametr);

В панель уведомлений можно если это процесс страницы:

Page.BaseMessagePanel.AddMessage("Warning", VidPerevozkiParametr, MessageType.Warning);

изменил сценарий вызывающий

Page.TextEdit5.SetValue("авто");
VidPerevozkiParametr= "авто";
System.IO.File.AppendAllText("C:\\debug.txt", "перед входом в сценарий "+VidPerevozkiParametr+"\n");
ScriptTask10Execute(context); // скрыть линее в зависимости от вида
System.IO.File.AppendAllText("C:\\debug.txt", "до входа в сценарий "+VidPerevozkiParametr+"\n");
return true;

и сценарий принимающий

System.IO.File.AppendAllText("C:\\debug.txt", "в сценарии"+VidPerevozkiParametr+"\n");
...

В файл попадает только вот что:

в сценарии

Если это полное содержимое файла, то очевидно, что у вас не выполняется первый скрипт-таск.

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

Page.TextEdit5.SetValue("авто");

В таком случае остается только отладиться.
Рекомендую к ознакомлению:
BPMonline: отладка конфигурации On-Site для 5.X
Отладка в Visual Studio

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

Версия bpm 5.4.
Подскажите, как открыть URL карточки редактирования контрагента и передать туда параметр?

Например, есть у меня входящий звонок через Oktell, и я открываю карточку новой записи Контрагента http://.....?phone_number=8913...

В результате необходимо получить открытую карточку нового контрагента с заполненным полем "телефонный номер".

Нравится

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

Здравтсвуйте, Илья!
Карточку редактирования из бизнес-процесса можно открыть с помощью действия "Открыть страницу".
Пример:
Создать Действие процесса (UserTask). Действие = Открыть страницу

Создать скрипт подготовки перед действием и написать в нем следующее:

EntitySchemaUId = Page.DataSource.SchemaUId;
string recordId = Guid.Empty.ToString(); //Id записи
string customParameter = "test";
 
UserTaskRunSAObjectEditPage.OpenerPage = Page;
UserTaskRunSAObjectEditPage.OpenerPage = Page;
UserTaskRunSAObjectEditPage.PageUId = EditPageUId; //UID вашей страницы
var parameters = new Dictionary<string, string> {
    {"recordId", recordId.ToString()},
    {"entitySchemaUId", EntitySchemaUId.ToString()}, //UID вашего объекта (не обязательно)
    {"treeGridId", Page.TreeGrid.ClientID}
    {"customParameter", customParameter}
};
UserTaskRunSAObjectEditPage.PageParameters = parameters;
UserTaskRunSAObjectEditPage.Centered = true;
UserTaskRunSAObjectEditPage.CloseOpenerOnLoad = false;

Затем на странице можно прочитать параметр:

string customParameter = Page.GetParameterValue("customParameter") != null ? Page.GetParameterValue("customParameter").ToString() : "" ;

А как открыть карточку по URLи передать в нее параметры из URL строки?

Илья,

Можно вручную распарсить URL и передать полученные значения параметров так, как было предложено в ответе Андрея Каспаревича (у действия "Открыть страницу" есть параметр PageUrl).

"Maxim Gritsenko" написал:

Илья,

Можно вручную распарсить URL и передать полученные значения параметров так, как было предложено в ответе Андрея Каспаревича (у действия "Открыть страницу" есть параметр PageUrl).

Да работает, а как реализовать, чтобы при загрузке страницы автоматически прочитывался параметр?
Поместил в процедуру PageInitScriptTaskExecute - ничего не происходит.
Вот скрин с кода: http://joxi.ru/HoeVU_3JTJAZY8FPihk

На ините источник данных еще не загружен.
Пользоваться следует событием PageLoadComplete, Андрей показывал как:

string customParameter = Page.GetParameterValue("customParameter") != null ? Page.GetParameterValue("customParameter").ToString() : "" ;
Page.TextEdit2.SetValue(customParameter);
Page.DataSource.ActiveRow.SetColumnValue("MyField", customParameter);

"Maxim Gritsenko" написал:

На ините источник данных еще не загружен.

Пользоваться следует событием PageLoadComplete, Андрей показывал как:

поместил в обработчик ScriptPageLoadCompleteExecute код:

if (Page.GetParameterValue("tel") != null)
{	Page.TextEdit2.Text= Page.GetParameterValue("tel").ToString();}

при загрузке страницы код не запускается

Илья, Вам необходимо использовать метод SetValue() также установить значение в ActiveRow

if (Page.GetParameterValue("tel") != null) {
   Page.TextEdit2.SetValue(tel);
   Page.DataSource.ActiveRow.SetColumnValue("MyField", tel);
}

"Lymar Maxim" написал:

Илья, Вам необходимо использовать метод SetValue() также установить значение в ActiveRow

Опять пустота.

Если я открываю карточку еще не созданного объекта, т.е. с recordid=00.... , то следующий код, как я понимаю не обязателен

Page.DataSource.ActiveRow.SetColumnValue("MyField", tel);

Даже если Page.TextEdit2.SetValue(tel)= "22222"; пишу, ничего не происходит.

Устанавливать значение следующим способом

Page.TextEdit2.SetValue(tel)= "22222"

нельзя.

сначала Вам нужно инициализировать переменную tel , например

string tel = "22222";

а затем вызвать для контрола TextEdit2 метод SetValue() следующим способом:

Page.TextEdit2.SetValue(tel);

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

"Lymar Maxim" написал:string customParameter =

код такой:

if (Page.GetParameterValue("tel") != null) 
{
   string tel= Page.GetParameterValue("tel");
   Page.TextEdit2.SetValue(tel);
   Page.DataSource.ActiveRow.SetColumnValue("Phone", tel);
}

URL такая:

http://111-dns:81/0/ViewPage.aspx?Id=7a62325f2e73484ba21fc468db94f8f1&recordId=00000000-0000-0000-0000-000000000000&entitySchemaUId=08ca70da-f05a-4b29-9fac-cf824a4d45f2&treeGridId=PageContainer_ApplicationSectionPage_Grid_TreeGrid&SysModuleEditId=aaf43af2-d2dc-4aa9-b4d7-37532fdfca42&folderId=398ac1f5-53c7-467b-84d3-33a2b75e5d25&tel=8989

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

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

Guid EntitySchemaUId = new Guid("16BE3651-8FE2-4159-8DD0-A803D4683DD3");//Page.DataSource.SchemaUId;
string recordId = Guid.Empty.ToString(); //Id записи
string customParameter = "test";
 
Guid EditPageUId = new Guid ("10e5b380-25f3-474d-8dec-6b4084180ac7");
UserTaskOpenContactEditPage.PageUId = EditPageUId; //UID вашей страницы
var parameters = new Dictionary<string, string> {
    {"recordId", recordId.ToString()},
    {"entitySchemaUId", EntitySchemaUId.ToString()}, //UID вашего объекта (не обязательно)
    {"customParameter", customParameter}
};
 
UserTaskOpenContactEditPage.PageParameters = parameters;
UserTaskOpenContactEditPage.Centered = true;
UserTaskOpenContactEditPage.CloseOpenerOnLoad = false;
return true;

Далее в процессе карточки Контакта на PageLoadComplete считываем параметр и для примера выводим его в поле Адрес.

string customParameter = Page.GetParameterValue("customParameter") != null ? Page.GetParameterValue("customParameter").ToString() : "" ;
Page.AddressEdit.SetValue(customParameter);
Page.DataSource.ActiveRow.SetColumnValue("Address", customParameter);
return true;

Ниже представлена карточка контакта с параметром записанным в поле Адрес.

"Lymar Maxim" написал:

Добавил в ScriptPageLoadCompleteExecute карточки контакта код

string customParameter = Page.GetParameterValue("customParameter") != null ? Page.GetParameterValue("customParameter").ToString() : "" ;
Page.AddressEdit.SetValue(customParameter);
Page.DataSource.ActiveRow.SetColumnValue("Address", customParameter);

и при вызове страницы по URL

http://111-dns:81/0/ViewPage.aspx?Id=10e5b38025f3474d8dec6b4084180ac7&recordId=00000000-0000-0000-0000-000000000000&entitySchemaUId=16be3651-8fe2-4159-8dd0-a803d4683dd3&treeGridId=PageContainer_ContactsModulePage_Grid_TreeGrid&SysModuleEditId=d2ec5d94-7f80-e011-afbc-00155d04320c&folderId=f35a1295-dca5-df11-831a-001d60e938c6&customParameter=2423

в адрес ничего не записывается, вот скриншот: http://joxi.ru/uzWYU_3JTJBBYyJBKyg

Илья, URL страницы у Вас сформирован корректно, вероятнее всего, Вы производите считывание параметра до промежуточного генерирующешо сообщения "PageLoadComplete". Вам нужно считывать параметр в кодовом блоке обозначенном на рисунке ниже, после промежуточного генерирующешо сообщения "PageLoadComplete".

"Lymar Maxim" написал:


переход по URL происходит не из бизнес процесса, мне просто надо открыть URL и считать параметр
ввожу данные URL в браузере и надо считать параметр

Не важно, откуда происходит открытие страницы. Считывание параметра происходит в логике страницы, в предыдущем сообщение описывалось считывание параметра, а не открытие страницы.

такого скрипта PageLoadComplete нет, есть только ScriptPageLoadCompleteExecute
судя по вашему скриншоту у вас скрипт называется PageLoadCompleteScriptTask. Такого скрипта так же нет.

Из ScriptPageLoadCompleteExecute:
1. не считывается параметр
2. в интересующее поле даже константа не записывается

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

Не получается.
Вот бизнес-процесс запуска: http://joxi.ru/t12iUxjKTJATH5qZNTs

А вот код в этом обработчике, который ничего не меняет в карточке:

Page.TextEdit2.SetValue("22222");

Илья, просьба проверить, чтобы в Вашем бизнес-процессе

в "промежуточном генерирующем сообщении" "ParentPageLoadComplete", был установлен признак "Отправить в родительский процесс".

И в скрипте "PageLoadCompleteScriptTask" устанавливалось значение и в контрол и в ActiveRow, пример в приведенном ниже коде.

string customParameter = Page.GetParameterValue("customParameter") != null ? Page.GetParameterValue("customParameter").ToString() : "" ;
Page.AddressEdit.SetValue(customParameter);
Page.DataSource.ActiveRow.SetColumnValue("Address", customParameter);

Также проверьте, пожалуйста, чтобы в "начальном сообщении" и в "промежуточном генерирующем сообщении" было прописано сообщение "PageLoadComplete".

Спасибо, теперь передается параметр.

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

Задача
В БП проверить контрагента в базе по реквизитам и дальше заполнить реквизиты нового заказчика, если такого нет в базе.

(требование клиента)
Через сервис окна в Terrasoft запрашиваются реквизиты у пользователя :
- Наименование;
- Регион;
- Город;
- Телефон;

Создаем форму wnd_name_reg_city_phone унаследуем ее от wnd_BaseEdit, в Невизуальные компоненты добавляем даталинки на справочники датасетов ds_City и ds_State. Добавляем 4 ре контрола два из них LookupControl (для выбора справочников, заметьте НЕ LookupDataControl) и два Edit контрола.

edtName – Edit возвращает значение текст
edtState – LookupControl возращает ID выбранного региона
edtCity – LookupControl возращает ID выбранного города
edtPhone - возвращает значение текст

Получаем следующую форму (сама форма в прикрепленных файлах)
1
Далее для того что бы считывать логику необходимо подключить (создать) к окну скрипт. Выберете контрол Ok, событие OnClick два раза кликните на колонку Значение, дальше дизайнер предложить вам создать скрипт

На событие Ок, пропишем логику считывания значений, и запись их в атрибуты окна, для последующей передачи их в БП

//-----------------------------------------------------------------------------
// wnd_name_reg_city_phoneScript
//-----------------------------------------------------------------------------


function btnOKOnClick(Control) {

var AccountName = edtName.Value;
var AccountStateID = edtState.Value;
var AccountCityID = edtCity.Value;
var AccountPhone =  edtPhone.Value

SetAttribute(Control.ParentWindow, 'AccountName',AccountName);
SetAttribute(Control.ParentWindow, 'AccountStateID',AccountStateID);
SetAttribute(Control.ParentWindow, 'AccountCityID',AccountCityID);
SetAttribute(Control.ParentWindow, 'AccountPhone',AccountPhone);
         SendNotify(Control.ParentWindow, MSG_OK);
}


function Main() {
         var Window = Services.GetNewItemByUSI('wnd_name_reg_city_phone');
         Window.IsDesigning = false;        
         Window.Prepare();
         Window.Show();      
}

function Main() в данном коде необходима для реализации возможности и вызова окна по нажатию F9
Создаем БП
В БП следует создать параметры
2
Элемент Открытие окна в следующем варианте с следующими опциями
3

4
Каждый из параметров должен быть установлен с следующей опцией
5
6
Предварительный вид БП будет следующим видом
7
Элемент scr это скрипт, в котором мы считаем параметры с Окна, и запустим хранимую процедуру Базы данных, которая реализует выборку из базы по условию:

(требование клиента)
Name содержит N &
StateID содержит P &
CityID содержит G &
(Communication1 содержит T) или (Communication2 содержит T) или (Communication3 содержит T) или (Communication4 содержит T) или (Communication5 содержит T)

Хранимая процедура будет иметь вид:

CREATE  procedure [dbo].[tsp_check_name_reg_city_phone]
      @AccountName nvarchar(250),
      @AccountStateID uniqueidentifier ,
      @AccountCityID uniqueidentifier,
      @AccountPhone nvarchar(250),
      @Result int output
  AS
begin
      declare @AccountNameLike nvarchar(300)
      declare @AccountPhoneLike nvarchar(300)
     
    SET @AccountNameLike = '%'+ @AccountName + '%';
    SET @AccountPhoneLike= '%'+ @AccountPhone + '%';


DELETE FROM  tbl_Account_b;

INSERT INTO [dbo].[tbl_Account_b]
SELECT [ID]
      ,[CreatedOn]
      ,[ModifiedOn]
      ,[Name]
      ,[CreatedByID]
      ,[ModifiedByID]
      ,[OfficialAccountName]
      ,[PrimaryContactID]
      ,[TerritoryID]
      ,[AnnualRevenue]
      ,[EmployeesNumber]
      ,[OwnerID]
      ,[CampaignID]
      ,[AddressTypeID]
      ,[Address]
      ,[CityID]
      ,[StateID]
      ,[ZIP]
      ,[CountryID]
      ,[ActivityID]
      ,[FieldID]
      ,[Communication1]
      ,[Communication2]
      ,[Communication3]
      ,[Communication4]
      ,[Communication5]
      ,[Communication1TypeID]
      ,[Communication2TypeID]
      ,[Communication3TypeID]
      ,[Communication4TypeID]
      ,[Communication5TypeID]
      ,[Description]
      ,[AccountTypeID]
      ,[Code]
      ,[TaxRegistrationCode]
      ,[SettledCredit]
      ,[PostponementPayment]
FROM [dbo].[tbl_Account]
WHERE [Name] LIKE @AccountNameLike
AND [StateID] = @AccountStateID
AND [CityID] = @AccountCityID
AND (
   [Communication1] LIKE @AccountPhoneLike
OR [Communication2] LIKE @AccountPhoneLike
OR [Communication3] LIKE @AccountPhoneLike
OR [Communication4] LIKE @AccountPhoneLike
OR [Communication5] LIKE @AccountPhoneLike
)

 SET @Result = (SELECT count(*) FROM  [dbo].[tbl_Account_b]);

end  

Возращает процедура количество записанных данных.

Причем подразумевается что таблица tbl_Account_b есть, ее можно создать к примеру запросом

SELECT * INTO tbl_Account_b FROM tbl_Account WHERE 1 = 0

Дальше в БП мы должны вызвать данную процедуру.

В элементе scr в БП пишем код (предварительно подключив скрипты scr_DB, scr_WindowUtils,scr_WorkflowUtils)
9

function Item3OnExecute(ScriptItem, IsComplete) {
var vAccountNameBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountNameBP');
var vAccountStateIDBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountStateIDBP');
var vAccountCityIDBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountCityIDBP');
var vAccountPhoneBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountPhoneBP');


var Parameters = CreateSPParameters();
CreateSPParameter(Parameters, 'AccountName', pdtString, vAccountNameBP);
CreateSPParameter(Parameters, 'AccountStateID', pdtString, vAccountStateIDBP);
 CreateSPParameter(Parameters, 'AccountCityID', pdtString, vAccountCityIDBP);
CreateSPParameter(Parameters, 'AccountPhone', pdtString, vAccountPhoneBP);

CreateSPParameter(Parameters, 'OutTest', pdtInteger, 0);
Parameters.ItemsByName('OutTest').ParamType = 1;

var SQLText =
'exec dbo.tsp_check_name_reg_city_phone :AccountName, :AccountStateID, :AccountCityID,:AccountPhone,:OutTest OUTPUT';
Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);

var res = Parameters.ItemsByName('OutTest').ValAsInt;
WFSetParamValue(ScriptItem.ParentItems.ParentDiagram, 'Acc_count', res);  
}

В строчках WFSetParamValue(ScriptItem.ParentItems.ParentDiagram, 'Acc_count', res);
Мы записываем полученное значение с процедуры в параметр БП 'Acc_count', после чего в элементе test_res в качестве примера выводим полученное значение.

Дальше по параметру 'Acc_count' можно анализировать значение переменной, и в зависимости от этого создавать нового контрагента

Окончательный вид всех параметров БП
9
Все сервисы прикреплены к данному сообщению

Нравится

Поделиться

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

Алексей, почему вы используете varchar вместо nvarchar? Вы потеряете юникод.
Создавать таблицу tbl_Account_b лучше запросом:

SELECT * INTO tbl_Account_b FROM tbl_Account Where 1 = 0

Таким образом у вас tbl_Account_b будет пустая, а не содержать всех Контрагентов.

Александр, спасибо за замечания, исправил предыдущий пост.

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

Здравствуйте!
Пытаюсь разобраться с бизнес-процессами.
Версия 3.3.2.

Нужно создать окно поиска по абонентам. И отобразить грид с результатом.

Я правильно понимаю, что у меня должно быть два action "Открытие окна", одно с окном поиска, другое с окном грида?
Из окна поиска мне нужно получить то, что ввели и сделать поиск по абонентам. И на основе отфильтрованной датасет уже делать грид?

Где делать сам поиск?
В скрипте поиска или передать параметры того что ввели куда-то еще, там сделать поиск и по получившемуся датасет строить грид?

С передачей параметров тоже не очень выходит. Создала параметр Name у диаграммы и у действия, связала их, но достать то, что ввели из Action1OnAfterExecute не получается.

Помогите, пожалуйста.

Нравится

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

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

Здравствуйте Светлана,

Предлагаю вам создать сервис окна (Window) поместить в него компонент Edit, кнопку поиска и DataGrid, вызывать данное окно в БП можно с помощью действия "Открытия окна", далее выберете опцию "Другое окно" и выбирете сервис окна.
По нажатию кнопки проводить фильрацию датасета, согласно строке поиска.
Пример :

var Dataset = dlData.Dataset;
Dataset.Close();
ApplyDatasetFilter(Dataset, 'NameLike',edtFind.Value, true);
Dataset.Open();	

где NameLike - имя фильтра в датасете,
edtFind - имя контрола Edit

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

Хочу добавить поле поиска на вкладку контрагенты.

Добавил на wnd_AccountsWorkspace

как советовал Алексей компонент Edit, кнопку поиска.
В обработчике события вставил код

var Dataset = dlAccounts.Dataset;
 Dataset.Close();
 ApplyDatasetFilter(Dataset, 'Name',admSerch.Value, true);
 Dataset.Open();
if (ShowConfirmationDialog("Событие по нажатию кнопки поиска") != wmrYes) {
			return; }

Больше нигде ничего не менял.
Поиск не выполняется, подскажите как реализовать

Здравствуйте Владимир,
В случае с контрагентами, срабатывает событие отключения фильтров, так сделано для того что бы срабатывали представления (которые реализованы как фильтры)
В Вашем случае следует сделать так:

function btnSrchClick(Control) {
dlData.Dataset.DisableEvents();
dlData.Dataset.Close();
//MessageBox(edtAccountName.Value);
if (edtAccountName.Value != '') 
{
ApplyDatasetFilter(dlData.Dataset,'Name',edtAccountName.Value,true);
}
else 
{ApplyDatasetFilter(dlData.Dataset,'Name',edtAccountName.Value,false);
}
dlData.Dataset.Open();
dlData.Dataset.EnableEvents();
}

Если значение в edtAccountName есть включаем фильтр, если значения нет, выключаем фильтр, что бы оторражалось все так как в наших представлениях в Контрагентах

Спасибо Все зарабртало.
Сменил имя датасета и едитов и все гуд!

Сейчас идет строгий поиск а я хочу сделать поиск на основе фильтра "Содержит"

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

Владимир, здравствуйте!

Для реализации Вашей задачи рекомендую создать функцию:

function searchName()
{ 		
        var Dataset = dlData.Dataset;
	Dataset.DisableEvents();
	Dataset.Close(); 
        ApplyDatasetFilter(Dataset, 'NameByLike', edtEdit.Value, true);
	Dataset.Open();
	Dataset.EnableEvents();
}

где NameByLike - фильтр типа Like. (tbl_Account.Name содержит Parameter: NameByLike).

Далее, на событии OnChange для Edit контрола, прописать приблизительно следующий код:

function edtEditOnChange(Edit) {
	if (edtEdit.Value.length > 2)
	{
		searchName();
	}
	if (edtEdit.Value.length == 0)
	{
		var Dataset = dlData.Dataset;
		Dataset.DisableEvents();
		Dataset.Close();
		ApplyDatasetFilter(Dataset, 'NameByLike', edtEdit.Value, false);
		Dataset.Open();
		Dataset.EnableEvents();
	}
}

Спасибо за ответ.
У меня ругается на

ApplyDatasetFilter(Dataset, 'NameByLike', edtEdit.Value, true);

Если я ставлю фильтр 'Name' то все работает.
Где можно посмотреть список фильтров, может это поможет решить вопрос

Здравствуйте Владимир,

"Олейник Дмитрий" написал:где NameByLike - фильтр типа Like. (tbl_Account.Name содержит Parameter: NameByLike).

NameByLike в примере Дмитрия, это названия фильтра, который предварительно необходимо создать
1
Скорее всего у Вас он не создан

Фильтр NameByLike существет, но параметер у него "Name", хотя как я понимаю, это не важно, а ошибка все равно осталась.
Создавал свой фильтр и результат тот-же!

Спасибо Алимовой Анне помогла.
Реально важно чтоб имя параметра совпадало с именем фильтра

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

Всем добрый день, делаю первые шаги в написании отчетов. Раньше работал с проектом, где встроенный был FastReport 2.5 и использовались "родные" визуальные компоненты... поэтому вопросов куча, попробую поточнее сформулировать на примере.
Версия TS XRM 3.3.0.49, MS SQL Server 2008 R2 Express
Задача: визуализировать запрос, который выбирает небольшую статистику по сотрудникам из раздела задачи.
Пример Запроса, который я написал в MS SQL Management Stadio

SELECT c.ID, c.Name,
(SELECT COUNT(t1.ID) FROM dbo.tbl_Task AS t1 WHERE c.ID=t1.OwnerID
AND t1.TypeID = 'CED7CC70-81CB-4AB1-A9F2-521998B14723'/*Тип задачи - Звонок*/
AND   t1.StartDate >= '01.03.2011'
AND   t1.StartDate = '31.03.2011'
AND   t1.StatusID = 'F598ECDB-4EEF-4FA8-9E69-A36B053501E5'/*Выполнена*/
AND   t1.ProjectID IS NULL AND t1.OpportunityID IS NULL ) AS Q_TaskOfCall
FROM dbo.tbl_Contact AS c
WHERE   EXISTS(SELECT t.ID FROM dbo.tbl_Task AS t WHERE c.ID=t.OwnerID
AND   t.StartDate >= '01.03.2011'
AND   t.StartDate = '31.03.2011')
ORDER BY c.Name

Хотелось бы при вводе первоначальных данных иметь возможность задать
- Интервал дат для фильтра по дате начала задачи
- Сотрудника в т.ч. по нескольким из списка.
Сервисы типа sq_StatisticByTask и ds_StatisticByTask я сделал.
В сервисе sq_StatisticByTask я добавил два параметра "BDATE"- Начальная дата периода, Конечная дата периода "EDATE" с типом Дата/Время, для отладки поставил туда значения явно.
Подзапросы оформил в виде объекта "Колонка с текстом SQL"
(SELECT COUNT(t1.ID)
FROM dbo.tbl_Task AS t1
WHERE tbl_Contact.ID=t1.OwnerID
AND t1.TypeID = 'CED7CC70-81CB-4AB1-A9F2-521998B14723'/*Тип задачи - Звонок*/
AND   t1.StartDate >= :BDATE
AND   t1.StartDate = :EDATE
AND   t1.StatusID = 'F598ECDB-4EEF-4FA8-9E69-A36B053501E5'/*Выполнена*/
AND   t1.ProjectID IS NULL AND t1.OpportunityID IS NULL)

Судя по работе в предпросмотре, в подзапрос параметры передаются.
Начал делать сервис fr_StatisticByTask подключил датасет, хотел использовать стандартное окно фильтрации, НО в поля фильтра можно добавить только поля, которые явно заданы в датасете, или я ошибаюсь? Соответственно вопрос: можно ли передать из стандартного окна фильтрации даты, которых нет в запросе датасета явно? Или вариант писать только свое окно фильтрации?

Нравится

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

Посмотрите, пожалуйста, вот эту тему. Объяснения в ней помогут Вам понять где и как передавать параметры фильтрации.

Спасибо, за топик, я его уже читал раньше... а так же основательно порылся поиском, однако, проблемы остались.
Сделал собственное окно фильтрации предварительных данных.
Положил компоненты: два DateTimeControl'а для задания начала и конца периода отчета и LookUpControl для выбора списка сотрудников.
Пытаюсь наладить передачу параметров EADTE и BDATE в датасет отчета перед его открытием на событии OnClic кнопки ОК в собственном окне фильтрации, - пусто. Ставлю в запросе даты явно - отчет формируется, убираю- пусто. Эти же переменные я передаю в отчет, и они туда попадают благополучно и отображаются.

function btnOkOnClick(Control) {
	//TODO
var ReportPreviewer = Self.Attributes('ReportPreviewer');	
var ReportWork = Services.GetNewItemByUSI('fr_StatisticByTask');
//var ReportPrevWork = Services.GetNewItemByUSI('wnd_BaseFastReportPreview');
//-----------------------
//var ReportPreviewerComponent = ReportPrevWork.Attributes('ReportPreviewer');
//SetAttribute(ReportPrevWork, 'Report', ReportWork);
//-----------------------
var FromDate = DateEdit1.Value;
var ToDate   = DateEdit2.Value;
var ActsDS = Services.GetNewItemByUSI('ds_StatisticByTask');
var Param = ActsDS.SelectQuery.Parameters;
Param.ItemsByName('BDATE').Value = FromDate;
Param.ItemsByName('EDATE').Value = ToDate;
ActsDS.Open();
//SetAttribute(ReportWork, 'StartDate', DateEdit1.Value);
//SetAttribute(ReportWork, 'FinishDate', DateEdit2.Value);
//ReportPrevWork.Build();
//ReportPrevWork.Prepare();
ReportPreviewer.DatasetByComponentName('ds_StatisticByTask') = ActsDS;
ReportPreviewer.Report.Attributes('StartDate') = FromDate;
ReportPreviewer.Report.Attributes('FinishDate') = ToDate;
SendNotify(Self, MSG_OK);
}

Где я накосячил?

Руслан, вот фрагмент из скрипта окна фильтрации wnd_ReportOpportunitiesDateFilterScript. Этот фрагмент выполняется по нажатию на ОК.

    var Dataset = dlData.Dataset;
    var FromDate = Dataset.Values('From');
    var ToDate = Dataset.Values('To');
 
    var FromDateFilterEnabled = (FromDate != null);
    var ToDateFilterEnabled = (ToDate != null);
    var DatasetUSIList = ReportPreviewer.Report.Attributes('DatasetUSIList');
	for (var i = 0; i < DatasetUSIList.length; i++) {
	    var ReportDatasetUSI = DatasetUSIList[i];
	    var ReportDataset =	ReportPreviewer.DatasetByUSI(ReportDatasetUSI);
		ApplyDatasetFilter(ReportDataset, 'FromDate', FromDate,
			FromDateFilterEnabled);
		ApplyDatasetFilter(ReportDataset, 'ToDate', ToDate,
			ToDateFilterEnabled);
	}
	ReportPreviewer.Report.Attributes('FromDate') = FromDate;
	ReportPreviewer.Report.Attributes('ToDate') = ToDate;

Ваша ошибка, видимо, была в том, что Вы не фильтровали датасет отчета, а пытались его получить, отфильтровать и присвоить отчету. Нужно наоборот: получить ReportPreviewer.DatasetByUSI(...) и отфильтровать через ApplyDatasetFilter, предварительно считав параметры из окна фильтрации.

Ну совсем простенький текст :-), учитывая, что там еще функция, которая присваивает массив значениям кодов датасетов и т.д. А нельзя в базовой конфигурации, сделать пару вариантов отчетов - с окном фильтрации с датой, с lookUpControl multi&singl окном выбора предварительных параметров с подробно комментированным кодом? Это наверно аццкий труд коментровать свой код для двух отчетов? Или разместите руководство по созданию отчета с стандартным и собственным окном фильтрации... Я конечно понимаю, а типа бесплатно, так ройте пацаны рогами форум...НО тех поддержка то давно не бесплатна, и идет в "обязы" с любыми продуктами...

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

"Черных Руслан" написал:А нельзя в базовой конфигурации, сделать пару вариантов отчетов - с окном фильтрации с датой, с lookUpControl multi&singl окном выбора предварительных параметров с подробно комментированным кодом? Это наверно аццкий труд коментровать свой код для двух отчетов?

Совсем программисты разленились)) Кнопка С с контролом затыкана до дыр, наверное ? ;)

"Доленко Юрий" написал:Кнопка С с контролом затыкана до дыр, наверное ? ;)

Да, и пальцы стерты вместе с кнопками, и "отладчик" уже не запускается.... говорит - "хочу в отпуск"... ;-)

"Стоян Виталий" написал:Я готов объяснить по коду, если указанный фрагмент вызвал у Вас затруднения.

Спасибо за намек :-), я уже разобрался, проблема была действительно в том что я пытался не получить Датасет отчета, а присвоить ему другой датасет. Исправил и все заработало, сделал также и в своем окне LookUpControl с MultiSelect Window для выбора сотрудника(ов) в принципе все работает. Есть еще мелкие вопросы, если не разберусь спрошу.Как все отлажу - положу в этот топик свои труды может кому пригодяться :-)

Хорошо, обращайтесь.
Удачи Вам!

Продолжу этот топик, так как есть предистория. При запуске отчета с правами пользователя возникает ошибка:
Оригинальное сообщение об ошибке: Запрещено разрешение "SELECT" на объект "tbl_Task" базы данных "TSDistr", схемы "dbo"
Ошибка открытия источника данных "ds_StatisticByTask".
Запрос в датасете сутью тот, что я дал в первом сообщении топика, там есть обращение к таблице tbl_Task в подзапросе фильтра.
Я понимаю, что права на чтение на таблицу tbl_Task даны только администраторам БД(явно неназначены), соответственно выборку по идее надо делать из представления vw_Task, НО смотрю на отчет "Список задач", где в датасете тоже выбирается ТАБЛИЦА, а не ПРЕДСТАВЛЕНИЕ и этот отчет с теми же правами пользователя нормально формируется. Я облазил весь датасет, просмотрел и события датасета и скрипт и события отчета... нигде явно запрос не подменяется, почему тогда работает(там тоже в запросе датасета явное чтение из tbl_Task)?
И второй вопрос, если в принципе в системе постоянно подменяется выборка из таблицы на соответствующую выборку из представления, где можно пример посмотреть в отчетах?

Проблема с подзапросом, который выполняется, как SQL-текст.
Рекомендую переписать подзапрос с Custom SQL колонки на обычный подзапрос в администраторе. После этого ошибка должна устраниться.
Другой вариант -- на OnBeforeOpen датасета подменять в запросе на выборку таблицу на представление, например такой функцией:

function ReplaceTableOnViewInColumnSQLIfNeed(SelectQuery, ColumnName,TableName, ViewName) {
	//Example:
	//ReplaceTableOnViewInColumnSQLIfNeed(SelectQuery, 'CustomSQLColumn',/\[tbl_Document\] AS/gi, '[vw_Document] AS');
	//TableName = /\[tbl_Document\] AS/gi
	if (CurrentUser.IsAdmin||CurrentUser.IsSysAdmin) {
		return;
	}
	var Select;
	var Column;
	if (IsUndefined(ViewName)) {
		var ViewName = TableName.Replace(/tbl_/i,'vw_');
	}
	for (var i = 0; i < SelectQuery.Count; i++) {
		Select = SelectQuery.Items(i);
		Column = Select.Columns.ItemsByAlias(ColumnName);
		Column.SQLText = Column.SQLText.replace(TableName,ViewName);
	}
}

Спасибо, за верное направление...
1. Код

 if (IsUndefined(ViewName)) {
                 var ViewName = TableName.Replace(/tbl_/i,'vw_');
         }

не работает - Object doesn't support this property or method. В принципе логично Replace такого метода в jscript нет, есть replace. После замены результат тот же, я думаю, что - TableName это регулярное выражение, а не просто текст и видимо к нему на прямую не применяется метод replace. Как это обойти я не придумал. Поэтому остановился на явном вводе при вызове функции имени представления -ViewName.
2. Подстановка по аналогии с TableName = /\[tbl_Document\] AS/
gi
TableName = /\[tbl_Task\] AS/gi
не дала результата, ошибка о запрете чтения из таблицы tbl_Task возникала все равно. Столкнулся с еще одной проблемой - Профайлере я не как не мог увидеть запрос...это потому что фактически он не выполнялся? Т.е. профайлер отображает только успешно завершенные запросы, а вариант нарушения прав доступа там нельзя посмотреть в тексте запроса или это особенность при вызове предпросмотра Фаст Репорта? Честно не понял зачем такая сложная строка на поиск вхождения /\[tbl_Document\] AS/
gi заменил на /tbl_Task AS/gi и все поехало...

Руслан, если второй вариант не решает проблему (остается ошибка с правами), то попробуйте первый -- перепишите подзапрос с Custom SQL на стандартный подзапрос.

Да, в общем я разобрался, просто регулярное выражение упростил, посмотрел на переменную Column.SQLText вывел ее в лог, т.к. не смог добиться от профайлера этого запроса :-(, по этому поводу и был вопрос.

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

Добрый день, господа.
Понимаю, что похожая тема неоднократно поднималась, но, видимо, изменения в версиях требуют уточнений.
Моя версия: Terrasoft XRM 3.3.2.43.

Надо: в ходе выполнения бизнес-процесса передать параметр AccountID из одной задачи в другую.

Сделал:

  1. 1. В диаграмме БП создал строковый параметр диаграммы AccounID.
  2. 2. В описание wa_TaskAction добавил строковый параметр элемента AccountID.
  3. 3. В диаграмме БП связал у задач параметр AccountID с соответствующим параметром диаграммы, у первой задачи указав его модификатор как "Входящий\Исходящий".

В коде скрипта wa_TaskActionScript параметр AccountID, насколько я понял, всё-таки сериализуется, поэтому дописывать там ничего не стал.

В итоге: значение контрагента не передается :(

Подскажите, пожалуйста, в чем проблема или каков радиус кривизны рук?

Нравится

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

Сергей, Ваше замечание передано для анализа в департамент разработки продуктов.

Пока могу предложить обходное решение: в обработчике OnAfterExecute элемента БП написать код:

if (IsComplete) {
	WFSetParamValue(ActionItem.ParentItems.ParentDiagram, 'AccountID',
		ActionItem.Parameters('AccountID').Value);
}

Для работы данного решения достаточно только добавить в диаграмму параметр AccountID. Элемент "Задача" изменять нет необходимости.

Спасибо, Олег.

Сергей, добрый день.

Для решения проблемы попробуйте внести следующие изменения в функцию wa_TaskActionOnInitialize скрипта wa_TaskActionScript:

function wa_TaskActionOnInitialize(WorkflowAction, ActionItem) {
	WFConnectParams(ActionItem, 'AccountID', 'AccountID', pdtString, wpmitInOut);
	WFConnectParams(ActionItem, 'ContactID', 'ContactID', pdtString, wpmitInOut);
	/* MODULE OPPORTUNITIES */
	WFConnectParams(ActionItem, 'OpportunityID', 'OpportunityID', pdtString, wpmitInOut);
	/* ENDMODULE OPPORTUNITIES */
	WFConnectParams(ActionItem, 'ContractID', 'ContractID', pdtString, wpmitInOut);
	..............
	// аналогичные изменения для остальных параметров
}

Здравствуйте,
Мне нужна помощь, как построит такой процесс: проверить, является ли уже такой клиент в системе. Если нет - создать запись нового клиента, если да – уточнить информацию. Спасибо

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

Не стоит забывать о стандартном функционале, когда при создании нового контрагента и контакта идет проверка существования в системе таких сущностей по указанным в настройках полях (функционал проверки дублей в БД).

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

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

Подскажите, пожалуйста, как правильно реализовать такое действие при разработке отчета в разделе Операции:
дать возможность пользователю при открытии отчета заполнять данные об остатках по всем кассам, потом передать эти данные в отчет (основное "тело" отчета - это кросс-таблица в разрезе по кассам), и вывести результаты, которые равны "Итоги по каждой кассе + введенные остатки по кассам"

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

Нравится

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

Виктория, посмотрите на реализацию базовых отчётов, которые используют окно фильтрации, отличное от wnd_ReportFilters. Например, отчёт "Анализ конкурентов", который использует в качестве окна фильтрации wnd_ReportOpportunitiesDateFilter. По аналогии с этим отчётом, Вы можете создать собственное окно фильтрации, в обработчике btnOKOnClick которого запускать формирование отчёта, предварительно передав ему все необходимые параметры.

Значения из окна фильтрации отчёту можно передать, например, так:

	// получаем значения из датасета окна фильтрации
	var Dataset = dlData.Dataset;
	var FromDate = Dataset.Values('From');
	var ToDate = Dataset.Values('To');
 
	// включаем фильтры датасета (если необходимо)
	var ReportDatasetUSI = <USI датасета>;
	var ReportDataset =	ReportPreviewer.DatasetByUSI(ReportDatasetUSI);
	ApplyDatasetFilter(ReportDataset, 'FromDate', FromDate,
			FromDateFilterEnabled);
	ApplyDatasetFilter(ReportDataset, 'ToDate', ToDate,
			ToDateFilterEnabled);
 
	// передаём параметры в сервис отчёта
	ReportPreviewer.Report.Attributes('FromDate') = FromDate;
	ReportPreviewer.Report.Attributes('ToDate') = ToDate;

В форме отчёта к этим параметрам можно обратиться так: [FromDate]

Спасибо за ответ. Попробую так и сделать

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