从 Excel 文档中的代码隐藏获取 ActiveX 或表单对象(文本框)
Reach ActiveX or Form objects (textbox) from codebehind in an Excel document
excel 文件中有几个文本框作为 ActiveX 对象,我想从代码隐藏中访问它们。
我正在为其他字段使用 ClosedXML,但我愿意接受其他建议。
您可以在 VBA 中创建文件(在 %appdata% 文件夹中),并在该文件中保存文本框值 (by example, .ini file)。
然后在 C# 中打开文件。
VBA(.xlsm 文件)
' PtrSafe for 64bit (for 32bit, remove it)
Private Declare PtrSafe Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, ByVal lpKeyName As Any, _
ByVal lpString As Any, ByVal lpFileName As String) As Long
Private Sub TextBox1_Change()
WritePrivateProfileString "Page1", "TextBox1", TextBox1.Text, "C:\Users\HS\Desktop\exceltab.ini"
End Sub
C:\Users\HS\Desktop\exceltab.ini
[Page1]
TextBox1=ok
如果您想使用 ClosedXML,您可以 link 具有 LinkedCell
属性的文本区域和单元格。
像这样:
参见:
如果您使用的是 ClosedXML,则应查看 XLWSContentManager
根据Microsoft:
ActiveX controls are represented by OLEObject objects in the OLEObjects collection (all OLEObject objects are also in the Shapes collection)
因此,使用 ClosedXML,您需要使用 XLWSContents.OleObjects
,但如果控件不是 ActiveX 控件,而是内置的 Excel Form 控件,你需要使用 XLWSContents.Controls
.
但请注意 MS 文档 - ClosedXML 的实现可能还需要您检查形状。
您可以如下遍历所有OLE 对象,并通过文本框名称或文本框Text 来识别您需要的文本框。您可以使用工作簿外部或任何代码的工作表引用,而不是我。
Private Sub GetActiveXControls()
For Each Item In Me.OLEObjects
'Debug.Print Item.Name
If TypeName(Item.Object) = "TextBox" Then
Debug.Print "text = " & Item.Object.text
End If
Next
End Sub
要从 C# 访问 OLE 对象,请添加对 Microsoft Forms 2.0 对象库的引用。您可以遍历所需复选框和文本框的控件。享受!
using Excel = Microsoft.Office.Interop.Excel;
using VBE = Microsoft.Vbe.Interop.Forms;
private static void ExcelOperation(string xlFileName)
{
var xlApp = new Excel.Application();
var xlWorkbook = xlApp.Workbooks.Open(xlFileName);
var xlSheet = xlWorkbook.Worksheets["your_sheet_Name"] as Excel.Worksheet;
try
{
Excel.OLEObjects oleObjects = xlSheet.OLEObjects() as Excel.OLEObjects;
foreach (Excel.OLEObject item in oleObjects)
{
if (item.progID == "Forms.TextBox.1")
{
VBE.TextBox xlTB = item.Object as VBE.TextBox;
Console.WriteLine("Name: " + item.Name);
Console.WriteLine("Text: " + xlTB.Text);
Console.WriteLine("Value: " + xlTB.get_Value());
Marshal.ReleaseComObject(xlTB); xlTB = null;
}
else if (item.progID == "Forms.CheckBox.1")
{
VBE.CheckBox xlCB = item.Object as VBE.CheckBox;
Console.WriteLine("checkbox: " + item.Name);
Console.WriteLine("Value: " + xlCB.get_Value());
Marshal.ReleaseComObject(xlCB); xlCB = null;
}
}
Marshal.ReleaseComObject(oleObjects); oleObjects = null;
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Marshal.ReleaseComObject(xlSheet); xlSheet = null;
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook); xlWorkbook = null;
Marshal.ReleaseComObject(xlApp); xlApp = null;
}
excel 文件中有几个文本框作为 ActiveX 对象,我想从代码隐藏中访问它们。
我正在为其他字段使用 ClosedXML,但我愿意接受其他建议。
您可以在 VBA 中创建文件(在 %appdata% 文件夹中),并在该文件中保存文本框值 (by example, .ini file)。
然后在 C# 中打开文件。
VBA(.xlsm 文件)
' PtrSafe for 64bit (for 32bit, remove it)
Private Declare PtrSafe Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, ByVal lpKeyName As Any, _
ByVal lpString As Any, ByVal lpFileName As String) As Long
Private Sub TextBox1_Change()
WritePrivateProfileString "Page1", "TextBox1", TextBox1.Text, "C:\Users\HS\Desktop\exceltab.ini"
End Sub
C:\Users\HS\Desktop\exceltab.ini
[Page1]
TextBox1=ok
如果您想使用 ClosedXML,您可以 link 具有 LinkedCell
属性的文本区域和单元格。
像这样:
参见:
如果您使用的是 ClosedXML,则应查看 XLWSContentManager
根据Microsoft:
ActiveX controls are represented by OLEObject objects in the OLEObjects collection (all OLEObject objects are also in the Shapes collection)
因此,使用 ClosedXML,您需要使用 XLWSContents.OleObjects
,但如果控件不是 ActiveX 控件,而是内置的 Excel Form 控件,你需要使用 XLWSContents.Controls
.
但请注意 MS 文档 - ClosedXML 的实现可能还需要您检查形状。
您可以如下遍历所有OLE 对象,并通过文本框名称或文本框Text 来识别您需要的文本框。您可以使用工作簿外部或任何代码的工作表引用,而不是我。
Private Sub GetActiveXControls()
For Each Item In Me.OLEObjects
'Debug.Print Item.Name
If TypeName(Item.Object) = "TextBox" Then
Debug.Print "text = " & Item.Object.text
End If
Next
End Sub
要从 C# 访问 OLE 对象,请添加对 Microsoft Forms 2.0 对象库的引用。您可以遍历所需复选框和文本框的控件。享受!
using Excel = Microsoft.Office.Interop.Excel;
using VBE = Microsoft.Vbe.Interop.Forms;
private static void ExcelOperation(string xlFileName)
{
var xlApp = new Excel.Application();
var xlWorkbook = xlApp.Workbooks.Open(xlFileName);
var xlSheet = xlWorkbook.Worksheets["your_sheet_Name"] as Excel.Worksheet;
try
{
Excel.OLEObjects oleObjects = xlSheet.OLEObjects() as Excel.OLEObjects;
foreach (Excel.OLEObject item in oleObjects)
{
if (item.progID == "Forms.TextBox.1")
{
VBE.TextBox xlTB = item.Object as VBE.TextBox;
Console.WriteLine("Name: " + item.Name);
Console.WriteLine("Text: " + xlTB.Text);
Console.WriteLine("Value: " + xlTB.get_Value());
Marshal.ReleaseComObject(xlTB); xlTB = null;
}
else if (item.progID == "Forms.CheckBox.1")
{
VBE.CheckBox xlCB = item.Object as VBE.CheckBox;
Console.WriteLine("checkbox: " + item.Name);
Console.WriteLine("Value: " + xlCB.get_Value());
Marshal.ReleaseComObject(xlCB); xlCB = null;
}
}
Marshal.ReleaseComObject(oleObjects); oleObjects = null;
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Marshal.ReleaseComObject(xlSheet); xlSheet = null;
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook); xlWorkbook = null;
Marshal.ReleaseComObject(xlApp); xlApp = null;
}