Добрый день
Подскажите, пожалуйста, как лучше сделать логику заполнения поля в карточке КЕ:
нужно, чтобы поле содержало строго 10 символов (или цифр?), при заполнении этого поля должна быть проверка на уникальность (значения этого поля не должны повторяться).
Примеры заполнения поля: 0000000001, 0000000002, ..., 0000000011, ....
Заранее спасибо
Нравится
Здравствуйте, Татьяна!
С примером настройки автонумерации в 5.x вы можете ознакомиться в этом посте - ссылка.
Проверку можно сделать на нажатии ОК в карточке. Как здесь, только без вопроса.
В MSDN описана работа со строками в C#, смотрите там.
Решила сделать сист.настройку "Текущий номер КЕ" (числовое, не кешируется. Наименование - KELastNumber), без маски номера.
В дизайнере процессов Конф.единица делаю:
Сохранила, опубликовала без ошибок.
При создании новой КЕ - в поле ITNumber (в котором и должен подставляться текущий номер) вообще нет никаких значений. В чем моя ошибка, подскажите, пожалуйста.
// не поняла, должна ли в схеме "Сгенерировать номер по порядку" указываться моя новая системная настройка KELastNumber и где именно указывается связь этой настройки с полем ITNumber в карточке КЕ
Татьяна, смотрите, как сделано в других разделах и делайте всё аналогично.
Если не хотите аналогично, изучайте схему «Сгенерировать номер по порядку», переделывайте её по-своему.
По стандартной логике, название системных настроек должно быть совпадающим с названием схемы плюс «LastNumber» и «CodeMask» соответственно.
Я хочу воспользоваться станд.логикой, смотрю, как сделано в других разделах. Изменила название своей новой сист.настройки ConfigurationItemLastNumber (чтобы соответствовала станд.логике), добавила сист.настройку маска номера КЕ (ConfigurationItemCodeMask). Все равно не работает, ничего в поле ITNumber в карточке КЕ не записывает. Подскажите, пожалуйста, на что еще обратить внимание?
Да, попробуйте очистить Redis и профиль.
Если после этого функциональность не заработает, следовательно ошибка в реализации и её следует искать в программном коде. В таком случае, нужно будет отладиться.
Такую функциональность вообще можно реализовать на уровне СУБД.
1. В bpm'online создайте системную настройку, в которой будет храниться номер последней созданной записи.
2. Потом на уровне СУБД реализовать триггер, который будет срабатывать на добавление новой записи. В этом триггере нужно считывать номер из системной настройки, вычислять значение нового номера = номер из системной настройки + 1, устаналивать его в нужное поле в таблицу и обновлять значение системной настройки новым номером.
Татьяна, чтобы сделать проверку на уникальность, можете на нажатии OK в обработчике сделать запуск Select, который ищет в разделе записи с таким же значением. И если находит таковых больше нуля, показывать пользователю сообщение. А если таких нет — запускать базовую логику кнопки OK, которая проведёт сохранение и закрытие карточки.
Правильно понимаю?:
var select = new Select(userConnection)
.Column("%Имя колонки Инвент.номер%")
.From(%раздел КЕ%)
.Where(Column.Const("%Имя колонки Инвент.номер%")).IsEqual(%Введенный Инвент.Номер%);
А IsEqual(%Введенный Инвент.Номер%) - здесь что имеется в виду?
Нет, неправильно. В Const передавать значение, а не название поля.
Татьяна, класс Select — это представление обычных SQL-запросов. Напишите сначала запрос в СУБД, убедитесь, что он работает правильно и возвращает что нужно, и тогда переписывайте на C#.
// выбираю все записи в КЕ, где значение колонки ITNumber равно конкретному значению, выбранному не из справочника.
// На обработчике нажатии ОК в карточке КЕ:
var text = Page.ITNumberEdit.Value;
var select = new Select(userConnection)
.Column(Column.Asterisk())
.From("ConfigurationsItem")
.Where(Column.Const("text")).IsEqual("ITNumber");
// дальше нужно сравнивать, найдено или нет такое же значение?
Не забудьте также, что при редактировании записи (а не созании новой) в базе уже будет запись с таким кодом. То есть в запросе нужно отбросить запись с Id как у записи, открытой в карточке.
И кавычки вокруг text лишние.
Татьяна, напишите сначала SQL-запрос, который удовлетворяет нужную потребность, затем переведите на C#. Поскольку проверяется только факт наличия или отсутствия, лучше вытягивать не все колонки, а только Id.
Затем делаете чтение из Select и если в нём было хотя бы значение, то одно, если нет — то другое.
using (var dbExecutor = UserConnection.EnsureDBConnection()) { using (IDataReader dr = select.ExecuteReader(dbExecutor)) { if (dr.Read()) { //do something } else { //do something else } } }
Посмотрите многочисленные примеры в конфигурации, там Select используется часто.
Татьяна, ну возьмите базу и проверьте.
"Зверев Александр" написал:Не забудьте также, что при редактировании записи (а не созании новой) в базе уже будет запись с таким кодом. То есть в запросе нужно отбросить запись с Id как у записи, открытой в карточке.
Татьяна, почитайте текст сообщения. Оно требует подключения нужного using (пространства имён).
Они подключаются в дереве элементов БП. Какого именно — можно помотреть в аналогичных случаях других карточек, где есть работа с классом Select.
Using в дереве справа в редакторе процессов БП. Откройте любой другой аналогичный процесс и посмотрите, что подключать.
В таком случае рекомендую найти другой процесс, в котором используется Select, и посмотреть, какие подключены там и как всё сделано на уровне кода. Возможно, допущена где-то опечатка.
Либо не добавлено нужное Using, либо добавлено ненужное, либо опечатки в коде.
Раз везде работает, а тут нет, значит, не то же самое.
Попробуйте сравнить существующий код с новым, скопировать из существующего.
Документация по работе с Select.
Не знаю, может у Вас там в названии «ExecuteReader» нелатинские буквы оказались?
В таком случае попробуйте написанный вами код в другом месте и код из другого места — в этом.
Нужно понять, дело в коде или в Using.
Написала на обработчике нажатия ОК, после чего откомпилировалось без проблем:
var recordId = new Guid(Page.GetParameterValue("recordId").ToString());
var text = Page.ITNumberEdit.Value;
/*var select = SELECT ("recordId")
.FROM ("ConfigurationsItem")
.WHERE (("ITNumber" = text)&&("Id" != recordId));*/
var select = new Terrasoft.Core.DB.Select(context.UserConnection)
.Column(Column.Asterisk())
.From("ConfigurationsItem")
.Where(Column.Const(text)).IsEqual("ITNumber") as Terrasoft.Core.DB.Select;
using (var DBExecutor = UserConnection.EnsureDBConnection())
{
using (var reader = select.ExecuteReader(DBExecutor))
{
if (reader.Read())
{
//do something
Page.BaseMessagePanel.AddMessage(Warning, "Внутр.инвент.номер (ИТ) должен быть уникальным! ", MessageType.Warning);
return false;
}
else
IsServicesClosing = false;
var configurationItem = Page.DataSource.ActiveRow as Terrasoft.Configuration.ConfigurationItem;
if (configurationItem == null || configurationItem.StatusId == configurationItem.GetTypedOldColumnValue("StatusId")) {
return true;
}
if (!SetWrittenOffOnEditEnabled()) {
var entitySchemaManager = Page.Schema.SchemaManagerProvider.GetManager("EntitySchemaManager") as EntitySchemaManager;
var schema = entitySchemaManager.GetInstanceByName("ServiceInConfigurationItem");
var entitySchemaQuery = new EntitySchemaQuery(entitySchemaManager, schema.Name);
var idColumn = entitySchemaQuery.AddColumn(schema.PrimaryColumn.Name);
entitySchemaQuery.Filters.Add(entitySchemaQuery.CreateFilterWithParameters(
FilterComparisonType.Equal, "ConfigurationItem", configurationItem.Id));
var collection = entitySchemaQuery.GetEntityCollection(UserConnection);
IsServicesClosing = collection.Count > 0;
}
}}
return true;
Но если изменили поле ITNumber в карточке КЕ и хотим сохранить карточку, то система выдает ошибку:
Это значит, что у Вас в конфигурации нет объекта «ConfigurationsItem».
Да, спасибо, все сработало. Но эта логика работает при создании новой карточки КЕ, а если берем уже существующую, то ее ИД нужно убрать из выборки.
var recordId = new Guid(Page.GetParameterValue("recordId").ToString());
Подскажите, пожалуйста, как это учесть в Select ?