Коллеги, всем доброго дня!

У нас есть справочник, абсолютно обычный, никакого кастома. Некий отдельный процесс наполняет данный справочник записями в соответствии с алгоритмом своей работы, порядка 2-3 тысяч записей. После обработки данных записей пользователи производят удаление стандартными методами: Действия - Выбрать все записи, затем Удалить. По истечению некоторого времени получаем ошибку вида: "Произошла ошибка. Пожалуйста, обратитесь к администратору". Скажите, возможно есть какие-то подводные камни у данного механизма удаления, что может стать причиной такого поведения, как можно диагностировать и устранить проблему? Справочник абсолютно линейный и простой, никакого кастомного кода в нем нет, логики на объекте справочника тоже нет.

Буду признателен за любые идеи в решении данного вопроса!

Нравится

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

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

- у пользователя под которым выполняется данная операция (удалить), нет соответствующих прав;  

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

Добрый день.

 

Часто такая ошибка возникает, когда происходит свал по тайм ауту.

 

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

 

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

Алла Савельева,

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

На тайм аут это действительно больше всего похоже. Но пока не знаем как выйти из положения, разве что написать кастомный сервис зачистки данного справочника. Удаление частями выход, но это крайне неудобно пользователям (как бить записи на группы, если их 3000, и помечать их к удалению)?

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

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

 

Если Вам в какой-то момент надо удалить из таблицы вообще все записи, быстро это можно сделать SQL-запросом truncate, который нужно будет вызвать из серверной логики. Если же по условию, то останется удалять по частям в цикле с паузами по таймеру, чтобы не сильно нагружать сервер.

 

Ещё длительное удаление может быть связано с логикой, которая добавлена во встроенном или отдельном БП на событии удаления для этого объекта.  В таком случае она отработает только при удалении средствами EntiteSchemaQuery (оно происходит и при удалении пользователем вручную). А при удалении средствами класса Delete она не вызывается: будет намного быстрее, но логика не отработает, что нужно будет учесть и реализовать нужные вычисления отдельно.

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

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

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

Итог. Теперь 4 детали с одинаковым именем зарегестрировано + выдают ошибку при заполнении детали и дальнейшем сохранении.

Как пофиксить?

Нравится

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

Сергей, здравствуйте!

Инструкцию по удалению детали Вы найдете на Академии: https://academy.terrasoft.ru/documents/sales-enterprise/7-11/chasto-zadavaemye-voprosy-po-masteru-razdelov

Ошибка, скриншот которой Вы предоставили, может возникать в том случае, если одно из полей, которое заполняется на детали, ссылается или на несуществующий справочник, или на удаленное значение справочника. Для более детального анализа проблем напишите нам на support@terrasoft.ru, и мы обязательно рассмотрим Ваше обращение.

Одеяненко Юлия,

Спасибо, со справочником, да, накосячил frown

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

Коллеги, подскажите.

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

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

Нужно именно убрать данную опцию, а не отключить права.

Нравится

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

как вариант заместить BasePageV2, код

define("BasePageV2", [],
	function() {
		return {
			messages: {},
			mixins: {},
			attributes: {},
			modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
			methods: {
				onLookupDataLoaded: function(config) {
					config.collection.each(function (item) {
						var key = item.get("value");
						config.objects[key] = item.model.attributes;
					}, this);
				}
			},
			diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
		};
	});

 

В своё время получили ответ, что убрать невозможно.
В итоге сделали в карточках (не в справочниках) хоть одно обязательное поле кроме главного. Тогда хотя бы не "по-тихому" создается новая запись, а пользователь осознанно и ответственно нажимает Save

Варфоломеев Данила пишет:
как вариант заместить BasePageV2, код

А это можно сделать для конкретных  lookup'ов?

Владимир Соколов пишет:
А это можно сделать для конкретных lookup'ов?

В config.columnName приходит название колонки, так что в теории - да.

Варфоломеев Данила,

 Большое спасибо, все получилось

 

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

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

Есть страница редактирования PageEdit1 в Package1, которая наследуется от базовой в некотором пакете, также есть PageEdit2 (наследник от PageEdit1) в Package2 и PageEdit3 (наследник от PageEdit2) в Package3.

Пакеты наследуются от верхнего к нижнему в такой последовательности: Package1 -> Package2 -> Package3.

Нужно удалить PageEdit2.

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

Нравится

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

Только удалить PageEdit2, и пересоздать PageEdit3, указав нового родителя.

А после этого нужно сгенерировать исходные схемы или скомпилировать все?

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

А вообще схемы лучше не удалять.

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

Добрый день, подскажите, пожалуйста, как можно реализовать sql запрос на удаление данных в элементе "Задание- сценарий" БП или же в схеме карточки:

DELETE FROM [dbo].[Lead] WHERE [Id] = 'c6deb935-c86e-44f6-9101-eec17473c1df'

В БП в сценарии таким способом не выходит подключить userConnection:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using Terrasoft.Common;
using Terrasoft.Core;
using Terrasoft.Core.DB;
using Terrasoft.Core.Entities;
var delete = new Delete(userConnection)
.From("Lead")
.Where("Id").IsEqual(Column.Parameter("{c6deb935-c86e-44f6-9101-eec17473c1df}"));
return true;

Нравится

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

Добрый день, Мария!

Вы можете получить экземпляр UserConnection следующим образом:

UserConnection UserConnection = Get("UserConnection");

Спасибо, теперь возникает ошибка:

The type arguments for method 'Terrasoft.Core.Process.ProcessModel.Get(string)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Если убрать галочку с "Для интерпретируемого процесса", то процесс выполняется успешно, но лид не удаляется, хотя напрямую sql запросом удаление происходит, в чем может быть проблема?

"Maria H" написал:пасибо, теперь возникает ошибка:

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

var userConnection = Get<UserConnection>("UserConnection");
Показать все комментарии

Добрый день!

Коллеги, подскажите, пожалуйста, какой наиболее корректный способ массово (в цикле) удалять записи в БД с помощью ESQ?

Вариант с foreach:

EntitySchema schemaDeleteEntity =userConnection.EntitySchemaManager.GetInstanceByName(EntityName);
EntitySchemaQuery esqDeleteEntity = new EntitySchemaQuery(schemaDeleteEntity);
esqDeleteEntity.AddAllSchemaColumns();
esqDeleteEntity.Filters.Add(esqDeleteEntity.CreateFilterWithParameters(FilterComparisonType.Equal, AccountIdField, AccountId));
EntityCollection entitiesDeleteEntity = esqDeleteEntity.GetEntityCollection(userConnection);
  foreach (Entity deleteentity in  entitiesDeleteEntity)
  {
      deleteentity.Delete();
  }

возвращает exception "Коллекция была изменена после создания экземпляра перечислителя."

Если заменить на простой for:

for(int i = entitiesDeleteEntity.Count-1;i>=0;i--)
{
        entitiesDeleteEntity[i].Delete();
}

Код отрабатывает корректно, но при нагрузке удаление периодически вызывает exception о незавршённых транзакциях вида:
Данный SqlTransaction завершен; его повторное использование невозможно.   в System.Data.SqlClient.SqlTransaction.ZombieCheck()
   в System.Data.SqlClient.SqlTransaction.Rollback()
   в Terrasoft.Core.DB.DBExecutor.RollbackTransaction()
   в Terrasoft.Core.Entities.Entity.ExecuteDelete(Delete delete, Object keyValue)
   в Terrasoft.Core.Entities.Entity.Delete(Object keyValue)
   в Terrasoft.Core.Entities.Entity.Delete()

Как всё-таки правильнее?

Спасибо!

Нравится

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

Добрый день!
Для массового удаления лучше не использовать EntitySchemaQuery, так как ESQ накладывает права на запрос. Лучше всего использовать либо класс Delete, или же использовать хранимую процедуру.
Единственный случай, когда нужно использовать ESQ - это если вам нужно запускать процессы, которые настроенны на сигнал "удаления записи", но и в этом случае лучше найти альтернативу по запуску доп логики после удаления

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

Добрый день! При создании проблем не случается. Но возникают проблемы при модифицировании или удаления. Подскажите, пожалуйста, как правильно удалять разделы в bpm'online? Ведь много записей в таблице создается и других связок.

Нравится

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

и про детали тоже интересно

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

Сами разделы/детали (их страницы редактирования, а также объекты, на которые они ссылаются) Вы можете удалить из конфигурации.
При этом в базе данных останутся записи. Необходимо удалить записи с таблиц:
SysModule
SysModuleEdit
SysModuleEditLcz

"Демьяник Алексей Олегович" написал:Необходимо удалить записи с таблиц:

Что же так не любят SQL-запрос предоставить? :)

"Владимир Соколов" написал:

Что же так не любят SQL-запрос предоставить? :)


А разгадка проста: разделы стараются не удалять. Максимум — скрыть в рабочих местах и удалить из раздела все записи.

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

А полностью скрывать детали от пользователей нужно с помощью прав доступа?

Спасибо за ответы

Мне нужно удалить пользовательский раздел в BPMOnline. Сервисов, связанных с ним нет, но раздел в списке присутствует. Я удалил запись из SysModule, но это не помогло. В таблицах SysModuleEdit,
SysModuleEditLcz информации по нему нет.

"Зверев Александр" написал:Максимум — скрыть в рабочих местах и удалить из раздела все записи.

Проблема в том, что "мусор" появляется в условиях фильтрации и только усложняет её.

"Владимир Соколов" написал:

Что же так не любят SQL-запрос предоставить? :)

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

declare @SectionObject varchar(50)
set @SectionObject = /*Название объекта раздела*/
delete from SysModule where SysModule.SysModuleEntityId in
(select SysModuleEntity.Id from SysModuleEntity
join SysSchema
on SysSchema.UID = SysModuleEntity.SysEntitySchemaUId
where SysSchema.Name = @SectionObject)

Для выполнения запроса нужно еще очистить связи.

"Тюльпа Владимир" написал:

Мне нужно удалить пользовательский раздел в BPMOnline. Сервисов, связанных с ним нет, но раздел в списке присутствует. Я удалил запись из SysModule, но это не помогло. В таблицах SysModuleEdit,
SysModuleEditLcz информации по нему нет.

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

"Тюльпа Владимир" написал:

Мне нужно удалить пользовательский раздел в BPMOnline. Сервисов, связанных с ним нет, но раздел в списке присутствует. Я удалил запись из SysModule, но это не помогло. В таблицах SysModuleEdit,
SysModuleEditLcz информации по нему нет.

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

Ниже инструкция по удалению типового раздела из системы:

Пусть «ToDelete» - название обьекта раздела

1. Выполнить скрипт в БД для удаления регистрационных данных:

DECLARE @UId UNIQUEIDENTIFIER;
DECLARE @ModuleEntityUID UNIQUEIDENTIFIER;
DECLARE @ModuleID UNIQUEIDENTIFIER;
DECLARE @Name NVARCHAR(max) = 'ToDelete';
select @UId = UId from SysSchema where Name Like @Name
select @ModuleEntityUID = Id from SysModuleEntity where SysEntitySchemaUId = @UId
select @ModuleID = Id from SysModule where SysModuleEntityId = @ModuleEntityUID;
delete from SysModuleInWorkplace where SysModuleId = @ModuleID;
delete from SysModule where Id = @ModuleID;
delete from SysModuleEdit where SysModuleEntityId = @ModuleEntityUID;
delete from SysModuleEntity where Id = @ModuleEntityUID;
delete from SysDetail where EntitySchemaUId = @UId;
delete from SysLookup where SysEntitySchemaUId = @UId;
delete from [Lookup] where SysEntitySchemaUId = @UId;

2. Через конфигурацию удалите схемы в следующем порядке:

Клентские схемы (раздела, редактирования, детали)
ToDeleteFile
ToDeleteInFolder
ToDeleteInTag
ToDeleteTag
ToDeleteFolder
ToDelete

Проще всего запустить профайлер и создать ещё один раздел, посмотреть, в какие таблицы идёт запись.

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

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

Я создавал новый раздел. Раздел создал и нажал "Сохранить" без создания страницы. Создать это раздел повторно нельзя - такой уже есть, продолжить работу с ним нельзя, он не появляется в списке. Удалить нельзя, в указанных таблицах он не упоминается.

Добрый день, Владимир!

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

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

Здравствуйте!
Я решил сделать в продажах деталь продукты по аналогии с разделом документы.
Для этого создал представление на основе таблицы "Продукты в продаже" чтобы имя подставлялось в зависимости от заполненного поля(продукт, произвольный продукт). Все работает, но при удалении продукта из детали, возникает ошибка: "Выбранные элементы удалить невозможно, так как они используются в других объектах.".
Так же в события Страницы реестра интересов к продуктам я добавил два событийных подпроцесса(по аналогии с продуктами в документах): OfferingChanged и DeleteYesMessage. Правда не понял откуда они вызываются и где их нужно регистрировать, чтобы они работали. Но они вроде как и нужны для того, чтобы удаление работало.
Подскажите, пожалуйста, что можно сделать, чтобы удаление работало?
Спасибо!

Нравится

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

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

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

Нет, там нету никаких внешних таблиц, которые ссылаются на удаляемую таблицу. Да и запись я только создаю и потом пытаюсь удалить сразу.

Добрый день, Павел!

В данном случае, для проведения анализа реализованного Вами функционала, прошу предоставить ссылку на бекап БД (в личном сообщении), или предоставить сеанс удаленного подключения к Вашему ПК.

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

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

Запрет на редактирование полей карточки редактирования, отвечающих за постановку задачи я реализовал (код ниже).

//В событии OnPrepare wnd_TaskEdit
if (dlData.Dataset.Values('AuthorID') != Connector.CurrentUser.ContactID && Connector.CurrentUser.IsAdmin == false) {
                fgMainData.IsEnabled = false;
                edtTitle.IsEnabled = false;
        } else {
                fgMainData.IsEnabled = true;
                edtTitle.IsEnabled = true;
        }

Теперь думаю о том, как запретить удаление задач не авторами. Была идея повешать return на событие нажатие кнопки удаления при условии, что текущий пользователь не является автором выделенной записи. Подскажите, как определить значение поля "AuthorID" для выделенной записи в разделе в скрипте wnd_TasksWorkspace. Быть может есть более правильный путь? Спасибо.

Нравится

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

Если идти по пути интерфейса - можно "отключить" кнопку "удалить" если автор не совпадает с текущим пользователем для выделенной записи. Только делать это надо в wnd_TasksGridArea. В скрипте scr_TasksGridArea поправить функцию InitializeControls().
AuthorID получить можно как BaseGridArea.GridDataset.Values('AuthorID')

"Карпенков Никита Олегович" написал:Быть может есть более правильный путь?

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

Т.е. выбрав в фильтре спраава группу "Менеджеры" и настроив для нее некие права, вы получите, что при создании записи пользователем, входящим в группу "Менеджеры" на запись добавятся права согласно сделанным настройкам + полные права на данного пользователя

Раздел должен быть "Администрируемым по записям" (см. мануал)

"Андросов Дмитрий" написал:да, есть, и находится он в разделе Администрирование - права доступа по-умолчанию.

Есть нюанс.
Ответственный всегда получит полные права на задачу (см скрипт ds_TaskScript в нем в SelfOnDatasetAfterPost() вызывается функция GiveRightsToRecordOwner()). Вот если поправить GiveRightsToRecordOwner() поставить там CanDelete = false то все будет хорошо :smile:

"Александр Кудряшов" написал:Ответственный всегда получит полные права на задачу

да, так давно отключил, что уже и не помню :wink:

"Андросов Дмитрий" написал:да, так давно отключил, что уже и не помню :wink:

Теплые ламповые скрипты 3.х :cool:

Александр Кудряшов, спасибо за подсказку, BaseGridArea.GridDataset.Values('AuthorID') - то, что нужно.
Андросов Дмитрий, про права доступа знаю и использую, но задачу поставили именно такую, как я написал. Через права доступа это реализовать нельзя.

"Карпенков Никита Олегович" написал:задачу поставили именно такую, как я написал. Через права доступа это реализовать нельзя.

Через права доступа реализуется вполне запрет на удаление... кнопка удалить блокируется если прав нет...
только старые записи обработать придется :)

"Карпенков Никита Олегович" написал:задачу поставили именно такую

иногда входящие надо корректировать, но вам виднее

"Александр Кудряшов" написал:только старые записи обработать придется

и это решаемо http://www.community.terrasoft.ru/blogs/9611

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

Здравствуйте! Использую стандартный delete query dq_FileInItem. Столкнулся с проблемой: под админом запрос на удаление выполняется нормально, под другим польз-ем выдает ошибку:
"The multi-part identifier "tbl_Files.ID" could not be bound". Посмотрел в профайлере, что за запрос уходит на сервер:
exec sp_executesql N'DELETE FROM [dbo].[vw_Files]
WHERE([tbl_Files].[ID] = @P1)',N'@P1 uniqueidentifier','803B0D68-1052-4E00-A3C4-A5374143FD25'

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

TS XRM 3.4.0.144

Нравится

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

Получается, что при выполнении dq не подставляется vw. Решил проблему использованием ds_Files.Delete(), через датасет запрос на удаление отрабатывает корректно!

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