Одна из задач отдела технической экспертизы в части нормоконтроля — выявление в проектно-сметной документации устаревших ссылок на нормативные документы. Следовательно, при каждой проверке документации неизбежно сравнение существующих ссылок на ГОСТ, ОСТ, СНиП
Поначалу выглядит нереальной даже частичная автоматизация такой работы. Тем не менее, если разбить задачу на части и вооружиться подходящими инструментами, проблема оказывается вполне разрешимой.
Во-первых, как уже сказано, в качестве электронного архива используется TDMS, где каждый документ любого объекта доступен с помощью кода, написанного на VBScript.
Во-вторых, необходима база данных нормативно-технической документации, к которой можно было бы обращаться запросами либо SQL, либо существующего API. Выбираем NormaCS, продукт с открытой архитектурой. В программе реализована COM-модель для работы с базой и получения доступа к документам и их атрибутам.
В-третьих, нужен программист, который уверенно пишет на VBScript и AutoLISP. С таким особых проблем нет. Сначала я писал сам (особенно в части AutoLISP), а окончательную доводку передал коллеге.
Итак, что имеется:
Наибольший интерес представляет сбор текстовых строк из чертежа AutoCAD, то есть из формата DWG. Сбор осложняется тем, что текст может храниться самым разным образом — в объектах типа AcDbAttributeReference, AcDbMText, AcDbText.
Эту задачу решили, что называется, «в лоб»: перебираются все объекты, а при обнаружении объектов нужного типа текстовые строки добавляются к списку. Код написан на AutoLISP:
(defun alxd:text_from_drawing( / oDoc oBlocks oBlkDef oObj sObjName ret)
(setq
oDoc (vlax-get-property (vlax-get-acad-object) 'ActiveDocument)
oBlocks (vlax-get-property oDoc 'Blocks)
ret (list)
)
(vlax-for oBlkDef oBlocks
(vlax-for oObj oBlkDef
(setq sObjName (vlax-get-property oObj 'ObjectName))
(if (or (= sObjName "AcDbText") (= sObjName "AcDbMText") (= sObjName "AcDbAttributeReference"))
(setq ret (append ret (list (vlax-get-property oObj 'TextString))))
)
)
)
(vlax-release-object oBlocks)
(vlax-release-object oDoc)
ret
)
Выполнение кода происходит в момент закрытия документа в приложении.
Приводить весь код нет необходимости — ограничимся одним лишь шаблоном регулярного выражения. Здесь это самое главное:
Set rexp = CreateObject("VBScript.RegExp")
rexp.Global = True
rexp.IgnoreCase = False
rexp.Pattern = "([A-Я][A-Яa-я]+[ +]?[A-Яa-я]?[ ]?\d[0-9.+]+\d\*?)"
Set mchs = rexp.Execute(context)
Set fnd = NormacsApplication.Find
if rexp.Test(code) then
Set mchs = rexp.Execute(code)
fnd.Index = mchs(0).SubMatches(0)
fnd.Number = mchs(0).SubMatches(1)
if Len(fnd.Index) = 0 or Len(fnd.Number ) = 0 then exit function
fndres = fnd.Execute
if fndres = true then result = 1
if fndres = true and fnd.Documents(1).IsActual then
result = 2
end if
end if
В итоге сравнение идет по двум критериям: наличию в базе и актуальности документа.
Следует помнить, что предлагаемое решение не позволяет автоматически искать ссылки, которые существуют в виде растрового изображения в документе. Существуют и другие ограничения: найденный в NormaCS документ невозможно открыть средствами TDMS, а при огромных объемах текстовых данных не следует ждать высокой скорости выполнения операций. Однако при этом инженер получает возможность уже на ранней стадии проектирования проверить актуальность используемого нормативно-технического документа. И уж тем более очевидны преимущества для специалиста по нормоконтролю: