I have tried making a macro to move many views by the name of the view and specifying a X & Y locating point on the drawing using swView.Position callout. The issue I am having is that it is not correctly moving the view in the specified X & Y location. It only moves in the Y direction. How can I get my view to move in the specified location? Is swView.Position the wrong callout to use?
Thank you in advance for any help!
Sub MoveMultipleViews()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim viewNames As Variant
Dim newPositions As Variant
Dim i As Integer
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
' Define view names and corresponding new positions (in meters)
viewNames = Array("Section View K-K", "Drawing View30", "Drawing View25")
newPositions = Array( _
Array(4.2, 4.15), _
Array(4.3, 4.25), _
Array(4.1, 4.1) _
)
For i = 0 To UBound(viewNames)
Set swView = swDraw.GetFirstView
Set swView = swView.GetNextView ' Skip sheet view
Do While Not swView Is Nothing
If swView.GetName2 = viewNames(i) Then
swView.Position = newPositions(i)
Exit Do
End If
Set swView = swView.GetNextView
Loop
Next i
swModel.EditRebuild3
MsgBox "Views moved successfully!"
End Sub
Did you RMB on your views > Alignment > break alignment? I guess that is your problem.
If you don’t break the alignment, your positioning will not work because view alignment forces it to follow the parent view and not the x value you want.
“Any view alignments that might affect this view are handled the same way as if you were using the SOLIDWORKS user interface to draw the view to move it. If it is aligned with another view, it will only be allowed to move along the alignment vector. If it has child views that are aligned with it, those views will also be moved along with this view.”
Dim swApp As SldWorks.SldWorks
Dim mDoc As ModelDoc2
Dim dDoc As DrawingDoc
Sub main()
Set swApp = Application.SldWorks
Set mDoc = swApp.ActiveDoc
Dim sheetView As View
Set dDoc = mDoc
Set sheetView = dDoc.GetFirstView
Do While Not sheetView Is Nothing
Set sheetView = sheetView.GetNextView
If sheetView Is Nothing Then Exit Sub
Dim coords(1) As Double
coords(0) = 0#
coords(1) = 0#
sheetView.Position = coords
mDoc.ForceRebuild3 False
Loop
End Sub
This code works exactly as shown in the pictures you attached. All views orient to the 0,0 location on my drawing.
Why would my code not work then is my head scratching question. Am I using the array incorrectly for the locating X & Y values?
It’s your array. Arrays in VBA are a little goofy, and I’m no expert on them. To test, I changed your code to build your array in a different way and it works:
Dim swApp As SldWorks.SldWorks
Dim mDoc As ModelDoc2
Dim dDoc As DrawingDoc
Dim xCoords
Dim yCoords
Sub main()
xCoords = Array(4.2, 4.3, 4.1)
yCoords = Array(4.15, 4.25, 4.1)
Dim newPositions(2) As Variant
Dim i As Integer
For i = LBound(newPositions) To UBound(newPositions)
Dim pos(1) As Double
pos(0) = xCoords(i)
pos(1) = yCoords(i)
newPositions(i) = pos
Next i
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim viewNames As Variant
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
' Define view names and corresponding new positions (in meters)
viewNames = Array("Section View A-A", "Drawing View1", "Drawing View2")
For i = 0 To UBound(viewNames)
Set swView = swDraw.GetFirstView
Set swView = swView.GetNextView ' Skip sheet view
Do While Not swView Is Nothing
If swView.GetName2 = viewNames(i) Then
swView.Position = newPositions(i)
Exit Do
End If
Set swView = swView.GetNextView
Loop
Next i
swModel.EditRebuild3
MsgBox "Views moved successfully!"
End Sub
Thanks for the solution. I could not figure out a good way to do it without using arrays. I’m no expert at coding, but since you said arrays are a bit goofy, would you suggest another method?
Agreed… Arrays in SW are often a huge pain. Just to add a tiny bit of detail to Jim’s example code, usually (in my experience anyway), any time a SW API call takes an array argument, it has to be specifically declared as an array of that type. The VBA “Array” function creates a Variant array, even if the stuff you put in it is objects, doubles, etc. Specifically declaring the “pos” array as Double is what makes it work. Loading this Double array into a Variant array later is no problem because you actually pull it “out” of the variant array before you pass it to the SW API call.
You definitely still have to use arrays. The API call requires an array as input. You just need to declare the array specifically as a Double instead of using the VBA “Array” function to create it. (see my add-on reply to Jim’s message above)
It gets even worse when you start getting into creating full MathTransform objects from array data. You have to specifically load each element of an array of 16 doubles.
@JimSculley@josh Do you happen to know if I would I be limited to the amount of views I can locate using this script?
I am asking because I started to add more views to this macro and it refuses to work now. the error message that I am getting says; Run-time error ‘9’: Subscript out of range.
I have about 20 views I am looking to add to this script
I understand now. The newPositions(x) must be defined for the amount of values in the array. hence the count for newPositions(i) in the loop starting with i=0.
The correct answer is already there, but I have a fetish related to Dictionaries in VBA. Here is a version with Drawing View and their coordinates in Dictionaries.
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Or swModel.GetType <> swDocDRAWING Then
MsgBox "Active document is not a drawing!", vbExclamation
Exit Sub
End If
Set swDraw = swModel
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
' Adding views and coordinates (in meters!)
dict.Add "Section View A-A", Array(4.2, 4.15)
dict.Add "Drawing View1", Array(4.3, 4.25)
dict.Add "Drawing View2", Array(4.1, 4.1)
Dim viewName As Variant
Dim failedViews As String
Dim total As Long: total = 0
Dim failed As Long: failed = 0
For Each viewName In dict.Keys
Dim posXY(1) As Double
posXY(0) = dict(viewName)(0)
posXY(1) = dict(viewName)(1)
total = total + 1
If Not MoveViewByName(swDraw, viewName, posXY) Then
failedViews = failedViews & vbCrLf & "• " & viewName
failed = failed + 1
End If
Next
swModel.EditRebuild3
If failed = 0 Then
MsgBox "All views moved successfully (" & total & ")."
Else
MsgBox "Some views were not moved (" & failed & " of " & total & "):" & failedViews, vbExclamation
End If
End Sub
Function MoveViewByName(swDraw As SldWorks.DrawingDoc, ByVal viewName As String, posXY() As Double) As Boolean
Dim swView As SldWorks.View
Set swView = swDraw.GetFirstView
Set swView = swView.GetNextView ' skip sheet
Do While Not swView Is Nothing
If swView.GetName2 = viewName Then
swView.Position = posXY
MoveViewByName = True
Exit Function
End If
Set swView = swView.GetNextView
Loop
MoveViewByName = False ' not found
End Function