Доброго времени суток.
AutoCAD 2009 SP3 x64 Enu
Атрибуту программно назначено следующее значение:
%<\AcExpr ((%<\AcObjProp.16.2 Object(%<\_ObjId 8796087905888>%,1).InsertionPoint \f "%lu2%pt2">%-%<\AcObjProp.16.2 Object(%<\_ObjId 8796087894560>%,1).InsertionPoint \f "%lu2%pt2">%)/1000) \f "%lu2%pr3%ds44">%
Это значение корректно работает: создаётся поле, отображающее нужное значение.
Как видим, в тексте присутствуют идентификаторы (точнее Handle) двух объектов. Программно требуется получить их. На данный момент, я выполняю это посредством Regex. Упрощённый (для наглядности) код выглядит так:
// Текстовое значение фильтра: "Object\(%<\\_ObjId ([0-9]{1,19})>%.* Object\(%<\\_ObjId ([0-9]{1,19})>%"
Match match = Regex.Match(attValue, ElevationLabelExtension.RegexFilter);
Group group = match.Groups[2];
Int64 anchorPtr = 0;
Int64.TryParse(group.Value, out anchorPtr);
Db.ObjectId anchorId = new Db.ObjectId(new IntPtr(anchorPtr));
Всё работает, однако мне бы хотелось получать идентификатор не при помощи Regex, но используя объекты класса Field. Правильно ли я понимаю, что всё, что содержит в себе текст, начинающийся с "%<\" и заканчивается ">%" трактуется как поле? Т.е. в приведённой выше строке текста полей содержится 5 шт.: AcExpr, AcObjProp.16.2, ObjId, AcObjProp.16.2, ObjId.
Ориентируясь на такую трактовку, я набросал следующий код:
...
// Рекурсивно ищу поля и вывожу на консоль информацию о них
if (attRef.HasFields) {
Db.ObjectId fieldId = attRef.GetField();
Db.Field field = tr.GetObject(fieldId, Db.OpenMode.ForRead) as Db.Field;
Db.Field[] fields = field.GetChildren();
PrintFields(ed, fields);
}
...
private static void PrintFields(Ed.Editor ed, Db.Field[] fields) {
foreach (Db.Field childField in fields) {
String code = childField.GetFieldCode(
Db.FieldCodeFlags.AddMarkers | Db.FieldCodeFlags.FieldCode);
String value = childField.GetStringValue();
ed.WriteMessage("Code: {0}\nValue: {1}\n",code, value);
if (childField.HasFields) PrintFields(ed, childField.GetChildren());
}
}
На консоль получаю такой результат:
Code: %<\AcExpr ((%<\AcObjProp.16.2 Object(%<\_ObjId 8796087905888>%,1).InsertionPoint \f "%lu2%pt2">%-%<\AcObjProp.16.2 Object(%<\_ObjId 8796087894560>%,1).InsertionPoint \f "%lu2%pt2">%)/1000) \f "%lu2%pr3%ds44">%
Value: 0,000
Т.е. видимо я неверно понимаю, сколько полей в моей строке и на самом деле там оно действительно одно? Если эту строку формировать в AutoCAD посредством дизайнера полей, то сначала я создаю выражение и затем в нём создаю два поля... Можно ли посредством Field получить значение идентификатора, как я это делаю при помощи Regex?
Спасибо.