Как стать автором
Обновить

Автоматизация разработки конструкторской документации средствами VBA. Продолжение

Время на прочтение7 мин
Количество просмотров5.5K

Как часто в горестной разлуке,
В моей блуждающей судьбе,
Комплект КД, я думал о тебе!

Итак, в предыдущей статье я остановился на автоматизации отдельного документа и пообещал рассказать о том, как удалось организовать работу с комплектом разнородных документов при помощи вспомогательной базы Excel и как оказалось возможным делать комплекты документов вообще не открывая Word.

Под комплектом я здесь понимаю набор файлов форматов Word, Visio и AutoCAD, относящихся к одному общему проекту или изделию. То есть те файлы, которые представляют документы с одинаковыми, взаимно синхронизируемыми текстовыми полями. Далее, я буду называть этот комплект - автоматизированным комплектом документов или АКД.

Давайте посмотрим, как выглядит АКД в проводнике Windows.

Автоматизированный комплект документов стать
Автоматизированный комплект документов стать

Обратите внимание на файл variables.xls. Именно здесь располагаются все переменные, которые мы хотим централизованно распределять по нашему комплекту. В этом файле, при работе макросов VBA Word, Visio, AutoCad - автоматически создаются страницы, соответствующие этим файлам и содержащим все специфические переменные этих файлов.

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

Так как в предыдущей статье я уже рассказал о принципе формирования и обработки полей-переменных, то сейчас расскажу только о дополнительных вещах, относящихся к работе с файлом переменных. На следующем рисунке показана связь переменных, которые мы создаем с файлом variables.xls. Имя файла может быть любым и оно задается в основном окне макроса - в нижнем белом поле.

Связь переменных с файлом Excel
Связь переменных с файлом Excel

Методом проб и ошибок я пришел к такой организации работы со своим "детищем":

  1. Создается новый файл. Как правило, уже на основе имеющегося шаблона.

  2. В окне макроса нажимается кнопка "Сохранить". При этом в фале переменных автоматически создается новая вкладка для этого файла и на нее заносятся имеющиеся в документе переменные. Если эти переменные уже есть на вкладке "All" - то они не вносятся на персональную вкладку документа.

  3. После сохранения, все "персональные" переменные документа отображаются и редактируются на вкладке окна макроса "Локальные". Общие переменные АКД - отображаются на вкладке "Общие". (Кстати, там они не редактируются, а только отображаются, во избежание ошибочных изменений, которые затронут весь комплект)

  4. Если я хочу сделать какие-то из переменных документа - общими, то я просто потом перехожу в файл Excel и перетаскиваю их строки с листа документа на лист "All". А если я хочу переопределить общую переменную персонально для конкретного файла, например, если везде разработчик один и тот же, но в единственном документе он другой то я копирую строку с листа "All" на персональную вкладку этого самого "особенного" документа.

  5. Такое повторяется для каждого документа комплекта (если комплект создается "с нуля". Если комплект типовой - то вообще ничего делать не надо, только в 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 полностью. Разве что придется открыть эти файлы, нажать кнопку макроса "Обновить" и убедиться в корректной подстановке значений в поля перед печатью этого документа.


Теперь давайте посмотрим, что можно сделать, если какой-либо документ комплекта требует специфической проработки. Например, это, в моем случае, будет таблица соединений и подключений.

Exel и Word. (... Добро и зло. А выбрать нам дано - одно.) :)))
Exel и 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-ами.

Теги:
Хабы:
+2
Комментарии3

Публикации

Информация

Сайт
www.stc-spb.ru
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия

Истории