【发布时间】:2021-07-13 22:59:03
【问题描述】:
我从一位称职的用户那里得到了这个代码,不确定他是否想被命名。该代码在 HTML 内容中搜索某些标签的 innerText 并将它们传输到 Excel 表格中,在标题下很好地排序,结构为枢轴。
Public Sub GetDataFromURL()
Const URL = "URL"
Dim html As MSHTML.HTMLDocument, xhr As Object
Set html = New MSHTML.HTMLDocument
Set xhr = CreateObject("MSXML2.ServerXMLHTTP.6.0")
With xhr
.Open "POST", URL, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.send "...parameters..."
html.body.innerHTML = .responseText
End With
Dim table As MSHTML.HTMLTable, r As Long, c As Long, headers(), row As MSHTML.HTMLTableRow
Dim results() As Variant, html2 As MSHTML.HTMLDocument
headers = Array("HDR01", "HDR02", "HDR03", "HDR04")
ReDim results(1 To 100, 1 To UBound(headers) + 1)
Set table = html.querySelector("table")
Set html2 = New MSHTML.HTMLDocument
Dim lastRow As Boolean
For Each row In table.Rows
lastRow = False
Dim header As String
html2.body.innerHTML = row.innerHTML
header = Trim$(row.Children(0).innerText)
If header = "HDR01" Then
r = r + 1
Dim dict As Scripting.Dictionary: Set dict = GetBlankDictionary(headers)
On Error Resume Next
dict("HDR02") = Replace$(html2.querySelector("a").href, "about:", "https://URL")
On Error GoTo 0
End If
If dict.Exists(header) Then dict(header) = Trim$(row.Children(1).innerText)
If (header = vbNullString And html2.querySelectorAll("a").Length > 0) Then
dict("HDR03") = Replace$(html2.querySelector("a").href, "about:blank", "URL")
lastRow = True
ElseIf header = "HDR04" Then
If row.NextSibling.NodeType = 1 Then lastRow = True
End If
If lastRow Then
populateArrayFromDict dict, results, r
End If
Next
results = Application.Transpose(results)
ReDim Preserve results(1 To UBound(headers) + 1, 1 To r)
results = Application.Transpose(results)
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
With re
.Global = False
.MultiLine = False
.IgnoreCase = True
.Pattern = "\s([0-9.]+)\sm²"
End With
Dim ie As SHDocVw.InternetExplorer
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
For r = LBound(results, 1) To UBound(results, 1)
If results(r, 7) <> vbNullString Then
.Navigate2 results(r, 7), headers:="Referer: " & URL
While .Busy Or .readyState <> READYSTATE_COMPLETE: DoEvents: Wend
'On Error Resume Next
results(r, 8) = re.Execute(.document.querySelector("#anz").innerHTML)(0).Submatches(0)
'On Error GoTo 0
End If
Next
.Quit
End With
With ActiveSheet
.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers
.Cells(2, 1).Resize(UBound(results, 1), UBound(results, 2)) = results
End With
End Sub
它在 Excel 中完美运行,但我需要它用于 Access 表。我的名为 tblTab01 的 Aceess 表包含 headers = array("...") 中的代码中存在的所有字段,并且我禁用了以下行在代码中:
results = Application.Transpose(results)
和
ActiveSheet.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers
相反,我添加了以下几行:
Dim db As DAO.Database
Dim strInsert
Set db = CurrentDb
strInsert = "INSERT INTO tblTab01 VALUES (results);"
db.Execute strInsert
但我只会得到所有可能的错误!
如何修改代码以用于 Access 表?谢了
【问题讨论】:
-
它们有完全不同的对象模型,需要大量重写。此外,除非您确切知道从 html 收到的内容,否则您可以使用正则表达式 cannot parse 它。
-
虽然保存为 CSV 并导入 Access 可能会奏效,但您只会为未来制造巨大的混乱。最好退后一步,从 Access 开始(如果那里是数据所在的位置)并将其拆分为小步骤。首先获取网页,然后解析出您需要的数据,最后将其添加到 Access 表中。如果遇到问题,请发布您拥有的代码和数据,预期结果,并正确解释问题。
-
根据结构,Access 可以导入/链接到 HTML 文档。如果您使用 VALUES 子句,则需要指定要插入的字段。但是,AFAIK 不能在 INSERT 操作中使用这样的数组对象。
-
读取HTML和提取数据应该与Excel VBA中的基本相同(RegEx在Access VBA中可用,假设RegEx合适)。 VBA 将数据写入表可以通过以下几种方式完成:1)打开记录集并将记录添加到记录集对象或 2)插入操作 SQL。循环遍历数组对象以将其元素写入 Access 表。
-
如果您从 Excel 写入 csv,您可以从 Access(甚至只是从 Excel)导入。而不是担心任何重写。很确定这是在 Access 中单击几下按钮。
标签: html sql excel vba ms-access