在VB.net中执行Excel中的事件,主程序被初始化,该怎么解决

在VB.net中执行Excel中的事件,主程序被初始化
本帖最后由 zfybs 于 2014-10-17 01:34:11 编辑
问题描述:具体的需求比较复杂,我就不说了,在出现问题后,我将问题进行了排查,最后发现问题所在,并简化程序如下:

1、新建一个Visual Basic.NET的窗口项目,然后在项目中引用了Excel。

2、然后在主程序启动时创建了一个新的Excel程序,为了执行Excel关闭的事件,添加了一个新的Workbook以用来引发Excel的Application.WorkbookBeforeClose事件

3、测试时一共执行三步操作:  先点击主程序窗口,此时立即窗口中显示:
在主程序中:123
在testclass类中:123


4、然后点击关闭Excel程序,此时立即窗口中显示:
在testclass类的WorkbookBeforeClose事件中:0
说明:在调试时,发现在提取Form1.WillReNew属性值时,会再次进入类Form1,对其中的每一个属性值进行初始化!!!
我猜测问题的关键词可能与“线程”有关。


5、最后再点击主程序窗口,此时立即窗口中显示:
在主程序中:123
在testclass类中:123



问题就是:
为什么在第4步时要对Form1进行初始化(类似于重新声明了一个Form1的对象),这样我就没法在这个事件中对原来的主程序Form1进行相关操作了。
而第5步又说明原来的Form1的对象还是存在的。


代码如下:
1.在窗口类Form1:
******************************************************
Imports Microsoft.Office.Interop.Excel
Public Class Form1

    Private ReNew As Integer
    Public Property WillReNew As Integer
        Get
            Return ReNew
        End Get
        Set(value As Integer)
            ReNew = value
        End Set
    End Property

    Dim b As testclass
    Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
        Debug.Print("在主程序中:" & Me.WillReNew)  
         '第一次点击时返回123,第二次点击时还是返回123
        Call b.test()
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        ReNew = 123          '对Form1的WillReNew属性进行初始化,为123。
        b = New testclass
        b.application = New Application
        b.application.Visible = True
        b.application.Workbooks.Add()
    End Sub

End Class


2、在类testclass中:
****************************************
Imports Microsoft.Office.Interop.Excel
Public Class testclass

    Private WithEvents app As Application
    Public Property application As Application
        Get
            Return app
        End Get
        Set(value As Application)
            app = value
        End Set
    End Property

    Public Sub test()
        Debug.Print("在testclass类中:" & Form1.WillReNew) 
       ' '第一次点击时返回123,第二次点击时还是返回123
    End Sub

   ' 出现问题的事件
    Private Sub refresh(wkbk As Workbook, ByRef cancel As Boolean) _
               Handles app.WorkbookBeforeClose

        Debug.Print("在testclass类的WorkbookBeforeClose事件中:" & Form1.WillReNew)        

        '这里Form1.WillReNew返回integer的初始值0,
         '在调试中发现它进入Form1中对其每一个属性或域值进行了初始化
        '(类似于重新声明了一个Form1的对象)
        '猜测可能是线程的问题,因为下一次点击窗口时还是能返回123

    End Sub

End Class

------解决思路----------------------
WillReNew 不同的地方 Handle 值是否一致。
不一致就是多个实例,你的设计就有问题了。
------解决思路----------------------
这个对象之间的关系只有你自己清楚了。
简单地说就是要把显示窗体的实例传给 testclass,通过传入实例而不是全局的 Form1 去取 WillReNew 。