Добрый день!
TS CRM 3.4.0.190

Где взять информацию по поводу типов EditMaskKind в поле типа IEdit, чем они отличаются и что нужно писать в поле EditMask каждого типа, желательно полное описание?

Нравится

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

Здравствуйте! Очень нужна Ваша помощь!!! Проблема заключается в том, что в скрипте где-то допущена ошибка, но распознать ее я пока не могу. Ошибка при сохранении карты контрагента: Account.ModifiedCommunicationPosisitionArray.length. Параллельно с этим появляется ошибка в карте контакты при попытке ее сохранения. Помогите, пожалуйста, разобраться! Буду признательна за любую помощь!

Нравится

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

вот так выглядят ошибки в карточке

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

Вероятнее всего, параметр ModifiedCommunicationPosisitionArray не существует.

Но более точно сможет сказать отладка.

Необходимо:

1) Включить отладку скриптов в реестре Windows:
HKEY_CURRENT_USER\Software\Microsoft\Windows Script\Settings

Установить значение параметра JITDebug с 0 на 1.

2) Установить инструментарий для отладки:

либо Microsoft Script Debugger:
http://www.microsoft.com/en-us/download/details.aspx?id=22185
либо Microsoft Visual Studio Express 2012:
http://www.microsoft.com/ru-ru/download/details.aspx?id=34673

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

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

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

Анна,

предположительно проблема возникает в функции SelfOnDatasetAfterPost:

function SelfOnDatasetAfterPost(Dataset) {
GiveRightsToRecordOwner(Dataset);
if (Account.ModifiedCommunicatonPositionArray.length) {
ActualizeCommunicationEx(Dataset,
Account.ModifiedCommunicatonPositionArray, 'AccountID');
}
...
}

Необходимо проверить в отладчике, чему равно значение параметра:

function ds_AccountOnDatasetBeforePost(Dataset, DoPost) {
Account.ModifiedCommunicatonPositionArray =
GetModifiedCommunicatonPositionArray(Dataset, Account.CommunicationCount);
...
}

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

function SelfOnDatasetAfterPost(Dataset) {
/*if (Account.ModifiedCommunicatonPositionArray.length) {
ActualizeCommunicationEx(Dataset,
Account.ModifiedCommunicatonPositionArray, 'AccountID');*/
}
...
}

спасибо большое, проблему решила)))

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

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

Перехожу на версию 351 и теперь в гриде Продаж при клике в строке по например Клиенту переходим не к карточке редактирования (как в 332) Клиента, а открывается эта Продажа, её карточка.
Подскажите, как сделать, чтобы открывались Карточки (Клиент, Контакт и т.п.), если кликать по данным в столбцах?

Нравится

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

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

Вопрос закрыт.

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

Добрый день.
Есть у меня wnd_CallEdit
Я написал код который удаляет звонки определенного после закрытия wnd_CallEdit.
Подскажите как мне после закрытия окна обновить и wnd_CallGridArea. Чтобы удаленный звонок пропал из грида.

Нравится

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

Здравствуйте, Константин!

Попробуйте вот так:

var CallGridAreaDataset = Self.Attributes('NotifyObject').ComponentsByName('dlData').Dataset;
RefreshDataset(CallGridAreaDataset);

P.S. Проверьте, чтобы был подключен скрипт scr_DB, т.к. функция RefreshDataset описана там.

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

Не работает вызов System.MessageDialog в событие OnTimer на карточке wnd_IncidentsGridArea. Стек вызова:

Стек вызова
TSScriptUtils.TSScriptUtils.TScriptUtils.MessageDialog ()
TSScriptUtils.TSScriptUtils.TScriptUtils.MessageDialog ()
TSAutomationObject.TSAutomationObject.TAutomationObject.Invoke ()
TSScript.TSScript.TScript.ExecuteMethod ()
TSScriptableService.TSScriptableService.TScriptableService.ExecuteScriptMethod ()
TSWindow.TSWindow.TWindow.ExecuteScriptMethod ()
TSObjectEventsDispatcher.TSObjectEventsDispatcher.TObjectEventsDispatcher.AttemptToExecuteScriptMethod ()
TSObjectEventsDispatcher.TSObjectEventsDispatcher.TObjectEventsDispatcher.Invoke ()
TSConnectionPoints.TSConnectionPoints.TConnectionPointDispatcher.Invoke ()
Comobj.DispatchInvokeError ()
Comobj.DispatchInvokeError ()
TSTimer.TSTimer.TTimer.DoTimer ()
TSTimer.TSTimer.TTimer.OnTimer ()
JvTimer.JvTimer.TJvTimer.Timer ()
JvTimer.JvTimer.TJvTimer.DoTimer ()
Classes.TDataModule.WriteHeight ()

Вызывающий код:

function TimerOnTimer(Timer) {
System.MessageDialog("Не проставлены группы у новых инцидентов!", mdtInformation, mdbOK, 0);
}

Клиент: 3.4.0.141

Нравится

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

Здравствуйте, Михаил!

Проверил на последней версии исполняемых файлов, - ошибку не воспроизвел.

Попробуйте:

1) Очистить Cache приложения (%appdata%\Terrasoft\3.4.0\Cache)
2) Обновить исполняемые файлы до последней версии (3.4.0.190) и воспроизвести проблему повторно.

Получить обновленную сборку Вы можете по запросу в техническую поддержку (support@terrasoft.ru).

[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1215/b1/7f951477…]

Спасибо. Создал обращение. Пока протестировал еще и на 3.4.0.180, те же симптомы, окно сообщения создается из обычного события, но не создается из события тика.

Здравствуйте.
До 3.4.0.190 обновился, кэш чистил, ничего не помогло. Меня беспокоит, что с новым клиентом не поставляется обновления для сервисов, потому что если в дебаге посмотреть описание сервисов, то там стоит старая версия.

1) Обновлений для сервисов нет в 3.4.0.190?
2) System.MessageDialog вызывался из таймера? Можно выложить файл сервиса где был тест проведен? Ошибка уровня ядра, не проявляется если вызывать не из таймера.

Здравствуйте, Михаил.

Нет, обновления сервисов отсутствуют, я использую базовую конфигурацию версии 3.4.0.130 (продукт XRM Distribution + Service Desk) и бинарные файлы 3.4.0.190.

System.MessageDialog вызывался из таймера.

Прикладываю сервисы wnd_IncidentsGridArea и wnd_IncidentsGridAreaScript.

Дополнительно прикладываю скриншоты:

[URL=http://fastpic.ru/][IMG]http://i63.fastpic.ru/big/2014/1217/bd/4687bfd0…]
[URL=http://fastpic.ru/][IMG]http://i63.fastpic.ru/big/2014/1217/4f/164ba997…]

Спасибо, разобрался. Загруженные сервисы то же падают, но реже. Идут два сообщения подряд, скорей всего wnd_IncidentsGridArea используется в деталях тоже. Похоже с некоторой вероятностью одновременное асинхронное вызывание окна дает падение. После того как вынес код в wnd_Workspace, сообщение стало одно за тик и никогда не падает.

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

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

Подскажите, можно ли реализовать изменение списка доступных состояний инцидента в зависимости от его типа?
Например, в справочнике состояний есть состояния С1,С2,С3,С4. И типы Т1,Т2. Вот для типа Т1 должны быть доступны состояния С1, С2, С4. Для типа Т2 - С1, С3, С4.

Нравится

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

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

Безусловно, реализация возможна.

Подробный пример, правда, на основе других справочников, рассмотрен в статье по ссылке:
http://www.community.terrasoft.ua/blogs/6373

Андрей, спасибо. После прочтения остались подозрения, что в примере реализована связка "один к одному", т.е. определённому типу подставляется определённая категория, а не предлагается выбор перечня категорий, разрешенных для выбранного типа. Для проверки пробую реализовать, но, начиная с п.10 картинки не соответствуют тексту, и часть картинок не прогружается :-(

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

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

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

Сервис таблицы и поля "Тип инцидента" и "Состояние инцидента":

[URL=http://fastpic.ru/][IMG]http://i68.fastpic.ru/big/2014/1202/43/35c3bb57…]
[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/ec/ed496f64…]
[URL=http://fastpic.ru/][IMG]http://i65.fastpic.ru/big/2014/1202/86/a3c69797…]

Сервисы запроса и датасета:

[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/fd/cbfdae97…]
[URL=http://fastpic.ru/][IMG]http://i67.fastpic.ru/big/2014/1202/73/45088163…]

Если Вы хотите "красиво" связывать Тип и Состояние через клиентскую часть, Вам также потребуется создать сервис окна. Для примера можете посмотреть wnd_IncidentPriorityDictionary.

Но для примера "сделал и забыл" можно просто заинзертить записи через SQL:

insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values (
(select Id from tbl_IncidentStatus where NAme = 'C1'),(select Id from tbl_IncidentType where NAme = 'T1')
)
insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values (
(select Id from tbl_IncidentStatus where NAme = 'C2'),(select Id from tbl_IncidentType where NAme = 'T1')
)
insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values (
(select Id from tbl_IncidentStatus where NAme = 'C4'),(select Id from tbl_IncidentType where NAme = 'T1')
)
insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values (
(select Id from tbl_IncidentStatus where NAme = 'C1'),(select Id from tbl_IncidentType where NAme = 'T2')
)
insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values (
(select Id from tbl_IncidentStatus where NAme = 'C3'),(select Id from tbl_IncidentType where NAme = 'T2')
)
insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values (
(select Id from tbl_IncidentStatus where NAme = 'C4'),(select Id from tbl_IncidentType where NAme = 'T2')
)

В сервисе wnd_IncidentEditScript в функции DataChange(DataField) допишем код:

if (Name == 'IncidentTypeID') { // если изменяется поле "Тип", то...
	Dataset.Values('StatusID') = null; // очищаем значение Состояния
        edtStatus.UnprepareDropDownList(); //указываем полю карточки, что в следующий раз нужно зачитать список Состояний из БД, а не из кэша значений
// без данной операции получить в выпадающем списке требуемый набор значений будет невозможно
}

В сервисе запроса sq_IncidentStatus "заджойнить" созданную нами развязочную таблицу:

[URL=http://fastpic.ru/][IMG]http://i67.fastpic.ru/big/2014/1202/36/641fa651…]

Тут же создать параметр:

[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/34/7bedfa90…]

...и фильтр сравнения:

[URL=http://fastpic.ru/][IMG]http://i63.fastpic.ru/big/2014/1202/b6/c4ee3bca…]

В сервисе ds_Incident необходимо определить событие OnDatasetBeforeLookupDatasetOpen:

[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/8a/347fb16f…]

... и в его обработчике написать (привожу весь листинг функции):

function ds_IncidentOnDatasetBeforeLookupDatasetOpen(Dataset, LookupDataField, LookupDataset) {
        var Name = LookupDataField.Name; 
        if (Name == 'StatusID') {// если обрабатывается именно поле Состояние, то...
                var IncidentTypeID = Dataset.Values('IncidentTypeID'); //... считываем текущее значение Типа инцидента...
                ApplyDatasetFilter(LookupDataset, 'IncidentTypeID', IncidentTypeID, true); // ...и накладываем фильтр по типам инцидентов
        }
}

В функции wnd_IncidentEditOnPrepare(Window) в самом ее конце дописать:

edtStatus.UnprepareDropDownList(); 
/*Это действие при каждом открытии карточки Инцидента приведет к тому, что контрол, в котором отображается список Состояний, при появлении списка будет в любом случае считывать (отфильтрованные) данные из БД, а не старый (закешированный) список значений Состояний, которых сохранился после предыдущего открытия карточки инцидента. По умолчанию LookupDataControl, который отображает данные в виде выпадающего списка, считывает из БД и запоминает перечень показанных значений, и впоследствии использует для показа этот список без обращения в базу. Это очень удобно в случае статичных списков, но в Вашем случае этот механизм приходится отключать функцией контрола UnprepareDropDownList().*/

Проверим результат:

[URL=http://fastpic.ru/][IMG]http://i65.fastpic.ru/big/2014/1202/3a/7624ee5e…]
[URL=http://fastpic.ru/][IMG]http://i63.fastpic.ru/big/2014/1202/6b/f1028c06…]

Андрей, огромное спасибо за столь подробное описание. Сам я бы до этого долго шел. Получилось именно то, что хотелось!

Пришлось вернуться к вопросу.
Пропала возможность выбирать состояние инцидента в фильтрах. Падает сообщение "Исключен DataField 'Тип' isn't enabled". Думаю, что связано с этой доработкой. Где мог косякнуть?

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

В запросе sq_* нет фильтра, на который ссылается скрипт обработчика события. Наиболее частовозникает при отсутствии фильтра по ID.

Я понял: мы в sq_IncidentStatus прицепили линковочную таблицу и создали параметр для фильтра по IncidentTypeID. На том сейчас и падаем. Видимо, в карточке инцидента придётся использовать какой-то запрос-дублёр, аналог sq_IncidentStatus с проведённой ранее доработкой, а sq_IncidentStatus вернуть в исходное. Подскажите, в каком месте и каким образом производится подмена запроса для карточки?

Андрей, не совсем так. Найдите поле "Тип" (что-то вроде IncidentTypeID или TypeID) в sq_ и проставьте галочку "всегда выбирать в запросе".

Точно! В sq_incident сия галочка помогла. Спасибо!

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

Добрый день!

Есть ли обработчик наведения на заголовок грида?

ЗАДАЧА: нужно при наведении на заголовок (название колонки) грида отображать расширенное наименование названия.
ПРИМЕР: Наименование колонки "Ответственный", всплывающий текст при наведении "Сотрудник, который отвечает за заказы данного клиента" .

Спасибо.

Нравится

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

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

Какую версию клиента Террасофт Вы используете?

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

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

Какую версию клиента Террасофт Вы используете?

Сергей, добрый день!
Версия с билдом 3.4.1.171 (правда у большинства пользователей стоит билд 91 :sad: )

Добрый день, AleXS!

Начиная с версии 3.4.0.63 у большинства компонентов системы появилось свойство Hint. Но для колонки грида у меня не получилось его добавить. Я передал вопрос коллегам из департамента разработки, для того чтобы прояснить ситуацию с данным функционалом. По результатам сразу напишу.

"Резниченко Сергей" написал:По результатам сразу напишу.

Спасибо, Сергей! Очень жду...

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

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

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

Добрый день,
Проводим импорт в рабочую базу данных из Excel.
Для прописывания средств связи из карточки КА в закладку/деталь (для использования в рассылках) используем скрипт (прилагается).
Происходит дублирование уже имеющихся средств связи в закладке/детали КА.
Подскажите что и как дописать чтобы не допустить дубли - может поставить ограничение на дату создания записи?
Заранее спасибо.

declare @Communication1TypeID uniqueidentifier
declare @Communication2TypeID uniqueidentifier
declare @Communication3TypeID uniqueidentifier
declare @Communication4TypeID uniqueidentifier
declare @Communication5TypeID uniqueidentifier
declare @Communication1 nvarchar(250)
declare @Communication2 nvarchar(250)
declare @Communication3 nvarchar(250)
declare @Communication4 nvarchar(250)
declare @Communication5 nvarchar(250)
declare @AccountID uniqueidentifier

declare [Account_Cursor] cursor FOR
SELECT ID, Communication1TypeID, Communication2TypeID, Communication3TypeID,
Communication4TypeID, Communication5TypeID,
Communication1, Communication2, Communication3, Communication4, Communication5
FROM tbl_Account
open [Account_Cursor]

while (1 = 1)
begin
fetch next FROM [Account_Cursor]
INTO @AccountID, @Communication1TypeID, @Communication2TypeID, @Communication3TypeID,
@Communication4TypeID, @Communication5TypeID,
@Communication1, @Communication2, @Communication3, @Communication4, @Communication5
IF @@fetch_status = -1 break
IF @@fetch_status = -2 continue

IF NOT (@Communication1 IS NULL)
begin
INSERT INTO tbl_AccountCommunication
(AccountID, Number, CommunicationTypeID, Position)
VALUES (@AccountID, @Communication1, @Communication1TypeID, 1)
end
IF NOT (@Communication2 IS NULL)
begin
INSERT INTO tbl_AccountCommunication
(AccountID, Number, CommunicationTypeID, Position)
VALUES (@AccountID, @Communication2, @Communication2TypeID, 2)
end
IF NOT (@Communication3 IS NULL)
begin
INSERT INTO tbl_AccountCommunication
(AccountID, Number, CommunicationTypeID, Position)
VALUES (@AccountID, @Communication3, @Communication3TypeID, 3)
end
IF NOT (@Communication4 IS NULL)
begin
INSERT INTO tbl_AccountCommunication
(AccountID, Number, CommunicationTypeID, Position)
VALUES (@AccountID, @Communication4, @Communication4TypeID, 4)
end
IF NOT (@Communication5 IS NULL)
begin
INSERT INTO tbl_AccountCommunication
(AccountID, Number, CommunicationTypeID, Position)
VALUES (@AccountID, @Communication5, @Communication5TypeID, 5)
end
end
close [Account_Cursor]
deallocate [Account_Cursor]

Нравится

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

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

Попробуйте добавить условия:

IF NOT (@Communication1 IS NULL) and

(@Communication1 not in (select Number from tbl_AccountCommunication where AccountID = @AccountID))

begin
INSERT INTO tbl_AccountCommunication
(AccountID, Number, CommunicationTypeID, Position)
VALUES (@AccountID, @Communication1, @Communication1TypeID, 1)
end

Добрый день, Андрей,
Спасибо большое. Все получилось!

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

При добавлении Складского документа (Накладной) в нижней части во вкладке Доступ создаются определенные Группы и Пользователи - автор (a.ivanov,Ответственный) созданного Складского документа (скриншот).
При изменении Ответственного (b.petrov) в этом документе в Доступе появляется этот Пользователь (b.petrov).
При ещё раз изменении Ответственного в этом документе в Доступе появится этот новый Пользователь, но при этом предыдущий Ответственный (b.petrov) останется и может видеть данный документ.

Возникло два вопроса:
1. Как при добавлении в Доступ Пользователя (при смене Ответственного), который находится в определенной группе (к примеру Менеджеры) права этого Пользователя были только Чтение. Сейчас видно, что у a.ivanov права Чтение, Удаление и Изменение доступа.
2. Как при смене Ответственного удалять предыдущего Ответственного (но только, если он находится в группе Менеджеры). А то получается Ответственный поменялся, но предыдущий ответственный может видеть данный складской документ.

Нравится

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

Добрый день!

Раздача прав доступа ответственному записи происходит на событии AfterPost в скрипте датасета.
За это отвечает функция GiveRightsToRecordOwner скрипта scr_Access, которая используется во всех разделах.

В ней прописана раздача прав на чтение и запись для нового ответственного:

	var CanRead = true;
	var CanWrite = true;
	var CanDelete = false;
	var CanChangeAccess = false;

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

Идентификатор предыдущего ответственного записывается в атрибут InitOwnerID датасета в функции InitRecordOwnerData скрипта scr_Access. Используя его, Вы можете реализовать его удаление с таблицы tbl_[таблица]Right также на событии AfterPost датасета.

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

Добрый день!

Подскажите, пожалуйста, можно ли в Bug report сменить support@tscrm.com на внутренний ящик?

Нравится

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

Любите читать логи об ошибках, Александр? :wink:

scr_MailUtils - function SupportSendMail() но это может быть не совсем то, что нужно

"Александр Кудряшов" написал:

Любите читать логи об ошибках, Александр? :wink:

scr_MailUtils - function SupportSendMail() но это может быть не совсем то, что нужно


Александр, увы это не то!

Сменить не сможете, реализовано на уровне ядра.

AlexLS, можете попробовать следующее:

1) В папке Terrasoft\Settings найти и открыть файл ProductSettings.xml:

[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1108/8d/9ce0669f…]

2) В нем найти строчку SupportMail и для свойства DefaultCaption изменить адрес на желаемый:

[URL=http://fastpic.ru/][IMG]http://i67.fastpic.ru/big/2014/1108/eb/199ed46d…]

3) Проверка (сделаем что-нибудь плохое):

[URL=http://fastpic.ru/][IMG]http://i64.fastpic.ru/big/2014/1108/f1/625d7f55…]

[URL=http://fastpic.ru/][IMG]http://i68.fastpic.ru/big/2014/1108/6a/1b3c4c54…]

Интересно, а я не нашла :sad: и была уверена что в ядре.
Андрей, спасибо.

Вот я же помнил, что где-то в настройках, но не нашел беглым просмотром конфигов :)

"Безродный Андрей" написал:AlexLS, можете попробовать следующее:

1) В папке Terrasoft\Settings найти и открыть файл ProductSettings.xml:

Огромное спасибо, Андрей!

"Александр Кудряшов" написал:не нашел беглым просмотром конфигов :)

Спасибо, Александр! Думаю теперь мы будем и без беглого просмотра про это знать! :smile:

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