Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 项目搜索宏_Vba_Excel_Internet Explorer - Fatal编程技术网

Vba 项目搜索宏

Vba 项目搜索宏,vba,excel,internet-explorer,Vba,Excel,Internet Explorer,我有一个Excel宏,可以从网站上搜索商品编号,并从网页上删除一些特定信息,如可用性、价格、页面URL。但在抓取了一些页面后,它给了我以下错误: 运行时错误91,未设置对象变量或带块变量 我不知道为什么这种事一次又一次地发生。这个宏的工作速度也很慢。是否可以与所有Internet Explorer(IE9、IE10、IE11等)合作?有人能修这个吗 我有Office2007和IE9 Sub xtremeExcel() Dim HTMLDoc As HTMLDocument Dim oBrowse

我有一个Excel宏,可以从网站上搜索商品编号,并从网页上删除一些特定信息,如可用性、价格、页面URL。但在抓取了一些页面后,它给了我以下错误:

运行时错误91,未设置对象变量或带块变量

我不知道为什么这种事一次又一次地发生。这个宏的工作速度也很慢。是否可以与所有Internet Explorer(IE9、IE10、IE11等)合作?有人能修这个吗

我有Office2007和IE9

Sub xtremeExcel()
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Dim oHTML_Element As IHTMLElement
Set oBrowser = New InternetExplorer
oBrowser.Visible = True
oBrowser.navigate "http://cpc.farnell.com/"
Do
Loop Until oBrowser.readyState = READYSTATE_COMPLETE

For i = 3 To Sheet1.Range("A:A").Find(what:="*", searchdirection:=xlPrevious).Row
    Set HTMLDoc = oBrowser.document
    xc = 0
    Do While (HTMLDoc.getElementById("searchTerms") Is Nothing)
        Application.Wait (Now() + TimeValue("00:00:01"))
        xc = xc + 1
        If xc > 15 Then
            Exit Do
        End If
    Loop
    Set HTMLDoc = oBrowser.document
    HTMLDoc.getElementById("searchTerms").Value = Cells(i, 1).Value
    HTMLDoc.getElementById("go").Click

    xc = 0
    flag = 0
    Do While (HTMLDoc.getElementsByClassName("prodDetailAvailability")(0) Is Nothing)
        Application.Wait (Now() + TimeValue("00:00:01"))
        xc = xc + 1
        If xc > 15 Then
            Exit Do
        End If
    Loop

    If HTMLDoc.getElementsByClassName("prodDetailAvailability")(0) Is Nothing Then
         xc = 0
        Do While (HTMLDoc.getElementById("totalNoResultsSlotAtTop") Is Nothing)
            Application.Wait (Now() + TimeValue("00:00:01"))
            xc = xc + 1
            If xc > 10 Then
                Exit Do
            End If
        Loop
        flag = 2
    End If


    If flag <> 2 Then
        Sheet1.Cells(i, 2).Value = Replace(HTMLDoc.getElementsByClassName("prodDetailAvailability")(0).innerText, "Availability: ", "")
        unitprice = HTMLDoc.getElementsByClassName("unitprice")(0).innerText
        If InStr(1, unitprice, "(") > 0 Then
            Sheet1.Cells(i, 3).Value = Replace(Left(unitprice, InStr(1, unitprice, "(") - 1), "Unit Price: ", "")
            Sheet1.Cells(i, 4).Value = Mid(unitprice, InStr(1, unitprice, "(") + 1, InStr(1, unitprice, ")") - 1 - (InStr(1, unitprice, "(")))
        Else
            Sheet1.Cells(i, 3).Value = unitprice
        End If

        Sheet1.Cells(i, 5).Value = oBrowser.LocationURL
    Else
        Sheet1.Cells(i, 2).Value = "Not Found"
    End If
 oBrowser.GoBack
Next
End Sub
Sub-xtremeExcel()
将HTMLDoc设置为HTMLDocument
作为InternetExplorer的Dim oBrowser
尺寸oHTML\U元件作为IHTML元件
Set oBrowser=新的InternetExplorer
oBrowser.Visible=True
oBrowser.navigate“http://cpc.farnell.com/"
做
循环直到oBrowser.readyState=readyState\u完成
对于i=3到Sheet1.Range(“A:A”).Find(what:=“*”,searchdirection:=xlPrevious)。行
设置HTMLDoc=oBrowser.document
xc=0
Dowhile(HTMLDoc.getElementById(“searchTerms”)什么都不是)
Application.Wait(现在()+TimeValue(“00:00:01”))
xc=xc+1
如果xc>15,则
退出Do
如果结束
环
设置HTMLDoc=oBrowser.document
HTMLDoc.getElementById(“searchTerms”).Value=单元格(i,1).Value
HTMLDoc.getElementById(“go”)。单击
xc=0
标志=0
Do While(HTMLDoc.getElementsByClassName(“prodDetailAvailability”)(0)为空)
Application.Wait(现在()+TimeValue(“00:00:01”))
xc=xc+1
如果xc>15,则
退出Do
如果结束
环
如果HTMLDoc.getElementsByClassName(“prodDetailAvailability”)(0)为空,则
xc=0
Dowhile(HTMLDoc.getElementById(“totalNoResultsSlotAtTop”)什么都不是)
Application.Wait(现在()+TimeValue(“00:00:01”))
xc=xc+1
如果xc>10,则
退出Do
如果结束
环
标志=2
如果结束
如果是标志2,那么
Sheet1.Cells(i,2).Value=Replace(HTMLDoc.getElementsByClassName(“prodDetailAvailability”)(0).innerText,“Availability:”,“”)
unitprice=HTMLDoc.GetElementsByCassName(“unitprice”)(0)。innerText
如果仪表(1,单价,“(”)大于0,则
表1.单元格(i,3).值=替换(左)(单价,仪表(1,单价,“(”)-1),“单价:”,“)
表1.单元格(i,4).值=中间(单价,单位价格,“(”)+1,单位价格,“)”)-1-(单价,单位价格,“(”))
其他的
表1.单元格(i,3).值=单价
如果结束
Sheet1.单元格(i,5).Value=oBrowser.LocationURL
其他的
表1.单元格(i,2).Value=“未找到”
如果结束
长尾蛇
下一个
端接头
tl;dr; 您可以按如下所示的方式循环;等待设置项目

函数
WaitUntilReady
循环直到
.document.getElementById(“sProdList”)
可以设置。这是保存要返回的信息的表。您可能希望添加一些错误处理和超时,以便循环不会冒无限循环的风险

我在
searchTerms
数组中列出了2个搜索词。您可以扩展它。它将搜索词连接到URL中,因此直接搜索,而不是总是点击登陆和重新定向

注意:

如果计划进行大量搜索或循环搜索结果页面,我将研究是否有可用的API。下面只做每个页面的第一页,但已经给了您大量代码。如果尝试XHR,您的IP将被阻止,因此下面的方法是一种折衷。我很愿意放弃IE的任何解决方案


页面结果示例: 示例代码输出:


VBA:
选项显式
公共子GetInfo()
Dim IE作为InternetExplorer,一个作为HTMLTable,一个作为工作表的wsTarget,currSearch作为Long,searchTerms
Application.ScreenUpdating=False
Set IE=新的InternetExplorer
Set-wsTarget=ThisWorkbook.Worksheets(“Sheet2”)
wsTarget.UsedRange.ClearContents
searchTerms=阵列(“CCTV”、“粉丝”)
与IE
.Visible=True
ApplyHeaders wsTarget
对于currSearch=LBound(搜索术语)到UBound(搜索术语)
.导航“http://cpc.farnell.com/search?st=&searchTerms(currSearch)&aka_re=1
设置a=WaitUntilReady(即)
将所有行设置为对象,类名称()
Set allRows=a.GetElementsByCassName(“altRow”)
classNames=数组(“productImage mftrPart”、“sku”、“说明”、“可用性”、“priceFor”、“priceBreak”)
Dim i长,y长,r长,tempString长,j长,k长
r=GetLastRow(wsTarget,1)+1
对于所有行,i=0。长度为-1
对于j=LBound(类名)到UBound(类名)
对于k=0的所有行(i).getElementsByClassName(classNames(j)).Length-1
tempString=tempString&vbNewLine&TidyString(allRows(i).getElementsByClassName(classNames(j))(k).innerText)
下一个k
有目标
.Cells(r,j+1).Value=tempString
以
tempString=vbNullString
下一个j
r=r+1
接下来我
r=r+1
下一步搜索
退出
以
整洁的目标
Application.ScreenUpdating=True
端接头
公共函数GetLastRow(ByRef ws作为工作表,可选ByVal columnNumber作为Long=1)的长度为
与ws
GetLastRow=.Cells(.Rows.Count,columnNumber).End(xlUp).Row
以
端函数
公共函数TidyString(ByVal inputString作为字符串)作为字符串
TidyString=Application.WorksheetFunction.Clean(inputString)
TidyString=Trim$(Replace$(Replace$(TidyString,Chr$(10),vbNullString),vbCrLf,vbNullString))
结束函数
Option Explicit

Public Sub GetInfo()
    Dim IE As InternetExplorer, a As HTMLTable, wsTarget As Worksheet, currSearch As Long, searchTerms
    Application.ScreenUpdating = False
    
    Set IE = New InternetExplorer
    Set wsTarget = ThisWorkbook.Worksheets("Sheet2")
    wsTarget.UsedRange.ClearContents
    searchTerms = Array("CCTV", "FANS")
    
    With IE
        .Visible = True
        ApplyHeaders wsTarget
        For currSearch = LBound(searchTerms) To UBound(searchTerms)
            .navigate "http://cpc.farnell.com/search?st=" & searchTerms(currSearch) & "&aka_re=1"

            Set a = WaitUntilReady(IE)

            Dim allRows As Object,classNames()
            Set allRows = a.getElementsByClassName("altRow")
            classNames = Array("productImage mftrPart", "sku", "description", "availability", "priceFor", "priceBreak")
    
            Dim i As Long, y As Long, r As Long, tempString As String, j As Long, k As Long
            r = GetLastRow(wsTarget, 1) + 1
           
            For i = 0 To allRows.Length - 1
                For j = LBound(classNames) To UBound(classNames)
                    For k = 0 To allRows(i).getElementsByClassName(classNames(j)).Length - 1
                        tempString = tempString & vbNewLine & TidyString(allRows(i).getElementsByClassName(classNames(j))(k).innerText)
                    Next k
                    With wsTarget
                        .Cells(r, j + 1).Value = tempString
                    End With
                    tempString = vbNullString
                Next j
                r = r + 1
            Next i
            r = r + 1
        Next currSearch
        .Quit
    End With
    TidySheet wsTarget
    Application.ScreenUpdating = True
End Sub

Public Function GetLastRow(ByRef ws As Worksheet, Optional ByVal columnNumber As Long = 1) As Long
    With ws
        GetLastRow = .Cells(.Rows.Count, columnNumber).End(xlUp).Row
    End With
End Function

Public Function TidyString(ByVal inputString As String) As String
    TidyString = Application.WorksheetFunction.Clean(inputString)
    TidyString = Trim$(Replace$(Replace$(TidyString, Chr$(10), vbNullString), vbCrLf, vbNullString))
End Function
   
Public Sub ApplyHeaders(ByVal wsTarget As Worksheet)
    Dim headers(), i As Long
    headers = Array("Manufacturer Part No", "Order Code", "Manufacturer / Description", "Avail", "Price For", "Price Ex. VAT (Inc. VAT)")
    For i = LBound(headers) To UBound(headers)
        wsTarget.Cells(1, i + 1).Value = headers(i)
    Next i
End Sub

Public Function WaitUntilReady(ByVal IE As InternetExplorer) As HTMLTable
    With IE
        While .Busy Or .readyState < 4: DoEvents: Wend
        Do
            DoEvents
            On Error Resume Next
            Set WaitUntilReady = .document.getElementById("sProdList")
            On Error GoTo 0
        Loop While WaitUntilReady Is Nothing
    End With
End Function

Public Sub TidySheet(ByVal wsTarget As Worksheet)
    With wsTarget
        .Rows("2:" & .Cells.Find(What:="*", After:=.Range("A1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row).RowHeight = 25
        .UsedRange.Columns.AutoFit
    End With
End Sub