paulakin
Mechanical
- Jan 15, 2015
- 1
Hello,
I am new to VBA and SNAP, and I'm having trouble getting my code to work at one particular point in the program I'm trying to cobble together.
I'm trying to make a program that will write a material from a custom library to every body of every part in an assembly. I've found a journal that I've altered to do this and I would like to add a dialog box to it to make it easier for other people to use.
The code I'm using I got from here from the poster named "jpetach."
So far I've changed the code to use a custom library and I've used the block UI styler to make a dialog box for it. I'm using a string block at the moment as I haven't figured out a way to read the entire material library into a list or a dropdown. However, whenever I declare a string that I believe is exactly the same as the strings that are manually put in the code for the material, the code throws an error in the information window: "Error running application: No object found with this name."
Essentially what I've done is this, I've taken the two lines responsible for writing the material to the part and replaced them with a variable (and changed the library).
So orginally it was this, where you would have to manually changed the "Alumnium_6061," in the code to the material you need to apply.
...and I've changed it to this, where "Mat" and "Mat2" should take the place of those two strings.
Where I've defined my variables like so:
Although if I ignore the block input completely and just define my variables outright with no input the same thing occurs, for some reason it seems like the strings have to be *in* the function. What am I missing?
My entire code for reference:
I am new to VBA and SNAP, and I'm having trouble getting my code to work at one particular point in the program I'm trying to cobble together.
I'm trying to make a program that will write a material from a custom library to every body of every part in an assembly. I've found a journal that I've altered to do this and I would like to add a dialog box to it to make it easier for other people to use.
The code I'm using I got from here from the poster named "jpetach."
So far I've changed the code to use a custom library and I've used the block UI styler to make a dialog box for it. I'm using a string block at the moment as I haven't figured out a way to read the entire material library into a list or a dropdown. However, whenever I declare a string that I believe is exactly the same as the strings that are manually put in the code for the material, the code throws an error in the information window: "Error running application: No object found with this name."
Essentially what I've done is this, I've taken the two lines responsible for writing the material to the part and replaced them with a variable (and changed the library).
So orginally it was this, where you would have to manually changed the "Alumnium_6061," in the code to the material you need to apply.
Code:
Try
'load from library in case it is not used in the part yet
physicalMaterial1 = workPart.MaterialManager.PhysicalMaterials.LoadFromNxmatmllibrary("Aluminum_6061")
Catch ex as Exception
' the material is already known in the part so use it
physicalMaterial1 = CType(workPart.MaterialManager.PhysicalMaterials.FindObject("PhysicalMaterial[Aluminum_6061]"), PhysicalMaterial)
End Try
...and I've changed it to this, where "Mat" and "Mat2" should take the place of those two strings.
Code:
Try
'load from library in case it is not used in the part yet
physicalMaterial1 = workPart.MaterialManager.PhysicalMaterials.LoadFromMatmlLibrary("C:\Users\P\Documents\290\TEST\Material Library BBG&NX.xml", Mat)
Catch ex As Exception
' the material is already known in the part so use it
physicalMaterial1 = CType(workPart.MaterialManager.PhysicalMaterials.FindObject(Mat2), PhysicalMaterial)
End Try
Where I've defined my variables like so:
Code:
Module NXJOURNAL
' Declare module variables. These are available to all subroutines.
Dim theSession As Session = Session.GetSession()
Dim alreadyProcessed As Hashtable
Dim knt As Integer = 0
Dim partLoadStat As PartLoadStatus
Dim LW As ListingWindow = theSession.ListingWindow
Dim displayPart As Part = theSession.Parts.Display
Dim workPart As Part
Dim Mat As String = Nothing
Dim Mat2 As String = Nothing
...and written to from the string box in the block UI styler like so:
Public Function apply_cb() As Integer
Dim errorCode As Integer = 0
Infowindow.Writeline("Hello World!")
Dim Mat As String = Materialval.value
Infowindow.Writeline(Mat)
Dim Mat2 As String = "PhysicalMaterial[" &Mat &"]"
Although if I ignore the block input completely and just define my variables outright with no input the same thing occurs, for some reason it seems like the strings have to be *in* the function. What am I missing?
My entire code for reference:
Code:
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections
Imports NXOpen
Imports NXOpen.BlockStyler
Imports Snap, Snap.Create
Imports NXOpen.Assemblies
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.UIStyler
Module NXJOURNAL
' Declare module variables. These are available to all subroutines.
Dim theSession As Session = Session.GetSession()
Dim alreadyProcessed As Hashtable
Dim knt As Integer = 0
Dim partLoadStat As PartLoadStatus
Dim LW As ListingWindow = theSession.ListingWindow
Dim displayPart As Part = theSession.Parts.Display
Dim workPart As Part
Dim Mat As String = Nothing
Dim Mat2 As String = Nothing
Public Class block5
'class members
Private Shared theSession As Session
Private Shared theUI As UI
Private theDlxFileName As String
Private theDialog As NXOpen.BlockStyler.BlockDialog
Private label0 As NXOpen.BlockStyler.Label ' Block type: Label
Private group0 As NXOpen.BlockStyler.Group ' Block type: Group
Private Materialval As NXOpen.BlockStyler.StringBlock ' Block type: String
#Region "Block Styler Dialog Designer generator code"
Public Sub New()
Try
theSession = Session.GetSession()
theUI = UI.GetUI()
theDlxFileName = "C:\Users\P\Documents\290\TEST\block\block5.dlx"
theDialog = theUI.CreateDialog(theDlxFileName)
theDialog.AddApplyHandler(AddressOf apply_cb)
theDialog.AddInitializeHandler(AddressOf initialize_cb)
Catch ex As Exception
'---- Enter your exception handling code here -----
Throw ex
End Try
End Sub
#End Region
Public Shared Sub Main()
Dim theblock5 As block5 = Nothing
Try
theblock5 = New block5()
' The following method shows the dialog immediately
theblock5.Show()
Catch ex As Exception
'---- Enter your exception handling code here -----
theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString)
Finally
If theblock5 IsNot Nothing Then
theblock5.Dispose()
theblock5 = Nothing
End If
End Try
End Sub
Public Shared Function GetUnloadOption(ByVal arg As String) As Integer
'Return CType(Session.LibraryUnloadOption.Explicitly, Integer)
Return CType(Session.LibraryUnloadOption.Immediately, Integer)
' Return CType(Session.LibraryUnloadOption.AtTermination, Integer)
End Function
Public Shared Sub UnloadLibrary(ByVal arg As String)
Try
Catch ex As Exception
'---- Enter your exception handling code here -----
theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString)
End Try
End Sub
'------------------------------------------------------------------------------
'This method shows the dialog on the screen
'------------------------------------------------------------------------------
Public Sub Show()
Try
theDialog.Show
Catch ex As Exception
'---- Enter your exception handling code here -----
theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString)
End Try
End Sub
'------------------------------------------------------------------------------
'Method Name: Dispose
'------------------------------------------------------------------------------
Public Sub Dispose()
If theDialog IsNot Nothing Then
theDialog.Dispose()
theDialog = Nothing
End If
End Sub
'------------------------------------------------------------------------------
'---------------------Block UI Styler Callback Functions--------------------------
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'Callback Name: initialize_cb
'------------------------------------------------------------------------------
Public Sub initialize_cb()
Try
label0 = CType(theDialog.TopBlock.FindBlock("label0"), NXOpen.BlockStyler.Label)
group0 = CType(theDialog.TopBlock.FindBlock("group0"), NXOpen.BlockStyler.Group)
Materialval = CType(theDialog.TopBlock.FindBlock("Materialval"), NXOpen.BlockStyler.StringBlock)
Catch ex As Exception
'---- Enter your exception handling code here -----
theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString)
End Try
End Sub
'------------------------------------------------------------------------------
'Callback Name: apply_cb
'------------------------------------------------------------------------------
Public Function apply_cb() As Integer
Dim errorCode As Integer = 0
Infowindow.Writeline("Hello World!")
Dim Mat As String = Materialval.value
Infowindow.Writeline(Mat)
Dim Mat2 As String = "PhysicalMaterial[" &Mat &"]"
LW.Open()
LW.WriteLine("Listing child components")
Try
Dim part1 As Part = theSession.Parts.Work
LW.WriteLine("Work part: " & part1.FullPath)
LW.WriteLine(part1.Leaf)
LW.WriteLine(CType(TimeOfDay(), String))
' Initialize a hash table to store components that have been processed.
' This will prevent components from being processed twice
alreadyProcessed = New Hashtable
Dim c As ComponentAssembly = part1.ComponentAssembly
LW.WriteLine("first walk: ")
Walk(c.RootComponent, 0)
' When the program is done "walking" the assembly it will return here.
' Set the work part back to what it was
LW.WriteLine("Done: ")
theSession.Parts.SetDisplay(part1, False, False, partLoadStat)
LW.WriteLine(CType(TimeOfDay(), String))
Catch e As Exception
LW.WriteLine("Error running application: " & e.Message)
End Try
End Function
Sub Walk(ByVal c As Component, ByVal level As Integer)
LW.WriteLine("Walking: ")
Dim ufs As UFSession = UFSession.GetUFSession()
'Dim wrap As String = Chr(10)
'Dim dwrap As String = wrap & wrap
'Dim title As String
'Dim value As String
'Dim inx As Integer = 0
Dim prototype As Part
Dim children As Component() = c.GetChildren()
Dim child As Component
prototype = CType(c.Prototype, Part)
'LW.WriteLine("Component: " & child.ToString)
LW.WriteLine("Component: " & c.ToString)
If Not alreadyProcessed.Contains(prototype.Leaf) Then
' Add this prototype to the hash table so that we don't process it again
alreadyProcessed.Add(prototype.Leaf, prototype.Leaf)
knt = knt + 1
Dim msgText As String
msgText = knt.ToString & " " & New String(" "c, (level * 4)) & prototype.Leaf
'LW.WriteLine(msgText.ToString)
theSession.Parts.SetDisplay(prototype, False, False, partLoadStat)
' displayPart = theSession.Parts.Display
'==============
Dim workPart As Part = theSession.Parts.Work
Dim physicalMaterial1 As PhysicalMaterial
Try
'load from library in case it is not used in the part yet
physicalMaterial1 = workPart.MaterialManager.PhysicalMaterials.LoadFromMatmlLibrary("C:\Users\P\Documents\290\TEST\Material Library BBG&NX.xml", Mat)
Catch ex As Exception
' the material is already known in the part so use it
physicalMaterial1 = CType(workPart.MaterialManager.PhysicalMaterials.FindObject(Mat2), PhysicalMaterial)
End Try
Dim bodies As BodyCollection = workPart.Bodies
Dim solidBodies(0) As NXObject
Dim counter As Integer = 0
Dim bodyCount As Integer = bodies.ToArray.Length
LW.WriteLine("Total Bodies in Work Part: " & bodyCount.ToString())
If bodyCount > 0 Then
For Each thisBody As Body In bodies
If thisBody.IsSheetBody.Equals(False) Then
ReDim Preserve solidBodies(counter)
solidBodies(counter) = thisBody
LW.WriteLine("Solid Body: " & thisBody.ToString())
counter += 1
End If
Next
Dim solidBodyCount As Integer = solidBodies.Length()
LW.WriteLine("Solid Bodies in Work Part: " &
solidBodyCount.ToString())
' At this point, all solid bodies
' should be in an array called solidBodies
If (solidBodies.Length > 0) Then
physicalMaterial1.AssignObjects(solidBodies)
End If
End If
Else
LW.WriteLine("Already processsed")
'theSession.DisplayManager.MakeUpToDate()
End If ' not already processed
'==================
For Each child In children
LW.Writeline("next child = " & child.ToString)
Walk(child, level + 1)
Next
End Sub
End Class
End Module