访问VBA将值插入到webform中,但没有可预测的元素ID

时间:2015-11-26 01:39:05

标签: vba internet-explorer ms-access access-vba ms-access-2010

我正在开发一个vba脚本,通过IE 11将Access 2010数据库中的信息插入到Web表单中。我有Microsoft Internet Controls,Microsoft HTML Object Library和Microsoft Form Library引用集。

目的是通过网络表格将支付信息从我办公室的数据库插入客户的数据库。我现有的代码遍历两页登录。第一页将我们作为客户系统的正确用户进行身份验证。第二页请求有关帐户持有人的信息。第三页是我遇到问题的地方。每个帐户持有人可能有多个帐户。第三页是动态生成的,我无法弄清楚如何获取正确的元素id并将正确的id与我的数据库中的信息匹配,以便可以插入值。

例如,我的数据库将包含以下有关4个帐户的帐户持有者的示例数据:

Anum        Pay
8677229     $25
10289183    $40
11981680    null
13043481    $2

我希望插入信息的第三页将包含如下所示的输入元素:

<input name="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:0:paymentAmount" class="paymentInput" id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:0:paymentAmount" style="text-align: right;" onkeyup="handlePaymentChange(this,'13043481')" type="text">

<input name="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:1:paymentAmount" class="paymentInput" id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:1:paymentAmount" style="text-align: right;" onkeyup="handlePaymentChange(this,'10289183')" type="text">

<input name="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:2:paymentAmount" class="paymentInput" id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:2:paymentAmount" style="text-align: right;" onkeyup="handlePaymentChange(this,'8677229')" type="text">

<input name="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:paymentAmount" class="paymentInput" id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:paymentAmount" style="text-align: right;" onkeyup="handlePaymentChange(this,'11981680')" type="text">

我的数据库中的帐号(Anum)位于每个输入框的onkeyup事件中。如您所见,它不是可预测的顺序。我想获取该数字并将我的数据库中的Pay值插入相应的input元素。不幸的是,我不知道如何。我研究过.GetElementsByName,htmlelementscollection和其他方法,似乎都不是关键。我也查看了innertext方法,但是我不确定如何在阅读之后调用它。

就我而言,VBA如下所示。 SendKeys§函数是我在网上找到的Sendkeys的替代品,有时我发送一个零长度字符串作为睡眠函数的替代品:

Public Sub Login_Pay2()
'set reference to microsoft internet controls and microsoft html library
'add reference to microsft form library by browsing for FM20.dll in system32
Dim ieApp As InternetExplorer
Dim iePage As HTMLDocument
Dim ieObj As HTMLInputElement
Dim tries As Integer
Dim user As String
Dim pass As String
Dim dnumorig As String
Dim govone As String

user = "myuser"
pass = "mypass"
dnumorig = "mydnum"
govone = "mygov"

Set ieApp = New InternetExplorer
ieApp.Visible = True
ieApp.Navigate "myurl"
'wait for page to load

Do Until ieApp.ReadyState = READYSTATE_COMPLETE
Loop
Set iePage = ieApp.Document

AppActivate ("mywindow")
tries = 0
tryagain:
With ieApp
Set ieObj = iePage.getElementById("username")
If ieObj Is Nothing Then
SendKeys§ "", 750
tries = tries + 1
If tries < 5 Then
GoTo tryagain
Else
Exit Sub
End If
End If
ieObj.Value = user

Set ieObj = iePage.getElementById("password")
ieObj.Value = pass
SendKeys§ "", 40
AppActivate ("mywindow")
SendKeys§ "{TAB}", 40
AppActivate ("mywindow")
SendKeys§ "{RETURN}", 40
End With

Do Until ieApp.ReadyState = READYSTATE_COMPLETE
Loop
Set iePage = ieApp.Document

AppActivate ("mywindow")

tries = 0
tryagain2:
With ieApp
Set ieObj = iePage.getElementById("myaccountpage:manageAccountsBlock:j_id2:searchText")
If ieObj Is Nothing Then
SendKeys§ "", 750
tries = tries + 1
If tries < 5 Then
GoTo tryagain2
Else
Exit Sub
End If
End If
ieObj.Value = dnumorig

Set ieObj = iePage.getElementById("myaccountpage:manageAccountsBlock:j_id2:j_id10")
ieObj.Value = govone
AppActivate ("mywindow")
SendKeys§ "", 40
AppActivate ("mywindow")
SendKeys§ "{RETURN}", 40
End With

'??? at this point I am at page 3 and am stumped.

感谢您的耐心等待,我们将不胜感激。

编辑:

我应该注意到我试图操作的元素位于更大的代码行的末尾 - 例如下面的代码:

</div></td><td class="dataCell clsCenter " id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:j_id63" colspan="1">ACCOUNT TYPE</td><td class="dataCell clsCenter " id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:j_id70" colspan="1"> $5,555.55</td><td class="dataCell clsCenter " id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:j_id74" colspan="1"> $55.55</td><td class="dataCell clsCenter " id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:j_id78" colspan="1"> $555.55</td><td class="dataCell clsCenter " id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:j_id81" colspan="1"> $6,666.66</td><td class="dataCell clsCenter " id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:j_id85" colspan="1" style="min-width:195px;">$<input id="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:paymentAmount" type="text" name="myaccountpage:myAccountsBlock:accountForm:contactDisplayArea2:3:paymentAmount" class="paymentInput" onkeyup="handlePaymentChange(this,'11981680')" style="text-align:right" /></td></tr></tbody></table>

编辑2: 非常感谢。我添加了以下代码,在修改加载时间后,添加了延迟,并且您的代码将一个付款金额注入一个paymentInput元素:

Do Until ieApp.ReadyState = READYSTATE_COMPLETE
Loop
Set iePage = ieApp.Document
SendKeys§ "", 2000
AppActivate ("Case Representative - Internet Explorer")

Dim paymentInputElements As IHTMLElementCollection
Set paymentInputElements = iePage.getElementsByClassName("paymentInput")
Dim Anum As String
Anum = "10289183"
Dim pay As String
pay = "40.00"


' Assuming that the account number is in a string variable called Anum
Dim paymentInput As IHTMLElement
' Use this to check if we found the account - initializes to False
Dim bFoundAnum As Boolean
For Each paymentInput In paymentInputElements
    If (InStr(paymentInput.getAttribute("onkeyup"), Anum) > 0) Then
        ' do stuff
        bFoundAnum = True
        paymentInput.Value = pay
        Exit For
    End If
Next paymentInput

' Check we found something
If Not bFoundAnum Then
    MsgBox ("no matching anum")
End If

如果我的声誉允许,我会尝试将您的答案标记为已接受。如果您愿意继续帮助我,我将无法确定如何从我的数据库中导出多个Anums和Pay金额,并将其与每个匹配的paymentInput元素进行匹配(每个帐户持有人将有一个或多个Anum来应用付款)。如果您对此有任何想法,我会全力以赴。

2 个答案:

答案 0 :(得分:0)

如果你安装了IE9或更高版本,那么HTMLDocument有一个getElementsByClassName方法,它选择其class属性包含指定类的每个元素,所以:

Dim paymentInputElements As IHTMLElementCollection
Set paymentInputElements = iePage.getElementsByClassName("paymentInput")

(对于IE8,您可以通过用Set paymentInputElements = iePage.querySelectorAll(".paymentInput")替换第二行来获得相同的结果)

我们现在可以遍历集合,直到找到相关元素:

' Assuming that the account number is in a string variable called Anum
Dim paymentInput As IHTMLElement
' Use this to check if we found the account - initializes to False
Dim bFoundAnum As Boolean
For Each paymentInput In paymentInputElements
    If (Instr(paymentInput.getAttribute("onkeyup"), Anum) > 0) Then
        ' do stuff
        bFoundAnum = True
        Exit For
    End If
Next paymentInput

' Check we found something
If Not bFoundAnum Then
    ' do something - e.g. report an error
End If

答案 1 :(得分:0)

您可以使用dictionaryquerySelector通过CSS定位要更新的元素。字典键(Anum)用于集中到CSS选择器中,以input属性值为键值的onkeyup标签为目标。密钥的关联dictionary值用于分配值。

Option Explicit
Public Sub MakePayments()
    Dim paymentDict As Object
    Set paymentDict = CreateObject("Scripting.Dictionary")

    paymentDict.Add 8677229, "$25"
    paymentDict.Add 10289183, "$40"
    paymentDict.Add 11981680, "null"
    paymentDict.Add 13043481, "$2"

    'Code to get HTMLDocument

    For Each Key In paymentDict.keys
       On Error Resume Next
       iePage.querySelector("input[onkeyup='handlePaymentChange(this,'" & Key & "')']").Value = paymentDict(Key)
      On Error GoTo 0
    Next Key
End Sub

这是使用最后一个键(13043481)的示例CSS选择器的外观:

CSS query