Excel VBA: 如何从 Internet Explorer 复制字段值
Excel VBA: How to copy value of a field from Internet Explorer
我正在尝试访问 Internet Explorer 上的表单,然后复制某些字段的值(我知道名称和 ID)并将这些值复制到 Excel sheet .那是我正在尝试做的简化版本。所以现在我可以打开我的网页,然后打开其中包含的子表单。但是当我开始复制我感兴趣的字段的值时。我无法设置变量,因此我可以将其复制回 Excel.
下面是我的代码。我的评论之间的问题。
Private Sub Open_multiple_sub_pages_from_main_page()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = True
' Send the form data To URL As POST binary request
IE.navigate "http://webpage.com/"
' Wait while IE loading...
While IE.Busy
DoEvents
Wend
Set objCollection = IE.Document.getElementsByTagName("input")
i = 0
While i < objCollection.Length
If objCollection(i).Name = "txtUserName" Then
' Set text for search
objCollection(i).Value = "1234"
End If
If objCollection(i).Name = "txtPwd" Then
' Set text for search
objCollection(i).Value = "password"
End If
If objCollection(i).Type = "submit" And objCollection(i).Name = "btnSubmit" Then ' submit button if found and set
Set objElement = objCollection(i)
End If
i = i + 1
Wend
objElement.Click ' click button to load page
' Wait while IE re-loading...
While IE.Busy
DoEvents
Wend
' Show IE
IE.Visible = True
Set Doc = IE.Document
Dim links, link, value_to_copy
Dim j As Integer 'variable to count items
j = 0
Set links = IE.Document.getelementbyId("dgTime").getElementsByTagName("a")
n = links.Length
While j <= n 'loop to go thru all "a" item so it loads next page
links(j).Click
While IE.Busy
DoEvents
Wend
'------------THE PROBLEM IS HERE---------------------------
Set value_to_copy = IE.Document.getelementbyId("mainTable").getElementsByTagName("txtProject").innerText
'----------VALUE_TO_COPY WILL REMAIN AT "" VALUE
IE.Document.getelementbyId("DetailToolbar1_lnkBtnSave").Click 'save
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now) 'wait
Loop
IE.Document.getelementbyId("DetailToolbar1_lnkBtnCancel").Click 'close
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now) 'wait
Loop
Set links = IE.Document.getelementbyId("dgTime").getElementsByTagName("a")
j = j + 2
Wend
End Sub
下面是我试图从中检索 "txtProject" 值的页面的 html 代码。在该特定情况下,该值为“0000001”。这就是我需要复制的价值。
<table width="100%" class="Form" id="mainTable" border="0" cellspacing="0" cellpadding="0">
<tbody><tr id="TRCustomer">
<td class="titleLabel"><span id="lblCustomer">
<u>C</u>lient : </span></td>
<td><input name="txtCustomer" id="txtCustomer" accesskey="C"
language="javascript" onchange="__doPostBack('txtCustomer','')"
type="text"></td>
<td><a class="Button" id="lnkBtnCustomer" href="javascript:__doPostBack('lnkBtnCustomer','')">
<img id="imgCustomer" alt="" src="images/toolbar/b_preview.gif"
border="0"></a></td>
<td class="tdDescriptionLabel"><span class="DescriptionLabel"
id="lblCustomerDescription"> </span></td>
</tr>
<tr id="TRProject">
<td width="110" class="titleLabel">
<span id="lblProject">Pro<u>j</u>et : </span></td>
<td width="152"><input name="txtProject" tabindex="2" id="txtProject"
accesskey="J" language="javascript"
onkeypress="return LookupButton(event,'lnkBtnProject')"
onchange="__doPostBack('txtProject','')" type="text"
value="0000001"></td>
<td width="20"><a class="Button" id="lnkBtnProject"
href="javascript:__doPostBack('lnkBtnProject','')">
<img id="imgProject" alt="" src="images/toolbar/b_preview.gif"
border="0"></a></td><td class="tdDescriptionLabel">
<span class="DescriptionLabel"
任何帮助将不胜感激。
提前Tx.
Set
关键字用于对象,这里有一个变量。从赋值语句中删除 Set
。 value_to_copy = IE.Document.getelementbyId("mainTable").getElementsByTagName("txtProject").innerText
innerText
属性returns一String
类型。这意味着,您不需要关键字 Set
而是用于将变量设置为指向特定对象的指针。字符串是原生类型,所以不要使用关键字 Set。试试这个:
'------------THE PROBLEM IS HERE---------------------------
value_to_copy = IE.Document.getelementbyId("mainTable").getElementsByTagName("txtProject").innerText
'----------VALUE_TO_COPY WILL REMAIN AT "" VALUE
在文档中 id
应该是唯一的,因此您可以直接使用它:
value_to_copy = IE.Document.getelementbyId("txtProject").Value
getElementsByTagName()
不用于通过 id 定位元素,并且在任何情况下 return 是一个 匹配集合 ,而不是单个元素,所以你不能像那样分配它的 return 值。这就是您通常使用它的方式:
value_to_copy = IE.Document.getelementsbyTagName("input")(0).Value
这是一个微妙的问题。简而言之,您不应该使用 innertext
属性。相反,您想检索 txtProject element
.
的 childNodes
属性 返回的 "value" node
的值
您检索的数据实际上不是 "innertext."Innertext 是出现在开始和结束标记之间的文本。来自 MSDN https://msdn.microsoft.com/en-us/library/ie/ms533899(v=vs.85).aspx:
The innerText property is valid for block elements only. By definition, elements that do not have both an opening and closing tag cannot have an innerText property.
例如,在以下代码段中:
<h1>Header Text</h1>
<h1>
标签的内文是 "Header text"
在您的代码段中,标签实际上没有任何内部文本。您有一个带有属性的 td 元素,但 <td...>
和 </td>
:
之间没有任何内容
<td width="152"><input name="txtProject" tabindex="2" id="txtProject"
accesskey="J" language="javascript"
onkeypress="return LookupButton(event,'lnkBtnProject')"
onchange="__doPostBack('txtProject','')" type="text"
value="0000001"></td>'
这就是 innertext 属性 失败的原因。您的代码段 getElementsByTagName("txtProject")
returns 一个 Element
对象。元素是 nodes
的集合。您的元素具有名为 name
、tabindex
、id
、accesskey
、language
、onkeypress
、onchange
、[=33 的节点=] 和 value
。这些节点中的每一个都有一个与之关联的值。您需要访问 value
节点并查询其值。
我怀疑以下方法或类似方法会起作用。
set txtProject = IE.Document.getelementbyID("mainTable").getElementsByTagName("txtProject")
' returns a `<td..></td>` element
value_to_copy = txtProject.childNodes("value")
'Should return the default property of the node "value".
'The default property should be the string "00000001".
'But I'm not sure so you might want to do more
'research on `childNodes` and `nodes`
或者,但不太直观:
value_to_copy = IE.Document.getelementbyID("mainTable") _
.getElementsByTagName("txtProject") _
.childNodes("value")
我从 https://msdn.microsoft.com/en-us/library/ms757053(v=vs.85).aspx 上的以下代码片段改编而来。所以如果我上面的建议不起作用,也许这会有所帮助。
The following script example uses the childNodes property (collection) to return an IXMLDOMNodeList, and then iterates through the collection, displaying the value of each item's xml property.
root = xmlDoc.documentElement;
oNodeList = root.childNodes;
for (var i=0; i<oNodeList.length; i++) {
Item = oNodeList.item(i);
WScript.Echo(Item.xml);
}
我正在尝试访问 Internet Explorer 上的表单,然后复制某些字段的值(我知道名称和 ID)并将这些值复制到 Excel sheet .那是我正在尝试做的简化版本。所以现在我可以打开我的网页,然后打开其中包含的子表单。但是当我开始复制我感兴趣的字段的值时。我无法设置变量,因此我可以将其复制回 Excel.
下面是我的代码。我的评论之间的问题。
Private Sub Open_multiple_sub_pages_from_main_page()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = True
' Send the form data To URL As POST binary request
IE.navigate "http://webpage.com/"
' Wait while IE loading...
While IE.Busy
DoEvents
Wend
Set objCollection = IE.Document.getElementsByTagName("input")
i = 0
While i < objCollection.Length
If objCollection(i).Name = "txtUserName" Then
' Set text for search
objCollection(i).Value = "1234"
End If
If objCollection(i).Name = "txtPwd" Then
' Set text for search
objCollection(i).Value = "password"
End If
If objCollection(i).Type = "submit" And objCollection(i).Name = "btnSubmit" Then ' submit button if found and set
Set objElement = objCollection(i)
End If
i = i + 1
Wend
objElement.Click ' click button to load page
' Wait while IE re-loading...
While IE.Busy
DoEvents
Wend
' Show IE
IE.Visible = True
Set Doc = IE.Document
Dim links, link, value_to_copy
Dim j As Integer 'variable to count items
j = 0
Set links = IE.Document.getelementbyId("dgTime").getElementsByTagName("a")
n = links.Length
While j <= n 'loop to go thru all "a" item so it loads next page
links(j).Click
While IE.Busy
DoEvents
Wend
'------------THE PROBLEM IS HERE---------------------------
Set value_to_copy = IE.Document.getelementbyId("mainTable").getElementsByTagName("txtProject").innerText
'----------VALUE_TO_COPY WILL REMAIN AT "" VALUE
IE.Document.getelementbyId("DetailToolbar1_lnkBtnSave").Click 'save
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now) 'wait
Loop
IE.Document.getelementbyId("DetailToolbar1_lnkBtnCancel").Click 'close
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now) 'wait
Loop
Set links = IE.Document.getelementbyId("dgTime").getElementsByTagName("a")
j = j + 2
Wend
End Sub
下面是我试图从中检索 "txtProject" 值的页面的 html 代码。在该特定情况下,该值为“0000001”。这就是我需要复制的价值。
<table width="100%" class="Form" id="mainTable" border="0" cellspacing="0" cellpadding="0">
<tbody><tr id="TRCustomer">
<td class="titleLabel"><span id="lblCustomer">
<u>C</u>lient : </span></td>
<td><input name="txtCustomer" id="txtCustomer" accesskey="C"
language="javascript" onchange="__doPostBack('txtCustomer','')"
type="text"></td>
<td><a class="Button" id="lnkBtnCustomer" href="javascript:__doPostBack('lnkBtnCustomer','')">
<img id="imgCustomer" alt="" src="images/toolbar/b_preview.gif"
border="0"></a></td>
<td class="tdDescriptionLabel"><span class="DescriptionLabel"
id="lblCustomerDescription"> </span></td>
</tr>
<tr id="TRProject">
<td width="110" class="titleLabel">
<span id="lblProject">Pro<u>j</u>et : </span></td>
<td width="152"><input name="txtProject" tabindex="2" id="txtProject"
accesskey="J" language="javascript"
onkeypress="return LookupButton(event,'lnkBtnProject')"
onchange="__doPostBack('txtProject','')" type="text"
value="0000001"></td>
<td width="20"><a class="Button" id="lnkBtnProject"
href="javascript:__doPostBack('lnkBtnProject','')">
<img id="imgProject" alt="" src="images/toolbar/b_preview.gif"
border="0"></a></td><td class="tdDescriptionLabel">
<span class="DescriptionLabel"
任何帮助将不胜感激。
提前Tx.
Set
关键字用于对象,这里有一个变量。从赋值语句中删除 Set
。 value_to_copy = IE.Document.getelementbyId("mainTable").getElementsByTagName("txtProject").innerText
innerText
属性returns一String
类型。这意味着,您不需要关键字 Set
而是用于将变量设置为指向特定对象的指针。字符串是原生类型,所以不要使用关键字 Set。试试这个:
'------------THE PROBLEM IS HERE---------------------------
value_to_copy = IE.Document.getelementbyId("mainTable").getElementsByTagName("txtProject").innerText
'----------VALUE_TO_COPY WILL REMAIN AT "" VALUE
在文档中 id
应该是唯一的,因此您可以直接使用它:
value_to_copy = IE.Document.getelementbyId("txtProject").Value
getElementsByTagName()
不用于通过 id 定位元素,并且在任何情况下 return 是一个 匹配集合 ,而不是单个元素,所以你不能像那样分配它的 return 值。这就是您通常使用它的方式:
value_to_copy = IE.Document.getelementsbyTagName("input")(0).Value
这是一个微妙的问题。简而言之,您不应该使用 innertext
属性。相反,您想检索 txtProject element
.
childNodes
属性 返回的 "value" node
的值
您检索的数据实际上不是 "innertext."Innertext 是出现在开始和结束标记之间的文本。来自 MSDN https://msdn.microsoft.com/en-us/library/ie/ms533899(v=vs.85).aspx:
The innerText property is valid for block elements only. By definition, elements that do not have both an opening and closing tag cannot have an innerText property.
例如,在以下代码段中:
<h1>Header Text</h1>
<h1>
标签的内文是 "Header text"
在您的代码段中,标签实际上没有任何内部文本。您有一个带有属性的 td 元素,但 <td...>
和 </td>
:
<td width="152"><input name="txtProject" tabindex="2" id="txtProject"
accesskey="J" language="javascript"
onkeypress="return LookupButton(event,'lnkBtnProject')"
onchange="__doPostBack('txtProject','')" type="text"
value="0000001"></td>'
这就是 innertext 属性 失败的原因。您的代码段 getElementsByTagName("txtProject")
returns 一个 Element
对象。元素是 nodes
的集合。您的元素具有名为 name
、tabindex
、id
、accesskey
、language
、onkeypress
、onchange
、[=33 的节点=] 和 value
。这些节点中的每一个都有一个与之关联的值。您需要访问 value
节点并查询其值。
我怀疑以下方法或类似方法会起作用。
set txtProject = IE.Document.getelementbyID("mainTable").getElementsByTagName("txtProject")
' returns a `<td..></td>` element
value_to_copy = txtProject.childNodes("value")
'Should return the default property of the node "value".
'The default property should be the string "00000001".
'But I'm not sure so you might want to do more
'research on `childNodes` and `nodes`
或者,但不太直观:
value_to_copy = IE.Document.getelementbyID("mainTable") _
.getElementsByTagName("txtProject") _
.childNodes("value")
我从 https://msdn.microsoft.com/en-us/library/ms757053(v=vs.85).aspx 上的以下代码片段改编而来。所以如果我上面的建议不起作用,也许这会有所帮助。
The following script example uses the childNodes property (collection) to return an IXMLDOMNodeList, and then iterates through the collection, displaying the value of each item's xml property.
root = xmlDoc.documentElement;
oNodeList = root.childNodes;
for (var i=0; i<oNodeList.length; i++) {
Item = oNodeList.item(i);
WScript.Echo(Item.xml);
}