Vb.net 控制台应用程序中不会触发工作表更改事件
我一直在尝试开发一个控制台应用程序,它将打开现有的Excel工作簿并将数据写入工作表。它收集的数据来自另一个叫做NX的应用程序,一个CAD程序。我使用Framework4.5和Office2010在VB.NET中编写了控制台应用程序。除了基于事件的代码之外,代码的工作方式与它应该的一样。我包括了一些在发生选择更改事件时应该触发的功能。我花了数周时间进行研究,试图发现为什么我的基于事件的代码不会启动。我似乎得出的唯一结论是,控制台应用程序正在立即关闭/完成,并且没有给事件处理程序“足够的时间”来启动 这是我的密码:Vb.net 控制台应用程序中不会触发工作表更改事件,vb.net,excel,console-application,Vb.net,Excel,Console Application,我一直在尝试开发一个控制台应用程序,它将打开现有的Excel工作簿并将数据写入工作表。它收集的数据来自另一个叫做NX的应用程序,一个CAD程序。我使用Framework4.5和Office2010在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
选项严格关闭
选项推断
导入System.IO
导入System.Runtime.Remoting
导入System.Runtime.Remoting.Channel
导入系统文本
导入系统。诊断
导入系统集合
导入System.Collections.Generic
导入NXOpen
导入NXOpen.Assemblies
导入NXOpen.Utilities
导入NXOpen.UF
导入Microsoft.Office.Interop“导入Excel互操作命名空间”
导入System.Runtime.InteropServices.Marshal
导入Microsoft.Office.Interop.Excel
导入System.Windows.Forms
模块远程处理客户端测试
Public theSession As Session=DirectCast(Activator.GetObject(GetType(Session))“http://localhost:4567/NXOpenSession(第次会议)
公共ufs作为UFSession=DirectCast(Activator.GetObject(GetType(UFSession))“http://localhost:4567/UFSession(会议期间)
公共工作部件作为部件=session.Parts.Work
Public Display Part As Part=session.Parts.Display
公共标记标识符,只要
公共行的长度=3
副标题()
将myForm设置为新Form1
'需要初始化excel对象变量的值
OpenWorkBook(“C:\Path文件”)
myForm.ProcessNXData()
端接头
公共子目录(作为[字符串])
Session.GetSession().LogFile.WriteLine
控制台写入线(s)
端接头
子回显(ByVal输出为字符串)
theSession.ListingWindow.Open()文件
Session.ListingWindow.WriteLine(输出)
session.LogFile.WriteLine(输出)
端接头
作为整数的公共函数GetVal(ByVal伪字符串)
立即返回Session.LibraryUnloadOption
端函数
端模块
公开课表格1
Private WithEvents excel作为excel.Application
Private WithEvents工作簿格式为Excel.工作簿
Private WithEvents myWorksheet作为Excel.Worksheet
公共子OpenWorkBook(路径为字符串)
如果excel什么都不是,那么
excel=新的excel.Application
excel.Visible=True“用户负责关闭excel
excel.UserControl=True
excel.EnableEvents=True
如果结束
如果工作簿不是空的,那么
FreeCOM(工作簿)
如果结束
将工作簿设置为Excel.workbooks=Excel.workbooks
工作簿=工作簿。打开(路径)
FreeCOM(工作手册)
如果我的工作表不是空的,那么
FreeCOM(我的工作表)
如果结束
将工作表调整为Excel.Sheets=工作簿.Worksheets
myWorksheet=CType(Worksheets.Item(1),Microsoft.Office.Interop.Excel.Worksheet)1基于索引
工作表(“NX数据”).Activate()
我的工作表=工作表(“NX数据”)
端接头
公共共享子FreeCOM(ByVal-COMObj作为对象,可选ByVal-GCCollect作为布尔值=False)
尝试
如果COMObj不是什么,那么
System.Runtime.InteropServices.Marshal.FinalEleaseComObject(ComObject)
如果结束
最后
COMObj=无
如果你愿意,那么
GC.Collect()
GC.WaitForPendingFinalizers()
如果结束
结束尝试
端接头
公共子进程nxdata()
'这假定程序集已加载。
Dim dp As Part=session.Parts.Display
当长=3时变暗行
session.EnableRedo(False)
将下一个实体的尺寸标注为NXOpen.Tag=NXOpen.Tag.Null
做
将t作为整数,将st作为整数
Dim isOcc作为布尔值=False
将ProtoTag调暗为NXOpen.Tag=NXOpen.Tag.Null
将拥有零件的尺寸标注为NXOpen.Tag=nextBody
Dim partName As String=“”
ufs.Obj.CycleTypedObjsInPart(dp.Tag,UFConstants.UF_solid_type,nextBody)
如果nextBody.Equals(NXOpen.Tag.Null),则
退出Do
如果结束
ufs.Obj.ASK类型和子类型(下一个主体,t,st)
如果st UFConstants.UF_solid_body_子类型,则
继续做
如果结束
isOcc=ufs总成等电流(下一个车身)
如果isOcc.等于(真),则
'Echo(“找到出现正文:&nextBody.ToString())
theProtoTag=ufs.Assem.AskPrototypeOfOcc(下一个主体)
ufs.Obj.asknowningPart(专利、所有权部分)
ufs.Part.AskPartName(owningPart,partName)
Echo(“拥有部件:”&部件名)
如果结束
将nxom设置为NXObjectManager=theSession.GetObjectManager
将对象设置为NXObject=nxom.gettaggeObject(nextBody)
将车身尺寸调整为车身=C类型(theObj,车身)
Dim myMeasure As MeasureManager=theSession.Parts.Display.MeasureManager()
尺寸质量单位(4)作为单位
质量单位(0)=session.Parts.Display.UnitCollection.GetBase(“区域”)
质量单位(1)=session.Parts.Display.UnitCollection.GetBase(“体积”)
质量单位(2)=session.Parts.Display.UnitCollection.GetBase(“质量”)
质量单位(3)=session.Parts.Display.UnitCollection.GetBase(“长度”)
Dim singleBodyArray()作为主体={theBody}
Dim mb作为MeasureBodies=myMeasure.NewMassProperties(质量单位,1,singleBodyArray)
mb.InformationUnit=measure