在 VB.Net Windows 应用程序中,我通过早期绑定创建一个 Excel 对象,并使用从 SQL 返回的行填充电子表格。
目的是允许用户从电子表格中选择 1 行或多行,捕获选择事件,然后检索所选行中的所有数据以进行进一步处理。我知道如果我用 SQL 数据填充 datagridview 但用户坚持使用 Excel,这会很简单。
尽管我进行了搜索,但我无法发现是否可以在.Net 中捕获 select 事件。
如果可能的话,请告诉我如何操作或给我一个有关该主题的好文章的链接。如果没有,也请告诉我。
谢谢你!
谢谢你的总结,迈克。既然我已经有了良好的基础,我将做更多的研究。我的用户将在电子表格中执行各种操作:1)选择行以进行进一步处理(路由操作);可能是不连续的 2) 如果操作未出现在输入中(未路由操作),则添加行,然后选择它们。3)可能添加列数据(我想限制此功能,但用户是老板......)
我将进行实验,但你能告诉我如何区分行选择和列选择吗?即我想要响应的选择更改和我不响应的选择更改?
您正在寻找“SelectionChange”事件。与此相关的事件有 3 个:Worksheet.SelectionChange、Workbook.SheetSelectionChange和Application.SheetSelectionChange。
我认为出于您的目的,使用Worksheet.SelectionChange可能是您想要的,因为您已经知道您感兴趣的工作表,但这里有一个使用所有三个工作表作为示例的示例:
Public Class ExcelEventHandlingClass
Dim WithEvents xlApp As Excel.Application
Dim WithEvents myWorkbook As Excel.Workbook
Dim WithEvents myWorksheet As Excel.Worksheet
Sub New()
xlApp = New Excel.Application
xlApp.Visible = True
myWorkbook = xlApp.Workbooks.Add
myWorksheet = CType(myWorkbook.Worksheets.Add, Excel.Worksheet)
End Sub
Private Sub xlApp_SheetSelectionChange( _
ByVal Sh As Object, _
ByVal Target As Excel.Range) _
Handles xlApp.SheetSelectionChange
MessageBox.Show( _
"xlApp_SheetSelectionChange: " & _
Target.Address(External:=True) & " was selected")
End Sub
Private Sub myWorkbook_SheetSelectionChange( _
ByVal Sh As Object, _
ByVal Target As Excel.Range) _
Handles myWorkbook.SheetSelectionChange
MessageBox.Show( _
"myWorkbook_SheetSelectionChange: " & _
Target.Address(External:=True) & " was selected")
End Sub
Private Sub myWorksheet_SelectionChange( _
ByVal Target As Excel.Range) _
Handles myWorksheet.SelectionChange
MessageBox.Show( _
"myWorksheet_SelectionChange: " & _
Target.Address(External:=True) & " was selected")
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式运行上面的命令:
Dim o As ExcelEventHandlingClass
Private Sub StartExample()
o = New ExcelEventHandlingClass
End Sub
Run Code Online (Sandbox Code Playgroud)
在此示例中,如果您更改活动工作表上的选择,则所有三个事件处理程序都会触发,并且您会看到 3 个消息框。这有点烦人,哈哈,但这证明了这一点。
当然,您不必使用WithEvents来连接事件处理程序,您可以使用 AddHandler 代替:
AddHandler xlApp.SheetSelectionChange, AddressOf xlApp_SheetSelectionChange
AddHandler myWorkbook.SheetSelectionChange, AddressOf myWorkbook_SheetSelectionChange
AddHandler myWorksheet.SelectionChange, AddressOf myWorksheet_SelectionChange
Run Code Online (Sandbox Code Playgroud)
一旦您的处理程序被调用,它就可以使用自动化来提取值。您可以使用该Range.Value属性从单个单元格获取值,或从多单元格区域返回二维范围的值。当然,一旦您根据选择知道想要哪些行,您就可以再次运行 SQL,但我只是想指出您可以直接提取单元格值。
希望这可以帮助!
麦克风
编辑:更新 Melody 的回复
“非常感谢你的帮助,迈克!”
没问题。:-)
“我需要了解 Target.Address(External:=True) 位的本质。我假设目标包含有关所选内容的信息?您能提供更多信息吗?它是否封装了行号或行号?选定的行?它是否包含可用于获取列值的索引或项属性?External=True 参数只是说这是来自非托管代码,还是我的假设不正确?”
这只是一个示例,展示如何报告所选范围的地址。让我们看一下 Worksheet.SelectionChange 事件处理程序的方法签名:
Private Sub myWorksheet_SelectionChange( _
ByVal Target As Excel.Range) _
Handles myWorksheet.SelectionChange
' Your code goes here...
End Sub
Run Code Online (Sandbox Code Playgroud)
该事件有一个参数,即Target As Excel.Range参数。(Application.SheetSelectionChange和Workbook.SheetSelectionChange事件有第二个参数,说明选择更改发生在哪个工作表上,但在更改事件的情况下,Worksheet.Selection我们已经知道选择更改发生在哪个工作表上,因此省略该参数。)
关键是你可以利用 Target As Excel.Range参数来确定你想要什么。要获取本地地址,其中包括范围地址,但不包括工作表地址(例如“A1:C3”):
Dim localAddress As String = Target.Address
Run Code Online (Sandbox Code Playgroud)
要获取完整路径地址(例如“[Book1.xls]Sheet1!A1:C3”):
Dim localAddress As String = Target.Address(External:=True)
Run Code Online (Sandbox Code Playgroud)
要获取选定的行数:
Dim numRows As Integer = Target.Rows.Count
Run Code Online (Sandbox Code Playgroud)
要获取工作表上该范围顶行的行索引(请记住:Excel 工作表使用 Base 1 寻址!):
Dim topRowIndex As Integer = Target.Row
Run Code Online (Sandbox Code Playgroud)
要获取最后一行的行索引:
Dim lastRowIndex As Integer = Target.Rows(Target.Rows.Count).Row
Run Code Online (Sandbox Code Playgroud)
这些只是一些例子。您必须使用 Excel VBA 帮助文件(或 Google)来获取有关 Range 类成员的更多信息。
由于假期的关系,我可能无法立即回复您,但我很感谢您的帮助。
懒鬼。开个玩笑,周末愉快。:-)