我一直在尝试开发一个控制台应用程序,它将打开现有的Excel工作簿并将数据写入工作表。它收集的数据来自另一个名为NX的应用程序,即CAD程序。我使用Framework 4.5和Office 2010在VB.NET中编写了控制台应用程序。除了基于事件的代码之外,代码可以正常工作。我包含了一些在选择更改事件发生时应该触发的功能。我花了几周时间做研究,并试图发现为什么我的基于事件的代码不会被激活。我似乎唯一得出的结论是控制台应用程序立即关闭/完成,并没有为事件处理程序提供“足够的时间”。
这是我的代码:
Option Strict Off
Option Infer Off
Imports System.IO
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Text
Imports System.Diagnostics
Imports System.Collections
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.Assemblies
Imports NXOpen.Utilities
Imports NXOpen.UF
Imports Microsoft.Office.Interop ' import Excel Interop Namespace
Imports System.Runtime.InteropServices.Marshal
Imports Microsoft.Office.Interop.Excel
Imports System.Windows.Forms
Module remoting_client_test
Public theSession As Session = DirectCast(Activator.GetObject(GetType(Session), "http://localhost:4567/NXOpenSession"), Session)
Public ufs As UFSession = DirectCast(Activator.GetObject(GetType(UFSession), "http://localhost:4567/UFSession"), UFSession)
Public workPart As Part = theSession.Parts.Work
Public displayPart As Part = theSession.Parts.Display
Public TagIdentifier As Long
Public row As Long = 3
Sub Main()
Dim myForm As New Form1
'need to initialize value of excel object variables
myForm.OpenWorkBook("C:\Path File")
myForm.ProcessNXData()
End Sub
Public Sub DoLog(s As [String])
Session.GetSession().LogFile.WriteLine(s)
Console.WriteLine(s)
End Sub
Sub Echo(ByVal output As String)
theSession.ListingWindow.Open()
theSession.ListingWindow.WriteLine(output)
theSession.LogFile.WriteLine(output)
End Sub
Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return Session.LibraryUnloadOption.Immediately
End Function
End Module
Public Class Form1
Private WithEvents excel As Excel.Application
Private WithEvents workbook As Excel.Workbook
Private WithEvents myWorksheet As Excel.Worksheet
Public Sub OpenWorkBook(path As String)
If excel Is Nothing Then
excel = New Excel.Application
excel.Visible = True ' user is responsible for closing Excel
excel.UserControl = True
excel.EnableEvents = True
End If
If workbook IsNot Nothing Then
FreeCOM(workbook)
End If
Dim workbooks As Excel.Workbooks = excel.Workbooks
workbook = workbooks.Open(path)
FreeCOM(workbooks)
If myWorksheet IsNot Nothing Then
FreeCOM(myWorksheet)
End If
Dim Worksheets As Excel.Sheets = workbook.Worksheets
myWorksheet = CType(Worksheets.Item(1), Microsoft.Office.Interop.Excel.Worksheet) ' 1 based indexing
Worksheets("NX Data").Activate()
myWorksheet = Worksheets("NX Data")
End Sub
Public Shared Sub FreeCOM(ByVal COMObj As Object, Optional ByVal GCCollect As Boolean = False)
Try
If COMObj IsNot Nothing Then
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(COMObj)
End If
Finally
COMObj = Nothing
If GCCollect Then
GC.Collect()
GC.WaitForPendingFinalizers()
End If
End Try
End Sub
Public Sub ProcessNXData()
' This assumes the assembly is loaded.
Dim dp As Part = theSession.Parts.Display
Dim row As Long = 3
theSession.EnableRedo(False)
Dim nextBody As NXOpen.Tag = NXOpen.Tag.Null
Do
Dim t As Integer, st As Integer
Dim isOcc As Boolean = False
Dim theProtoTag As NXOpen.Tag = NXOpen.Tag.Null
Dim owningPart As NXOpen.Tag = nextBody
Dim partName As String = ""
ufs.Obj.CycleTypedObjsInPart(dp.Tag, UFConstants.UF_solid_type, nextBody)
If nextBody.Equals(NXOpen.Tag.Null) Then
Exit Do
End If
ufs.Obj.AskTypeAndSubtype(nextBody, t, st)
If st <> UFConstants.UF_solid_body_subtype Then
Continue Do
End If
isOcc = ufs.Assem.IsOccurrence(nextBody)
If isOcc.Equals(True) Then
'Echo("Found occurrence body: " & nextBody.ToString())
theProtoTag = ufs.Assem.AskPrototypeOfOcc(nextBody)
ufs.Obj.AskOwningPart(theProtoTag, owningPart)
ufs.Part.AskPartName(owningPart, partName)
Echo("Owning Part: " & partName)
End If
Dim theNXOM As NXObjectManager = theSession.GetObjectManager
Dim theObj As NXObject = theNXOM.GetTaggedObject(nextBody)
Dim theBody As Body = CType(theObj, Body)
Dim myMeasure As MeasureManager = theSession.Parts.Display.MeasureManager()
Dim massUnits(4) As Unit
massUnits(0) = theSession.Parts.Display.UnitCollection.GetBase("Area")
massUnits(1) = theSession.Parts.Display.UnitCollection.GetBase("Volume")
massUnits(2) = theSession.Parts.Display.UnitCollection.GetBase("Mass")
massUnits(3) = theSession.Parts.Display.UnitCollection.GetBase("Length")
Dim singleBodyArray() As Body = {theBody}
Dim mb As MeasureBodies = myMeasure.NewMassProperties(massUnits, 1, singleBodyArray)
mb.InformationUnit = MeasureBodies.AnalysisUnit.PoundFoot
Dim centroidalPoint As Point3d = mb.Centroid()
Echo("Centroid: " & centroidalPoint.X & " " & centroidalPoint.Y & " " & centroidalPoint.Z)
Echo(" ")
'get parent tag
Dim parentTag As Tag
ufs.Assem.AskParentComponent(theBody.Tag, parentTag)
Dim bodyComp As Component = theSession.GetObjectManager.GetTaggedObject(parentTag)
'get root name
Dim c As ComponentAssembly = workPart.ComponentAssembly
excel.Cells(2, 2) = theBody.OwningPart.Leaf
excel.Cells(2, 3).value = c.RootComponent.GetStringAttribute("DB_PART_NAME")
'find attribute data
If bodyComp.HasUserAttribute("DB_PART_NAME", NXObject.AttributeType.String, -1) = True Then
excel.Cells(row, 3) = bodyComp.GetStringAttribute("DB_PART_NAME")
End If
If bodyComp.HasUserAttribute("MF Material", NXObject.AttributeType.String, -1) = True Then
excel.Cells(row, 7) = bodyComp.GetStringAttribute("MF Material")
End If
If bodyComp.HasUserAttribute("MF NN", NXObject.AttributeType.String, -1) = True Then
excel.Cells(row, 9) = bodyComp.GetStringAttribute("MF NN")
End If
If bodyComp.HasUserAttribute("MF Modifier", NXObject.AttributeType.String, -1) = True Then
excel.Cells(row, 8) = bodyComp.GetStringAttribute("MF Modifier")
End If
If bodyComp.HasUserAttribute("MF Type", NXObject.AttributeType.String, -1) = True Then
excel.Cells(row, 10) = bodyComp.GetStringAttribute("MF Type")
End If
'bounding box
Dim bodyLengths(2) As Double
bodyLengths = GetBoundingBox(theBody)
'Measures Min/Max of all model parts in assembly
Dim bbox(5) As Double
Dim tagList(0) As NXOpen.Tag
ufs.Modl.AskBoundingBox(theBody.Tag, bbox)
'write data to cells
excel.Cells(row, 2).value = bodyComp.Parent.Prototype.OwningPart.Leaf
excel.Cells(row, 4).value = bodyComp.Prototype.OwningPart.Leaf
excel.Cells(row, 11).value = mb.Volume.ToString
excel.Cells(row, 14).value = centroidalPoint.Z
excel.Cells(row, 16).value = centroidalPoint.X
excel.Cells(row, 18).value = centroidalPoint.Y
excel.Cells(row, 21) = (bbox(0) / 12) 'LCG
excel.Cells(row, 22) = (bbox(3) / 12)
excel.Cells(row, 23) = (bbox(2) / 12) 'VCG
excel.Cells(row, 24) = (bbox(5) / 12)
excel.Cells(row, 25) = (bbox(1) / 12) 'TCG
excel.Cells(row, 26) = (bbox(4) / 12)
excel.Cells(row, 50).value = nextBody.ToString
row = row + 1
Loop Until nextBody.Equals(NXOpen.Tag.Null)
End Sub
Private Function GetBoundingBox(ByVal solidBody As NXOpen.Body) As Double()
'AskBoundingBox returns min and max coordinates
'this function will simply return the box lengths (x, y, z)
Dim bboxCoordinates(5) As Double
Dim bboxLengths(2) As Double
Try
'get solid body bounding box extents
ufs.Modl.AskBoundingBox(solidBody.Tag, bboxCoordinates)
bboxLengths(0) = bboxCoordinates(3) - bboxCoordinates(0)
bboxLengths(1) = bboxCoordinates(4) - bboxCoordinates(1)
bboxLengths(2) = bboxCoordinates(5) - bboxCoordinates(2)
Return bboxLengths
Catch ex As NXException
MsgBox(ex.GetType.ToString & " : " & ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "Solid Body Bounds Error!")
bboxLengths(0) = 0
bboxLengths(1) = 0
bboxLengths(2) = 0
Return bboxLengths
End Try
End Function
Sub Echo(ByVal output As String)
theSession.ListingWindow.Open()
theSession.ListingWindow.WriteLine(output)
theSession.LogFile.WriteLine(output)
End Sub
Public Function GetUnloadOption(ByVal arg As String) As Integer
Return Session.LibraryUnloadOption.Immediately
End Function
Public Sub myWorksheet_SelectionChange(ByVal Target As Excel.Range) Handles myWorksheet.SelectionChange
MsgBox("its firing")
Dim theSession As Session = DirectCast(Activator.GetObject(GetType(Session), "http://localhost:4567/NXOpenSession"), Session)
Dim ufs As UFSession = DirectCast(Activator.GetObject(GetType(UFSession), "http://localhost:4567/UFSession"), UFSession)
Dim workPart As Part = theSession.Parts.Work
Dim dp As Part = theSession.Parts.Display
'Dim theCompName As String
Dim theCompTag As NXOpen.Tag = NXOpen.Tag.Null
Dim RowNum As Long
RowNum = Target.Row
TagIdentifier = excel.Cells(RowNum, 50).value()
ufs.Disp.SetHighlight(TagIdentifier, 1)
ReleaseComObject(Target)
End Sub
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
If myWorksheet IsNot Nothing Then
FreeCOM(myWorksheet)
End If
If workbook IsNot Nothing Then
FreeCOM(myWorksheet)
End If
If excel IsNot Nothing Then
FreeCOM(excel, True)
End If
End Sub
End Class
有人可以告诉我他们认为这个问题是什么吗?