如何在Excel互操作中强制单元格停止编辑?
本文关键字:单元格 编辑 Excel 互操作 | 更新日期: 2023-09-27 17:50:57
我有一个带ribbon的Excel 2007插件。功能区中的一个按钮触发了对当前工作表的大量操作,出于速度和用户体验的原因,我在操作期间设置了各种Excel.Application
属性,如Interactive
和EnableEvents
到false
。
我的问题是,功能区不会偷焦点,所以如果用户在编辑单元格时,他点击我的功能区按钮,设置Application.Interactive = false
时抛出异常,因为Excel认为用户仍在编辑单元格。
是否有一种方法可以通过保存或丢弃对单元格所做的更改来停止版本?
看来Range.DiscardChanges()
可能会解决我的问题,但它在2007年的API中不可用。
编辑:似乎Range.DiscardChanges()
是基于OLAP数据源的范围,所以它不会解决我的问题。
编辑:我试过在另一个细胞上呼叫Range.Activate()
。虽然我确实看到GUI中的单元格焦点发生了变化,但无论如何都会抛出异常。Range.Select()
不做任何事情
您不能停止编辑,但您可以检查编辑是否启用,然后告诉用户停止编辑:
private bool IsEditing(Microsoft.Office.Interop.Excel.Application excelApp)
{
if (excelApp.Interactive)
{
try
{
excelApp.Interactive = false;
excelApp.Interactive = true;
}
catch (Exception)
{
MessageBox.Show("Please stop cell editing before you continue.");
return true;
}
}
return false;
}
我在本页找到了答案,并将其从VBA更改为c#:https://www.add-in-express.com/creating-addins-blog/2011/03/23/excel-check-user-edit-cell/
因此,在寻找了几天并在MSDN上询问之后,最终的答案是API中根本没有此功能,并且如果不使用黑客解决方案1,则不可能实现。
Excel本身处理这种事情的方式只是在用户编辑时将其菜单变灰,所以我这样做是为了与主机应用程序保持一致。
1: Hacky,因为像使用SendKeys
这样的技术需要返回GUI以确保操作被处理,然后调用要求单元格不在版本中的方法。这在一个地方很好,但对每个调用Excel Interop的方法都这样做是疯狂的。
现在回答可能太晚了。但想想有人在寻找解决方案时会用这个技巧。
由于某种原因,sendkeys和单元格/范围激活命令没有运行。
解决这个问题的唯一方法是将焦点更改为另一个工作表,然后返回到当前工作表来欺骗excel。: -)
ExcelUtil.ActivateWorksheet("Sheet1");
currentWorksheet.Activate();
public static void ActivateWorksheet(string strWorksheetName)
{
bool found = false;
foreach (Excel.Worksheet sheet in Globals.ThisAddIn.Application.Worksheets)
{
if (sheet.Name.ToLower() == strWorksheetName.ToLower())
{
found = true;
break;
}
}
if (!found)
Globals.ThisAddIn.AddNewWorksheet(strWorksheetName);
((Excel.Worksheet)Globals.ThisAddIn.Application.Worksheets[strWorksheetName]).Activate();
}
希望对你有帮助。
Ram其他提出的解决方案都不适合我,然后我了解到我们可以在VB中使用excel Events。NET应用程序,并利用"BeforeClose"事件,强制Excel退出单元格编辑模式。
VB。NET代码:
'Declare Excel object'
Public WithEvents Excel As New Microsoft.Office.Interop.Excel.Application
public Fake_close as boolean
Public Function Is_in_edit_mode() As Boolean
Try
Excel.Interactive = Excel.Interactive
Catch Ex As Exception
Return True
End Try
Return False
End Function
Public Sub Exit_cell_edit_mode()
If Not Is_in_edit_mode() Then Exit Sub
'initiates closing the worksheet, which forces cancellation of cell edit mode.'
Fake_close = True 'Signal that the closing event is fake'
Excel.ActiveWorkbook.Close() 'This command will trigger the event below'
End Sub
'This event will be triggered in the VB.NET app before the workbook is closed on Excel'
Private Sub WorkbookBeforeClose(Wb As Workbook, ByRef Cancel As Boolean) Handles Excel.WorkbookBeforeClose
If Fake_close Then
Cancel = True 'Cancel the closing of the workbook'
Fake_close = False
End if
End Sub
如果选择另一个单元格或所有单元格,错误会消失吗?
private void myFunction()
{
xlSheet.Cells.Select();
//the rest of the work
}
我检测到问题并显示消息告诉用户:如果excelHelper.ExcelIsEditing(System.Media.SystemSounds.Beep.Play ()MsgBox("请完成编辑工作表!",vbCrLf,vbCrLf,"将光标移出当前单元格,然后重试按钮。")退出函数如果
函数ExcelIsEditing()作为BooleanExcelIsEditing = False
If ExcelApp.Interactive = False Then Return False
Try
ExcelApp.Interactive = False
ExcelApp.Interactive = True
Catch
Return True
End Try
结束功能
这是我能想到的最好的:_(