<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: setting Database.Cannoscale and deleting the old scale in .NET Forum</title>
    <link>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8516955#M23904</link>
    <description>&lt;P&gt;Thank you for your reply.&amp;nbsp; I like your examples, especially because they are very similar to mine! &lt;img id="smileyhappy" class="emoticon emoticon-smileyhappy" src="https://forums.autodesk.com/i/smilies/16x16_smiley-happy.png" alt="Smiley Happy" title="Smiley Happy" /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Yes, my code does much the same as yours&amp;nbsp;- including setting any viewports to 1:1 (or deleting them outright, which I have the luxury of doing in some cases), and it also removes the unwanted scales from every annotative object I can find in the drawing (see first few code snips below).&amp;nbsp;&amp;nbsp;But even after all this, whichever scale&amp;nbsp;had been active when the file was first read into memory, was not "freed up" and made deleteable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I came up with a hacky but satisfactory solution:&amp;nbsp; S ave and dispose the Database after setting Database.Cannoscale to 1:1, and then reopen the Database to&amp;nbsp;continue with the rest of the process (see code snips more toward the bottom).&amp;nbsp; For some reason, that worked.&amp;nbsp; But&amp;nbsp;I'm not marking my own answer as the solution, because I'm hoping someone out there has a better one, or can at least explain this weird behavior.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT size="4"&gt;Deleting Scales from All Annotative Objects (kind of a detour, just for interest's sake)&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;First&amp;nbsp;I get the ObjectIds of all annotative objects in all layouts:&lt;/P&gt;
&lt;PRE&gt;public static List&amp;lt;ObjectId&amp;gt; GetAnnoObjectIds(Database db)
{
	var result = new List&amp;lt;ObjectId&amp;gt;();
	using (var trans = db.TransactionManager.StartTransaction())
	{
		var blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
		//iterate through all layouts including model space
		var layoutDict = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite);
		foreach (DBDictionaryEntry layoutEntry in layoutDict)
		{
			var layout = (Layout)trans.GetObject(layoutEntry.Value, OpenMode.ForRead);
			var layoutBTR = (BlockTableRecord)trans.GetObject(layout.BlockTableRecordId, OpenMode.ForRead);
			//iterate through objects in this layout
			foreach (ObjectId objId in layoutBTR)
			{
				var obj = trans.GetObject(objId, OpenMode.ForRead);
				if (obj.Annotative == AnnotativeStates.True) result.Add(obj.ObjectId);
				obj.Dispose();
			}
		}
		trans.Commit();
	}
	return result;
}&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then I get the current scale list, using a method similar to your GetAnnotationScales() that I won't show here because it's so similar.&amp;nbsp; The&amp;nbsp;only difference is that instead of returning a Dictionary, it returns a List&amp;lt;&amp;gt; of a data transfer object I've defined (that I &lt;STRONG&gt;will&lt;/STRONG&gt; show here), for working with scales elsewhere in my codebase:&lt;/P&gt;
&lt;PRE&gt;public class ScaleDTO
{
	public bool isArchitectural { get; set; }
	public bool isCivil { get; set; }
	public string Name { get; set; }
	public string LongName { get; set; }
	public double ModelUnits { get; set; }
	public double PaperUnits { get; set; }
}&lt;/PRE&gt;
&lt;P&gt;Now that I have the List&amp;lt;ObjectId&amp;gt; of annotative object IDs, and the List&amp;lt;ScaleDTO&amp;gt; of current scales, I use the below method to delete all those scales from all those objects:&lt;/P&gt;
&lt;PRE&gt;public static void DeleteScalesFromObjects(Database db, List&amp;lt;ScaleDTO&amp;gt; scales, List&amp;lt;ObjectId&amp;gt; objectIds)
{
	//get ObjectContexts
	var occ = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");
	var contextsToDelete = new List&amp;lt;ObjectContext&amp;gt;();
	foreach (var scale in scales)
		if (occ.HasContext(scale.Name) &amp;amp;&amp;amp; scale.Name != "1:1" &amp;amp;&amp;amp; scale.Name != db.Cannoscale.Name)
			contextsToDelete.Add(occ.GetContext(scale.Name));

	//iterate through DBObjects
	using (var trans = db.TransactionManager.StartTransaction())
	{
		foreach (var objectId in objectIds)
		{
			var obj = trans.GetObject(objectId, OpenMode.ForWrite);
			//remove contexts from object
			foreach (var context in contextsToDelete)
				if (obj.HasContext(context))
					obj.RemoveContext(context);
		}
		trans.Commit();
	}
}&lt;/PRE&gt;
&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Hacky Quasi-Solution: Saving &amp;amp; Disposing the Database in Between&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Again, the above measures, combined with resetting or deleting viewports, and setting Database.Cannoscale,&amp;nbsp;were for some reason not enough to&amp;nbsp;free up the previous Database.Cannoscale for deletion.&amp;nbsp; I would get an eObjectIsReferenced exception.&amp;nbsp; So my hacky solution was to basically split the steps of the process into the below method (that only sets the .Cannoscale to 1:1, saves and disposes), and the rest of the process (i.e. delete or reset viewports, delete scales from annotative objects as above, and delete scales from the drawing itself).&amp;nbsp; For unknown reasons, that worked.&amp;nbsp; Note that the below method calls my method AddScalesToDwg() that I don't show here, but is similar to your CreateAnnotationScale().&amp;nbsp; (Except I use a List.&amp;nbsp; Apparently I love Lists.)&lt;/P&gt;
&lt;PRE&gt;/// &amp;lt;summary&amp;gt;
/// Creates if necessary the annotative scale 1:1 in the given .dwg file, and sets it current in model space via the Database.Cannoscale property.
/// Returns a List&amp;amp;lt;string&amp;amp;gt; of errors, which is empty in the success condition.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="filePath"&amp;gt;The full path to the .dwg file&amp;lt;/param&amp;gt;
public static List&amp;lt;string&amp;gt; SetUnityScaleCurrent(string filePath)
{
	var errors = new List&amp;lt;string&amp;gt;();

	//make sure path exists and points to a .dwg
	if (Path.GetExtension(filePath).ToUpper() != ".DWG")
	{
		errors.Add("Can't add annoscale 1:1 to " + filePath + " (file isn't a .dwg).");
		return errors;
	}
	else if (!File.Exists(filePath))
	{
		errors.Add("Can't add annoscale 1:1 to " + filePath + " (file doesn't exist).");
		return errors;
	}

	//load file into side database
	var db = new Database(false, true);
	db.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
	db.CloseInput(true);

	//make sure drawing has unity scale
	var unityScaleDTO = new ScaleDTO() { Name = "1:1", LongName = "1:1", ModelUnits = 1, PaperUnits = 1, ScaleFactor = 1 };
	var occ = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");
	if (!occ.HasContext("1:1"))
		errors.AddRange(AddScalesToDwg(db, new List&amp;lt;ScaleDTO&amp;gt;() { unityScaleDTO }));
	var unityScaleContext = occ.GetContext("1:1");

	//set unity scale current
	db.Cannoscale = (AnnotationScale)unityScaleContext;

	//save file &amp;amp; dispose
	db.SaveAs(db.Filename, db.OriginalFileVersion);
	db.Dispose();

	return errors;
}&lt;/PRE&gt;</description>
    <pubDate>Fri, 11 Jan 2019 19:00:02 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2019-01-11T19:00:02Z</dc:date>
    <item>
      <title>setting Database.Cannoscale and deleting the old scale</title>
      <link>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8495144#M23902</link>
      <description>&lt;P&gt;What am I leaving out?&amp;nbsp; I'm trying to open a .dwg, set its Database.Cannoscale&amp;nbsp;property, and delete all annoscales except one.&amp;nbsp; But whatever scale was active when I opened the drawing, can't be deleted because it's supposedly in use, and this happens ONLY when the dwg is opened as a side Database, not when it's open in the editor.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Example, let's say the .dwg's&amp;nbsp;current annoscale when I open it is called "scale A."&lt;/P&gt;
&lt;P&gt;I set Database.Cannoscale to "scale B."&amp;nbsp; (Later I can look at the saved dwg&amp;nbsp;and confirm this was successful.)&lt;/P&gt;
&lt;P&gt;I&amp;nbsp;iteratively&amp;nbsp;remove&amp;nbsp;all annoscales except "scale B" from every annotative object in the dwg.&lt;/P&gt;
&lt;P&gt;The drawing has no viewports in it, so no worries there.&lt;/P&gt;
&lt;P&gt;So the only annoscale in use at this point&amp;nbsp;should be scale B.&lt;/P&gt;
&lt;P&gt;Next I&amp;nbsp;try&amp;nbsp;to delete all annoscales from the dwg except scale B.&lt;/P&gt;
&lt;P&gt;If the drawing is currently open in the editor (i.e. if I'm using MdiActiveDocument.Database), this works.&lt;/P&gt;
&lt;P&gt;But if it's open as a side Database, "scale A" can't be deleted because it's supposedly in use.&amp;nbsp;&amp;nbsp;I get an eObjectIsReferenced exception from the ACAD runtime.&lt;/P&gt;
&lt;P&gt;Basically whatever scale was active when opening the drawing, remains "in use" despite setting the .Cannoscale to something else.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I tried&amp;nbsp;putting the Database.Cannoscale setting code inside a transaction - no luck.&lt;/P&gt;
&lt;P&gt;I tried saving the Database file and reopening it, in the hope of forcing something to update - no luck.&lt;/P&gt;
&lt;P&gt;I'm remembering to set HostApplicationServices.WorkingDatabase to my database temporarily, and restoring it at the end (both when using a side Database&amp;nbsp;and when using MdiActiveDocument.Database) - no luck.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Is there some step or command I'm missing?&lt;/P&gt;
&lt;P&gt;Code available on request, but first I thought I'd see if this sounds familiar to anybody.&lt;/P&gt;</description>
      <pubDate>Wed, 02 Jan 2019 03:23:19 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8495144#M23902</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2019-01-02T03:23:19Z</dc:date>
    </item>
    <item>
      <title>Re: setting Database.Cannoscale and deleting the old scale</title>
      <link>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8515377#M23903</link>
      <description>&lt;P&gt;Thanks to Kean i've written some methodes to remove these Annotation Scales&lt;/P&gt;
&lt;P&gt;Start with &lt;STRONG&gt;AnnotationScaleReset&lt;/STRONG&gt;. It will create a "1:1" Scale if it not exists or reset that scale to "1:1"&lt;/P&gt;
&lt;P&gt;Then all annotationscale references will be removed from the drawing objects, including Viewports.&lt;/P&gt;
&lt;P&gt;Finally the annotationscales, except the "1:1", will be removed from the drawing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This too solves the problems with the display of Linetypes beeing shown as solids in Modelspace.&lt;/P&gt;
&lt;P&gt;Although this also may be corrected by the user manually:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1. Check (Global)LineTypeScale //see pulldown linetypes/others&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2. LsLtScale=1, MsLtScale=0&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;3. Show AnnotationScale //Statusbar(3 horizontal lines)/Anotationscale&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;4. Click AnnotatioScale/Scroll Down at end, select Percentage&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;5. Set Scale: 1:1/100%&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Warning&lt;/STRONG&gt;: Removing the AnnotationScales may alter the (look of) drawing.&lt;/P&gt;
&lt;P&gt;Inspired by Kean:&lt;/P&gt;
&lt;P&gt;&amp;nbsp; //&lt;A href="https://www.keanw.com/2011/10/delete-all-but-current-annotation-scales-on-autocad-objects-using-net.html" target="_blank"&gt;https://www.keanw.com/2011/10/delete-all-but-current-annotation-scales-on-autocad-objects-using-net.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;public static void AnnotationScaleReset(Database db)
{
    if (db == null)
    {
        throw new System.Exception($"Invalid Argument: {nameof(db)} IS NULL");
    }

    var antScales = GetAnnotationScales(db);
    if (antScales == null)
        return;
    var antScale1To1 = CreateAnnotationScale(db, "1:1", 1, 1);
    db.Cannoscale = antScale1To1;

    foreach (var kvp in antScales)
    {
        RemoveAnnotScale(db, kvp.Key);
    }
    PurgeAnnotScales(db, antScales);
}&lt;/PRE&gt;
&lt;PRE&gt;public static Dictionary&amp;lt;string, AnnotationScale&amp;gt; GetAnnotationScales(Database db)
{
    Dictionary&amp;lt;string, AnnotationScale&amp;gt; annScales = null;

    if (db == null)
    {
        throw new System.Exception($"Invalid Argument: {nameof(db)} IS NULL");
    }

    var ocm = db.ObjectContextManager;
    if (ocm == null)
        throw new System.Exception($"Failed to Connect with ObjectContextManager");
    var occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
    if (occ == null)
        return null;

    annScales = new Dictionary&amp;lt;string, AnnotationScale&amp;gt;(StringComparer.OrdinalIgnoreCase);
    using (var tr = db.TransactionManager.StartTransaction())
    {
        foreach (ObjectContext oc in occ)
        {
            var annScale = oc as AnnotationScale;
            if (annScale != null)
            {
                var id = new ObjectId(annScale.UniqueIdentifier);
                annScales[annScale.Name] = annScale;
            }
        }
        tr.Commit();
    }
    return annScales;
}&lt;/PRE&gt;
&lt;PRE&gt;public static AnnotationScale CreateAnnotationScale(Database db, string scaleName, double paperUnits, double drawingUnits)
{
    AnnotationScale annotScale = null;

    if (db == null)
    {
        throw new System.Exception($"Invalid Argument: {nameof(db)} IS NULL");
    }
    if (string.IsNullOrWhiteSpace(scaleName))
    {
        throw new System.Exception($"Invalid Argument: {nameof(scaleName)} IS NULL");
    }
    if (paperUnits == 0)
    {
        throw new System.Exception($"Invalid Argument: {nameof(paperUnits)} IS NULL");
    }
    if (drawingUnits == 0)
    {
        throw new System.Exception($"Invalid Argument: {nameof(drawingUnits)} IS NULL");
    }

    var ocm = db.ObjectContextManager;
    if (ocm == null)
        throw new System.Exception($"Failed to Connect with ObjectContextManager");

    var occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
    if (occ != null)
    {
        annotScale = occ.GetContext(scaleName) as AnnotationScale;
        if (annotScale == null)
        {
            annotScale = new AnnotationScale();
            annotScale.Name = scaleName;
            annotScale.PaperUnits = paperUnits;
            annotScale.DrawingUnits = drawingUnits;
            occ.AddContext(annotScale);
        }
        annotScale.PaperUnits = paperUnits;
        annotScale.DrawingUnits = drawingUnits;
    }
    return annotScale;
}&lt;/PRE&gt;
&lt;PRE&gt;public static void RemoveAnnotScale(Database db, string antScaleName)
{
    if (db == null)
    {
        throw new System.Exception($"Invalid Argument: {nameof(db)} IS NULL");
    }

    if (string.IsNullOrWhiteSpace(antScaleName))
    {
        throw new System.Exception($"Invalid Argument: {nameof(antScaleName)} IS NULL");
    }

    var ocm = db.ObjectContextManager;
    if (ocm == null)
        throw new System.Exception($"Failed to Connect with ObjectContextManager");
    var occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
    if (occ != null)
    {
        var oct = occ.GetContext(antScaleName);
        using (var tr = db.TransactionManager.StartTransaction())
        {
            var blkTbl = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
            foreach (ObjectId blkId in blkTbl)
            {
                var blk = (BlockTableRecord)tr.GetObject(blkId, OpenMode.ForRead);
                if (blk.Annotative == AnnotativeStates.True &amp;amp;&amp;amp; blk.HasContext(oct))
                {
                    blk.UpgradeOpen();
                    //blk.Annotative = AnnotativeStates.False;
                    blk.RemoveContext(oct);
                }

                foreach (var id in blk)
                {
                    var obj = tr.GetObject(id, OpenMode.ForRead) as DBObject;
                    if (obj.Annotative == AnnotativeStates.True &amp;amp;&amp;amp; blk.HasContext(oct))
                    {
                        obj.UpgradeOpen();
                        //obj.Annotative = AnnotativeStates.False;
                        obj.RemoveContext(oct);
                    }
                    else if (obj is Viewport)
                    {
                        var vp = obj as Viewport;
                        vp.UpgradeOpen();
                        vp.AnnotationScale = db.Cannoscale;
                        //Not Implemented Yet: vp.RemoveContext(oct);
                    }
                }
            }
            tr.Commit();
        }
    }
    return;
}&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;public static void PurgeAnnotScales(Database db, Dictionary&amp;lt;string, AnnotationScale&amp;gt; scalesToRemove)
{
    if (db == null)
    {
        throw new System.Exception($"Invalid Argument: {nameof(db)} IS NULL");
    }

    if (scalesToRemove == null || scalesToRemove.Count == 0)
        return;

    var ocm = db.ObjectContextManager;
    if (ocm == null)
        throw new System.Exception($"Failed to Connect with ObjectContextManager");

    var occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
    if (occ != null)
    {
        using (var tr = db.TransactionManager.StartTransaction())
        {
            //Purge all ScaleList.
            var oic = new ObjectIdCollection();
            foreach (var kvp in scalesToRemove)
            {
                var antScale = kvp.Value;
                oic.Add(new ObjectId(antScale.UniqueIdentifier));
            }
            db.Purge(oic);
            foreach (ObjectId id in oic)
            {
                try
                {
                    var obj = tr.GetObject(id, OpenMode.ForWrite);
                    obj.Erase();
                }
                catch //(System.Exception ex)
                {
                }
            }
            tr.Commit();
            scalesToRemove = null;
        }
    }
}&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 11 Jan 2019 08:00:36 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8515377#M23903</guid>
      <dc:creator>SENL1362</dc:creator>
      <dc:date>2019-01-11T08:00:36Z</dc:date>
    </item>
    <item>
      <title>Re: setting Database.Cannoscale and deleting the old scale</title>
      <link>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8516955#M23904</link>
      <description>&lt;P&gt;Thank you for your reply.&amp;nbsp; I like your examples, especially because they are very similar to mine! &lt;img id="smileyhappy" class="emoticon emoticon-smileyhappy" src="https://forums.autodesk.com/i/smilies/16x16_smiley-happy.png" alt="Smiley Happy" title="Smiley Happy" /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Yes, my code does much the same as yours&amp;nbsp;- including setting any viewports to 1:1 (or deleting them outright, which I have the luxury of doing in some cases), and it also removes the unwanted scales from every annotative object I can find in the drawing (see first few code snips below).&amp;nbsp;&amp;nbsp;But even after all this, whichever scale&amp;nbsp;had been active when the file was first read into memory, was not "freed up" and made deleteable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I came up with a hacky but satisfactory solution:&amp;nbsp; S ave and dispose the Database after setting Database.Cannoscale to 1:1, and then reopen the Database to&amp;nbsp;continue with the rest of the process (see code snips more toward the bottom).&amp;nbsp; For some reason, that worked.&amp;nbsp; But&amp;nbsp;I'm not marking my own answer as the solution, because I'm hoping someone out there has a better one, or can at least explain this weird behavior.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT size="4"&gt;Deleting Scales from All Annotative Objects (kind of a detour, just for interest's sake)&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;First&amp;nbsp;I get the ObjectIds of all annotative objects in all layouts:&lt;/P&gt;
&lt;PRE&gt;public static List&amp;lt;ObjectId&amp;gt; GetAnnoObjectIds(Database db)
{
	var result = new List&amp;lt;ObjectId&amp;gt;();
	using (var trans = db.TransactionManager.StartTransaction())
	{
		var blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
		//iterate through all layouts including model space
		var layoutDict = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite);
		foreach (DBDictionaryEntry layoutEntry in layoutDict)
		{
			var layout = (Layout)trans.GetObject(layoutEntry.Value, OpenMode.ForRead);
			var layoutBTR = (BlockTableRecord)trans.GetObject(layout.BlockTableRecordId, OpenMode.ForRead);
			//iterate through objects in this layout
			foreach (ObjectId objId in layoutBTR)
			{
				var obj = trans.GetObject(objId, OpenMode.ForRead);
				if (obj.Annotative == AnnotativeStates.True) result.Add(obj.ObjectId);
				obj.Dispose();
			}
		}
		trans.Commit();
	}
	return result;
}&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then I get the current scale list, using a method similar to your GetAnnotationScales() that I won't show here because it's so similar.&amp;nbsp; The&amp;nbsp;only difference is that instead of returning a Dictionary, it returns a List&amp;lt;&amp;gt; of a data transfer object I've defined (that I &lt;STRONG&gt;will&lt;/STRONG&gt; show here), for working with scales elsewhere in my codebase:&lt;/P&gt;
&lt;PRE&gt;public class ScaleDTO
{
	public bool isArchitectural { get; set; }
	public bool isCivil { get; set; }
	public string Name { get; set; }
	public string LongName { get; set; }
	public double ModelUnits { get; set; }
	public double PaperUnits { get; set; }
}&lt;/PRE&gt;
&lt;P&gt;Now that I have the List&amp;lt;ObjectId&amp;gt; of annotative object IDs, and the List&amp;lt;ScaleDTO&amp;gt; of current scales, I use the below method to delete all those scales from all those objects:&lt;/P&gt;
&lt;PRE&gt;public static void DeleteScalesFromObjects(Database db, List&amp;lt;ScaleDTO&amp;gt; scales, List&amp;lt;ObjectId&amp;gt; objectIds)
{
	//get ObjectContexts
	var occ = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");
	var contextsToDelete = new List&amp;lt;ObjectContext&amp;gt;();
	foreach (var scale in scales)
		if (occ.HasContext(scale.Name) &amp;amp;&amp;amp; scale.Name != "1:1" &amp;amp;&amp;amp; scale.Name != db.Cannoscale.Name)
			contextsToDelete.Add(occ.GetContext(scale.Name));

	//iterate through DBObjects
	using (var trans = db.TransactionManager.StartTransaction())
	{
		foreach (var objectId in objectIds)
		{
			var obj = trans.GetObject(objectId, OpenMode.ForWrite);
			//remove contexts from object
			foreach (var context in contextsToDelete)
				if (obj.HasContext(context))
					obj.RemoveContext(context);
		}
		trans.Commit();
	}
}&lt;/PRE&gt;
&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Hacky Quasi-Solution: Saving &amp;amp; Disposing the Database in Between&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Again, the above measures, combined with resetting or deleting viewports, and setting Database.Cannoscale,&amp;nbsp;were for some reason not enough to&amp;nbsp;free up the previous Database.Cannoscale for deletion.&amp;nbsp; I would get an eObjectIsReferenced exception.&amp;nbsp; So my hacky solution was to basically split the steps of the process into the below method (that only sets the .Cannoscale to 1:1, saves and disposes), and the rest of the process (i.e. delete or reset viewports, delete scales from annotative objects as above, and delete scales from the drawing itself).&amp;nbsp; For unknown reasons, that worked.&amp;nbsp; Note that the below method calls my method AddScalesToDwg() that I don't show here, but is similar to your CreateAnnotationScale().&amp;nbsp; (Except I use a List.&amp;nbsp; Apparently I love Lists.)&lt;/P&gt;
&lt;PRE&gt;/// &amp;lt;summary&amp;gt;
/// Creates if necessary the annotative scale 1:1 in the given .dwg file, and sets it current in model space via the Database.Cannoscale property.
/// Returns a List&amp;amp;lt;string&amp;amp;gt; of errors, which is empty in the success condition.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="filePath"&amp;gt;The full path to the .dwg file&amp;lt;/param&amp;gt;
public static List&amp;lt;string&amp;gt; SetUnityScaleCurrent(string filePath)
{
	var errors = new List&amp;lt;string&amp;gt;();

	//make sure path exists and points to a .dwg
	if (Path.GetExtension(filePath).ToUpper() != ".DWG")
	{
		errors.Add("Can't add annoscale 1:1 to " + filePath + " (file isn't a .dwg).");
		return errors;
	}
	else if (!File.Exists(filePath))
	{
		errors.Add("Can't add annoscale 1:1 to " + filePath + " (file doesn't exist).");
		return errors;
	}

	//load file into side database
	var db = new Database(false, true);
	db.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
	db.CloseInput(true);

	//make sure drawing has unity scale
	var unityScaleDTO = new ScaleDTO() { Name = "1:1", LongName = "1:1", ModelUnits = 1, PaperUnits = 1, ScaleFactor = 1 };
	var occ = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");
	if (!occ.HasContext("1:1"))
		errors.AddRange(AddScalesToDwg(db, new List&amp;lt;ScaleDTO&amp;gt;() { unityScaleDTO }));
	var unityScaleContext = occ.GetContext("1:1");

	//set unity scale current
	db.Cannoscale = (AnnotationScale)unityScaleContext;

	//save file &amp;amp; dispose
	db.SaveAs(db.Filename, db.OriginalFileVersion);
	db.Dispose();

	return errors;
}&lt;/PRE&gt;</description>
      <pubDate>Fri, 11 Jan 2019 19:00:02 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/setting-database-cannoscale-and-deleting-the-old-scale/m-p/8516955#M23904</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2019-01-11T19:00:02Z</dc:date>
    </item>
  </channel>
</rss>

