<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>Комментарии на: Удаление слоя</title>
	<atom:link href="https://autolisp.ru/2019/05/14/layer-erase/feed/" rel="self" type="application/rss+xml" />
	<link>https://autolisp.ru/2019/05/14/layer-erase/</link>
	<description>LISP для AutoCAD</description>
	<lastBuildDate>Tue, 24 Feb 2026 16:11:05 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.0</generator>
	<item>
		<title>От: Кулик Алексей aka kpblc</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97344</link>
		<dc:creator><![CDATA[Кулик Алексей aka kpblc]]></dc:creator>
		<pubDate>Sun, 25 Jul 2021 12:26:04 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97344</guid>
		<description><![CDATA[И я очень сильно подозреваю, что вариант Димы будет как минимум а) быстрее и б) устойчивее.]]></description>
		<content:encoded><![CDATA[<p>И я очень сильно подозреваю, что вариант Димы будет как минимум а) быстрее и б) устойчивее.</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: Кулик Алексей aka kpblc</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97343</link>
		<dc:creator><![CDATA[Кулик Алексей aka kpblc]]></dc:creator>
		<pubDate>Sun, 25 Jul 2021 12:13:30 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97343</guid>
		<description><![CDATA[Дима дал разрешение на публикацию, чем я и воспользуюсь :)

&lt;code&gt;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
// Комментарии и разбор - Загорулькин Дмитрий https://www.youtube.com/channel/UCZqgdyZEplDlXagGv6OlmdA
namespace NetToLisp
{
    public class LayerErase
    {
        [LispFunction(&quot;_kpblc-layer-erase&quot;)]
        public static bool LispEraseLayer(ResultBuffer arguments)
        {
            //Array args = arguments.AsArray();
            TypedValue[] args = arguments.AsArray();
            bool res = false;
            if (args.Length == 1 &amp;&amp; args[0].TypeCode == (int)LispDataType.Text)
            {
                //string sLayerName = ((TypedValue)(args.GetValue(0))).Value.ToString();
                string sLayerName = args[0].Value.ToString();

                // Тут ещё добавил проверку на пустоту строки на всякий случай - не знаю,
                // как поведёт себя layerTable.Has, если ему сунуть пустую строку... Может и зря паникую
                if (!string.IsNullOrEmpty(sLayerName) &amp;&amp; sLayerName != &quot;0&quot;)
                {
                    Document doc = Application.DocumentManager.MdiActiveDocument;
                    Database db = doc.Database;

                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
                        if (layerTable.Has(sLayerName))
                        {
                            ObjectId idLayerDelete = layerTable[sLayerName];
                            ObjectId idCurrentLayer = db.Clayer;

                            if (idCurrentLayer == idLayerDelete)
                            {
                                //db.Clayer = layerTable[&quot;0&quot;];
                                db.Clayer = db.LayerZero;
                            }

                            // Здесь слой открывать не нужно, сделаем это перед удалением
                            //LayerTableRecord layer = (LayerTableRecord)tr.GetObject(idLayerDelete, OpenMode.ForRead);
                            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

                            //layer.IsLocked = false; // &lt;- Вот тут, по идее, должно упасть. Объект layer открыт на чтение.
                            //layer.IsFrozen = false; // &lt;- Вот тут, по идее, должно упасть. Объект layer открыт на чтение.
                            // Вообще, в .NET API об этом можно не париться. Достаточно использовать перегрузку метода открытия объекта:
                            // tr.GetObject(id, OpenMode.ForWrite, false, true) &lt;- последняя true - это разрешить оперировать объектами на блокированных слоях
                            // а то что слой выключен или заморожен, вроде как, .NETу фиолетово (хотя, могу ошибаться - лучше перепроверить)

                            foreach (ObjectId btrId in blockTable)
                            {
                                BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                                if (!blockTableRecord.IsFromExternalReference)
                                {
                                    foreach (ObjectId entId in blockTableRecord)
                                    {
                                        //Entity ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);
                                        // Использовать преобразование через as безопаснее. Если объект не того типа - то будет просто null.
                                        // А если использовать преобразование типа через скобочки спереди (Entity), то если объект вдруг окажется не Entity,
                                        // то будет исключение и сбой. В этом случае такое маловероятно, но в других - вполне возможно
                                        Entity ent = tr.GetObject(entId, OpenMode.ForRead, false, true) as Entity;

                                        //if (ent.Layer.ToUpper() == sLayerName.ToUpper())
                                        if (ent.LayerId.Equals(idLayerDelete))
                                        {
                                            // У транзакций есть один косяк - не любят этот метод
                                            // Я не ловил с этим пролем, но вроде как они есть
                                            // Исправлять не буду, если интересно - почитай: https://adn-cis.org/v-autocad-2018.1-metod-upgradeopen-privodit-k-fatalnoj-oshibke-vnutri-tranzakczii.html
                                            ent.UpgradeOpen();
                                            ent.Erase();
                                        }
                                        //else

                                        // Можно одним выражением &quot;убить двух зайцев&quot; - и проверить что это блок и сохранить его в переменной
                                        else if (ent is BlockReference blkRef)
                                        {
                                            //BlockReference blkRef = ent as BlockReference;
                                            //if (blkRef != null)
                                            //{
                                            // Что-то мне кажется это неправильно - удалять атрибуты блока, оставляя при этом сам блок...
                                            // Может, лучше их на другой слой кидать?
                                            foreach (ObjectId attId in blkRef.AttributeCollection)
                                            {
                                                //AttributeReference att = (AttributeReference)tr.GetObject(attId, OpenMode.ForRead);
                                                AttributeReference att = tr.GetObject(attId, OpenMode.ForRead, false, true) as AttributeReference;
                                                //if (att.Layer.ToUpper() == sLayerName.ToUpper())
                                                // Добавил проверку на null на всякий случай
                                                if (att != null &amp;&amp; att.LayerId.Equals(idLayerDelete))
                                                {
                                                    att.UpgradeOpen();
                                                    att.Erase();
                                                }
                                            }
                                            //}
                                        }
                                    }
                                }
                            }
                            
                            LayerTableRecord layer = (LayerTableRecord)tr.GetObject(idLayerDelete, OpenMode.ForWrite);
                            //layer.UpgradeOpen();
                            layer.Erase();

                            res = true;
                        }
                        tr.Commit();
                    }
                }
            }            
            return res;
        }
    }
}
&lt;/code&gt;]]></description>
		<content:encoded><![CDATA[<p>Дима дал разрешение на публикацию, чем я и воспользуюсь <img src="https://autolisp.ru/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p><code><br />
using Autodesk.AutoCAD.ApplicationServices;<br />
using Autodesk.AutoCAD.DatabaseServices;<br />
using Autodesk.AutoCAD.Runtime;<br />
// Комментарии и разбор - Загорулькин Дмитрий https://www.youtube.com/channel/UCZqgdyZEplDlXagGv6OlmdA<br />
namespace NetToLisp<br />
{<br />
    public class LayerErase<br />
    {<br />
        [LispFunction("_kpblc-layer-erase")]<br />
        public static bool LispEraseLayer(ResultBuffer arguments)<br />
        {<br />
            //Array args = arguments.AsArray();<br />
            TypedValue[] args = arguments.AsArray();<br />
            bool res = false;<br />
            if (args.Length == 1 &#038;& args[0].TypeCode == (int)LispDataType.Text)<br />
            {<br />
                //string sLayerName = ((TypedValue)(args.GetValue(0))).Value.ToString();<br />
                string sLayerName = args[0].Value.ToString();</p>
<p>                // Тут ещё добавил проверку на пустоту строки на всякий случай - не знаю,<br />
                // как поведёт себя layerTable.Has, если ему сунуть пустую строку... Может и зря паникую<br />
                if (!string.IsNullOrEmpty(sLayerName) &#038;& sLayerName != "0")<br />
                {<br />
                    Document doc = Application.DocumentManager.MdiActiveDocument;<br />
                    Database db = doc.Database;</p>
<p>                    using (Transaction tr = db.TransactionManager.StartTransaction())<br />
                    {<br />
                        LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);<br />
                        if (layerTable.Has(sLayerName))<br />
                        {<br />
                            ObjectId idLayerDelete = layerTable[sLayerName];<br />
                            ObjectId idCurrentLayer = db.Clayer;</p>
<p>                            if (idCurrentLayer == idLayerDelete)<br />
                            {<br />
                                //db.Clayer = layerTable["0"];<br />
                                db.Clayer = db.LayerZero;<br />
                            }</p>
<p>                            // Здесь слой открывать не нужно, сделаем это перед удалением<br />
                            //LayerTableRecord layer = (LayerTableRecord)tr.GetObject(idLayerDelete, OpenMode.ForRead);<br />
                            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);</p>
<p>                            //layer.IsLocked = false; // < - Вот тут, по идее, должно упасть. Объект layer открыт на чтение.<br />
                            //layer.IsFrozen = false; // <- Вот тут, по идее, должно упасть. Объект layer открыт на чтение.<br />
                            // Вообще, в .NET API об этом можно не париться. Достаточно использовать перегрузку метода открытия объекта:<br />
                            // tr.GetObject(id, OpenMode.ForWrite, false, true) <- последняя true - это разрешить оперировать объектами на блокированных слоях<br />
                            // а то что слой выключен или заморожен, вроде как, .NETу фиолетово (хотя, могу ошибаться - лучше перепроверить)</p>
<p>                            foreach (ObjectId btrId in blockTable)<br />
                            {<br />
                                BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);<br />
                                if (!blockTableRecord.IsFromExternalReference)<br />
                                {<br />
                                    foreach (ObjectId entId in blockTableRecord)<br />
                                    {<br />
                                        //Entity ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);<br />
                                        // Использовать преобразование через as безопаснее. Если объект не того типа - то будет просто null.<br />
                                        // А если использовать преобразование типа через скобочки спереди (Entity), то если объект вдруг окажется не Entity,<br />
                                        // то будет исключение и сбой. В этом случае такое маловероятно, но в других - вполне возможно<br />
                                        Entity ent = tr.GetObject(entId, OpenMode.ForRead, false, true) as Entity;</p>
<p>                                        //if (ent.Layer.ToUpper() == sLayerName.ToUpper())<br />
                                        if (ent.LayerId.Equals(idLayerDelete))<br />
                                        {<br />
                                            // У транзакций есть один косяк - не любят этот метод<br />
                                            // Я не ловил с этим пролем, но вроде как они есть<br />
                                            // Исправлять не буду, если интересно - почитай: https://adn-cis.org/v-autocad-2018.1-metod-upgradeopen-privodit-k-fatalnoj-oshibke-vnutri-tranzakczii.html<br />
                                            ent.UpgradeOpen();<br />
                                            ent.Erase();<br />
                                        }<br />
                                        //else</p>
<p>                                        // Можно одним выражением "убить двух зайцев" - и проверить что это блок и сохранить его в переменной<br />
                                        else if (ent is BlockReference blkRef)<br />
                                        {<br />
                                            //BlockReference blkRef = ent as BlockReference;<br />
                                            //if (blkRef != null)<br />
                                            //{<br />
                                            // Что-то мне кажется это неправильно - удалять атрибуты блока, оставляя при этом сам блок...<br />
                                            // Может, лучше их на другой слой кидать?<br />
                                            foreach (ObjectId attId in blkRef.AttributeCollection)<br />
                                            {<br />
                                                //AttributeReference att = (AttributeReference)tr.GetObject(attId, OpenMode.ForRead);<br />
                                                AttributeReference att = tr.GetObject(attId, OpenMode.ForRead, false, true) as AttributeReference;<br />
                                                //if (att.Layer.ToUpper() == sLayerName.ToUpper())<br />
                                                // Добавил проверку на null на всякий случай<br />
                                                if (att != null &#038;& att.LayerId.Equals(idLayerDelete))<br />
                                                {<br />
                                                    att.UpgradeOpen();<br />
                                                    att.Erase();<br />
                                                }<br />
                                            }<br />
                                            //}<br />
                                        }<br />
                                    }<br />
                                }<br />
                            }</p>
<p>                            LayerTableRecord layer = (LayerTableRecord)tr.GetObject(idLayerDelete, OpenMode.ForWrite);<br />
                            //layer.UpgradeOpen();<br />
                            layer.Erase();</p>
<p>                            res = true;<br />
                        }<br />
                        tr.Commit();<br />
                    }<br />
                }<br />
            }<br />
            return res;<br />
        }<br />
    }<br />
}<br />
</code></code></p>
]]></content:encoded>
	</item>
	<item>
		<title>От: doctorraz</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97321</link>
		<dc:creator><![CDATA[doctorraz]]></dc:creator>
		<pubDate>Sat, 24 Jul 2021 10:07:24 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97321</guid>
		<description><![CDATA[поменял 
LayerTableRecord layer = (LayerTableRecord)tr.GetObject(idLayerDelete, OpenMode.ForWrite); //было ForRead

layer.IsFrozen = false; //иначе на этой строчке фаталил автокад 2021
------------
действительно работает очень шустро.
Надо в конце еще реген добавить]]></description>
		<content:encoded><![CDATA[<p>поменял<br />
LayerTableRecord layer = (LayerTableRecord)tr.GetObject(idLayerDelete, OpenMode.ForWrite); //было ForRead</p>
<p>layer.IsFrozen = false; //иначе на этой строчке фаталил автокад 2021<br />
------------<br />
действительно работает очень шустро.<br />
Надо в конце еще реген добавить</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: Кулик Алексей aka kpblc</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97299</link>
		<dc:creator><![CDATA[Кулик Алексей aka kpblc]]></dc:creator>
		<pubDate>Fri, 23 Jul 2021 10:43:57 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97299</guid>
		<description><![CDATA[Можно, конечно, но 2 года назад не сообразил ;)]]></description>
		<content:encoded><![CDATA[<p>Можно, конечно, но 2 года назад не сообразил <img src="https://autolisp.ru/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
	</item>
	<item>
		<title>От: doctorraz</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97298</link>
		<dc:creator><![CDATA[doctorraz]]></dc:creator>
		<pubDate>Fri, 23 Jul 2021 10:38:11 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97298</guid>
		<description><![CDATA[Вот и взял твой код за образец (списать)
Лисп попробовал весьма шустро работает!!!
Net то же домучу.
Кстати, а чего ты не проверяешь в начале слой на purge, а сразу идешь перебирать объекты?
Мож на слое ничего и нету, и его можно сразу удалять]]></description>
		<content:encoded><![CDATA[<p>Вот и взял твой код за образец (списать)<br />
Лисп попробовал весьма шустро работает!!!<br />
Net то же домучу.<br />
Кстати, а чего ты не проверяешь в начале слой на purge, а сразу идешь перебирать объекты?<br />
Мож на слое ничего и нету, и его можно сразу удалять</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: Кулик Алексей aka kpblc</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97297</link>
		<dc:creator><![CDATA[Кулик Алексей aka kpblc]]></dc:creator>
		<pubDate>Fri, 23 Jul 2021 10:30:41 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97297</guid>
		<description><![CDATA[ИМХО технология примерно такая же - пройтись по всем примитивам, проверить старый слой, установить новый. Потом попробовать удалить запись о старом слое в таблице слоев]]></description>
		<content:encoded><![CDATA[<p>ИМХО технология примерно такая же - пройтись по всем примитивам, проверить старый слой, установить новый. Потом попробовать удалить запись о старом слое в таблице слоев</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: doctorraz</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97296</link>
		<dc:creator><![CDATA[doctorraz]]></dc:creator>
		<pubDate>Fri, 23 Jul 2021 10:27:21 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97296</guid>
		<description><![CDATA[Спасибо!
Думал, что то не так делаю...
крашится автокад 2021, надо по шагам отладку запускать.
--------------
Конечная цель не удаление а laymrg
Разбираюсь]]></description>
		<content:encoded><![CDATA[<p>Спасибо!<br />
Думал, что то не так делаю...<br />
крашится автокад 2021, надо по шагам отладку запускать.<br />
--------------<br />
Конечная цель не удаление а laymrg<br />
Разбираюсь</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: Кулик Алексей aka kpblc</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97292</link>
		<dc:creator><![CDATA[Кулик Алексей aka kpblc]]></dc:creator>
		<pubDate>Fri, 23 Jul 2021 09:02:26 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97292</guid>
		<description><![CDATA[Вызов из-под лиспа (при условии, что dll скомпилирована и загружена в ACAD):
[cc lang=&quot;cadlisp&quot;](_kpblc-layer-erase &quot;ИмяСлояДляУдаления&quot;)[/cc]

Или вопрос был в том, как в C# обработать переданные параметры?

Другой вопрос, что Дима Загорулькин показал мне другой, более правильный вариант C#-кода (который, я надеюсь, он как-нибудь где-нибудь опубликует).]]></description>
		<content:encoded><![CDATA[<p>Вызов из-под лиспа (при условии, что dll скомпилирована и загружена в ACAD):<br />
[cc lang="cadlisp"](_kpblc-layer-erase "ИмяСлояДляУдаления")[/cc]</p>
<p>Или вопрос был в том, как в C# обработать переданные параметры?</p>
<p>Другой вопрос, что Дима Загорулькин показал мне другой, более правильный вариант C#-кода (который, я надеюсь, он как-нибудь где-нибудь опубликует).</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: doctorraz</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-97276</link>
		<dc:creator><![CDATA[doctorraz]]></dc:creator>
		<pubDate>Thu, 22 Jul 2021 08:10:10 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-97276</guid>
		<description><![CDATA[Только начинаю разбираться с C#
Если не затруднит дай пожалуйста пример вызова, не знаю, как получить входной параметр типа   ResultBuffer]]></description>
		<content:encoded><![CDATA[<p>Только начинаю разбираться с C#<br />
Если не затруднит дай пожалуйста пример вызова, не знаю, как получить входной параметр типа   ResultBuffer</p>
]]></content:encoded>
	</item>
	<item>
		<title>От: Кулик Алексей aka kpblc</title>
		<link>https://autolisp.ru/2019/05/14/layer-erase/comment-page-1/#comment-95913</link>
		<dc:creator><![CDATA[Кулик Алексей aka kpblc]]></dc:creator>
		<pubDate>Tue, 16 Mar 2021 12:51:14 +0000</pubDate>
		<guid isPermaLink="false">http://autolisp.ru/?p=3869#comment-95913</guid>
		<description><![CDATA[Код надо компилировать в dll, а потом уже загружать через netload.]]></description>
		<content:encoded><![CDATA[<p>Код надо компилировать в dll, а потом уже загружать через netload.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
