Модуль Paragon САПР Aveva плохо дружит с русскими символами: наличие их в именах каталожных элементов может привести к неприятным ошибкам в работе системы. Самый простой способ предотвратить эти ошибки - запретить вводить русские буквы в атрибут NAME. Для этого был сделан небольшой сервис, который отслеживает изменения атрибута NAME текущего элемента и при появлении в нём русских букв возвращает предыдущее значение атрибута, при создании же нового элемента с русскими буквами в названии - удаляет его. Ниже код сервиса:
namespace SMFD_Paragon_DisallowRussianChars
{
public class RussianCharsService
{
#region Свойства
private DbElement elem;
private string oldElemName;
///<summary>
/// Регулярное выражение для поиска букв русского алфавита
///</summary>
private Regex regex;
private static RussianCharsService instance;
#endregion
#region Конструктор
///<summary>
/// Конструктор
///</summary>
private RussianCharsService()
{
this.regex = new Regex(@"[а-я]{1,}", RegexOptions.IgnoreCase | RegexOptions.Compiled);
}
#endregion
#region Методы
///<summary>
/// Проверяет и переименовывает подчинённые элементы
///</summary>
///<param name="dbEle">Элемент</param>
private void CheckMembers(DbElement dbEle)
{
foreach (DbElement mem in dbEle.Members())
{
string oldElemName = mem.GetString(DbAttributeInstance.NAME);
if (!oldElemName.StartsWith("=") && regex.Match(oldElemName).Success)
{
string newElemName = regex.Replace(oldElemName, string.Empty);
if (!string.IsNullOrEmpty(newElemName))
mem.SetAttribute(DbAttributeInstance.NAME, newElemName);
else
mem.SetAttribute(DbAttributeInstance.NAME, string.Empty);
this.CheckMembers(mem);
}
}
}
///<summary>
/// Удаляет дочерние элементы
///</summary>
///<param name="dbEle">Элемент</param>
private void DeleteChildren(DbElement dbEle)
{
foreach (DbElement ele in dbEle.Members())
{
this.DeleteChildren(ele);
if (!ele.IsDeleted)
ele.Delete();
}
}
#endregion
#region Общие свойства
///<summary>
/// Текущий элемент, за которым ведётся наблюдение
///</summary>
public DbElement Elem
{
get { return this.elem; }
set
{
if (this.elem != null && !this.elem.IsDeleted && !this.elem.Db.IsReadOnly && (this.elem.Db.Type == DbType.Catalog || this.elem.Db.Type == DbType.Property))
{
string newElemName = this.elem.GetString(DbAttributeInstance.NAME);
if (!newElemName.StartsWith("="))
{
if (regex.Match(newElemName).Success)
{
string message =
string.Format(
"Имя элемента не может содержать символы русского алфавита.{0}Атрибут NAME элемента будет изменён на предыдущее значение:{0} с\t{1}{0} на\t{2}",
Environment.NewLine,
newElemName,
string.IsNullOrEmpty(this.oldElemName) ? "значение по умолчанию" : this.oldElemName);
Forms.MessageBox.Show(
message,
"Ошибка: русские буквы в атрибуте NAME",
Forms.MessageBoxButtons.OK,
Forms.MessageBoxIcon.Error,
Forms.MessageBoxDefaultButton.Button1);
if (!this.oldElemName.StartsWith("="))
this.elem.SetAttribute(DbAttributeInstance.NAME, this.oldElemName);
else
this.elem.SetAttribute(DbAttributeInstance.NAME, string.Empty);
this.CheckMembers(this.elem);
CurrentElement.Element = this.elem;
}
}
}
this.elem = value;
this.oldElemName = this.elem.GetString(DbAttributeInstance.NAME);
if (!this.oldElemName.StartsWith("=") && regex.Match(this.oldElemName).Success && !this.elem.Db.IsReadOnly && (this.elem.Db.Type == DbType.Catalog || this.elem.Db.Type == DbType.Property))
{
// Проверяем был ли элемент создан или просто выбран в дереве элементов
bool isCreated;
elem.HasElementBeenCreatedSince(elem.Db.CurrentSession, out isCreated);
if (isCreated)
{
string message =
string.Format(
"Имя элемента не может содержать символы русского алфавита.{0}Элемент {1} не будет создан!",
Environment.NewLine,
this.oldElemName);
Forms.MessageBox.Show(
message,
"Ошибка: русские буквы в атрибуте NAME",
Forms.MessageBoxButtons.OK,
Forms.MessageBoxIcon.Error,
Forms.MessageBoxDefaultButton.Button1);
this.DeleteChildren(this.elem);
DbElement owner = this.elem.Owner;
this.elem.Delete();
CurrentElement.Element = owner;
}
else
{
string newElemName = regex.Replace(this.oldElemName, string.Empty);
string message =
string.Format(
"Имя элемента не может содержать символы русского алфавита.{0}Из атрибута NAME элемента будут убраны все русские буквы.{0}Атрибут NAME будет изменён:{0} с\t{1}{0} на\t{2}",
Environment.NewLine,
this.oldElemName,
string.IsNullOrEmpty(newElemName) ? "значение по умолчанию" : newElemName);
Forms.MessageBox.Show(
message,
"Ошибка: русские буквы в атрибуте NAME",
Forms.MessageBoxButtons.OK,
Forms.MessageBoxIcon.Error,
Forms.MessageBoxDefaultButton.Button1);
if (!string.IsNullOrEmpty(newElemName))
this.elem.SetAttribute(DbAttributeInstance.NAME, newElemName);
else
this.elem.SetAttribute(DbAttributeInstance.NAME, string.Empty);
this.CheckMembers(this.elem);
CurrentElement.Element = this.elem;
}
}
}
}
///<summary>
/// RussianCharsService Instance
///</summary>
public static RussianCharsService Instance
{
get
{
if (instance == null)
instance = new RussianCharsService();
return instance;
}
}
#endregion
}
}
Код модуля, подключающего сервис к парагону:
namespace SMFD_Paragon_DisallowRussianChars
{
public class Main : IAddin
{
public void Start(ServiceManager servMan)
{
if (servMan.ApplicationName == "Paragon") // подписываемся
CurrentElement.CurrentElementChanged += CurrentElement_CurrentElementChanged;
}
public void Stop()
{
if (ServiceManager.Instance.ApplicationName == "Paragon") // отписываемся
CurrentElement.CurrentElementChanged -= CurrentElement_CurrentElementChanged;
}
public string Description { get { return "Сервис запрещающий русские символы в именах элементов в модуле Paragon"; } }
public string Name { get { return "SMFD.Paragon.DisallowRussianChars addin"; } }
private void CurrentElement_CurrentElementChanged(object sender, CurrentElementChangedEventArgs e)
{
RussianCharsService.Instance.Elem = e.Element;
}
}
}
Чтобы Aveva подхватила модуль в файл ParagonAddins.xml, находящийся в папке с Aveva'ой, необходимо добавить строку:
<string>SMFD_Paragon_DisallowRussianChars</string>
Как это работает
1. Запускаем Paragon, становимся на какой-либо элемент
2. В атрибут NAME вписываем какие-либо русские буквы => выдаётся сообщение об ошибке, значение атрибута возвращается к предыдущему
3. При включённом Autoname при переименовании категории (к примеру), имена подчинённых элементов также приводятся в норму
Во вложении находится готовый проект.