Компания
35,88
рейтинг
17 октября 2013 в 10:53

Разработка → Работа с таблицами в MultiCAD.NET. Часть 1. Создание отчета на основе шаблона



Этой публикацией мы открывам цикл статей про возможности и особенности API для работы с таблицами в MultiCAD.NET.

Как известно, практически ни один чертеж не обходится без табличного оформления: таблицы применяются для создания объектов, содержащих количественную информацию о конструкции, ведомостей элементов, спецификаций и др. Типичной задачей, с которой сталкиваются проектировщики, является формирование табличного отчета по выбранным объектам чертежа. Автоматизация этой задачи позволит избавить пользователя от рутинной работы, тем самым сократив затраченное время и количество ошибок.

В качестве примера рассмотрим формирование итоговой ведомости электроприборов по плану расположения оборудования (или, проще говоря, по чертежу, иллюстрирующему распределение электрических розеток по помещениям).

Каждая розетка отмечена многоуровневой выноской, которая содержит следующую информацию:

  • тип розетки,
  • артикул/производитель,
  • номер помещения для установки.



Процесс решения поставленной задачи может быть разбит на три этапа:

  1. создание собственного шаблона таблицы для отчета,
  2. загрузка шаблона и последовательное заполнение таблицы данными,
  3. разбивка и постраничная вставка таблицы.

Создание шаблона таблицы

Табличные отчеты обычно формируются на базе стандартных шаблонов, для создания которых чаще используется табличный UI. Однако, в целях демонстрации мы создадим свой собственный шаблон программными средствами MultiCAD.NET. Общий вид итоговой таблицы будет выглядеть следующим образом:



Значения ячеек соответствуют количеству установленных электрических розеток конкретной модели в конкретном помещении. Таблица также будет содержать два верхних колонтитула: обычный колонтитул, который в случае разбивки таблицы будет добавляться к каждой странице отчета, кроме первой, и колонтитул первой страницы.

Пример метода, который создает такой шаблон и сохраняет его в файл с указанным именем
bool CreateTemplate(string FileName)
{
  McTable table = new McTable();
  table.DefaultCell.HorizontalTextAlign = HorizTextAlign.Center;
  table.DefaultCell.VerticalTextAlign = VertTextAlign.Center;
  table.Columns.AddRange(0, 2);
  table.Columns[0].Width = 55;
  table.Columns[1].Width = 10;

  // Добавляем секцию верхнего колонтитула первой страницы
  table.Rows.InsertSection(SectionTypeEnum.HeaderFirst, 0, 2);
  System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, 1, 0);
  table.Merge(rect);
  table[0, 0].TextHeight = 3.5;
  table.Rows[0].Height = 10;
  table[0, 0].Value = "Ведомость электрических розеток по номеру помещения";

  foreach (var cell in table.Rows[0].Cells)
    cell.SetBorderLineweight(BorderTypesEnum.ButBottom, -9);

  table.Rows[1].Height = 8;
  foreach (var cell in table.Rows[1].Cells)
  {
    cell.TextHeight = 2.5;
  }
  table[1, 0].Value = "Артикул изделия";
  table[1, 1].Value = "#room";

  // Добавляем секцию верхнего колонтитула
  table.Rows.InsertSection(SectionTypeEnum.Header, 2);
  table.Rows[3].Height = 8;
  foreach (var cell in table.Rows[3].Cells)
  {
    cell.TextHeight = 2.5;
  }
  table[3, 0].Value = "Артикул изделия";
  table[3, 1].Value = "#room";
      
  // Добавляем секцию данных
  table.Rows.InsertSection(SectionTypeEnum.None, 4);
  table.Rows[5].Height = 6;
  table[5, 0].Value = "#code";
  
  // Сохраняем таблицу во внешний файл          
  if (!table.SaveToFile(FileName))
  {
    return false;
  }
  return true;
}


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

В данной реализации ячейки шаблона содержат специальные строки-идентификаторы "#code" и "#room", которые в ходе заполнения таблицы позволят определить какие данные должны быть записаны в конкретную ячейку. Это обеспечит корректное наполнение таблицы даже при возможном изменении количества строк и столбцов в шаблоне.

Формирование отчета

Алгоритм построения таблицы отчета можно разделить на следующие шаги:

  1. регистрация команды создания отчета,
  2. выбор на чертеже всех выносок, содержащих описание электрических розеток,
  3. загрузка шаблона, запуск табличного редактора для возможного изменения шаблона,
  4. структурирование данных выбранных объектов для последующей записи в таблицу,
  5. заполнение колонтитулов таблицы (название таблицы, названия столбцов по числу помещений),
  6. заполнение строк таблицы.

Полный код примера доступен по этой ссылке, а мы остановимся на некоторых ключевых моментах.

Регистрация команды создания отчета

Добавим «главный» метод приложения, который является обработчиком команды smpl_CreateTableReport и будет содержать реализацию алгоритма:

[CommandMethod("smpl_CreateTableReport", CommandFlags.NoCheck | CommandFlags.NoPrefix)]
public void smpl_CreateTableReport()
{
  // Код примера
}

Выбор объектов

Выбор объектов типа «выноска для многослойных конструкций» осуществляется стандартным способом, с помощью задания фильтра объектов:

McObjectId[] idSelecteds = ObjectFilter.Create(true).AddType(McNoteMultilayer.TypeID).GetObjects().ToArray();
if (idSelecteds == null || idSelecteds.Length == 0)
{
  return;
}

В результате выбора объектов по фильтру мы получили массив Id всех выносок на чертеже. По Id можно получить содержимое строк каждой выноски:

 McNoteUnitCollection units=(McNoteMultilayer)id.GetObject()).Units;

Для заполнения таблицы будет удобно записать содержимое всех выбранных объектов в единую структуру данных, подходящую для поиска и сортировки элементов. В данном примере используется структура из вложенных словарей вида: <артикул<номер_помещения, количество>>.

Загрузка шаблона

Будем считать, что у нас уже создан шаблон нужной структуры с помощью метода CreateTemplate() и сохранен в файл, например, «C:\template.dat». Загрузка таблицы из внешнего файла осуществляется с помощью метода McTable.LoadFromFile(). Создадим объект таблицы, загрузим для него структуру и наполнение из созданного шаблона, а также вызовем табличный редактор, чтобы дать пользователю возможность внести правки в шаблон, если такие имеются. Конечно, при этом шаблон таблицы должен быть записан в формат, позволяющий сохранить не только содержимое, но и структуру и форматирование таблицы.

const string FileName = "C:\\template.dat";
McTable Table = new McTable();
if (!Table.LoadFromFile(FileName))
{
  return;
}
Table.OnEdit();




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

Разбивка таблицы на страницы

Отдельно стоит упомянуть такую полезную возможность при работе с таблицами, как разбивка на страницы. По умолчанию отчет представлен в виде единой таблицы, размер которой при большом количестве строк может быть критичным. Разбить таблицу на страницы с ограничением их высоты можно с помощью метода McTable.PagesTable.SetPageHeight(). Следующий фрагмент кода разобьет таблицу на страницы высотой не более 50:

const double pageHeight = 50;
double tableHeight = Table.DbEntity.BoundingBox.SizeByY;
if (tableHeight > pageHeight)
{
  Table.Pages.SetPageHeight(pageHeight);
}



Дополнительный способ — вставить принудительный разрыв страницы с помощью метода McTable.PagesTable.SetPageBreak(). Например, чтобы разбить таблицу на две страницы в строке с индексом 7:

Table.Pages.SetPageBreak(7);

Результатом будет таблица, состоящая из двух страниц:


После того, как таблица была разбита любым из этих способов, необходимо задать точку вставки каждой из страниц относительно точки вставки таблицы с помощью метода McTable.PagesTable.SetOriginPage(), первый аргумент которого — это номер страницы, а второй — координаты точки. Например, для размещения страниц с интервалом в 5 единиц:

for (int n = 0; n < Table.Pages.Count; n++)
{
  Table.Pages.SetOriginPage(n, new Point3d(n * (tableWidth + 5 * Table.DbEntity.Scale), 0, 0));
}

Загрузка приложения в AutoCAD

Как обычно, наш пример будет запускаться в среде nanoCAD после загрузки построенной библиотеки и запуска зарегистрированной команды smpl_CreateTableReport. Для запуска приложений MultiCAD.NET в среде AutoCAD требуется использование специального приложения-адаптера (Object Enabler). Необходимо отметить, что стандартный MultiCAD Enabler for AutoCAD не содержит средств для работы с объектами из пространства имен Multicad.Symbols, поэтому для запуска приложений, имеющих дело с такими объектами, необходимо предварительно загрузить приложения СПДС GraphiCS или MechaniCS, которые содержат все примитивы, включая таблицы и выноски.

Обсуждение статьи доступно также и на нашем форуме: forum.nanocad.ru/index.php?showtopic=6510.

Перевод статьи на английский: Tables in MultiCAD.NET. Generating reports based on table templates.

Смотрите также:

Работа с таблицами в MultiCAD.NET. Часть 2. Создание и редактирование
Работа с таблицами в MultiCAD.NET. Часть 3. Внешние файлы таблиц и обмен данными с Microsoft Excel
Автор: @ISL

Комментарии (12)

  • 0
    Простите за оффтопик, но ШГ
    • 0
      Аббревиатура ШГ верна, но смысл её другой: Шрифт ГОСТ 2.304.
      • 0
        у меня этот шрифт в ttf нормальный вид имеет.
        видать у автокада (или откуда у ас скриншоты?) рендерер повышенной угрёбищности :(
  • 0
    Задумка неплохая — я про цикл статей, только более развернуто) Но для таблиц лучше использовать ATable
    • 0
      Более развернуто в какую сторону?

      Мы совсем не против ATable, работающего под nanoCAD-ом, пользователям от этого только плюс. Тогда можно будет обмениваться чертежами между платформами и они везде будут «живыми», т.е. без мёртвой прокси графики.

      Осталось только автора уговорить портировать ATable на nanoCAD, поможете?

    • 0
      А чем лучше?

      После беглого просмотра списка возможностией ATable — таблицы мультикада могут все это и гораздо больше.
      • 0
        А вы не бегло просмотрите/прочитайте, а попробуйте. Да и как часто бывает схожие по «названию» функции, на практике разительно отличаются.
        • 0
          Хм, а вы пробовали таблицы Мультикада, что однозначно пишите «Лучше»?

          Функционал таблиц в целом огромен, и произвести адекватное сравнение это сложная задача. Если есть что то конкретное — намекните хоть в какой области, что попробовать то?

          Кроме того в статье речь про API на .net, а полные возможности таблиц тут и не описаны. Их надо смотреть в документации на продукт. В ATable — «COM модель для работы с таблицами программно (новинка!)».

          Ну если смотреть более внимательно: то не вижу многих нужных фич, как например вставки блока в ячейку, динамического отчета по объектам.
          • 0
            Вы совершено не поняли о чем я говорил. ATable это как для примера. Прочтите этот и выделите основную мысль. И не стоит частные случаи выдавать за потребность большинства. Я, может, считаю что в екселе нужная фича — дамп памяти произвольной программы, но этого там нет, потому как это не нужно всем, а можно добавить и говорить что это колоссальное преимущество перед таблицами LibreOffice. И не стоит холивары разводить, занимаясь буквоедством.
            • 0
              Что вы, никакого буквоедства и холиваров. Они бессмысленны.
              Просто вы так увернно написали «Лучше», думал ваше мнение на чем то основано…

            • 0
              Вы видимо исходите из предположения что это повторение автокадовских таблиц и специально адаптированные будут лучше в любом случае, тогда стало бы понятно, раз ATable просто пример. Тут я с вами готов согласиться.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка