Nhấp vào một mục trong danh sách tự động hoàn thành với VBA và HTML


13

Tôi đã tạo một tự động hóa trong đó nó sẽ cho phép tôi nhập chi tiết trên một trang web (mặc dù tôi không thể chia sẻ nó vì nó là nội bộ). Mã của tôi dưới đây chỉ hoạt động cho đến khi nó nhập một văn bản trên "nhận được từ". Tuy nhiên, trường "nhận từ" này có danh sách tự động hoàn thành và tôi cần chọn nó để điền vào các trường khác như TIN và Địa chỉ.

Danh sách tự động hoàn thành khá giống với danh sách trong https://jqueryui.com/autocomplete/ hoặc http://demos.codexworld.com/autocomplete-textbox-USE-jquery-php-mysql/

Dưới đây là mã của tôi:

Sub Automate_IE_Enter_Data()
'This will load a webpage in IE
Dim i               As Long
Dim Url             As String
Dim IE              As InternetExplorer
Dim objElement      As Object
Dim objCollection   As Object
Dim HWNDSrc         As Long
Dim wsTemplate      As Worksheet
Dim objEvent        As Object
Dim li_arr          As Variant
Dim NodeList        As Object
Dim x               As Long


Set wsTemplate = ThisWorkbook.Sheets("Template")

'Create InternetExplorer Object
Set IE = New InternetExplorerMedium

'Set IE.Visible = True to make IE visible, or False for IE to run in the background
IE.Visible = True

'Define URL by getting the value in rngURL; can be found in the main sheet
Url = "http://URL Path"

'Navigate to URL
IE.Navigate Url

' Statusbar let's user know website is loading
Application.StatusBar = Url & " is loading. Please wait..."

Do
DoEvents
Loop Until IE.ReadyState = READYSTATE_COMPLETE

'Webpage Loaded
Application.StatusBar = Url & " Loaded"

'Get Window ID for IE so we can set it as activate window
HWNDSrc = IE.hwnd
'Set IE as Active Window
SetForegroundWindow HWNDSrc
ShowWindow IE.hwnd, SW_SHOWMAXIMIZED

Dim Doc As HTMLDocument
Set Doc = IE.document

inputString = "Nuevo"

With Doc.getElementById("supName")

    .Focus
    SendKeys inputString 'Trigger the field to show autocomplete list

End With

'----THIS IS WHERE I AM TRYING TO CLICK THE AUTOCOMPLETE LIST THAT IS BEING DISPLAYED-----
'-----HOWEVER, CLICKING DOESN'T SEEM TO WORK.-----

Set NodeList = Doc.querySelectorAll(".ui-active-menuitem[role=""menuitem""]")

For x = 0 To NodeList.Length - 1
'Debug.Print NodeList.Item(x).Click '<==this way
NodeList.Item(x).Focus
NodeList(x).Click   '<==Or this method

Next x


MsgBox "Done"

'Unload IE
endmacro:
Set IE = Nothing
Set objElement = Nothing
Set objCollection = Nothing

End Sub

Dưới đây là HTML mà tôi nghĩ sẽ hữu ích để hiểu vấn đề của mình:

'----- NAME OF THE FIELD THAT HAS AN AUTOCOMPLETE LIST----
<INPUT name=supName class="required-placeholder simple-placeholder ui-autocomplete-input placeholding" id=supName role=textbox aria-haspopup=true aria-autocomplete=list type=text value=Required jQuery17102032699680461189="39" placeholder="Required" autocomplete="off">

<UL class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all" role=listbox aria-activedescendant=ui-active-menuitem style="WIDTH: 400px; LEFT: 751px; Z-INDEX: 1; DISPLAY: none; TOP: 287px" jQuery17102032699680461189="42"><LI class=ui-menu-item role=menuitem jQuery17102032699680461189="104"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="114">List 0</A></LI>

<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="105"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="115">List 1</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="106"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="116">List 2</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="107"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="117">List 3</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="108"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="118">List 4</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="109"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="119">List 5</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="110"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="120">List 6</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="111"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="121">List 7</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="112"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="122">List 8</A></LI>
<LI class=ui-menu-item role=menuitem jQuery17102032699680461189="113"><A tabIndex=-1 class=ui-corner-all jQuery17102032699680461189="123">List 9</A></LI></UL>

Một ảnh chụp màn hình mẫu của danh sách tự động hoàn thành:

nhập mô tả hình ảnh ở đây

Thêm về HTML:

<DIV class="ui-tabs-panel ui-widget-content ui-corner-bottom" id=ui-tabs-1 jQuery17109198838813964318="12">

  <FORM id=receiptEntryForm action=/ReceiptEntry/SaveReceipt method=post jQuery17109198838813964318="40">

    <DIV id=receipt-entry>
      <DIV class=receipt-content>
        <DIV class=content-label>
          <LABEL>OR No:</LABEL>
          <LABEL>Date:</LABEL>
          <LABEL>Received From:</LABEL>
          <LABEL>TIN:</LABEL>
          <LABEL>Address:</LABEL> </DIV>
        <DIV class=content-input>
          <INPUT name=ReceiptNumber disabled id=ReceiptNumber type=text data-val-required="The ReceiptNumber field is required." data-val-number="The field ReceiptNumber must be a number." data-val="true">

          <INPUT name=printDate class="datepicker hasDatepicker" id=printDate type=text jQuery17109198838813964318="38">

          <INPUT name=supName class="required-placeholder simple-placeholder ui-autocomplete-input placeholding" id=supName role=textbox aria-haspopup=true aria-autocomplete=list type=text value=Required jQuery17109198838813964318="39" placeholder="Required" autocomplete="off">

          <INPUT name=SupplierCode id=SupplierCode type=hidden data-val-required="The SupplierCode field is required." data-val="true" data-val-length-max="20" data-val-length="You&amp;#39;ve reached the maximum length allowed.">

          <INPUT name=SupTIN class="required-placeholder placeholding simple-placeholder" id=SupTIN type=text value=Required jQuery17109198838813964318="41" placeholder="Required" ,>

          <TEXTAREA name=SupAdd class="textarea-wide required-placeholder" id=SupAdd rows=3 cols=48 placeholder="Required"></TEXTAREA>
        </DIV>
      </DIV>
      <DIV class=editor-label>
        <LABEL id=sum-label>The sum of ****:</LABEL>
        <LABEL class=grayed-out id=total-amount-words></LABEL>
        <LABEL class=right id=total-amount></LABEL>
      </DIV>
      <BR>
      <BR>
      <BR>
      <DIV id=receipt-selection>
        <DIV class=content-label>
          <LABEL id=receipt-type-label>Receipt Type:</LABEL>
          <LABEL for=chk-vatable>VATable Receipt:</LABEL>
          <H5>IN PAYMENT OF</H5>
          <BR>
        </DIV>
        <DIV class=content-iput>
          <SELECT id=receiptentry-type jQuery17109198838813964318="36">
            <OPTION value=cr selected>Collection Receipt</OPTION>
            <OPTION value=or>Official Receipt</OPTION>
          </SELECT>
          <BR>
          <INPUT disabled id=chk-vatable type=checkbox jQuery17109198838813964318="37"> </DIV>
        <DIV id=receiptentry-receipt-table>
          <DIV>
            <TABLE>
              <THEAD>
                <TR>
                  <TH>INVOICE NO.</TH>
                  <TH>AMOUNT</TH>
                  <TH colSpan=3>FORM OF PAYMENT</TH>
                  <TH>AMOUNT</TH>
                </TR>
              </THEAD>
              <TBODY id=receipt-entry-table1>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice0 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount0 contentEditable=true jQuery17109198838813964318="44"></SPAN>
                  </TD>
                  <TD class="bold left-align" colSpan=3>CASH</TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=table1-cash-amount contentEditable=true jQuery17109198838813964318="53"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice1 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount1 contentEditable=true jQuery17109198838813964318="45"></SPAN>
                  </TD>
                  <TH>BANK</TH>
                  <TH>CHECK NO.</TH>
                  <TH>DATE</TH>
                  <TD>
                    <SPAN class="table1-amount2 right-align" jQuery17109198838813964318="54"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice2 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount2 contentEditable=true jQuery17109198838813964318="46"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname0 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck0 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate0 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount0 contentEditable=true jQuery17109198838813964318="55"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice3 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount3 contentEditable=true jQuery17109198838813964318="47"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname1 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck1 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate1 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount1 contentEditable=true jQuery17109198838813964318="56"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice4 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount4 contentEditable=true jQuery17109198838813964318="48"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname2 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck2 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate2 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount2 contentEditable=true jQuery17109198838813964318="57"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice5 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount5 contentEditable=true jQuery17109198838813964318="49"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname3 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck3 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate3 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount3 contentEditable=true jQuery17109198838813964318="58"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice6 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount6 contentEditable=true jQuery17109198838813964318="50"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname4 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck4 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate4 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount4 contentEditable=true jQuery17109198838813964318="59"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice7 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount7 contentEditable=true jQuery17109198838813964318="51"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname5 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck5 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate5 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount5 contentEditable=true jQuery17109198838813964318="60"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD>
                    <SPAN class="table1-invoice left-align" id=invoice8 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount1 right-align" id=invamount8 contentEditable=true jQuery17109198838813964318="52"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-bank left-align" id=bankname6 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-check left-align" id=bankcheck6 contentEditable=true></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-date center-align" id=bankdate6 contentEditable=true name="date"></SPAN>
                  </TD>
                  <TD>
                    <SPAN class="table1-amount2 right-align" id=bankamount6 contentEditable=true jQuery17109198838813964318="61"></SPAN>
                  </TD>
                </TR>
                <TR>
                  <TD class=td-title>TOTAL</TD>
                  <TD>
                    <SPAN class=right-align id=table1-amount1-total contentEditable=true></SPAN>
                  </TD>
                  <TD colSpan=3></TD>
                  <TD>
                    <SPAN class=right-align id=table1-amount2-total contentEditable=true></SPAN>
                  </TD>
                </TR>
              </TBODY>
            </TABLE>
          </DIV>
        </DIV>
      </DIV>
      <BR>
      <LABEL>THIS CANCELS OUR P.R.#</LABEL>
      <INPUT name=CancelPrNo id=CancelPrNo type=text data-val="true" data-val-length-max="50" data-val-length="You&amp;#39;ve reached the maximum length allowed.">
      <INPUT class="right button-style" id=add-receipt type=button value=Add jQuery17109198838813964318="43"> </DIV>
  </FORM>
</DIV>

Bảng điều khiển Chrome:

nhập mô tả hình ảnh ở đây

Kiểm tra phần tử của danh sách tự động hoàn thành:

<UL class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all" role=listbox aria-activedescendant=ui-active-menuitem style="WIDTH: 400px; LEFT: 559px; Z-INDEX: 1; DISPLAY: block; TOP: 287px" jQuery17100985129077826366="42">
<LI class=ui-menu-item role=menuitem jQuery17100985129077826366="62" sizcache02782874225672333="1" sizset="0">
<A tabIndex=-1 class=ui-corner-all jQuery17100985129077826366="63">
*TEXT RESULT OF THE AUTOCOMPLETE LIST*
</A>
</LI></UL>

Xin chào, tôi hy vọng đó không phải là một đề xuất ngớ ngẩn, nhưng bạn có thể tìm thấy chỉ mục của tùy chọn mà bạn đang tìm kiếm hay không (tự mình đếm sau khi nhập inputString, vì trường này dường như không có chỉ mục) các .selectedIndex = xtrên supName yếu tố?
St3ve

Xin chào, tôi đã kiểm tra điều này, tuy nhiên, lĩnh vực mà tôi đang cố kiểm soát không phải là danh sách thả xuống. Thay vào đó, nó là một lĩnh vực hiển thị các mục bằng một trò đùa.
Sevpoint

Bạn lấy nguồn HTML đó từ đâu? Nếu là từ "nguồn xem" thì nó có thể không phản ánh HTML cuối cùng - bạn cần sử dụng "phần tử kiểm tra" từ Công cụ dành cho nhà phát triển
Tim Williams

Xin chào @TimWilliams, tôi đã nhận được nguồn HTML từ phần tử kiểm tra. Đầu tiên, tôi kích hoạt trường (gõ vài chữ cái) và đợi danh sách tự động hoàn thành xuất hiện. Sau khi xuất hiện, tôi đã kiểm tra phần tử bởi thanh tra nhà phát triển. Và tôi đã nhận được HTML ở trên.
Sevpoint

Bạn có querySelectorAlltrả lại các mặt hàng li dự kiến?
Tim Williams

Câu trả lời:


4

Câu hỏi hay!

Internet Explorer có thể rất khó để tự động hóa bằng các phương thức tích hợp khi làm việc với các điều khiển tùy chỉnh jQuery. Rất may, có một cách để đưa JavaScript vào trình duyệt để sử dụng các phương thức hiện có của các điều khiển này, hoặc, chính jQuery (khi được tải trên trang) để làm cho cuộc sống dễ dàng hơn một chút.

Những gì tôi đã làm dưới đây được sử dụng trang này để kiểm tra, có kiểm soát tự động hoàn thành trên đó.

Bạn có thể cần phải thực hiện các thay đổi đối với các bộ chọn CSS để trỏ đến các thành phần chính xác trên trang của mình, nhưng các phương thức được sử dụng dưới đây sẽ hoạt động để kiểm soát phần tử bạn muốn theo chương trình.

Option Explicit

#If Win64 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

Sub AutoCompleteExamples()
    Dim ie As Object: Set ie = CreateObject("InternetExplorer.Application")
    ie.Visible = True
    LoadPage ie, "https://jqueryui.com/resources/demos/autocomplete/default.html"

    'Trigger autocomplete with jQuery. This select the first ui-autocomplete-input, you may need -
    'to adjust this, if this isn't the first autocomplete control on page
    ie.document.parentWindow.execScript "$('.ui-autocomplete-input').first().val('A').autocomplete('search')"

    'Select first item with jQuery, the UL updates in response to the click event
    'Result should be it selected 'ActionScript'
    ie.document.parentWindow.execScript "$('ul.ui-menu').children().first().click()"

    'Alternatively if you want to pick an item from the drop down with a specific value
    'You can look inside the ul-menu-items that are created and use Contains. The contains method is case sensitive
    ie.document.parentWindow.execScript "$('ul.ui-menu').children().find('.ui-menu-item-wrapper:contains(""ActionScript"")').click()"
End Sub

Public Sub LoadPage(ByRef ie As Object, ByVal URL As String)
    With ie
        .Navigate URL
        Sleep 500 'Add a built in delay
        Do While .busy And .readystate <> 4: DoEvents: Loop
        Sleep 500 'Add a built in delay
    End With
End Sub

1
Cảm ơn bạn cho câu trả lời này. Một cách tôi không biết cho đến bây giờ. Thật tuyệt vời :-)
Zwenn

@Zwenn cảm ơn! :)
Ryan Wildry

Cảm ơn bạn @RyanWildry, tôi đã làm cho nó hoạt động trên trang web nội bộ của chúng tôi bằng cách thay thế phần tử : $('input#supName').first().val('A').autocomplete('search'). Điều này kích hoạt tự động hoàn thành không có vấn đề. Tuy nhiên, khi nhấp vào, tôi không thể làm cho nó hoạt động : ie.document.parentWindow.execScript "$('ul.ui-menu-item').children().find('.ui-menu-item-wrapper:contains(""ActionScript"")').click()". Câu hỏi: Tại sao nó hoạt động khi tôi thay đổi thành phần này thành input#supNamekhông .supName? Cảm ơn rất nhiều! 😊
Sevpoint

1
Nó đang làm việc bây giờ! : D Đã thêm dòng này trước khi nhấp vào : $('ul.ui-menu').children().first().find('a').first().trigger('mouseover'). Mặc dù tôi có một câu hỏi về cách tôi có thể sử dụng điều này ie.document.parentWindow.execScript "$('ul.ui-menu').children().find('.ui-menu-item-wrapper:contains(""ActionScript"")').click()"vì tôi sẽ cần tìm kiếm danh sách chứa chuỗi. aTuy nhiên, tôi đã cố gắng sao chép định dạng , không hoạt động như mong đợi. Ngoài ra, vì tôi muốn đặt một số xác nhận nếu không có danh sách tự động hoàn thành hoặc không khớp.
Sevpoint

1
Tôi rất vui, yeah, nó có thể khó khăn tùy thuộc vào thiết lập trang. Tiêm thuốc jQuerysẽ là những gì tôi làm ở đây, đó là một cách tiếp cận tốt. Rất vui được giúp đỡ :)
Ryan Wildry

4

Tôi hy vọng trang ví dụ này thực sự khá giống với trang của bạn. Tôi đã sử dụng nó để cho thấy làm thế nào bạn có thể đối phó với những điều đó. Những gì bạn cần phải có trong đầu là suy nghĩ về tính năng động của một trang. Tôi đã nhận xét về macro một cách chi tiết. Xin vui lòng đọc mọi thứ cẩn thận để hiểu nó. Giải pháp bao gồm 3 phần sau. Sao chép tất cả vào một mô-đun.

Thứ nhất: Một phương pháp để thực hiện nghỉ ít hơn một giây. Chúng ta có thể làm điều đó với chức năng api của Windows:

'With the following Windows api function we can do breaks less than 1 second
'It works with Excel 32 bit an Excel 64 bit
#If Win64 Then
  'For 64 Bit Systems
  Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
  'For 32 Bit Systems
  Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Thứ hai: Phần chính nhấp qua menu bật lên

Sub JQueryAutocomplete()

  Dim url As String
  Dim browser As Object
  Dim nodeInput As Object
  Dim nodeUi As Object
  Dim nodeLi As Object
  Dim countOfLi As Long
  Dim controlValue As Long
  Dim searchString As String
  Dim countOfLiDone As Boolean
  Dim result As String

  'Initializing variables and load page
  '-------------------------------------------------------------------------------------------
  'Part of the string to autocomplete
  searchString = "h"

  'The controlValue shows the number of next li-tag in pop-up menu to pass through
  controlValue = 1

  'We use the iFrame document from the JQuery sample page directly
  'So we have less code overhead to reach the point we need in the HTML code
  url = "https://jqueryui.com/resources/demos/autocomplete/default.html"

  'Initialize Internet Explorer, set visibility,
  'call URL and wait until page is fully loaded
  Set browser = CreateObject("internetexplorer.application")
  browser.Visible = True 'You can set this to False because this macro don't use sendkeys()
  browser.navigate url
  Do Until browser.ReadyState = 4: DoEvents: Loop
  '-------------------------------------------------------------------------------------------

  'Try to get textbox for input
  '-------------------------------------------------------------------------------------------
  On Error Resume Next
  Set nodeInput = browser.document.getElementByID("tags")
  On Error GoTo 0

  'Check if nodeInput could be created
  If Not nodeInput Is Nothing Then
    'Loop over all auto completed strings in the pop-up menu
    'Yes, we start the loop before we know anything obout the pop-up menu
    '-----------------------------------------------------------------------------------------
    Do
      'Insert part of search string
      '---------------------------------------------------------------------------------------
      'Everytime we want to place text into the textbox, we must prepare it to react with the
      'pop-up menu. We do this by triggering the input HTML event of the textbox
      '(You do this with sendkeys in your macro. But sendkeys should be avoided if possible)
      Call TriggerEvent(browser.document, nodeInput, "input")

      'Insert text
      nodeInput.Value = searchString

      'Wait briefly to open the pop-up menu
      'It may be that with your computer speed and your internet speed (ping) it must be a
      'larger value or it may be a smaller value. 1 counts 1 millisecond. So 100 is a tenth
      'of a second and 1000 is one second
      Sleep (500)
      '---------------------------------------------------------------------------------------

      'Count generated li tags if not done in the past
      '---------------------------------------------------------------------------------------
      If countOfLiDone = False Then
        'Try to get pop-up menu
        'It may be that there is no pop-up menu if the string does not provide auto-completion
        'It is important to know this to be able to exit the loop
        On Error Resume Next
        Set nodeUi = browser.document.getElementByID("ui-id-1")
        On Error GoTo 0

        'Check if nodeUi could be created
        'If nodeUi couldn't be created, no pop-up menu. The variable countOfLi is 0 by default
        'and less than controlValue, which is 1 by initializing. The termination condition of
        'the loop is thus reached immediately
        If Not nodeUi Is Nothing Then
          'Count li tags in the pop-up
          countOfLi = nodeUi.getElementsByTagName("li").Length
          countOfLiDone = True
        End If
      End If
      '---------------------------------------------------------------------------------------

      'Go on if there is a pop-up menu
      '---------------------------------------------------------------------------------------
      If countOfLi > 0 Then
        'To get the text from the next li tag into the input textbox we must click the li tag
        nodeUi.getElementsByTagName("li")(controlValue - 1).Click

        'Here you can do what you want with the new situation of the page
        '-------------------------------------------------------------------------------------
        'If there come up new contents you need at first a short break after the click for the
        'same reason we wait earlier in the macro, after inserting our searchString
        Sleep (500)

        'I don't know what you want to da but on the example page nothing hapen than the
        'clicked text is now in the input textbox. So we gather all clicks in a string
        'to show something at the end of macro runtime
        result = result & nodeInput.Value & Chr(13)
        '---------------------------------------------------------------------------------------
      End If
      '---------------------------------------------------------------------------------------

      'Prepare next loop pass
      '---------------------------------------------------------------------------------------
      controlValue = controlValue + 1
      '---------------------------------------------------------------------------------------
    Loop Until controlValue > countOfLi
    '-----------------------------------------------------------------------------------------
  Else
    'nodeInput couldn't be created
    result = "Textbox to insert search string not found"
  End If
  '-------------------------------------------------------------------------------------------

  'Clean up
  '-------------------------------------------------------------------------------------------
  browser.Quit
  Set browser = Nothing
  Set nodeInput = Nothing
  Set nodeUi = Nothing
  Set nodeLi = Nothing
  '-------------------------------------------------------------------------------------------

  'Show the result of this demo
  '-------------------------------------------------------------------------------------------
  MsgBox result
  '-------------------------------------------------------------------------------------------
End Sub

Thứ ba: Chức năng kích hoạt sự kiện HTML. Vì vậy, bạn không cần sendkey ()

Private Sub TriggerEvent(htmlDocument As Object, htmlElementWithEvent As Object, eventType As String)

  Dim theEvent As Object

  htmlElementWithEvent.Focus
  Set theEvent = htmlDocument.createEvent("HTMLEvents")
  theEvent.initEvent eventType, True, False
  htmlElementWithEvent.dispatchEvent theEvent
End Sub

Cảm ơn bạn @Zwenn, đây chính xác là những gì tôi cần. Tuy nhiên, khi tôi cố gắng thay thế URL bằng trang web nội bộ của chúng tôi, nó sẽ nhắc tôi một lỗi trong Chức năng kích hoạt. Cụ thể Set theEvent = htmlDocument.createEvent("HTMLEvents"). Có một cái gì đó mà tôi cần phải xem xét để tham khảo?
Sevpoint

Chỉ cần thêm, nó nói 'Đối tượng không hỗ trợ thuộc tính hoặc phương thức này'.
Sevpoint

Ngoài ra để thêm: Khi tôi thay đổi URL sang trang web nội bộ của chúng tôi, tôi đã kiểm tra các giá trị cho TriggeEvent, giá trị cho htmlDocument và htmlEuityWithEvent là [object]. So sánh nó với jqueryui.com/autocomplete các giá trị là "[object HTMLDocument].
Sevpoint

@Sevpoint Nó không thể hoạt động bằng cách chỉ thay đổi url. Tôi chỉ cho bạn cơ chế làm thế nào để giải quyết vấn đề này. Bạn phải điều chỉnh trang này với trang nội bộ mà tôi không biết. Tôi có thể thử nó với mã HTML mà bạn đã đăng. Nhưng tôi sẽ không thể làm điều đó cho đến ngày mai.
Zwenn

Tôi quên đề cập đến mà tôi đã thay đổi Set nodeInput = browser.document.getElementByID("tags")đến Set nodeInput = browser.document.getElementByID("supName")Set nodeUi = browser.document.getElementByID("ui-id-1")đến Set nodeUi = browser.document.getElementByID("ui-menu-item"). Chắc chắn, tôi thực sự đánh giá cao sự giúp đỡ của bạn. Trong trường hợp, bất cứ điều gì cần thiết từ phía tôi, xin vui lòng cho tôi biết. Vì tôi thực sự không thể tìm thấy bất kỳ giải pháp nào trên các nguồn khác.
Sevpoint

0

Xem cách mục LI chứa thẻ. Bạn nên thử nhấp vào đứa trẻ đầu tiên.

Thay vì:

NodeList.Item(x).Focus
NodeList(x).Click  

Thử:

NodeList.Item(x).Focus
NodeList(x).FirstChild.Click  

https://www.w3schools.com/jsref/prop_node_firstchild.asp


Xin chào Peyter, tôi đã thử đề xuất của bạn, thật không may, nó không hoạt động với tôi.
Sevpoint

Vâng, chạy vào những thứ như thế này là điều đã thúc đẩy tôi sử dụng Selenium, Puppeteer hoặc PhantomJS.
Peyter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.