Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 控制台应用程序中不会触发工作表更改事件_Vb.net_Excel_Console Application - Fatal编程技术网

Vb.net 控制台应用程序中不会触发工作表更改事件

Vb.net 控制台应用程序中不会触发工作表更改事件,vb.net,excel,console-application,Vb.net,Excel,Console Application,我一直在尝试开发一个控制台应用程序,它将打开现有的Excel工作簿并将数据写入工作表。它收集的数据来自另一个叫做NX的应用程序,一个CAD程序。我使用Framework4.5和Office2010在VB.NET中编写了控制台应用程序。除了基于事件的代码之外,代码的工作方式与它应该的一样。我包括了一些在发生选择更改事件时应该触发的功能。我花了数周时间进行研究,试图发现为什么我的基于事件的代码不会启动。我似乎得出的唯一结论是,控制台应用程序正在立即关闭/完成,并且没有给事件处理程序“足够的时间”来启

我一直在尝试开发一个控制台应用程序,它将打开现有的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