【问题标题】:VBA access drop downs properly in a website网站中的 VBA 访问下拉菜单正确
【发布时间】:2018-12-31 06:33:35
【问题描述】:

我有点问题。我希望一些VBA大师可以帮助我。我有一个网站,其中包含我希望能够选择的下拉选项。现在我的代码关闭了,我不确定我做错了什么。我查看了该网站,试图找出我做错了什么,但没有发现可以直接回答我的问题。任何帮助将不胜感激。

这是我所拥有的:

Private Sub CMReportExport()
    Dim IEapp As Object
    Dim WebUrl As String
    Dim yearList As Object
    Dim prefixList As Object
    Dim versionList As Object

    Set IEapp = CreateObject("InternetExplorerMedium.Application")
    'Set IEapp = CreateObject("InternetExplorer.Application")

    WebUrl = "http://reporthub/Enterprise/Pages/Report.aspx?ItemPath=%2fSupply+Chain%2fProduction%2fContribution+Margin%2fNonFood%2fNonFood+CM+RetailCat"

    With IEapp
        .Silent = True
        .Visible = True
        .navigate WebUrl
    End With
    While IEapp.Busy Or IEapp.readyState < 4: DoEvents: Wend '<== Ensure page loaded

    Set yearList = IEapp.document.querySelectorAll("#ctl32_ctl04_ctl03_ddValue option")  '<==apply CSS selector to get nodeList
    Set prefixList = IEapp.document.querySelectorAll("#ctl32_ctl04_ctl05_ddValue option")
    Set versionList = IEapp.document.querySelectorAll("#ctl32_ctl04_ctl07_ddValue option")

    yearList.item(2).Selected = True  'Index into nodeList e.g. second item is at index 2 = year 2018
    prefixList.item(2).Selected = True
    versionList.item(1).Selected = True

    'Set IEapp.getElementById("ctl32_ctl04_ctl03_ddValue").selectedvalue = 2 'Year
    'Set IEapp.getElementById("ctl32_ctl04_ctl05_ddValue").selectedvalue = DA 'Prefix
    'Set IEapp.getElementById("ctl32_ctl04_ctl07_ddValue").selectedvalue = 1 'Version
End Sub

HTML 元素(一个块)如下:

<tr>
    <td class="ParamLabelCell"><label for="ctl32_ctl04_ctl03_ddValue"><span>Year</span></label>
    </td>
    <td class="ParamEntryCell" style="padding-right:0px;"><div id="ctl32_ctl04_ctl03">
        <select name="ctl32$ctl04$ctl03$ddValue" onchange="javascript:setTimeout('__doPostBack(\'ctl32$ctl04$ctl03$ddValue\',\'\')', 0)" id="ctl32_ctl04_ctl03_ddValue" disabled="disabled">
            <option selected="selected" value="0">&lt;Select&nbsp;a&nbsp;Value&gt;</option>
            <option value="1">2019</option>
            <option value="2">2018</option>
            <option value="3">2017</option>
            <option value="4">2016</option>
            <option value="5">2015</option>
        </select>
        </div></td><td class="InterParamPadding"></td><td class="ParamLabelCell"><label for="ctl32_ctl04_ctl05_ddValue"><span disabled="disabled">Offer</span></label></td><td class="ParamEntryCell" style="padding-right:0px;"><div id="ctl32_ctl04_ctl05">
            <select name="ctl32$ctl04$ctl05$ddValue" onchange="javascript:setTimeout('__doPostBack(\'ctl32$ctl04$ctl05$ddValue\',\'\')', 0)" id="ctl32_ctl04_ctl05_ddValue" disabled="disabled" class="EmptyDropDown">
            </select>
        </div>
    </td>
</tr>
<tr IsParameterRow="true">
    <td class="ParamLabelCell"><label for="ctl32_ctl04_ctl07_ddValue"><span disabled="disabled">Version</span></label></td>
    <td class="ParamEntryCell" style="padding-right:0px;"><div id="ctl32_ctl04_ctl07">
    <select name="ctl32$ctl04$ctl07$ddValue" id="ctl32_ctl04_ctl07_ddValue" disabled="disabled" class="EmptyDropDown">
</tr>

【问题讨论】:

    标签: html ms-access vba


    【解决方案1】:

    警告:

    我无法针对该网页进行测试,并且没有足够的 HTML 来了解是否还有表单/框架等可以协商。以下基于提供的 HTML sn-p。里程可能会有所不同。


    CSS 选择器:

    您可以使用 CSS 选择器来定位元素。例如,您可以使用以下选择器获取所有year 选项,然后索引到返回的nodeList:

    #ctl32_ctl04_ctl03_ddValue option
    

    上面的选择器表示所有带有option 标签的元素,其父元素的id 为ctl32_ctl04_ctl03_ddValue"#" 是 id 选择器。

    没有足够的 HTML 来为您确定要定位的其他元素提供建议,但请参阅底部的我的建议。这说明了使用 CSS 选择器通过页面样式来定位元素的原理。有关 CSS 选择器 herehere 的更多信息。


    提供的 HTML 部分的 CSS 查询结果:


    获取 nodeList 并选择一个选项 - VBA:

    当匹配多个元素时,querySelectorAll 方法用于应用选择器并返回匹配元素的nodeList

    例如:

    While IEapp.Busy Or IEapp.readyState < 4: DoEvents: Wend '<== Ensure page loaded
    Dim yearList As Object
    Set yearList = IEapp.document.querySelectorAll("#ctl32_ctl04_ctl03_ddValue option")  '<==apply CSS selector to get nodeList
    yearList.item(1).Selected = True  'Index into nodeList e.g. second item is at index 1 = year 2019 
    

    假设您的其他两个选项列表的模式相似:

    Dim prefixList As Object, versionList As Object
    Set prefixList = IEapp.document.querySelectorAll("#ctl32_ctl04_ctl05_ddValue option") 
    Set versionList = IEapp.document.querySelectorAll("#ctl32_ctl04_ctl07_ddValue option")
    

    然后索引到那些。

    如果 While IEapp.Busy 或 IEapp.readyState

    While IEapp.readyState < 4: DoEvents: Wend
    Dim waitUntil As Date
    waitUntil = Now + TimeValue("00:00:11")  '<==Adjust additional wait time in seconds here
    Do
      DoEvents
    Loop Until Now >= waitUntil
    

    XMLHttpRequest (XHR)

    您目前使用的是 IE 浏览器,这是一种较慢的抓取方法。您可以通过发出 XHR POST 请求来检索所需的信息。我无法针对该页面进行测试,但您可以找到更多信息 herehere

    【讨论】:

    • 我已经使用了你的建议,但得到一个调试错误,提示“对象'IWebBrowser 2'的方法'忙'失败。它专注于代码的While IEapp.Busy or IEapp.ReadyState &lt; 4
    • 尝试使用 Set IEapp = CreateObject("InternetExplorerMedium.Application")
    • 是的,设置为中高。我会联系我们的管理员看看可以做什么。
    • 本周与我们报告工具的管理员开会讨论这个问题。希望我们能找到一种方法让它发挥作用。我会及时通知你的!
    • 不,很遗憾没有。似乎存在无法解决的权限问题。
    猜你喜欢
    • 2017-05-10
    • 2022-01-13
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多