Программный перебор свойств контрола

Можно ли программно перебрать и распечатать в Debug.Print все свойства объёкта ChartObjectТипа For Each свойство In ChartObject.? Debug.Print свойство.Name, свойство.Value
8 ответов

Насколько мне известно, VBA (в отличие от других языков программирования) такого не позволяет.


Мне попадалось описание класса. Не помню где только. Кто-то сделал. Тогда думал не понадобится. Придётся все около 60 свойств проверять и считывать вручную


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


Вообще-то, есть один способ.Сохраняем копию книги в формате XLSX, переименовываем в ZIP (необязательно), разархивируем файл средствами Windows, среди извлечённых файлов находим папку xl/charts, в ней - файлы с именами типа chart1.xmlВ этом XML описаны все свойства (и их значения) вашей диаграммы.


Типа For Each свойство In ChartObject.? Debug.Print свойство.Name, свойство.Value
вообще-то, св-во это то, что справа от точки. Вопрос: что слева от нее? Как-то глупо и несерьезно получается. Куда смотрели разработчики? Мне подобная мысль приходила (это было бы слишком здорово). Явных решений не знаю. Попробуй задать вопрос здесь. Логика подсказывает, что если vbe может их получить, то и мы сможем ) В конце-концов, тип объекта мы же можем получить:
MsgBox TypeName(Cells(1))
 MsgBox TypeName(ActiveSheet)
 MsgBox TypeName(ThisWorkbook)
 MsgBox TypeName(Application)
Случайно открыл справочник функций:
Функция CallByName CallByName(Object,ProcName,CallType ,[Args() ]) Новая функция, которая появилась в версии Visual Basic 6.0 Функция выполняет метод объекта или наборов или возвращает свойства объекта
Может оно?Нет


А вот это не оно? Что-то пока не могу запустить:
Есть такая чудесная библиотека - TLBINF32.DLL, с помощью которой можно получить список всех свойств заданного элемента управления. Например:Код <pre name="code" class="prettyprint linenums"> Public Function CollectProperties(Target As Object) As Collection Dim oTLB As InterfaceInfo Dim sMemberName As String Dim sInvokeKind As String Dim i As Integer Dim kFuncReturn As Collection Dim o As clsMember Set kFuncReturn = New Collection Set oTLB = TLI.InterfaceInfoFromObject(Target) For i = 1 To oTLB.Members.Count sInvokeKind = ReturnInvokeKind(oTLB.Members(i).InvokeKind) If InStr(1, sInvokeKind, 'INVOKE_PROPERTY') > 0 Then sMemberName = oTLB.Members(i) If Left$(sMemberName, 1) <> '_' Then Set o = New clsMember o.MemberName = sMemberName o.MemberType = sInvokeKind kFuncReturn.Add o End If End If Next i Set CollectProperties = kFuncReturn End Function </pre> И пример вызова:Код <pre name="code" class="prettyprint linenums"> Dim propList As Collection Dim propMember As clsMember Dim ct As Control Set ct = Me.Text1 ' << просто для примера ' получаем список свойств контрола ct в коллекцию propList: Set propList = CollectProperties(ct) ' заполняем комбобокс cboProps свойствами контрола ct: For Each propMember In propList cboProps.AddItem propMember.MemberName Next propMember </pre> Примечание: класс clsMember описан так:Код <pre name="code" class="prettyprint linenums"> Public MemberName As String Public MemberType As String </pre>


Ошибка в строке
sInvokeKind = ReturnInvokeKind(oTLB.Members(i).InvokeKind)


Вот так уже работает
Private Sub ListProps(comServer As Object)
Dim IFaceInfo As TLI.InterfaceInfo
Dim mem As TLI.MemberInfo
Set IFaceInfo = TLI.InterfaceInfoFromObject(comServer)
On Error Resume Next
 For Each mem In IFaceInfo.Members
 If mem.InvokeKind = INVOKE_PROPERTYGET Then
 Debug.Print "Property " & mem.Name & " = " & _
 TLI.InvokeHook(comServer, mem.MemberId, INVOKE_PROPERTYGET)
 End If
 Next
End Sub
вызов:
Dim SH As ChartObject
Dim s As Legend
Set SH = ActiveSheet.ChartObjects.Add(100, 50, 200, 200)
SH.Activate
Application.Dialogs(xlDialogChartType).Show
ListProps SH
Debug.Print

Set s = ActiveChart.Legend
ActiveChart.Legend.Select
Application.Dialogs(xlDialogFormatLegend).Show 'формат легенды
ListProps s