Здравствуйте!
Совсем недавно начал изучать 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)
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 // проходит
}
}
Что делаю не так?
Заранее спасибо!
Нравится
Для доступа к таблицам, как Вы уже наверное разобрались, предусмотрены три сервиса -- собственно, сервис таблицы 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