Скрипты
Разработка

Некоторые основы написания скриптов в Terrasoft

Здравствуйте!
Совсем недавно начал изучать Terrasoft XRM 3.3.2.127 MS SQL, поэтому извините заранее за возможно «ламерские» вопросы. Что изучено и прочитано: TS_AG_3.3.2, TSCRM_SDK_3.0, раздел Разработчику на Terrasoft Community, просмотрены примеры реализации модуля Account и Contacts. То ли что то пропустил, а теперь не понимаю, то ли не там смотрю, но в описаниях нигде свои ответы явно не нашел.
Интересуют следующие:
1. Как осуществить доступ к полям какой либо таблицы из другого скрипта.
var Dataset = dlData.Dataset; ?

2. Передача параметров между функциями и скриптами. Если я правильно понял это или через глобальные переменные или через объект Connector?

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

3. Где можно найти описание Ваших функций из скриптов модуля Common/Library (назначение, параметры, формат, пример)

Так для примера. В Wizard создан новый раздел DocZakaz

Поля таблицы tbl_DocZakaz:

  • Code (тип строка)
  • ContactID (ссылка на справочник Contact)
  • DateZakaz (тип Дата/Время)

Нужно чтобы после нажатия на кнопку OK в окне редактирования раздела wnd_ DocZakazEdit автоматически открывалось окно создания нового проекта и автоматом заполнялись следующие поля:

  • Тип планирования(PlanningType ) сразу в 'Планировать в этом элементе'
  • Календарь (CalendarID) сразу в 'Базовый календарь'
  • Начало, план (EstimatedStartDate) = DateZakaz (из tbl_DocZakaz)

// wnd_ DocZakazEditScript

function btnOKOnClick(Control) {
    var Dataset = dlData.Dataset;
    var Value = Dataset.Values('Code');
    var ClientID=Dataset.Values('ContactID');
    var DateZakaz=Dataset.Values('DateZakaz');
    Connector.Attributes('IfZakaz')='true';
    Connector.Attributes('ZakazCode')=Value;
    Connector.Attributes('ZakazClientID')=ClientID;
    Connector.Attributes('ZakazDateZakaz')=DateZakaz;
        scr_BaseDBEdit.btnOKOnClick(Control);
        AddProjectRecord(Self, 'amiAddProject');
        Connector.Attributes('IfZakaz')='false';
}


// ds_ProjectScript

function ds_ProjectOnDatasetAfterAppend(Dataset) {
        var IsZakaz=Connector.Attributes('IfZakaz');
        if (IsZakaz=='true') {
            var Value=Connector.Attributes('ZakazCode');
            var ClientID=Connector.Attributes('ZakazClientID');  
            var DateZakaz=Connector.Attributes('ZakazDateZakaz');
            Dataset.Values('Name')=Value;
            Dataset.Values('CalendarID')='Базовый календарь';   //  вылетает ошибка OLE error 80020102
            Dataset.Values('PlanningType')='Планировать в этом элементе' ; // вылетает ошибка OLE error 80020102
            Dataset.Values('EstimatedStartDate')=DateZakaz;
            Dataset.Values('ContactID')=ClientID  // проходит        
        }
}

Что делаю не так?

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

Нравится

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

Для доступа к таблицам, как Вы уже наверное разобрались, предусмотрены три сервиса -- собственно, сервис таблицы tbl_*, сервис запроса на выборку sq_* и сервис набора данных ds_*.
Таблицы хранят данные, с помощью запросов на выборку эти данные выбираются (причем не только один к одному из таблицы, но и из других таблиц, с фильтрацией и подзапросами), а с помощью наборов данных они используются внутри системы. Для чтения/изменения данных нужно использовать сервисы датасетов (наборов данных).
Для доступа к определенному датасету нужно сначала его получить по заранее известному названию (например, получаем датасет контактов ds_Contact)

var Dataset = Services.GetNewItemByUSI('ds_Contact');

А потом уже можно использовать

if (!IsDatasetEmpty(Dataset)) {
    Dataset('Name') = 'Иванов И.И.';
}

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

Dataset('JobID') = '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}';

Как узнать нужный идентификатор? Сначала открываем датасет в администраторе, смотрим, из какого источника берутся данные для поля "Должность". В данном случае это ds_Job. Открываем последний, смотрим, из какого запроса на выборку берутся данные. В данном случае это sq_Job. Открываем его. На панели инструментов находим кнопку "Предпросмотр". Он и без того бывает полезным, но сейчас нас в нем интересует кнопка "Выполнить SQL". Внизу видим результаты выборки. По названию определяем нужный идентификатор.
Аналогично поступаем и в случае с перечислениями. Они описываются сервисами enm_* и также в датасете нужно посмотреть, из какого же перечисления для конкретного поля берется значение.

Что вы имеете в виду под описанием функций? Есть Terrasoft SDK. Есть Terrasoft Администратор, в котором можно открыть интересующий Вас скрипт из Common/Library и посмотреть, какие именно у функции параметры. Посмотреть, где используется данная функция можно, используя глобальный поиск (Инструменты - Grep search). В результатах поиска по конфигурации Вы сможете найти для себя множество примеров использования конкретной функции (как самого вызова, так и подготовки параметров).

Ваш пример можно реализовать немножко иначе. Открыть окно редактирования -- значит показать нужный сервис wnd_* с определенными параметрами. Создать новый проект -- значит получить датасет проектов, создать в нем новую запись и заполнить остальные параметры (это и будет "автоматом").
Например,

var ProjectDataset = Services.GetNewItemByUSI('ds_Project');
ProjectDataset.Append();
var NewID = Connector.GenGUID(); //генерируем новый уникальный идентификатор
ProjectDataset.ValAsGUID('ID') = NewID;
//пропиываем нужные параметры
ProjectDataset.Values('Name') = 'test_test';//Dataset('Code');   
ProjectDataset.Values('ParentProjectID') = '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'; //особенность проектов -- обязательно должно быть заполнено поле ParentProjectID
ProjectDataset('CalendarID') = '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'; //ID взять из sq_Calendar
ProjectDataset('PlanningType') = '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'; //ID взять из enm_ProjectPlanningType
ProjectDataset('EstimatedStartDate') = Dataset('DateZakaz');
ProjectDataset('ContactID') = Dataset('ContactID'); //проходит потому что в правой части ID
ProjectDataset.Post();
ProjectDataset.Close();
var Attributes = new ActiveXObject('Scripting.Dictionary');
Attributes.Add('RecordID', NewID);
ShowEditWindowEx('wnd_ProjectEdit', Attributes);

Стоян Виталий, Terrasoft Support Team

Виталий спасибо большое!! Вот это то, как раз чего я и не допонял.
Дополнение к примеру, если вдруг кому-то сгодится

function btnOKOnClick(Control) {
      var ZakazDataset = dlData.Dataset; // текущий Dataset
      var ProjectDataset = Services.GetNewItemByUSI('ds_Project');
      ProjectDataset.Append();
      var NewID = Connector.GenGUID(); //генерируем новый уникальный идентификатор
      ProjectDataset.ValAsGUID('ID') = NewID;
        //пропиываем нужные параметры
      ProjectDataset('Name') = ZakazDataset('Code');    
      ProjectDataset('ParentProjectID') = NewID; // обязательный, тот же что и ID
      ProjectDataset('EssenceType') = 'Project'; // 'Stage' - для стадий, 'Work' - для работ
      ProjectDataset('TypeID') = '{0304A9F6-CCC5-4C37-9843-FE9F05FE4389}'; // обязательный, тип выполнения, подробнее см. tbl_ProjectType
      ProjectDataset('StateID') = '{04009A52-FB1A-4CD8-8BB4-56977EF802F7}'; // обязательный, тип состояния, подробнее см. tbl_ProjectState
      ProjectDataset('CalendarID') = '{2534EA24-891E-45E4-9AA2-D53E4D4E4760}'; //ID взять из sq_Calendar
      ProjectDataset('PlanningType') = '{5D576142-CE74-4A8D-A4D6-BE52D5C8952E}'; //ID взять из enm_ProjectPlanningType
      ProjectDataset('EstimatedStartDate') = ZakazDataset('DateZakaz'); // дата начала
      ProjectDataset('EstimatedDueDate') =ZakazDataset('DateEnd') ; // дата окончания
      ProjectDataset('HasChilds') ='1'; // обязательный, если будут у проекта подчиненные стадии и работы
      ProjectDataset('ContactID') = ZakazDataset('ContactID'); //
      ProjectDataset('OwnerID') = ZakazDataset('CreatedByID') ; // оказывается тоже обязательный иначе вообще не отображается ни у кого, возможно его можно получить и по другому но почему то Connector.CurrentUser.ContactID дает null
      ProjectDataset.Post();
      ProjectDataset.Close();
 
      var Attributes = new ActiveXObject('Scripting.Dictionary');
      Attributes.Add('RecordID', NewID);
      ShowEditWindowEx('wnd_ProjectEdit', Attributes);
    scr_BaseDBEdit.btnOKOnClick(Control);
}	

Только вот еще вопрос.

  • Перед присваиванием, например ProjectDataset('EstimatedStartDate') = ZakazDataset('DateZakaz') нужно ли проверять, заполнен ли ZakazDataset('DateZakaz') чем нибудь, или пусто. В Delphi если переменной присваеваем не заполненое значение из таблицы он вывливается в ошибку Access... А в Terrasoft так можно делать, или надо проверять каждую переменную?

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

В Террасофте ошибка возникнет, если Вы пишете нулевое значение в поле ID, будет "несоответствие типа".
Проверку делать желательно. Есть функция IsEmptyValue скрипта scr_Utils.
Писать в идеальном случае лучше так:

if (!IsEmptyValue(ZakazDataset('DateZakaz'))) {
    ProjectDataset('EstimatedStartDate') = ZakazDataset('DateZakaz')
}

Ну и конечно перед этим нужно перевести датасет в режим редактирования ProjectDataset.Edit(), а потом подтвердить ProjectDataset.Post()

Стоян Виталий, Terrasoft Support Team

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