Как часто в горестной разлуке,
В моей блуждающей судьбе,
Комплект КД, я думал о тебе!
Итак, в предыдущей статье я остановился на автоматизации отдельного документа и пообещал рассказать о том, как удалось организовать работу с комплектом разнородных документов при помощи вспомогательной базы Excel и как оказалось возможным делать комплекты документов вообще не открывая Word.
Под комплектом я здесь понимаю набор файлов форматов Word, Visio и AutoCAD, относящихся к одному общему проекту или изделию. То есть те файлы, которые представляют документы с одинаковыми, взаимно синхронизируемыми текстовыми полями. Далее, я буду называть этот комплект — автоматизированным комплектом документов или АКД.
Давайте посмотрим, как выглядит АКД в проводнике Windows.

Обратите внимание на файл variables.xls. Именно здесь располагаются все переменные, которые мы хотим централизованно распределять по нашему комплекту. В этом файле, при работе макросов VBA Word, Visio, AutoCad — автоматически создаются страницы, соответствующие этим файлам и содержащим все специфические переменные этих файлов.
Есть два нюанса. Первый — страница «All». Она понадобилась для того, чтобы сохранять переменные, которые одинаковы для ВСЕХ без исключения документов АКД. Например, для переменной vObj — Объект проектирования = Зал славы. :)) Второй нюанс — для документов Visio вкладка создается для каждой страницы документа, так как обычно достаточно удобно держать все схемы проекта в одном файле. В принципе, никто не мешает разнести эти схемы и по разным файлам, но в Excel попадут все равно названия страниц этих документов. Ну и дополнительно, чисто для эстетики, цвета вкладок-листов Excel соответствуют типам файлов. Например, синие — это Word.
Так как в предыдущей статье я уже рассказал о принципе формирования и обработки полей-переменных, то сейчас расскажу только о дополнительных вещах, относящихся к работе с файлом переменных. На следующем рисунке показана связь переменных, которые мы создаем с файлом variables.xls. Имя файла может быть любым и оно задается в основном окне макроса — в нижнем белом поле.

Методом проб и ошибок я пришел к такой организации работы со своим «детищем»:
-
Создается новый файл. Как правило, уже на основе имеющегося шаблона.
-
В окне макроса нажимается кнопка «Сохранить». При этом в фале переменных автоматически создается новая вкладка для этого файла и на нее заносятся имеющиеся в документе переменные. Если эти переменные уже есть на вкладке «All» — то они не вносятся на персональную вкладку документа.
-
После сохранения, все «персональные» переменные документа отображаются и редактируются на вкладке окна макроса «Локальные». Общие переменные АКД — отображаются на вкладке «Общие». (Кстати, там они не редактируются, а только отображаются, во избежание ошибочных изменений, которые затронут весь комплект)
-
Если я хочу сделать какие-то из переменных документа — общими, то я просто потом перехожу в файл Excel и перетаскиваю их строки с листа документа на лист «All». А если я хочу переопределить общую переменную персонально для конкретного файла, например, если везде разработчик один и тот же, но в единственном документе он другой то я копирую строку с листа «All» на персональную вкладку этого самого «особенного» документа.
-
Такое повторяется для каждого документа комплекта (если комплект создается «с нуля». Если комплект типовой — то вообще ничего делать не надо, только в Excel или в окне макроса переменные менять.)
Ниже приведу, для примера, код функции, которая обеспечивает занесение переменных документа в файл.
Код функции записи переменных и дисклаймер
На всякий случай, сообщаю — я не профессиональный программист. Поэтому представленный код не является образцом для подражания и периодически балует меня окнами ошибок. Однако, моя идеология программирования заключается в том, чтобы не делать код таким, чтобы он вносил непоправимые ошибки в документы. Соответственно, по мере возникновения ошибок, я просто вношу соответствующие правки в код и работаю дальше.
Sub xlAddVars(ExcelFile As String) Dim xlWSh, xlWShAll As Object Dim xlWbk As Object Dim xlApp As Object Dim Checked As Boolean Dim FileEx As Boolean Dim AllLastRow, LastRow Dim SheetName As String SheetName = "" On Error Resume Next SheetName = ActiveDocument.Name On Error GoTo openexcel Set xlApp = GetObject(, "excel.application") Checked = False For a = 1 To xlApp.Workbooks.Count If xlApp.Workbooks(a).Name = ExcelFile Then Checked = True: Set xlWbk = xlApp.Workbooks(ExcelFile): Exit For Next If Not Checked Then On Error GoTo CreateFile FileEx = FileDateTime(ActiveDocument.Path + "" + ExcelFile) On Error GoTo 0 If FileEx Then Set xlWbk = xlApp.Workbooks.Open(ActiveDocument.Path + "\" + ExcelFile) End If Found = False For a = 1 To xlWbk.sheets.Count If xlWbk.sheets(a).Name = SheetName Then Found = True Next If Not Found Then Set xlWbs = xlWbk.sheets.Add(After:=xlApp.Worksheets(xlApp.Worksheets.Count)) xlWbs.Name = SheetName xlWbs.Tab.ColorIndex = 37 End If Set xlWSh = xlApp.ActiveWorkbook.Worksheets(SheetName) Set xlWShAll = xlApp.ActiveWorkbook.Worksheets("All") 'Calculate last used rows in sheets AllLastRow = xlWShAll.Cells(1, 1).End(-4121).Row If AllLastRow >= 65536 Then If xlWShAll.Cells(1, 1).Value = Empty Then AllLastRow = 0 Else AllLastRow = 1 End If LastRow = xlWSh.Cells(1, 1).End(-4121).Row If LastRow >= 65536 Then If xlWSh.Cells(1, 1).Value = Empty Then LastRow = 0 Else LastRow = 1 End If 'Запись кол-ва листов ActiveDocument.Variables("vPages").Value = ActiveDocument.BuiltInDocumentProperties(wdPropertyPages) For b = 1 To ActiveDocument.Variables.Count Checked = False 'Search in All sheet For a = 1 To AllLastRow If xlWShAll.Cells(a, 1).Value = ActiveDocument.Variables(b).Name Then Checked = True Exit For End If Next 'Search in self sheet If Not Checked Then For a = 1 To LastRow sL = ActiveDocument.Variables(b).Name sR = "" sL = Left(sL, InStr(1, sL, "_")) If sL = "" Then sL = ActiveDocument.Variables(b).Name Else sR = Right(ActiveDocument.Variables(b).Name, Len(ActiveDocument.Variables(b).Name) - InStr(1, ActiveDocument.Variables(b).Name, "_")) If xlWSh.Cells(a, 1).Value = sL Then If sR = "" Then xlWSh.Cells(a, 2).Value = "'" + CStr(ActiveDocument.Variables(b).Value) Checked = True Exit For Else For bb = 2 To 100 If xlWSh.Cells(1, bb).Value = sR Then xlWSh.Cells(a, bb).Value = "'" + CStr(ActiveDocument.Variables(b).Value) Checked = True Exit For End If Next End If End If Next End If 'If not found - add personal row in self sheet If Not Checked Then xlWSh.Cells(LastRow + 1, 1).Value = "'" + CStr(ActiveDocument.Variables(b).Name) xlWSh.Cells(LastRow + 1, 2).Value = "'" + CStr(ActiveDocument.Variables(b).Value) LastRow = LastRow + 1 End If Next Set xlApp = Nothing ' the application, then release the reference. Exit Sub CreateFile: Set xlWbk = xlApp.Workbooks.Add xlWbk.ActiveSheet.Name = "All" xlApp.DisplayAlerts = False For a = xlWbk.sheets.Count To 2 Step -1 xlWbk.sheets(a).Delete Next xlApp.DisplayAlerts = True Set xlWbs = xlWbk.sheets.Add(After:=xlApp.Worksheets(xlApp.Worksheets.Count)) xlWbs.Name = SheetName xlApp.Workbooks(xlWbk.Name).SaveAs (ActiveDocument.Path + "\" + ExcelFile) Resume openexcel: Set xlApp = CreateObject("excel.application") xlApp.Visible = True Resume End Sub
Как и в случае немодального окна макроса, я делаю Excel доступным для редактирования во время работы. Произвольным образом, при этом, могу редактировать значения переменных там, где мне удобно.
Итого, проработав все документы комплекта, мы получаем каталог файлов и один управляющий Excel-файл для централизованного внесения изменений. В некоторых случаях, комплекты получаются таковы, что отредактировав файл переменных можно избежать работы в Word полностью. Разве что придется открыть эти файлы, нажать кнопку макроса «Обновить» и убедиться в корректной подстановке значений в поля перед печатью этого документа.
Теперь давайте посмотрим, что можно сделать, если какой-либо документ комплекта требует специфической проработки. Например, это, в моем случае, будет таблица соединений и подключений.

Заполнять строки таблицы в Word мне неудобно, я лучше это сделаю в Excel. Тем более там можно произвести расчет значений, например, длин кабелей по формулам, автоматом пронумеровать по возрастанию порты, и т.п.
Для переноса этой информации в Word — я сделаю макрос импорта таблицы. При этом, так-как операция эта специфическая именно для «таблицы соединений», то этот макрос я буду создавать именно в этом файле, в файле шаблона таблицы, а не глобально в normal.dotm.
Он из себя представляет следующее: (см внутри)
'Формирование списка Sub BuildSpec2() Dim sTab As Table Dim xlWSh As Object Dim xlApp As Object Dim of As Boolean Dim nf As Boolean Dim cf As Boolean Dim oCol, nCol, cCol As Integer i = Selection.Rows.Count If i = 0 Then MsgBox ("Необходимо выделить строки спецификации, куда будет помещены строки раздела (Оборудование)!") Exit Sub End If Response = MsgBox("Экспортировать из Эксел?", _ vbYesNo, _ "Заполнение таблицы") If Response = vbNo Then Exit Sub On Error Resume Next Set xlApp = GetObject(, "Excel.Application") If Err.Number <> 0 Then Err.Clear ' Clear Err object in case error occurred. MsgBox ("Сначала необходимо открыть в Excel соответствующую спецификацию") Exit Sub End If On Error GoTo 0 Set xlRange = xlApp.Selection If xlRange.Rows.Count < 2 Then MsgBox ("Необходимо выделить диапазон строк в Экселе.") Exit Sub End If UserForm1.Show Application.ScreenUpdating = False Set sTab = Tables(1) i = Selection.Rows(1).Index - 1 For a = 1 To xlRange.Rows.Count - 1 sTab.Rows.Add For b = 1 To 9 sTab.Rows(a + i).Cells(b).Range.Text = xlRange.Rows(a).Cells(b).Text Next UserForm1.Label2.Caption = sTab.Rows(a + i).Cells(1).Range.Text UserForm1.Repaint Next UserForm1.Hide Application.ScreenUpdating = True Set xlApp = Nothing ' the application, then release the reference. End Sub
Принцип работы этого макроса заключается единственно в том, чтобы взять диапазон выделенных предварительно в Excel строк и перенести в заготовку таблицы, имеющуюся в шаблоне документа.
При этом, если шаблон сделан правильно (а он сделан правильно), то при заполнении таблицы на первом листе, новые строки таблицы появятся на вновь созданном втором (третьем, четвертом, …) листе (причем этот лист будт сделан уже с другими форматными рамками, соотвтетсвующими последующим листам ЕСКД, с маленькой нижней рамкой основной надписи).
Еще один специфичный документ — спецификация. Часть его заполняется на основе шаблона тем же макросом что и таблица кабелей (именно поэтому, если вы обратили внимание, там в названии макроса стоит Buildspec)
Здесь можно дополнительно сделать формирование списка документации, который… правильно! Соответствует набору вкладок в файле variables.xls. Поэтому очередной специфический макрос для документа «спецификация» будет осуществлять просмотр листов-вкладок «Excel» и в порядке следования занесет их в таблицу «Документация». Названия, коды, примечания — будут взяты из соответствующих переменных, введенных ранее для этих документов.
В комплекте документов есть еще ряд файлов Visio и AutoCAD. Работа с ними отличается от работы с Excel и Word, что само собой разумеется. И эти отличия заслуживают отдельного рассмотрения.
В следующей статье, я опишу принципы и некоторые детали реализации автоматизации Visio — документов. В том числе работу с шаблонами и Stencils-ами.
ссылка на оригинал статьи https://habr.com/ru/company/stc_spb/blog/651271/
Добавить комментарий