Получить объекты ActiveX или формы (текстовое поле) из кода в документе Excel

В файле Excel есть несколько текстовых полей в виде объектов ActiveX, и я хочу получить доступ к ним из кода.

Я использую ClosedXML для других полей, но я открыт для других предложений.

5 ответов

Решение

Для доступа к объектам OLE из C# добавьте ссылку на библиотеку объектов 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;
        }

Вы можете выполнить итерацию всех объектов OLE, как показано ниже, и определить нужное текстовое поле по имени текстового поля или текстового поля Текст. Вместо Меня вы можете использовать ссылку на лист вне книги или любого кода.

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

Если вы используете ClosedXML, вы должны взглянуть на XLWSContentManager

Согласно Microsoft:

Элементы управления ActiveX представлены объектами OLEObject в коллекции OLEObjects (все объекты OLEObject также находятся в коллекции Shapes)

Итак, используя ClosedXML, вам нужно использовать XLWSContents.OleObjects, но если элементы управления не являются элементами управления ActiveX, а представляют собой встроенные элементы управления формы Excel, вам необходимо использовать XLWSContents.Controls,

Но обратите внимание на документацию MS - реализация ClosedXML может потребовать, чтобы вы также проверили Shapes.

Вы можете создать файл в VBA (в папке%appdata%) и сохранить значение текстовых полей в этом файле ( например, файл.ini).

И после этого открыть файл в 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, вы можете связать текстовую область и ячейку с LinkedCell свойства.

Как это:

Увидеть:

Другие вопросы по тегам