У меня есть форма доступа с элементом управления веб-браузером (b). Я «пишу» контент b на лету:
Dim h as String
h = "<html><body>"
h = h & "<form id='bf' ...>"
h = h & "<input type='text' id='test' name='test'>"
h = h & "<input type='submit' value='Submit'>"
h = h & "</form>"
h = h & "</body></html>"
Call Me.b.Object.Document.Write(h)
Я хочу обработать ответ пользователя (на «Отправить») с помощью функции VBA.
В моем коде VBA доступ к HTML-форме bf можно получить через Me.b.Object.Document.getElementById("bf"), то есть через MSHTML.HtmlFormElement и предоставляет метод attachEvent с двумя аргументами:
Function attachEvent(event As String, pdisp As object) As Boolean
Как мне создать объект pdisp, чтобы выполнить следующее?
Call Me.b.Object.Document.getElementById("f").attachEvent("onsubmit", *???*)
Заранее благодарю за любую информацию по этой или любому альтернативному решению моей проблемы.
Предоставление «указателя функции» с помощью Address Of не работает. Я предполагаю, что требуемый объект должен быть экземпляром какого-то WithEvents класса, реализующего некоторый интерфейс... Но не удалось найти никакой документации по этому вопросу.
Несмотря на .Net, библиотека VBA MSHTML не обеспечивает доступ к ObjectForScripting...





Пример использования класса с WithEvents:
Модуль класса clsHtmlInput:
Option Explicit
Private WithEvents m_btn As MSHTML.HTMLInputElement
Private m_txt As MSHTML.HTMLInputElement
Public Sub SetInputs(theButton, theTextBox)
Set m_btn = theButton
Set m_txt = theTextBox
End Sub
Private Function m_btn_onclick() As Boolean
MsgBox "Clicked: " & m_txt.Value
End Function
Ваша пользовательская форма:
Dim eventHandler As clsHtmlInput '<< instance of your "withEvents" class
Private Sub UserForm_Activate()
Dim el As MSHTML.HTMLInputElement, h As String
With Me.wb1
.navigate "about:blank"
WaitFor wb1
.document.Open "text/html"
h = "<html><body>"
h = h & "<input type='text' id='test' name='test'>"
h = h & "<input type='submit' value='Submit' id='btnSubmit'>"
h = h & "</body></html>"
.document.Write h
.document.Close
WaitFor wb1
Set eventHandler = New clsHtmlInput
eventHandler.SetInputs .document.getElementById("btnSubmit"), _
.document.getElementById("test")
End With
End Sub
'utility sub to ensure page is loaded and ready
Sub WaitFor(IE)
Do While IE.readyState < 4 Or IE.Busy
DoEvents
Loop
End Sub
Если вы знакомы с HTML и JavaScript (или, по крайней мере, с подмножеством «современного» HTML/js, которое все еще поддерживается в старых элементах управления веб-браузером...), это может быть способом создания интерфейсов, выходящих за рамки базовые элементы управления формами VBA.
Хороший. Проголосовал за это...
Спасибо за четкое объяснение точного решения моей проблемы. Действительно, сама цель состоит в том, чтобы преодолеть ограничения форм VBA, особенно когда, в зависимости от данных, необходима динамическая структура элементов управления. Еще раз спасибо!
Вы можете использовать простой класс VBA и
WithEventsдля перехвата событий, происходящих с элементами HTML в элементе управления веб-браузера. См., например: stackoverflow.com/a/43988381/478884