Option Explicit
'Stores block names & attributes for 1st inserted block of each
Public AllBlocks As Scripting.Dictionary
'Stores attributes for selected block
Public AllAttribs As Variant
'Macro for user interface
Public Sub Ua()
Dim myFiles As Variant 'Stores filenames selected in array
myFiles = GetFiles 'Store filenames selected by user in array
'AllBlocks is a public variable
Set AllBlocks = New Scripting.Dictionary 'Initialize storage
BlockDialog.BlockPicked = "" 'Initialize check variable
Set AttribDialog.AttribPicked = Nothing 'Initialize check variable
TextDialog.DoUpdate = False 'Initialize check variable
'If files are selected
If IsArray(myFiles) Then
Dim myDoc As AcadDocument 'Need a variable for a drawing
'Get the first drawing selected by user
Set myDoc = AcadApplication.Documents.Open(myFiles(0))
GetBlocks myDoc, AllBlocks 'Get all attributed blocks in dwg
End If
'There may be no attributed blocks, so need to test
If AllBlocks.Count > 0 Then BlockDialog.Show 'Show list of blocks
'If a block was selected
If BlockDialog.BlockPicked"" Then
'Store attributes from selected block in public variable
AllAttribs = AllBlocks.Item(BlockDialog.BlockPicked)
AttribDialog.Show 'Show list of attributes
End If
'If an attribute was selected
If Not (AttribDialog.AttribPicked Is Nothing) Then
TextDialog.Show 'Display dialog to get new string
End If
'If OK was hit in the TextDialog
If TextDialog.DoUpdate Then
'Change all the drawings the user selected
ProcessDrawings myFiles, _
BlockDialog.BlockPicked, _
AttribDialog.AttribPicked.TagString, _
TextDialog.NewText
'Inform the user things are done
MsgBox "Process is complete.", vbOKOnly, "ABC's of VBA"
Else
myDoc.Close False 'Close drawing left open during cancel
End If
End Sub
'Open all given drawings and change selected attribute
Private Sub ProcessDrawings(ByVal Dwgs As Variant, _
ByVal BlockName As String, _
ByVal TagName As String, _
ByVal NewText As String)
'The following creates a selection set filter
Dim fType(0 To 1) As Integer 'Stores DXF-style codes
Dim fData(0 To 1) As Variant 'Stores filters
fType(0) = 0: fData(0) = "INSERT" 'Filter for block insertions
fType(1) = 2: fData(1) = BlockName 'Filter for specific block
Dim openFilename As String 'Stores name of open drawing
Dim myDwg As AcadDocument 'Stores each drawing in turn
Dim mySS As AcadSelectionSet 'Stores selection set
Dim myAtts As Variant 'Stores attributes for each insertion
Dim i As Long, j As Long 'Declare two counters
For i = 0 To UBound(Dwgs) 'Loop thru all drawings
openFilename = GetOpenFilename(Dwgs(i)) 'Checks if file is open
'If the drawing is open, just refer to open drawing
If openFilename"" Then
Set myDwg = AcadApplication.Documents.Item(openFilename)
Else 'Open the drawing
Set myDwg = AcadApplication.Documents.Open(Dwgs(i))
End If
Set mySS = GetSS(myDwg) 'Get a selection set
'Populate the selection set with specified block insertions
mySS.Select Mode:=acSelectionSetAll, _
FilterType:=fType, _
FilterData:=fData
For j = 0 To mySS.Count - 1 'Loop thru all selected blocks
ChangeAttrib mySS.Item(j), TagName, NewText 'Change attribute
Next j
mySS.Delete 'Always delete a selection set when done with it
myDwg.Close Not myDwg.ReadOnly 'Close drawing, saving changes
Next i
End Sub
'Checks to see if the given fully-qualified filename is open
'Returns the filename without path if it is open
Private Function GetOpenFilename(fqnName As Variant) As String
Dim i As Long 'Declare a counter
'Loop thru all open drawings
For i = 0 To AcadApplication.Documents.Count - 1
'Use the document given below for its properties
With AcadApplication.Documents.Item(i)
'Compare two strings, if they match (equal 0) then return Name
If StrComp(.FullName, fqnName, vbTextCompare) = 0 Then
GetOpenFilename = .Name
Exit For 'Since a match was found, exit the loop
End If
End With
Next i
End Function
'Returns a named selection set
Private Function GetSS(ByRef theDoc As AcadDocument, _
Optional ByVal Name As String = "mySS") _
As AcadSelectionSet
'Enable error handling, but just skip the error
On Error Resume Next
'Attempt to get the named selection set
Set GetSS = theDoc.SelectionSets.Item(Name)
GetSS.Clear 'Clear the selection set of any items
'If this error occurred, the selection set didn't exist, create it
If Err.Number = 91 Then Set GetSS = theDoc.SelectionSets.Add(Name)
End Function
'Change the given attribute in the given block reference
Private Sub ChangeAttrib(ByVal theBlock As AcadBlockReference, _
ByVal TagName As String, _
ByVal NewText As String)
Dim myAtts As Variant 'GetAttributes returns an array
myAtts = theBlock.GetAttributes 'Get the attributes
Dim i As Long 'Declare a counter
For i = 0 To UBound(myAtts) 'Loop thru all attributes
With myAtts(i) 'For each attribute
'If the current attribute is the correct one
If .TagString = TagName Then
.TextString = NewText 'change the attributes value
Exit For 'Exit the loop, we are done
End If
End With
Next i
End Sub
'Returns all the attributed inserted blocks in a drawings layouts
Private Function GetBlocks(ByVal theDoc As AcadDocument, _
ByRef BlockStore As Scripting.Dictionary)
'Set dictionary's comparison mode to work with text
BlockStore.CompareMode = TextCompare
Dim aEntity As AcadEntity 'Stores each entity in turn
Dim aLayout As AcadLayout 'Stores each layout in turn
Dim aBlkRef As AcadBlockReference 'Stores a block reference
For Each aLayout In theDoc.Layouts 'Loop thru all the layouts
'The below condition is for performance, it excludes ModelSpace
If Not (aLayout.ModelType) Then
For Each aEntity In aLayout.Block 'Loop thru all entities
'If the current entity is a block insertion
If TypeOf aEntity Is AcadBlockReference Then
Set aBlkRef = aEntity 'Cast the entity into a block ref
'If the block insertion has attributes
If aBlkRef.HasAttributes Then
'Use a procedure to add block to dictionary
'Need procedure for isolated error handling
AddBlock BlockStore, aBlkRef.Name, aBlkRef.GetAttributes
End If
End If
Next aEntity
End If
Next aLayout
End Function
'Adds a block name and its attributes to a dictionary
Private Sub AddBlock(ByRef BlockStore As Scripting.Dictionary, _
ByVal Name As String, _
ByVal Attribs As Variant)
'Enable error handling, but just skip the error
On Error Resume Next
'Attempt to add block name and its attributes to the dictionary
'If the block name already exists in the dictionary,
'an error occurs. So this procedure just skips the duplicate.
BlockStore.Add Name, Attribs
End Sub
'Display an open dialog, adds selected files to an array
Private Function GetFiles() As Variant
'Stores the object created by the CommonDialog class
Dim myOpen As CommonDialogProject.CommonDialog
Set myOpen = CommonDialogProject.Init 'Create the object
myOpen.DialogTitle = "Select drawings" 'Change the title
myOpen.Filter = "AutoCAD Drawing files (*.dwg)|*.dwg|" & _
"AutoCAD Drawing template files (*.dwt)|*.dwt"
myOpen.DefaultExt = "dwg"
'Set flags to limit behavior of the dialog box
myOpen.Flags = OFN_ALLOWMULTISELECT + _
OFN_EXPLORER + _
OFN_FILEMUSTEXIST + _
OFN_HIDEREADONLY + _
OFN_PATHMUSTEXIST
myOpen.InitDir = FindPath("path\to\files\no\leading\or\trailing\backslashes")
myOpen.MaxFileSize = 2048 'Increase buffer of filenames
Dim success As Long 'Stores the return value from CommonDialog
success = myOpen.ShowOpen 'Display the open dialog box
'If the dialog was not cancelled get array of filenames
If success > 0 Then GetFiles = myOpen.ParseFileNames
End Function
Private Function FindPath(ByVal path As String) As String
Dim X As Integer
For X = 67 To 69
rVal = Dir(Chr(X) & ":\" & path & "\*.*")
If rVal"" Then
FindPath = Chr(X) & ":\" & path
X = 70
Else
FindPath = "C:\"
End If
Next X
End Function
如果您更改每个计算机上绘图文件夹的路径,那么您在那里拥有的应该可以工作...减去绘图名称并减去驱动器号...因此,如果您的绘图路径是:
"C:\Program Files\Stored Data\Drawing\"
您将使用
MyOpen.InitDir = FindPath ("Program Files\Stored Data\Drawings")
然后它将返回"C:\"作为初始文件夹或"[驱动器号]:\Program Files\Stored Data\Drawing"作为初始文件夹
这更有意义吗? Keith 路径中唯一的区别是驱动器号。文件夹是相同的,所以我尝试把这个:
myOpen.InitDir = FindPath(“\Drawings”)
当我运行它时,我得到这个消息:
编译错误
变量未定义
,rVal
也突出显示,当你说我需要更改每台计算机上的图纸文件夹的路径时,你是什么意思?这个的目的是让它找到图纸文件夹,而不管它位于哪个驱动器上没有? 将
Dim rVal As String
添加到Dim X作为整数行之后的“findpath”函数
然后将您的函数调用更改为...
myOpen.InitDir = FindPath("Drawings")
如果您查看我提供的示例,您会看到我说过要省略开头的反斜杠和结尾的反斜杠 啊,是的,它起作用了。在我上次发布后,我删除了反斜杠。我将不得不去女孩的电脑那里,她的图纸在不同的驱动器中进行测试。谢谢一群人,这是一次很好的学习经历。我会告诉你进展如何
页:
1
[2]