Не меняются свойства некоторых ячеек

Автор Тема: Не меняются свойства некоторых ячеек  (Прочитано 13065 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет!
Имеется вставляемая таблица, у которой производится изменение некоторых свойств ячеек. Однако, изменение свойств производится не у всех ячеек!
Код примерно такой:
Код - C# [Выбрать]
  1. foreach (var range in tbl.Cells)
  2. {
  3.     var cell = tbl.Cells[range.Row, range.Column];
  4.  
  5.     if (cell.Borders.Bottom.LineWeight == LineWeight.ByBlock &&
  6.         thinLw.LineWeight != LineWeight.ByLineWeightDefault)
  7.     {
  8.         cell.Borders.Bottom.LineWeight = thinLw.LineWeight;
  9.     }
  10.     else if (cell.Borders.Bottom.LineWeight == LineWeight.LineWeight040 &&
  11.              thickLw.LineWeight != LineWeight.ByLineWeightDefault)
  12.     {
  13.         cell.Borders.Bottom.LineWeight = thickLw.LineWeight;
  14.         cell.Borders.Bottom.Color = Color.FromColorIndex(ColorMethod.ByColor, 1);
  15.     }
  16. }

Я пробегаю по всем ячейкам таблицы и меняю толщину границ. Для теста добавил установку цвета линии. При работе плагина получаю вот такой результат:



Код даже не выкладываю, ибо в нем ошибиться негде. При дебаге точно проверял, что ячейка 0,0 обрабатывается и значения меняются (даже на скриншоте верхняя граница этой ячейки изменена плагином)

В разных таблицах такая проблема у разных ячеек и разных сторон ячеек. Но в каждой таблице, обрабатываемой плагином, наблюдается проблема

Есть ли какой-то вариант, как обойти этот досадный баг?

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Есть ли какой-то вариант, как обойти этот досадный баг?
Попробуй
table.RecomputeTableBlock( true );

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Пекшев aka Modis,
Что-то подобное Андрей Бушман находил еще лет пять назад. Сейчас точно не помню как он выкрутился, но если не изменят память, то через COM/ActiveX
P.S.: Кстати, неплохо бы уточнить версию AutoCAD и проверить в AutoCAD 2021 со всеми обновлениями.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Пекшев aka Modis,
Я вижу, что у тебя это объединённая ячейка (во всяком случае на картинке). Для неё назначать границы нужно как для объединённой таблицы, т.е. как-то так: https://adn-cis.org/forum/index.php?topic=9693.msg42148#msg42148
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Видимо, это все-же баг. Я попробовал следующее:
- менять границы ячейки
- менять границы диапазона ячеек
- менять границы всех ячеек в диапазоне
- менять границы ячейки, указанной конкретными координатами (0, 3)

Код - C# [Выбрать]
  1. foreach (CellReference range in tbl.Cells)
  2. {
  3.     Cell cell = tbl.Cells[range.Row, range.Column];
  4.     if (cell.IsMerged == true)
  5.     {
  6.         var cellRange = cell.GetMergeRange();
  7.  
  8.         for (int column = cellRange.LeftColumn; column < cellRange.RightColumn; column++)
  9.         {
  10.             for (int row = cellRange.TopRow; row < cell.BottomRow; row++)
  11.             {
  12.                 ChangeCellRangeBorders(cellRange[column, row], thinLw, thickLw);
  13.             }
  14.         }
  15.        
  16.         ChangeCellRangeBorders(cellRange, thinLw, thickLw);
  17.     }
  18.  
  19.     ChangeCellRangeBorders(tbl.Cells[0, 3], thinLw, thickLw);
  20.  
  21.     //ChangeCellRangeBorders(cell, thinLw, thickLw);
  22.     tbl.RecomputeTableBlock(true);
  23.     break;
  24. }

Результат всегда одинаков:



Все меняется, кроме одной границы. Верхняя поменялась, правая поменялась, нижняя - нет

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
AutoCAD 2021.1

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Давай чертеж с одной такой таблицей и тестовый код (проект). Проверю и если не найду решения - отправляю в ADN DevHelp
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Во вложении тестовый код: пробежать по всем ячейкам и если толщина границы 0.40 мм, то поменять её на 2.00 мм и поменять еще цвет для наглядности.
Также во вложении файл с таблицами: только для одной таблицы код сработал. Во всех таблицах одна (причем, по моему всегда одна) граница одной или нескольких ячеек не меняется

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Пекшев aka Modis
1. Убедись, что у тебя действительно все линии в таблице были LineWeight.LineWeight040. Я вижу, что это не так. Например:

Тут явно самая левая вертикальная линия имеет другой вес.
2. Я для проверки запустил такой код:
Код - C# [Выбрать]
  1. namespace TryChangeTableBorders
  2. {
  3.   using Autodesk.AutoCAD.Colors;
  4.   using Autodesk.AutoCAD.DatabaseServices;
  5.   using Autodesk.AutoCAD.EditorInput;
  6.   using Autodesk.AutoCAD.Runtime;
  7.   using AcApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
  8.  
  9.   public static class TestCommand
  10.   {
  11.     [CommandMethod("ChangeTableBorders")]
  12.     public static void Start()
  13.     {
  14.       var doc = AcApp.DocumentManager.MdiActiveDocument;
  15.       var ed = doc.Editor;
  16.  
  17.       var result = ed.GetEntity(new PromptEntityOptions("\nPick table"));
  18.  
  19.       using (var tr = doc.TransactionManager.StartTransaction())
  20.       {
  21.         if (tr.GetObject(result.ObjectId, OpenMode.ForWrite) is Table table)
  22.         {
  23.           foreach (var range in table.Cells)
  24.           {
  25.             var cell = table.Cells[range.Row, range.Column];
  26.             ChangeCellRangeBorders(cell.IsMerged == true ? cell.GetMergeRange() : cell);
  27.           }
  28.           table.GenerateLayout();
  29.           table.RecomputeTableBlock(true);
  30.         }
  31.         tr.Commit();
  32.       }
  33.     }
  34.  
  35.     private static void ChangeCellRangeBorders(CellRange cell)
  36.     {
  37.       //if (cell.Borders.Top.LineWeight == LineWeight.LineWeight040)
  38.       {
  39.         cell.Borders.Top.LineWeight = LineWeight.LineWeight200;
  40.         cell.Borders.Top.Color = Color.FromColorIndex(ColorMethod.ByColor, 1);
  41.       }
  42.  
  43.       //if (cell.Borders.Left.LineWeight == LineWeight.LineWeight040)
  44.       {
  45.         cell.Borders.Left.LineWeight = LineWeight.LineWeight200;
  46.         cell.Borders.Left.Color = Color.FromColorIndex(ColorMethod.ByColor, 2);
  47.       }
  48.  
  49.       //if (cell.Borders.Right.LineWeight == LineWeight.LineWeight040)
  50.       {
  51.         cell.Borders.Right.LineWeight = LineWeight.LineWeight200;
  52.         cell.Borders.Right.Color = Color.FromColorIndex(ColorMethod.ByColor, 3);
  53.       }
  54.  
  55.       //if (cell.Borders.Bottom.LineWeight == LineWeight.LineWeight040)
  56.       {
  57.         cell.Borders.Bottom.LineWeight = LineWeight.LineWeight200;
  58.         cell.Borders.Bottom.Color = Color.FromColorIndex(ColorMethod.ByColor, 4);
  59.       }
  60.     }
  61.   }
  62. }
т.е. игнорирую веса линий которые были раньше и меняю на новые. Кстати, добавил на всякий случай
Код - C# [Выбрать]
  1.           table.GenerateLayout();
  2.           table.RecomputeTableBlock(true);
Результат на той же таблице (как и на всех остальных) нормальный:



Так что не так?

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Тут явно самая левая вертикальная линия имеет другой вес.
Так в том-то и соль - не все границы надо менять, а только те, у которых изначально толщина была LineWeight.LineWeight040. Вот именно в этой таблице, что на скриншоте, нужно поменять у первой ячейки верхнюю, правую и нижнюю границу. Меняются все, кроме нижней.

Разкомментируйте if и попробуйте еще раз

Отмечено как Решение Александр Пекшев aka Modis 27-09-2020, 23:31:41

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Меняются все, кроме нижней.
Обрати внимание что для неё cell.Borders.Bottom.LineWeight == null после изменения значения cell.Borders.Top.LineWeight. Почему так - не знаю:



Но выход есть и он прост. Сначала нужно получить все границы ячейки, а потом уже их менять:

Код - C# [Выбрать]
  1. namespace TryChangeTableBorders
  2. {
  3.   using Autodesk.AutoCAD.Colors;
  4.   using Autodesk.AutoCAD.DatabaseServices;
  5.   using Autodesk.AutoCAD.EditorInput;
  6.   using Autodesk.AutoCAD.Runtime;
  7.   using AcApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
  8.  
  9.   public static class TestCommand
  10.   {
  11.     [CommandMethod("ChangeTableBorders")]
  12.     public static void Start()
  13.     {
  14.       var doc = AcApp.DocumentManager.MdiActiveDocument;
  15.       var ed = doc.Editor;
  16.  
  17.       var result = ed.GetEntity(new PromptEntityOptions("\nPick table"));
  18.  
  19.       using (var tr = doc.TransactionManager.StartTransaction())
  20.       {
  21.         if (tr.GetObject(result.ObjectId, OpenMode.ForWrite) is Table table)
  22.         {
  23.           foreach (var range in table.Cells)
  24.           {
  25.             var cell = table.Cells[range.Row, range.Column];
  26.             ChangeCellRangeBorders(cell.IsMerged == true ? cell.GetMergeRange() : cell);
  27.           }
  28.           table.GenerateLayout();
  29.           table.RecomputeTableBlock(true);
  30.         }
  31.         tr.Commit();
  32.       }
  33.     }
  34.  
  35.     private static void ChangeCellRangeBorders(CellRange cell)
  36.     {
  37.       LineWeight? lwtop = cell.Borders.Top.LineWeight;
  38.       LineWeight? lwbottom = cell.Borders.Bottom.LineWeight;
  39.       LineWeight? lwleft = cell.Borders.Left.LineWeight;
  40.       LineWeight? lwright = cell.Borders.Right.LineWeight;
  41.  
  42.       if (lwtop == LineWeight.LineWeight040)
  43.       {
  44.         cell.Borders.Top.LineWeight = LineWeight.LineWeight200;
  45.         cell.Borders.Top.Color = Color.FromColorIndex(ColorMethod.ByColor, 1);
  46.       }
  47.  
  48.       if (lwleft == LineWeight.LineWeight040)
  49.       {
  50.         cell.Borders.Left.LineWeight = LineWeight.LineWeight200;
  51.         cell.Borders.Left.Color = Color.FromColorIndex(ColorMethod.ByColor, 2);
  52.       }
  53.  
  54.       if (lwright == LineWeight.LineWeight040)
  55.       {
  56.         cell.Borders.Right.LineWeight = LineWeight.LineWeight200;
  57.         cell.Borders.Right.Color = Color.FromColorIndex(ColorMethod.ByColor, 3);
  58.       }
  59.  
  60.       if (lwbottom == LineWeight.LineWeight040)
  61.       {
  62.         cell.Borders.Bottom.LineWeight = LineWeight.LineWeight200;
  63.         cell.Borders.Bottom.Color = Color.FromColorIndex(ColorMethod.ByColor, 4);
  64.       }
  65.     }
  66.   }
  67. }



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр Ривилис, спасибо! Как и всегда - меткое решение.

P.S. Если открыть код свойства "Толщина линии", то можно увидеть, что там и в геттере и в сеттере есть логика. Я изучать не стал, но возможно там есть ошибка

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Пекшев aka Modis,
Я завтра отправлю это как баг в ADN DevHelp. Пусть поразбираются.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Я завтра отправлю это как баг в ADN DevHelp. Пусть поразбираются.
Еще, бывают редкие глюки с таблицами в AutoCAD2010.

Пользователи меняют вручную границы ячеек, все выглядит хорошо.
Сохраняют, закрывают чертеж. После открытия часть границ меняет настройки обратно.

Не разбирался, скорее всего причины в том же.
На всякий случай, Александр Пекшев aka Modis,  попробуй сохранить, закрыть, открыть и снова проверить результат.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Пользователи меняют вручную границы ячеек, все выглядит хорошо.
Сохраняют, закрывают чертеж. После открытия часть границ меняет настройки обратно.
Нет. Это другой баг. Его исправили кажется в AutoCAD 2015 SP2. Я его передавал в ADN DevHelp по наводке Андрея Бушмана лет пять назад.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение