H
HotIndigo
Guest
I am developing an application (in Visual Basic) that consists of a MDI form (frm_Main) hosting a number of forms, one of which contains panels that display an Excel worksheet. Each panel can only be displayed one at a time, with the others being hidden. This works well but I cannot focus on any worksheet cell to get mouse or keyboard input - cell entries can only be made programmatically(!). When I paused the debugger I found that, when single stepping, the program looped through the following sequence:
Private Sub mdl_Reports_GotFocus(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.GotFocus
End Sub ' ** This code is in mdl_Reports **
Private Sub frm_Main_Activated(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.Activated
End Sub ' ** This code is in mdl_Main **
Private Sub mdl_Reports_LostFocus(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.LostFocus
End Sub ' ** This code is in mdl_Reports **
This is the essential code I am using (I have removed unrelated code):
Public Class frm_Main
Inherits Form
End Class
Public Class mdl_Reports
Inherits Form
Private Sub mdl_Reports_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) _
Handles MyBase.Load
Me.MdiParent = frm_Main
End Sub
Private Sub mnu_NewModel_Click(sender As Object,
e As EventArgs) _
Handles mnu_NewModel.Click
Dim Workbooks As Workbooks
oExcel = qExcel.Run_Excel()
ExHwnd = CType(oExcel.Hwnd, IntPtr)
With oExcel
SetParent(CInt(ExHwnd), CInt(pnl_Excel.Handle))
SendMessage(ExHwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
MoveWindow(ExHwnd, 0, -CtrlOffset, pnl_Excel.Width, pnl_Excel.Height + CtrlOffset, True)
End With
Workbooks = oExcel.Workbooks
Workbooks.Add()
oWB = oExcel.ActiveWorkbook
With oWB
.Activate()
.Title = "Template"
oSheet = CType(.Sheets.Add(), Worksheet)
End With
With oSheet
.Activate()
.Name = rName
.Visible = XlSheetVisibility.xlSheetVisible
If sheet Is Nothing Then
oSheet = DirectCast(oWB.Sheets.Add(After:=oWB.Sheets(oWB.Sheets.Count),
Count:=1,
Type:=XlSheetType.xlWorksheet),
Worksheet)
End If
.Range("A1").Value = "Model Name"
With oExcel
.SendKeys("{DOWN}", True)
.SendKeys("{DOWN}", True)
.SendKeys("^A", True)
End With
' Weirdness here - had to use above code because oExcel.Range("A3").Activate()
' or oExcel.Range("A3").Select() (or both together) did not work!
' Any comments or suggestions?
End With
With oExcel
.Visible = True
.EnableEvents = True
End With
SendMessage(ExHwnd, WM_ACTIVATE, WA_ACTIVE, 0)
End Sub
End Class
Friend Class qExcel
Shared WithEvents oExcel As doExcel = Nothing
Private Shared Running As Boolean = False
Friend Shared Function Run_Excel() As Office.Interop.Excel.Application
Dim rExcel = New Office.Interop.Excel.Application
oExcel = New doExcel(rExcel)
Running = True
ExcelRunning = True
Return rExcel
End Function
Friend Shared Sub QuitExcel(ByRef rExcel As Office.Interop.Excel.Application)
If Running Then
Try
rExcel.Quit()
rExcel = Nothing
oExcel.Dispose()
oExcel = Nothing
GC.Collect()
Running = False
ExcelRunning = False
Catch ex As Exception
End Try
End If
End Sub
Private Sub mnu_CloseTemplate_Click(sender As Object,
e As EventArgs) _
Handles mnu_CloseTemplate.Click
Call ReleaseWB()
Call qExcel.QuitExcel(oExcel)
End Sub
Private Sub ReleaseWB()
Dim ExcelWorkbooks As Workbooks = Nothing
Dim worksheets As Sheets = Nothing
Try
ExcelWorkbooks = oExcel.Workbooks
Catch ex As Exception
Exit Sub
End Try
For Each WB As Workbook In oExcel.Workbooks
worksheets = WB.Worksheets
For Each ws As Worksheet In worksheets
Try
Marshal.ReleaseComObject(ws)
Catch ex As Exception
End Try
Next
WB.Close(False) 'Don't save
Marshal.ReleaseComObject(WB)
Next
Try
Marshal.ReleaseComObject(worksheets)
worksheets = Nothing
Catch ex As Exception
End Try
Try
ExcelWorkbooks.Close()
Marshal.ReleaseComObject(ExcelWorkbooks)
ExcelWorkbooks = Nothing
Catch ex As Exception
End Try
End Sub
End Class
Friend Class doExcel
Implements IDisposable
Public Sub New(ByRef oExcel As Office.Interop.Excel.Application)
oExcel = New Office.Interop.Excel.Application
End Sub
Public Overloads Sub Dispose() Implements IDisposable.Dispose
End Sub
Protected Overrides Sub Finalize()
Dispose()
End Sub
End Class
frm_Main is the MDI container form. mdl_Reports is the child form.
It appears that focus is being constantly taken away from the Excel instance. Any clues as to why this looping is happening and is there a way to stop it so that I can achieve focus on the worksheet cells to enter values either by keyboard or mouse?
HotIndigo.
Continue reading...
Private Sub mdl_Reports_GotFocus(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.GotFocus
End Sub ' ** This code is in mdl_Reports **
Private Sub frm_Main_Activated(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.Activated
End Sub ' ** This code is in mdl_Main **
Private Sub mdl_Reports_LostFocus(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.LostFocus
End Sub ' ** This code is in mdl_Reports **
This is the essential code I am using (I have removed unrelated code):
Public Class frm_Main
Inherits Form
End Class
Public Class mdl_Reports
Inherits Form
Private Sub mdl_Reports_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) _
Handles MyBase.Load
Me.MdiParent = frm_Main
End Sub
Private Sub mnu_NewModel_Click(sender As Object,
e As EventArgs) _
Handles mnu_NewModel.Click
Dim Workbooks As Workbooks
oExcel = qExcel.Run_Excel()
ExHwnd = CType(oExcel.Hwnd, IntPtr)
With oExcel
SetParent(CInt(ExHwnd), CInt(pnl_Excel.Handle))
SendMessage(ExHwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
MoveWindow(ExHwnd, 0, -CtrlOffset, pnl_Excel.Width, pnl_Excel.Height + CtrlOffset, True)
End With
Workbooks = oExcel.Workbooks
Workbooks.Add()
oWB = oExcel.ActiveWorkbook
With oWB
.Activate()
.Title = "Template"
oSheet = CType(.Sheets.Add(), Worksheet)
End With
With oSheet
.Activate()
.Name = rName
.Visible = XlSheetVisibility.xlSheetVisible
If sheet Is Nothing Then
oSheet = DirectCast(oWB.Sheets.Add(After:=oWB.Sheets(oWB.Sheets.Count),
Count:=1,
Type:=XlSheetType.xlWorksheet),
Worksheet)
End If
.Range("A1").Value = "Model Name"
With oExcel
.SendKeys("{DOWN}", True)
.SendKeys("{DOWN}", True)
.SendKeys("^A", True)
End With
' Weirdness here - had to use above code because oExcel.Range("A3").Activate()
' or oExcel.Range("A3").Select() (or both together) did not work!
' Any comments or suggestions?
End With
With oExcel
.Visible = True
.EnableEvents = True
End With
SendMessage(ExHwnd, WM_ACTIVATE, WA_ACTIVE, 0)
End Sub
End Class
Friend Class qExcel
Shared WithEvents oExcel As doExcel = Nothing
Private Shared Running As Boolean = False
Friend Shared Function Run_Excel() As Office.Interop.Excel.Application
Dim rExcel = New Office.Interop.Excel.Application
oExcel = New doExcel(rExcel)
Running = True
ExcelRunning = True
Return rExcel
End Function
Friend Shared Sub QuitExcel(ByRef rExcel As Office.Interop.Excel.Application)
If Running Then
Try
rExcel.Quit()
rExcel = Nothing
oExcel.Dispose()
oExcel = Nothing
GC.Collect()
Running = False
ExcelRunning = False
Catch ex As Exception
End Try
End If
End Sub
Private Sub mnu_CloseTemplate_Click(sender As Object,
e As EventArgs) _
Handles mnu_CloseTemplate.Click
Call ReleaseWB()
Call qExcel.QuitExcel(oExcel)
End Sub
Private Sub ReleaseWB()
Dim ExcelWorkbooks As Workbooks = Nothing
Dim worksheets As Sheets = Nothing
Try
ExcelWorkbooks = oExcel.Workbooks
Catch ex As Exception
Exit Sub
End Try
For Each WB As Workbook In oExcel.Workbooks
worksheets = WB.Worksheets
For Each ws As Worksheet In worksheets
Try
Marshal.ReleaseComObject(ws)
Catch ex As Exception
End Try
Next
WB.Close(False) 'Don't save
Marshal.ReleaseComObject(WB)
Next
Try
Marshal.ReleaseComObject(worksheets)
worksheets = Nothing
Catch ex As Exception
End Try
Try
ExcelWorkbooks.Close()
Marshal.ReleaseComObject(ExcelWorkbooks)
ExcelWorkbooks = Nothing
Catch ex As Exception
End Try
End Sub
End Class
Friend Class doExcel
Implements IDisposable
Public Sub New(ByRef oExcel As Office.Interop.Excel.Application)
oExcel = New Office.Interop.Excel.Application
End Sub
Public Overloads Sub Dispose() Implements IDisposable.Dispose
End Sub
Protected Overrides Sub Finalize()
Dispose()
End Sub
End Class
frm_Main is the MDI container form. mdl_Reports is the child form.
It appears that focus is being constantly taken away from the Excel instance. Any clues as to why this looping is happening and is there a way to stop it so that I can achieve focus on the worksheet cells to enter values either by keyboard or mouse?
HotIndigo.
Continue reading...