Добрый день!

Есть желание увеличить быстродействие системы. Выполняю запрос по поиску полей таблиц к которым существует много запросов, но на них нет индексов. И одна из таблиц выпадает AccountCommunication [Средства связи Юр. лиц]. Сам объект унаследовал структуру от объекта [Базовое средство связи]. Так вот получается, что в базовом объекте нет индексов на основные поля для поиска, такие как Id,[Position]. Есть какая-то причина отсутствия индексов на этих полях или их можно создать?

Нравится

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

И как все-таки будет правильно, добавить индекс на базовый объект или в тот который унаследовал? Или при добавление в унаследованный объект в базовый он добавится автоматически?

Анастасия, с точки зрения БД родительский и дочерний объекты — это 2 разных таблицы. Следовательно, средствами Management Studio можно добавлять в дочернюю таблицу индексы, если в ходе анализа выяснилось, что это может увеличить производительность.
Сомневаюсь, что на Id стоит добавлять индекс, ведь это и так первичный ключ. А на второе — можно попробовать.

"Зверев Александр" написал:

Анастасия, с точки зрения БД родительский и дочерний объекты — это 2 разных таблицы. Следовательно, средствами Management Studio можно добавлять в дочернюю таблицу индексы, если в ходе анализа выяснилось, что это может увеличить производительность.

Сомневаюсь, что на Id стоит добавлять индекс, ведь это и так первичный ключ. А на второе — можно попробовать.


Вот и мне не понятно... Индекс уникальный некластеризованый в БД на Id стоит, а приложение показывает, чтот у этого объкта на этом поле нет индекса.

Смотрите на уровне БД, там вернее. Колонка Id в любой таблице bpm'online — первичный ключ. Возможно, поэтому её явно и не показывает как индекс.

"Астапеева Анастасия" написал:Есть желание увеличить быстродействие системы.

Желание или необходимость? :smile:

"Астапеева Анастасия" написал:Так вот получается, что в базовом объекте нет индексов на основные поля для поиска, такие как Id,[Position].

не думаю что поле Position - подходящая кандидатура для построения индекса (если я правильно понимаю, это порядковый номер в рамках 1 контрагента?)... кардинальность большая. Индексы хорошо строить по колонкам с практически уникальными значениями (опять же, если СУБД потом будет их использовать).

По-идее индекса по Id и AccountID должно быть вполне достаточно.

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

В общем, есть впечатление что не тут копаете, Анастасия... Могу посоветовать книгу, правда на английском... но может и русские версии уже есть: SQL Server 2008 Query Performance Tuning Distilled (2009)
версия СУБД может и немного старовата, но для CRM систем более чем сгодится.

"komgbu" написал:

Желание или необходимость? :smile:

В общем, есть впечатление что не тут копаете, Анастасия... Могу посоветовать книгу, правда на английском... но может и русские версии уже есть: SQL Server 2008 Query Performance Tuning Distilled (2009)

версия СУБД может и немного старовата, но для CRM систем более чем сгодится.

Именно желание. Спасибо большое за книгу и совет.

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

Добрый день.
Подскажите как при добавлении Дополнение к договору сделать автозаполнение поля Договор(справочник)(необходимо подставить договор)?
Добавил скриншот(договор 999007 )

Нравится

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

Можно на PageLoadComplete карточки проверять, если IsNew или IsCopy, то заполнять поле.
Или же настроить в свойствах детали в «Рабочих местах» ещё одну связь типа «Значение по умолчанию» с нужным полем.

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

Добрый день

Подскажите, как на С# написать условие:
если текстовое поле не заполнено, то...

Нравится

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

Работает:

if (Page.ChangeRequestEdit.Value != null) //&&(Page.IncidentEdit.Value == null))
{
Page.BaseMessagePanel.AddMessage(Warning, "Выберите номер Обращения, связанного с указанным ЗИ", MessageType.Warning);
return false;

}
else
{
return true;
}

А вот так не работает (опубликовывает без ошибок, но карточка без проблем закрывается):

if ((Page.ChangeRequestEdit.Value != null)&&(Page.IncidentEdit.Value == null))
{
Page.BaseMessagePanel.AddMessage(Warning, "Выберите номер Обращения, связанного с указанным ЗИ", MessageType.Warning);
return false;

}
else
{
return true;
}

Подскажите, в чем ошибка? Мне нужно проверить условие если поле Запрос на изменение заполнен, а поле Инцидент не заполнен, то выводится сообщение об ошибке...

Нет, не правильное условие. У меня поле - это поле справочника, а не текстовое. Подскажите, как на С# написать условие: если поле справочника не заполнено?

Там может быть не только null, но и Guid.Empty.
То есть, для каждого поля проверять так:

if (Page.AccountEdit.Value == null || new Guid(Page.AccountEdit.Value.ToString()) == Guid.Empty) {

Или так:

if (Page.CityEdit.Value == null || Page.CityEdit.Value.Equals(Guid.Empty)) {

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

спасибо, разобралась.

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

Добрый день

Подскажите, как сделать следующее:

Если поле ЗИ.Активность заполнено, то можно было бы выбрать номер того Обращения , который подвязан к этому Запросу на Изменение (ЗИ).

Нравится

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

Откомпилировалось без ошибок, но по-прежнему при определенном номере ЗИ выдает полный список номеров Обращений.

Page.IncidentEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
if (!Page.ChangeRequestEdit.Value.Equals(Guid.Empty)) {
var filters = e.Filters;
filters.Add(new Dictionary {
{"comparisonType", FilterComparisonType.Equal},
{"leftExpressionColumnPath", "ChangeRequest.Id"},
{"useDisplayValue", false},
{"rightExpressionParameterValues", new object[] {(Guid)Page.ChangeRequestEdit.Value}}});

}
};

- это нужно в ChildInitAfterParentScript, правильно?

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

на лукап я захожу, но не фильтрует...

так тоже опубликовывает, но не фильтрует:
Page.IncidentEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
if (!Page.ChangeRequestEdit.Value.Equals(Guid.Empty)) {
var filters = e.Filters;
filters.Add(new Dictionary {
{"comparisonType", FilterComparisonType.Equal},
{"leftExpressionColumnPath", "[ServiceRequestInChangeRequest:Incident].ChangeRequest.Id"},
{"useDisplayValue", false},
{"rightExpressionParameterValues", new object[] {(Guid)Page.ChangeRequestEdit.Value}}});

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

Если поле Активность.ЗИ заполнено, в поле Активность.Инцидент нужно поставить фильтр, чтобы при нажатии на лупу выводило список всех номеров Инцидентов, у которых поле Инцидент.ЗИ равен Активность.ЗИ.

Есть связь м/д объектами Запрос на изменение и Инцидент и запрос на обслуживание: ChangeRequestInServiceRequest.

Пишу в ChildInitAfterParentScript на странице карточки задачи:
Page.IncidentEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
var changerequestId = (Guid)Page.ChangeRequestEdit.Value;
if (changerequestId !=Guid.Empty) {
Collection> filters = e.Filters;
filters.Add(new Dictionary {
{"comparisonType", FilterComparisonType.Equal},
{"leftExpressionColumnPath", "[ChangeRequestInServiceRequest:ServiceRequest].ChangeRequest.Id"},
{"useDisplayValue", false},
{"rightExpressionParameterValues", new object[] {(Guid)Page.ChangeRequestEdit.Value}}});

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

Татьяна, попробуйте запустить профайлер и посмотрите, что за запросы идут.
Неужели так сложно сделать наложение фильтра?
См. также обсуждение тут и другие обсуждения по фильтрам.

не соображу, какое именно наложение фильтра сделать нужно.

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

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

Если Вы написали код и он не работает — то либо фильтр не накладывается, либо накладывается, но не тот. Вы можете запустить профайлер и посмотреть, какой уходит запрос, затем его запустить в Management Studio и посмотреть, пускает ли фильтр то, что нужно и если нет, то почему.

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

Добрый день.

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

Нравится

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

Добрый день
Подскажите, пожалуйста, как создать кнопку "Переслать" в реестре активностей, которая стояла бы на одному ряду с кнопками Добавить, Копировать,Изменить,Удалить ?

Нравится

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

И чтобы при нажатии на эту кнопку появлялась новая е-мейл-активность

И чтобы при нажатии на эту кнопку появлялась новая е-мейл-активность

Как создать кнопку "Переслать" в реестре активностей - это я сделала. Подскажите, как при нажатии на эту кнопку сделать так, чтобы появлялась новая е-мейл-активность с параметрами "старой" ?

Добрый день.
Создала кнопку "Переслать" непосредственно на странице карточки e-mail, обработчик:

все опубликовалось без ошибок. Но при нажатии на кнопку "Переслать" новое окно е-мейл активности не создается. Подскажите, почему?

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

var defValuesId = Guid.NewGuid();
var defValues = new Dictionary ();
defValues.Add("Contact", Page.ContactEdit.Value.ToString());
defValues.Add("Account", Page.AccountEdit.Value.ToString());
defValues.Add("CopyRecepient", Page.CopyRecepientEdit.Value.ToString());
defValues.Add("Recepient", Page.SenderEdit.Value.ToString());
defValues.Add("Body", Page.BodyEdit.Value.ToString());

var ActivityId = Guid.NewGuid();

UserConnection.SessionData[defValuesId.ToString()] = defValues;
var parameters =
new Dictionary {
{"createWithUId", ActivityId.ToString()},
{"entitySchemaUId", "C449D832-A4CC-4B01-B9D5-8A12C42A9F89"},
{"defValuesId", defValuesId.ToString()}
};
OpenTaskEditPage.OpenerInstanceId = InstanceUId;
OpenTaskEditPage.UseCurrentActivePage = true;

OpenTaskEditPage.PageUId = new Guid("dcdda065-321b-4560-aacb-05f6cc72cd80");
OpenTaskEditPage.PageParameters = parameters ;
return true;

Возможно, дело в формате объекта defValues.
Обычно он такого типа:

var defValues = new Dictionary <string, object>();
defValues["SysAdminUnitType"] = SysAdminUnitTypeId;

Записывается не строка, а значение типа Guid.

Если же дело не в этом, попробуйте провести отладку и посмотреть, как отрабатывает OpenPageUserTask.

я за основу брала : http://www.community.terrasoft.ru/forum/topic/9208
мне же не нужно создавать инцидент, генерировать номер для активности не нужно. Достаточно ли будет сигнала нажатия на кнопку "Переслать" и скрипта по открытию окна е-мейл активности?

пишу в этом скрипте:
var defValuesId = Guid.NewGuid();
var defValues = new Dictionary ();

defValues.Add("Contact", Page.ContactEdit.Value.ToString());
defValues.Add("Account", Page.AccountEdit.Value.ToString());
defValues.Add("CopyRecepient", Page.CopyRecepientEdit.Value.ToString());
defValues.Add("Recepient", Page.SenderEdit.Value.ToString());
defValues.Add("Body", Page.BodyEdit.Value.ToString());

var ActivityId = Guid.NewGuid();

UserConnection.SessionData[defValuesId.ToString()] = defValues;
var parameters =
new Dictionary {
{"createWithUId", ActivityId.ToString()},
{"entitySchemaUId", "c449d832-a4cc-4b01-b9d5-8a12c42a9f89"},
{"defValuesId", defValuesId.ToString()}
};
OpenTaskEditPage.OpenerInstanceId = InstanceUId;
OpenTaskEditPage.UseCurrentActivePage = true;

OpenTaskEditPage.PageUId = new Guid("dcdda065-321b-4560-aacb-05f6cc72cd80");
OpenTaskEditPage.PageParameters = parameters ;

return true;

Опубликовывает без ошибок, но рез-та нет: при нажатии на кнопку "переслать" ничего не происходит.

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

"TatianaM" написал:

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

var defValuesId = Guid.NewGuid();

var defValues = new Dictionary ();

defValues.Add("Contact", Page.ContactEdit.Value.ToString());

defValues.Add("Account", Page.AccountEdit.Value.ToString());

defValues.Add("CopyRecepient", Page.CopyRecepientEdit.Value.ToString());

defValues.Add("Recepient", Page.SenderEdit.Value.ToString());

defValues.Add("Body", Page.BodyEdit.Value.ToString());

var ActivityId = Guid.NewGuid();

UserConnection.SessionData[defValuesId.ToString()] = defValues;

var parameters =

new Dictionary {

{"createWithUId", ActivityId.ToString()},

{"entitySchemaUId", "C449D832-A4CC-4B01-B9D5-8A12C42A9F89"},

{"defValuesId", defValuesId.ToString()}

};

OpenTaskEditPage.OpenerInstanceId = InstanceUId;

OpenTaskEditPage.UseCurrentActivePage = true;

OpenTaskEditPage.PageUId = new Guid("dcdda065-321b-4560-aacb-05f6cc72cd80");

OpenTaskEditPage.PageParameters = parameters ;

return true;

Ваш объект называется OpenTaskEditPage1 а в скрипте OpenTaskEditPage

невнимательность... огромное спасибо.

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

Да, можно.

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

а в каком месте? и какого поля значение?

Это зависит от того, что Вы хотите запрограммировать.

"TatianaM" написал:

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

Попробуйте после скрипта открытия 2й страницы добавить вторую ветку процесса(с помощью элемента "И")
и послать завершающий сигнал( с передачей в родительский процесс) нажатие кнопки Cancel (точно не помню как называется, вроде, CancelButtonClick) или OK

А, так требуется карточку активности закрыть? Думал, что речь о состоянии «Закрыта». Если карточку, то действительно нужно в старой активности после открытия карточки новой вызвать код, как на кнопке закрытия:

(Page.AspPage as Terrasoft.UI.WebControls.Page).Close();

Или же смотрите рекомендации автора предыдущего сообщения.

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

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

"Зверев Александр" написал:Или же смотрите рекомендации автора предыдущего сообщения.

Сделала по рекомендации, но при нажатии на ОК в новой активности появляется ошибка, и окно активности не закрывается:

Предупреждение
The INSERT statement conflicted with the FOREIGN KEY constraint "FKInijGB83hrW19KtJno3hZK8". The conflict occurred in database "bptest", table "dbo.ChangeRequest", column 'Id'.
The statement has been terminated.

Такое сообщение говорит о том, что Вы неправильно заполнили в сохраняемой записи поле «Запрос на изменение». Смотрите рекомендации другого автора предыдущего сообщения:

"Мария Ватулина" написал:

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

"Зверев Александр" написал:Такое сообщение говорит о том, что Вы неправильно заполнили в сохраняемой записи поле «Запрос на изменение»

сама разобралась...

пишу:
defValues.Add("Incident",Page.IncidentEdit.Value.ToString());

но если поле Incident в "старой" е-мейл активности не заполнено, то при нажатии на ОК система выдает ошибку о том, что неправильно заполнили в сохраняемой записи поле "Инцидент".

Тогда делаю проверку на заполнение:
if (Page.IncidentEdit.Value != null)
{defValues.Add("Incident",Page.IncidentEdit.Value.ToString());}
else
{ defValues.Add("Incident","");} - то опубликовывает без ошибок, но не срабатывает при проверке, опять выдает ошибку о неправильно заполненном в сохраняемой записи поле "Инцидент".

Это потому, что Вы непонятно зачем работаете с полем «Инцидент» как с текстовым. А оно справочное. Если в копируемой записи поле не заполнено, то вообще нет смысла из него копировать.

нет, мне нужно его копировать, потому что поле "инцидент" может быть как заполнено, так и не заполнено.
пишу проверку так:

if (new Guid (Page.IncidentEdit.Value.ToString()) != Guid.Empty)
{defValues.Add("Incident",Page.IncidentEdit.Value.ToString());}
else {defValues.Add("Incident","");}

опубликовывает без ошибок, но при открытии новой е-мейл активности система выдает:
Exception Message: Нераспознанный формат идентификатора GUID.

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

понятно, получилось так:

if (new Guid (Page.IncidentEdit.Value.ToString()) != Guid.Empty)
{defValues.Add("Incident",Page.IncidentEdit.Value.ToString());}

"Зверев Александр" написал:Если карточку, то действительно нужно в старой активности после открытия карточки новой вызвать код, как на кнопке закрытия:
(Page.AspPage as Terrasoft.UI.WebControls.Page).Close();

а как написать, что нужно именно старую активность закрывать?

Код должен выполняться в той карточке, которую надо потом закрыть.

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

Коллеги, прошу помочь.
задача: необходимо очистить измененные сервисы, чтобы они локально обновились без полной очистки профиля.

версия 5 сервис деск

Был применен скрипт:
delete from "SysProfileData"
where "ObjectId" =(select distinct "SysSchemaId" from "SysSchemaInSolution"
where "Name" = 'Название схемы');
commit;

где значение Name - название схем, а именно:
BaseApprovalGridPage
ApprovalInServiceRequestGridPage.

Например, для очистки, профилей пользователей страницы
BaseApprovalGridPage. Скрипт будет иметь вид:

delete from "SysProfileData"
where "ObjectId" =(select distinct "SysSchemaId" from "SysSchemaInSolution"
where "Name" = 'BaseApprovalGridPage');
commit;
"
Данный скрипт не удаляет настроек колонок

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

Нравится

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

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

SELECT TOP 1000 [Id]
      ,(select max([Name]) from [SysSchemaInSolution] where [SysSchemaId]  = [ObjectId])
      ,[ModifiedOn]
      ,[CreatedOn]
      ,[CreatedById]
      ,[ModifiedById]
      ,[SysUserId]
      ,[ObjectId]
      ,[Key]
      ,[ObjectData]
      ,[ObjectDifference]
  FROM [SysProfileData]
  order by [ModifiedOn] desc

Если меняем настройки колонок в нескольких разделах, появляются изменённые записи, все связанные со схемой MainPage, но с разным значением поля Key.
Попробуйте поменять настройки средствами пользователя и посмотреть, какие записи при этом обновятся.

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

Здравствуйте.
Использую для раздела несколько карточек, в зависимости от типа. Добавила в рабочих местах новую деталь. Возможно ли отображать эту деталь не во всех карточках этого раздела, а только одного типа? И как это сделать?

Нравится

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

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

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

Алексей, добрый день.
Подскажите каким образом?

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

Антонина, текущая логика формирования списка деталей в карточке реализована в BaseModuleEditPage, где на Init вызывается специальное действие InitializeDetails.Насколько понимаю, текущая их реализация вообще не проверяет Id открываемой записи (и, соответственно, тип) и в момент Init, скорее всего, это значение ещё неизвестно. Возможно, стоит уже на PageLoadComplete проверить тип и в зависимости от этого скрыть те или иные вкладки, задав им свойство Hidden, но такие доработки ранее не встречались, нужно экспериментировать.

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

Доброго времени суток.
Воникла проблема с BPMonline Service Desk. Заходя во вкладку Инструменты - Администрирование - Пользователи портала, система выдает сообщение ошибки:

В работе приложения BPMonline возникла ошибка.
Exception Message: Невозможно получить экземпляр схемы типа "Terrasoft.Configuration.SysSSPUserQSchema"
Exception Type: Terrasoft.Common.NullOrEmptyException
Exception Source: Terrasoft.Core

Нравится

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

Стандартно в конфигурации нет схемы с названием «SysSSPUserQSchema». Возможно это какая-то доработка?
Что пишет в полном тексте сообщения?
Какая у Вас используется версия системы?

Exception Stack Trace:
   at Terrasoft.Core.SchemaManager`1.InitializeSchema(ISchemaManagerItem schemaManagerItem, Assembly assembly)
   at Terrasoft.Core.SchemaManagerItem`1.get_Instance()
   at Terrasoft.Core.Manager`2.GetInstanceByUId(Guid uid)
   at Terrasoft.UI.WebControls.Controls.EntityDataSource.get_Schema()
   at Terrasoft.UI.WebControls.Controls.DataSourceStructure.TryAddColumnByMetaPath(String schemaColumnMetaPath)
   at Terrasoft.WebApp.PortalUsersGridPageSchema.UpdateDataSource()
   at Terrasoft.WebApp.BaseGridPageSchema.InitializeControls()
   at Terrasoft.WebApp.PortalUsersGridPageSchema.InitializeControls()
   at Terrasoft.UI.WebControls.PageSchema.get_TopLevelControl()
   at Terrasoft.UI.WebControls.PageSchema.InitializeLocalizableValues(String resourceManagerName, String resourceGroupName)
   at Terrasoft.Core.SchemaManager`1.InitializeSchema(ISchemaManagerItem schemaManagerItem, Assembly assembly)
   at Terrasoft.Core.SchemaManagerItem`1.get_Instance()
   at Terrasoft.Core.Manager`2.GetInstanceByUId(Guid uid)
   at Terrasoft.UI.WebControls.Controls.PageContainer.LoadFromAssembly()
   at Terrasoft.UI.WebControls.Controls.PageContainer.LoadUserControl()
   at Terrasoft.UI.WebControls.Controls.PageContainer.OnInit(EventArgs e)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.AddedControl(Control control, Int32 index)
   at Terrasoft.UI.WebControls.PageControl.AddedControl(Control control, Int32 index)
   at Terrasoft.UI.WebControls.Controls.Container.AfterItemAdd(Component item)
   at Terrasoft.UI.WebControls.Utilities.ItemsCollection`1.Add(T item)
   at Terrasoft.UI.WebControls.Controls.PageContainer.LoadFromAssembly()
   at Terrasoft.UI.WebControls.Controls.PageContainer.LoadUserControl()
   at Terrasoft.UI.WebControls.Controls.PageContainer.OnInit(EventArgs e)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.AddedControl(Control control, Int32 index)
   at Terrasoft.UI.WebControls.PageControl.AddedControl(Control control, Int32 index)
   at Terrasoft.UI.WebControls.Controls.Container.AfterItemInsert(Int32 position, Component item)
   at Terrasoft.UI.WebControls.Utilities.ItemsCollection`1.Insert(Int32 index, T item)
   at Terrasoft.WebApp.MainPageEventsProcessSchema`1.InitScriptTaskExecute(ProcessExecutingContext context)
   at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)
   at Terrasoft.WebApp.MainPageEventsProcessSchema`1.ProcessQueue(ProcessExecutingContext context)
   at Terrasoft.WebApp.MainPageEventsProcessSchema`1.OnExecuted(Object sender, ProcessActivityAfterEventArgs e)
   at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)
   at Terrasoft.WebApp.MainPageEventsProcessSchema`1.ProcessQueue(ProcessExecutingContext context)
   at Terrasoft.WebApp.MainPageEventsProcessSchema`1.ThrowEvent(ProcessExecutingContext context, String message)
   at Terrasoft.UI.WebControls.PageSchemaUserControl.ThrowEvent(String message)
   at Terrasoft.UI.WebControls.Controls.PageContainer.LoadFromAssembly()
   at Terrasoft.UI.WebControls.Controls.PageContainer.LoadUserControl()
   at Terrasoft.UI.WebControls.Controls.PageContainer.OnInit(EventArgs e)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Application Version: 5.4.0.1315

А у Вас в разделе «Конфигурация» есть схема, называющаяся «SysSSPUserQSchema» или «SysSSPUserQ»?
Судя по коду, логика системы обращается к схеме по имени и не находит. Возможно, она не перенесена в корневую конфигурацию из другой или на основной сервер с сервера разработки.
Или где-то в коде портальной страницы допущена опечатка, вместо «SysSSPUser» написали «SysSSPUserQ».

При попытке открыть метаданные SysSSPUserQ выдало ошибку. (см. скриншоты)

Exception Message: Невозможно получить экземпляр схемы типа "Terrasoft.Configuration.SysSSPUserQSchema"
Exception Type: Terrasoft.Common.NullOrEmptyException
Exception Source: Terrasoft.Core
 
Exception Stack Trace:
   at Terrasoft.Core.SchemaManager`1.InitializeSchema(ISchemaManagerItem schemaManagerItem, Assembly assembly)
   at Terrasoft.Core.SchemaManagerItem`1.get_Instance()
   at Terrasoft.Core.Manager`2.GetInstanceByUId(Guid uid)
   at Terrasoft.Core.SchemaManager`1.GetReadableSchemaMetaData(Guid schemaUId, UserConnection userConnection)
   at Terrasoft.WebApp.SolutionExplorerModule.OnViewMetaDataMenuItemClick(Object sender, AjaxEventArgs e)
   at Terrasoft.UI.WebControls.Controls.ScriptManager.RaisePostBackEvent(String eventArgument)
   at Terrasoft.UI.WebControls.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 
Form:
	submitAjaxEventConfig: {&quot;config&quot;:{&quot;viewStateMode&quot;:&quot;include&quot;,&quot;extraParams&quot;:{&quot;tag&quot;:&quot;&quot;}}}
	__EVENTTARGET: ScriptManager
	__EVENTARGUMENT: ViewMetaDataMenuItem|event|Click
	__VIEWSTATEFIELDCOUNT: 13
	__VIEWSTATE0: /wEPGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYWBQ1TY3JpcHRNYW5hZ2VyBRlTeXNTY2hlbWFGb2xkZXJEYXRhU291cmNlBRNTeXNTY2hlbWFEYXRhU291cmNlBQlNYWluUGFuZWwFCUxlZnRQYW5lbAUPQWN0aW9uc1RhYlBhbmVsBQdGb.....................

Возможно, стандартную схему «SysSSPUser» кто-то пытался доработать и переименовать и сломал.
Посмотрите у неё значения «Изменено» и «Изменил».
Можно накатить схему, взятую с тестового (или наоборот, основного) сайта.
Ещё можно удалить самую свежую запись в таблице SysSchemaInSolution, где SysSchemaId равно Id этой схемы. Это вернёт предыдущую версию.

Exception Message: Элемент коллекции с идентификатором "{2BCBE4B8-FD0E-4CC6-A979-93574A377150}" не найден
Exception Type: Terrasoft.Common.ItemNotFoundException
Exception Source: Terrasoft.Core

Часто бывает и такое.

Это означает что не найден элемент с определенным идентификатором. Как пример, удалили поле в объекте, затем его добавили, но ранее уже была выполнена привязка к полю.

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

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

Я создал новый стандартный раздел(3 объекта и 3 страницы) в котором отображаю выборку данных из БД. Задаю фильтр и у меня выбираются определенные данные. Но когда я делаю двойной клик по этим данным, мне открывается новая вкладка с ошибкой. Возможно ли отключить открытие новой вкладки(возможно разрешить только чтение)? И как это сделать? Спасибо...

Нравится

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

Чтобы на странице реестра отключить обработку двойного клика, достаточно в БП страницы в функции GetRegisterTreeGridDblClickScript заменить содержимое на:

return string.Empty;

"Зверев Александр" написал:

Чтобы на странице реестра отключить обработку двойного клика, достаточно в БП страницы в функции GetRegisterTreeGridDblClickScript заменить содержимое на:

return string.Empty;


Александр огромное спасибо, за столь быстрый, точный и доступный ответ!

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