Как получить список листов чертежа и имена принтеров для каждого листа?

Автор Тема: Как получить список листов чертежа и имена принтеров для каждого листа?  (Прочитано 28829 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Я в твоём сообщении внёс ряд правок: http://adn-cis.org/forum/index.php?topic=7689.msg25241#msg25241Проверь.

Всё верно! Спасибо!

Завтра отпишусь о результате!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1115
  • Карма: 173
Я не очень понимаю, а почему не использовать подшивку / публикацию сразу? Без танцев с бубнами?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Я не очень понимаю, а почему не использовать подшивку / публикацию сразу? Без танцев с бубнами?

Потому что для начала её нужно сформировать (то есть не только сформировать, но и учесть только те листы, которые настроены на PDF-принтер, остальные проигнорировать), причём нужно убедиться, что печать пройдёт без «ой» и «ай-я-яй» (определить параметры настройки печати для каждого листа, а то вдруг какой-то лист имеет настройку на PDF-принтер, а рамка для печати смещена или ещё чего).

Эта задача подразумевает предварительную обработку данных по каждому чертежу.



Я нашёл решение, но увы, оно не в рамках LISP-программирования, но с помощью AcCoreConsole.exe. Подготавливаю ответ. Только вот хочу узнать у Александра Наумовича: выкладывать его здесь? Или создать другую тему?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1115
  • Карма: 173
Если мне не изменяет мой склероз, то выводить на pdf / dwf подшивку можно независимо от того, на какой физический принтер был настроен лист. Правый пинок -> печать в pdf (если, опять же, не ошибаюсь).
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Если мне не изменяет мой склероз, то выводить на pdf / dwf подшивку можно независимо от того, на какой физический принтер был настроен лист. Правый пинок -> печать в pdf (если, опять же, не ошибаюсь).

Вы правы, но только лишь в том случае, если формат листа, настроенного на физический принтер, также имеется и в PDF-принтере. Однако тогда печать такого листа (настроенный на физический принтер) будет иметь не совсем корректный (по ГОСТу) внешний вид. Именно по этой причине важно сперва определять данные о листе и его настройке принтера.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1115
  • Карма: 173
Ну, ко мне можно и на "ты" ;)
А так - насколько я помню, последние версии ГОСТ по ЕСКД допускали определенные вольности в оформлении листов. Особенно в части полей.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
А так - насколько я помню, последние версии ГОСТ по ЕСКД допускали определенные вольности в оформлении листов. Особенно в части полей.

Может быть, только в нашей организации пока таких вольностей не допускают.

Ну, ко мне можно и на "ты"

Хорошо, понял.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я нашёл решение, но увы, оно не в рамках LISP-программирования, но с помощью AcCoreConsole.exe. Подготавливаю ответ. Только вот хочу узнать у Александра Наумовича: выкладывать его здесь? Или создать другую тему?
Можешь выложить здесь. Если понадобится - я перенесу.

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

Отмечено как Решение Пашин Евгений 22-03-2017, 16:43:26

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
P.S.: Так мой код у тебя заработал или нет?

Увы, но не заработал.

Можешь выложить здесь. Если понадобится - я перенесу.

Итак, предупреждаю, решение не является оптимальным:

1. С помощью AcCoreConsole.exe (AutoCAD 2014) и скрипта start.scr я получаю dxf-файл.

start.scr выглядит так:

Код - INI [Выбрать]
  1. _filedia
  2. 0
  3. _dxfout
  4. "C:\Users\PASHIN~1\AppData\Local\Temp\DWG2PDF22032017172702888554\start.dxf"
  5. 16
  6. _filedia
  7. 1
  8.  

2. Парсим dxf-файл с помощью регулярных выражений и определяем листы с их настройками принтера. В моём случае я ограничился поиском тех листов, у которых имя принтера «DWG_To_PDF_Gallurgy.pc3». Для этого я создал свой класс, в который складывал имена принтеров, имена листов и форматы принтера. Затем я отсеял ненужные мне листы:

Как я парсил DXF-файл:
Код - vb.net [Выбрать]
  1.     Public Sub Read_DXF_And_Generate_DSD(ByVal OriginalDWG As String, ByVal DXFPath As String, ByVal DSDPath As String)
  2.         Dim DXF As String
  3.         DXF = IO.File.ReadAllText(DXFPath)
  4.  
  5.         Dim DSD As New acDsdData
  6.  
  7.         Dim regexp As New Regex("AcDbPlotSettings(.*?)• 71")
  8.         Dim regexpName As New Regex("•  2(.*?)•  4")
  9.         Dim regexpFormat As New Regex("•  4(.*?)•  6")
  10.         Dim regexpLayout As New Regex("•AcDbLayout(.*?)• 70")
  11.  
  12.         Dim PrinterName As String
  13.         Dim PrinterFormat As String
  14.         Dim LayoutName As String
  15.  
  16.         Dim i As Integer
  17.         Dim m As MatchCollection
  18.  
  19.         DXF = DXF.Replace(Chr(10), "•")
  20.  
  21.         m = regexp.Matches(DXF)
  22.         For i = 0 To m.Count - 1
  23.  
  24.             Dim mm As MatchCollection
  25.             mm = regexpName.Matches(m.Item(i).Value)
  26.             Try
  27.                 PrinterName = (mm.Item(0).Value)
  28.                 PrinterName = PrinterName.Replace("•  2", "")
  29.                 PrinterName = PrinterName.Replace("•  4", "")
  30.                 PrinterName = PrinterName.Replace(Chr(13), "")
  31.                 PrinterName = PrinterName.Replace("•", "")
  32.  
  33.                 Dim mmm As MatchCollection
  34.                 mmm = regexpFormat.Matches(m.Item(i).Value)
  35.                 PrinterFormat = (mmm.Item(0).Value)
  36.                 PrinterFormat = PrinterFormat.Replace("•  4", "")
  37.                 PrinterFormat = PrinterFormat.Replace("•  6", "")
  38.                 PrinterFormat = PrinterFormat.Replace(Chr(13), "")
  39.                 PrinterFormat = PrinterFormat.Replace("•", "")
  40.  
  41.                 Dim mmmm As MatchCollection
  42.                 mmmm = regexpLayout.Matches(m.Item(i).Value)
  43.                 LayoutName = (mmmm.Item(0).Value)
  44.                 LayoutName = LayoutName.Replace("•AcDbLayout", "")
  45.                 LayoutName = LayoutName.Replace("•  1", "")
  46.                 LayoutName = LayoutName.Replace("• 70", "")
  47.                 LayoutName = LayoutName.Replace(Chr(13), "")
  48.                 LayoutName = LayoutName.Replace("•", "")
  49.  
  50.                 Dim DSDL As New acLayoutInfo
  51.                 DSDL.PrinterFormat = PrinterFormat
  52.                 DSDL.PrinterName = PrinterName
  53.                 DSDL.LayoutName = LayoutName
  54.  
  55.                 DSD.Layouts.Add(DSDL)
  56.             Catch ex As Exception
  57.                 MsgBox(ex.Message)
  58.             End Try
  59.         Next
  60.  
  61. StartHerePlease:
  62.  
  63.         For Each DSDL As acLayoutInfo In DSD.Layouts
  64.  
  65.             If DSDL.LayoutName.Trim = "Model" Then
  66.                 DSD.Layouts.Remove(DSDL)
  67.                 GoTo StartHerePlease
  68.             End If
  69.  
  70.             If DSDL.LayoutName.Trim = "Модель" Then
  71.                 DSD.Layouts.Remove(DSDL)
  72.                 GoTo StartHerePlease
  73.             End If
  74.  
  75.             If DSDL.LayoutName.Trim = "Элементы оформления" Then
  76.                 DSD.Layouts.Remove(DSDL)
  77.                 GoTo StartHerePlease
  78.             End If
  79.  
  80.             If DSDL.PrinterName <> "DWG_To_PDF_Gallurgy.pc3" Then
  81.                 DSD.Layouts.Remove(DSDL)
  82.                 GoTo StartHerePlease
  83.             End If
  84.  
  85.         Next
  86.  
  87.         Make_DSD_File(OriginalDWG, DSDPath, DSD)
  88.  
  89.     End Sub
  90.  

Как я генерировал DSD-файл:

Код - vb.net [Выбрать]
  1.     Public Function Make_DSD_File(ByVal OriginalDWG As String, ByVal PathName As String, ByRef DSD As acDsdData) As Boolean
  2.  
  3.         Make_DSD_File = False
  4.  
  5.         Dim DsdFile As New List(Of String)
  6.  
  7.         If DSD.Layouts.Count > 0 Then
  8.  
  9.             ' Создаем DSD-файл
  10.             With DsdFile
  11.                 .Add("[DWF6Version]")
  12.                 .Add("Ver=1")
  13.                 .Add("[DWF6MinorVersion]")
  14.                 .Add("MinorVer=1")
  15.  
  16.                 For Each DSDL As acLayoutInfo In DSD.Layouts
  17.                     If DSDL.LayoutName.Trim = "Model" Then
  18.                     ElseIf DSDL.LayoutName.Trim = "Модель" Then
  19.                     ElseIf DSDL.LayoutName.Trim = "Элементы оформления" Then
  20.                     Else
  21.                         If DSDL.PrinterName = "DWG_To_PDF_Gallurgy.pc3" Then
  22.                             .Add("[DWF6Sheet:" & IO.Path.GetFileNameWithoutExtension(OriginalDWG) & "-" & DSDL.LayoutName & "]")
  23.                             .Add("DWG=" & OriginalDWG)
  24.                             .Add("Layout=" & DSDL.LayoutName)
  25.                             .Add("Setup=")
  26.                             .Add("OriginalSheetPath=" & OriginalDWG)
  27.                             .Add("Has Plot Port=0")
  28.                             .Add("Has3DDWF=0")
  29.                         End If
  30.                     End If
  31.                 Next
  32.  
  33.                 .Add("[Target]")
  34.                 .Add("Type=6")
  35.                 .Add("DWF=" & PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf"))
  36.                 .Add("OUT=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
  37.                 .Add("PWD=")
  38.  
  39.                 .Add("[MRU block template]")
  40.                 .Add("MRU=0")
  41.                 .Add("[MRU Local]")
  42.                 .Add("MRU=3")
  43.                 .Add("File0=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
  44.                 .Add("File1=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
  45.                 .Add("File2=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
  46.                 .Add("[MRU Sheet List]")
  47.                 .Add("MRU=0")
  48.  
  49.                 .Add("[AutoCAD Block Data]")
  50.                 .Add("IncludeBlockInfo=0")
  51.                 .Add("BlockTmplFilePath=")
  52.  
  53.                 .Add("[SheetSet Properties]")
  54.                 .Add("IsSheetSet=FALSE")
  55.                 .Add("IsHomogeneous=FALSE")
  56.                 .Add("SheetSet Name=")
  57.                 .Add("NoOfCopies=1")
  58.                 .Add("PlotStampOn=FALSE")
  59.                 .Add("ViewFile=FALSE")
  60.                 .Add("JobID=0")
  61.                 .Add("SelectionSetName=")
  62.                 .Add("AcadProfile=<<Профиль без имени>>")
  63.                 .Add("CategoryName=")
  64.                 .Add("LogFilePath=")
  65.                 .Add("IncludeLayer=FALSE")
  66.                 .Add("LineMerge=FALSE")
  67.                 .Add("CurrentPrecision=")
  68.                 .Add("PromptForDwfName=TRUE")
  69.                 .Add("PwdProtectPublishedDWF=FALSE")
  70.                 .Add("PromptForPwd=FALSE")
  71.                 .Add("RepublishingMarkups=FALSE")
  72.                 .Add("PublishSheetSetMetadata=FALSE")
  73.                 .Add("PublishSheetMetadata=TRUE")
  74.                 .Add("3DDWFOptions=0 1")
  75.             End With
  76.             IO.File.WriteAllLines(PathName.Replace(".dsd", "_1251.dsd"), DsdFile, System.Text.Encoding.GetEncoding(1251))
  77.  
  78.             Make_DSD_File = True
  79.  
  80.         Else
  81.  
  82.             MsgBox("Файл " & PathName & " не может быть переведен в PDF поскольку отсутствуют листы, настроенные на принтер DWG_To_PDF_Gallurgy.pc3")
  83.             Exit Function
  84.  
  85.         End If
  86.  
  87.         Return Make_DSD_File
  88.  
  89.     End Function

3. Запускаем AcCoreConsole.exe и Publish.scr:

Publish.scr

Код - INI [Выбрать]
  1. _filedia
  2. 0
  3. _-publish
  4. C:\Users\PASHIN~1\AppData\Local\Temp\DWG2PDF22032017172702888554\start_1251.dsd
  5. _filedia
  6. 1
  7.  

Как я запускаю AcCoreConsole.exe:

Код - vb.net [Выбрать]
  1.         Dim ExecutablePath As String = "C:\Program Files\Autodesk\AutoCAD 2014\accoreconsole.exe"
  2.         Dim arg As String = " /i """ & Path & """ /s """ & TempFolder &
  3.                 "\" & TempSCRFile & """ /l en-US"
  4.         DXF_OUT_START(ExecutablePath, arg)

Код - vb.net [Выбрать]
  1.     Public Sub DXF_OUT_START(ByVal ExecutableAppPath As String, ByVal Args As String)
  2.  
  3.         Try
  4.             Dim connect As System.Diagnostics.Process
  5.             connect = New System.Diagnostics.Process()
  6.             With connect
  7.                 .StartInfo.FileName = ExecutableAppPath
  8.                 .StartInfo.Arguments = Args
  9.                 .StartInfo.WindowStyle = ProcessWindowStyle.Hidden
  10.                 .StartInfo.UseShellExecute = False
  11.                 .StartInfo.RedirectStandardOutput = True
  12.                 .StartInfo.CreateNoWindow = True
  13.                 .Start()
  14.  
  15.                 Dim result2 As String = connect.StandardOutput.ReadToEnd ' Вот без преувеличения - это ВАЖНАЯ строка! Она не даёт подвисать AcCoreConsole.exe!!! Почему? Не знаю пока.
  16.  
  17.             End With
  18.         Catch ex As Exception
  19.  
  20.         End Try
  21.  
  22.     End Sub

Дополнительно:

1. Если тестировать будете с помощью BAT-файла, то кодировка должна быть OEM-866 (или просто 866). Содержание файла:

Код - INI [Выбрать]
  1. "C:\Program Files\Autodesk\AutoCAD 2014\accoreconsole.exe" /i "D:\Пашин Евгений\Рабочий стол\Лоция checker\для Пашина\22.132-04501-АП\22.132-04501-АП-17-Кабельный журнал.dwg" /s "C:\Users\PASHIN~1\AppData\Local\Temp\DWG2PDF22032017172702888554\Publish.scr" /l en-US
  2. Pause

2. SCR - файлы должны быть в кодировке UTF-8 (без BOM)
3. DSD - файлы должны быть в кодировке 1251
4. К сожалению, нет обратной связи с AcCoreConsole.exe (это я хотел бы как-то исправить, если кто знает как - подскажите!)
5. Пока неизвестно как всё это работает с файлами, созданными в разных вертикальных решениях AutoCAD-a.
6. Факт: вместо 10 минут (по старому варианту) вся обработка и публикация для 19 файлов заняла чуть менее 2 минут!!! Попробовал публикацию файлов с подложками, который старый вариант вообще никак не мог опубликовать, это решение выполнило публикацию за 6 секунд. Это просто неслыханно круто!

Вот видео готового решения:



Проверил для AcCoreConsole.exe AutoCAD 2017 - тоже отлично работает!

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
От себя добавлю: стоит подумать о создании на форуме раздела под AcCoreConsole.exe. Эта штука незаслуженно «пылится на полке».

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну если работает, то и слава Богу. Правда dxf-файлы бывают очень большими - сотни мегабайт, а то и гигабайты. А ты его сразу считываешь весь в память. Тут может быть проблема.
Смысла в отдельном разделе для AcCoreConsole я не вижу. Если использовать скрипты (.scr), как ты, то это сюда: http://adn-cis.org/forum/index.php?board=12.0 если lisp, то в этот раздел, а если .NET - то в раздел .NET
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Правда dxf-файлы бывают очень большими - сотни мегабайт, а то и гигабайты.

Один файл у меня занимал 134 Мб - файл Civil-a. Довольно шустро он с ним отработал. Всего 9 секунд на всё: создание dxf-файла, парсинг и публикацию в PDF. Я пока не обратил внимания на проблемы со скоростью создания dxf-файлов. Я использую File.ReadAllText - метод, чтобы затем пропарсить dxf-файл. Пока затрудняюсь сказать, будут ли проблемы с большими файлами - я, увы, не эксперт по данному направлению.

Если использовать скрипты (.scr), как ты, то это сюда: http://adn-cis.org/forum/index.php?board=12.0

То есть использование скриптов (.scr) в рамках AcCoreConsole.exe тоже можно перенести в этот раздел?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
То есть использование скриптов (.scr) в рамках AcCoreConsole.exe тоже можно перенести в этот раздел?
Пусть эта тема остаётся здесь, так как в неё есть предложения и средствами lisp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение