- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello everyone,
I would like to ask a question in the .NET forum of Autodesk, as I am facing difficulties with API programming. Specifically, I need help with a block named "DYN-LEVEL", which contains several attributes. One of the attributes, defined as "LEVEL", is linked to a field (FIELD).
Purpose of the Block:
This block is intended to display elevation values in construction drawings. The elevation value depends on the insertion point of the block and is read from the Y-value of the 3D point using a field formula.
The elevation is prefixed depending on its value:
- If the elevation is exactly **0**, the prefix `%%p` is used to show the symbol `+/-`.
- For **positive** values, a `+` sign is added.
- For **negative** values, no prefix is necessary, as the minus sign automatically appears.
The defined method is automatically triggered by the AutoCAD event ObjectModified.
Question:
My issue is that the field does not appear in the originally defined position within the block after the update. What errors could be causing this, or what additional steps are necessary to ensure the field displays in the correct position?
Thank you in advance for your support!
Block Definition:
Block with correct Attribut Position after inserting:
Block with wrong Attribut location after update:
/// <summary>
/// Updates the attribute field of a block reference based on its name and tag.
/// </summary>
/// <param name="blockId">The ObjectId of the block reference.</param>
/// <param name="blockName">The name of the block to match.</param>
/// <param name="tag">The tag of the attribute to update.</param>
public static void UpdateAttributeField(ObjectId blockId, string blockName, string tag)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
if (tr.GetObject(blockId, OpenMode.ForRead) is not BlockReference blockRef)
return;
BlockTableRecord blockDef = (BlockTableRecord)tr.GetObject(blockRef.DynamicBlockTableRecord, OpenMode.ForRead);
string blockDefName = blockDef?.IsDynamicBlock == true ? blockDef.Name : blockRef.Name;
if (!blockDefName.Contains(blockName, StringComparison.OrdinalIgnoreCase))
{
ed.WriteMessage($"Block name not found: {blockName}");
return;
}
foreach (ObjectId attId in blockRef.AttributeCollection)
{
if (tr.GetObject(attId, OpenMode.ForWrite) is not AttributeReference attRef || attRef.Tag != tag)
continue;
if (attRef.HasFields)
{
Field field = tr.GetObject(attRef.GetField(), OpenMode.ForWrite) as Field;
if (field == null)
{
ed.WriteMessage($"Field could not be updated for tag: {tag}");
continue;
}
string currentFieldCode = field.GetFieldCode(FieldCodeFlags.AddMarkers | FieldCodeFlags.FieldCode);
string prefix = GetPrefixForYPosition(blockRef.Position.Y);
string newFieldCode = prefix + ExtractFieldFormula(currentFieldCode);
Field replaceField = new Field(newFieldCode);
replaceField.Evaluate();
if (replaceField.EvaluationStatus.Status == FieldEvaluationStatus.Success)
{
attRef.SetField(replaceField);
tr.AddNewlyCreatedDBObject(replaceField, true);
}
else
{
ed.WriteMessage($"Field evaluation failed. Status: {replaceField.EvaluationStatus.Status}, Message: {replaceField.EvaluationStatus.ErrorMessage}");
}
}
// SOLUTION:
attRef.AdjustAlignment(db);
}
tr.Commit();
}
}
catch (Exception ex)
{
ed.WriteMessage("An error occurred: " + ex.Message);
}
}
/// <summary>
/// Determines the prefix for the field code based on the Y-coordinate of the insertion point.
/// </summary>
/// <param name="yPosition">The Y-coordinate of the insertion point.</param>
/// <returns>The prefix for the field code.</returns>
public static string GetPrefixForYPosition(double yPosition)
{
return yPosition > 0 ? "+" : yPosition < 0 ? "" : "%%p";
}
/// <summary>
/// Extracts the field formula from the input string by removing specific prefixes.
/// </summary>
/// <param name="input">The input string containing the field code.</param>
/// <returns>The cleaned field formula.</returns>
public static string ExtractFieldFormula(string input)
{
if (string.IsNullOrEmpty(input))
return input;
var prefixRegex = new Regex(@"^[+\-]|^%%p", RegexOptions.Compiled);
input = prefixRegex.Replace(input, string.Empty, 1);
int startIdx = input.IndexOf("%<\\AcExpr");
return startIdx != -1 ? input.Substring(startIdx) : input;
}
Solved! Go to Solution.