2013-08-30 213 views
2

问候知识的好...对象变量或带块变量未设置 - 接入2010 VBA

我一直在阅读有关此特定错误的众多职位,并没有发现任何解决我的具体问题。

我在Access 2010前端有一些VBA代码。有时,但并非总是,我得到一个“对象变量或未设置块变量”。错误。我的代码如下:在两个特定的地方发生

Public Sub ValidateAddress(PassedAddress As Object, PassedCity As Object, PassedState As Object, _ 
    PassedZIP As Object, PassedCongressionalDistrict As Object, PassedValidated As Object, HomeForm As Form) 

On Error GoTo ShowMeError 
    Dim strUrl As String ' Our URL which will include the authentication info 
    Dim strReq As String ' The body of the POST request 
    Dim xmlHttp As New MSXML2.XMLHTTP60 
    Dim xmlDoc As MSXML2.DOMDocument60 
    Dim dbs As Database 
    Dim candidates As MSXML2.IXMLDOMNode, candidate As MSXML2.IXMLDOMNode 
    Dim components As MSXML2.IXMLDOMNode, metadata As MSXML2.IXMLDOMNode, analysis As MSXML2.IXMLDOMNode 
    Dim AddressToCheck As Variant, CityToCheck As Variant, StateToCheck As Variant, ZIPToCheck As Variant 
    Dim Validated As Boolean, District As Variant, MatchCode As Variant, Footnotes As Variant 
    Dim candidate_count As Long, SQLCommand As String, Start, Finish 

    ' This URL will execute the search request and return the resulting matches to the search in XML. 
    strUrl = "https://api.smartystreets.com/street-address/?auth-id=<my_auth_id>" & _ 
    "&auth-token=<my_auth_token>" 

    AddressToCheck = PassedAddress.Value 
    CityToCheck = PassedCity.Value 
    StateToCheck = PassedState.Value 
    If Len(PassedZIP) = 6 Then ZIPToCheck = Left(PassedZIP.Value, 5) Else ZIPToCheck = PassedZIP.Value 

    ' Body of the POST request 
    strReq = "<?xml version=""1.0"" encoding=""utf-8""?>" & "<request>" & "<address>" & _ 
       " <street>" & AddressToCheck & "</street>" & " <city>" & CityToCheck & "</city>" & _ 
       " <state>" & StateToCheck & "</state>" & " <zipcode>" & ZIPToCheck & "</zipcode>" & _ 
       " <candidates>5</candidates>" & "</address>" & "</request>" 
    With xmlHttp 
     .Open "POST", strUrl, False      ' Prepare POST request 
     .setRequestHeader "Content-Type", "text/xml" ' Sending XML ... 
     .setRequestHeader "Accept", "text/xml"   ' ... expect XML in return. 
     .send strReq         ' Send request body 
    End With 

    ' The request has been saved into xmlHttp.responseText and is 
    ' now ready to be parsed. Remember that fields in our XML response may 
    ' change or be added to later, so make sure your method of parsing accepts that. 
    ' Google and Stack Overflow are replete with helpful examples. 

    Set xmlDoc = New MSXML2.DOMDocument60 
    If Not xmlDoc.loadXML(xmlHttp.ResponseText) Then 
     Err.Raise xmlDoc.parseError.errorCode, , xmlDoc.parseError.reason 
     Exit Sub 
    End If 

    ' According to the schema (http://smartystreets.com/kb/liveaddress-api/parsing-the-response#xml), 
    ' <candidates> is a top-level node with each <candidate> below it. Let's obtain each one. 
    Set candidates = xmlDoc.documentElement 

    ' First, get a count of all the search results. 
    candidate_count = 0 
    For Each candidate In candidates.childNodes 
     candidate_count = candidate_count + 1 
    Next 

    Set candidates = xmlDoc.documentElement 
    Select Case candidate_count 
     Case 0 ' Bad address cannot be corrected. Try again. 
      Form_frmPeople.SetFocus 
      MsgBox "The address supplied does not match a valid address in the USPS database. Please correct this.", _ 
       vbOKOnly, "Warning" 
      PassedAddress.BackColor = RGB(255, 0, 0) 
      PassedCity.BackColor = RGB(255, 0, 0) 
      PassedState.BackColor = RGB(255, 0, 0) 
      PassedZIP.BackColor = RGB(255, 0, 0) 
      Exit Sub 
     Case 1 ' Only one candidate address...use it and return. 
      For Each candidate In candidates.childNodes 
       Set analysis = candidate.selectSingleNode("analysis") 
       PassedAddress.Value = candidate.selectSingleNode("delivery_line_1").nodeTypedValue 
       Set components = candidate.selectSingleNode("components") 
       PassedCity.Value = components.selectSingleNode("city_name").nodeTypedValue 
       PassedState.Value = components.selectSingleNode("state_abbreviation").nodeTypedValue 
       PassedZIP.Value = components.selectSingleNode("zipcode").nodeTypedValue & "-" & _ 
        components.selectSingleNode("plus4_code").nodeTypedValue 
       Set metadata = candidate.selectSingleNode("metadata") 
       PassedCongressionalDistrict.Value = CInt(metadata.selectSingleNode("congressional_district").nodeTypedValue) 
       PassedValidated.Value = True 
      Next 
      Exit Sub 
     Case Else ' Multiple candidate addresses...post them and allow the user to select. 
      DoCmd.SetWarnings False 
      Set dbs = CurrentDb 
      If IsTableQuery("temptbl") Then dbs.Execute "DROP TABLE temptbl" 

      dbs.Execute "CREATE TABLE temptbl (Selected BIT, CandidateAddress CHAR(50), CandidateCity CHAR(25), _ 
     CandidateState CHAR(2), CandidateZIP CHAR(10), CandidateCongressionalDistrict INTEGER, _ 
     MatchCode CHAR(1), Footnotes CHAR(30));" 
      DoCmd.SetWarnings True 

      Start = Timer 
      Do While Timer < Start + 1 
       DoEvents 
      Loop 

      For Each candidate In candidates.childNodes 
       Set components = candidate.selectSingleNode("components") 
       AddressToCheck = candidate.selectSingleNode("delivery_line_1").nodeTypedValue 
       CityToCheck = components.selectSingleNode("city_name").nodeTypedValue 
       StateToCheck = components.selectSingleNode("state_abbreviation").nodeTypedValue 
       ZIPToCheck = components.selectSingleNode("zipcode").nodeTypedValue & "-" & _ 
        components.selectSingleNode("plus4_code").nodeTypedValue 
       Set metadata = candidate.selectSingleNode("metadata") 
       District = metadata.selectSingleNode("congressional_district").nodeTypedValue 
       Set analysis = candidate.selectSingleNode("analysis") 
       MatchCode = analysis.selectSingleNode("dpv_match_code").nodeTypedValue 
       Footnotes = analysis.selectSingleNode("dpv_footnotes").nodeTypedValue 
       DoCmd.SetWarnings False 
       dbs.Execute "INSERT INTO temptbl (CandidateAddress, CandidateCity, CandidateState, CandidateZIP, _ 
       CandidateCongressionalDistrict, MatchCode, Footnotes) " & vbCrLf & "SELECT """ & AddressToCheck & _ 
        """ AS Expr1, """ & CityToCheck & """ AS Expr2, """ & StateToCheck & """ AS Expr3, """ & _ 
        ZIPToCheck & """ AS Expr4, " & District & " AS Expr5, """ & MatchCode & """ AS Expr6, """ & _ 
        Footnotes & """ AS Expr7;" 
       DoCmd.SetWarnings True 
      Next 

      DoCmd.OpenForm "frmPeopleAddressMaintenance" 

      Do Until CurrentProject.AllForms("frmPeopleAddressMaintenance").IsLoaded = False 
       DoEvents 
      Loop 

      HomeForm.SetFocus 
      If IsTableQuery("temptbl") Then dbs.Execute "DROP TABLE temptbl" 
    End Select 
    dbs.Close 
    Exit Sub 

ShowMeError: 
    MsgBox Err.Description, vbOKOnly, "ERROR!" 
End Sub 

错误:

在 “案例1”:该错误后立即发生......

PassedCongressionalDistrict.Value = CInt(metadata.selectSingleNode("congressional_district").nodeTypedValue) 

...被执行。我调试了这一点并验证了该语句正确执行,并且“PassedCongressionalDistrict”对象的值是正确的。

然后,在“Case Else”下:For循环正确处理第一个项目列表,但在开始处理第二个项目时失败并出现已识别的错误,即使第二个项目中有合理的数据。

我希望我已经解释得很好。我似乎无法弄清楚(1)如何更充分地调试它以及(2)为什么发生错误,因为看起来我已经正确定义了所有的对象变量。

问候, 肯

+0

在过去的2007年迁移到他们2010年的时候我已经有项目报错了对我2010年的引擎是某种“更快”等有些情况下,我的代码似乎尝试并在对象被分配或实例化之前引用对象,并且错误只是有时会显示出来,而且当我一步一步地调试时,它总能正常工作,并且在2007年不会出错。因此,我对这些情况的修补程序是在有问题的行之前为第二个(或需要的时间)添加计时器延迟。不是一个优雅的解决方案,但它已为我多次工作。 – chiliNUT

+0

我也想过这个。现在我已经试过了,现在你已经提到过了。 – KACJR

+0

也许Access更喜欢不参加政治活动。 – HK1

回答

2

几乎可以肯定因为(有时)没有在XML体命名为“元数据”子节点成员 - 因此,当你尝试在“元数据”对象绑定到.selectSingleNode()方法返回Nothing。您可以随时检查,以确保它实际上必然......

'// ...start code snippet... 

    Set metadata = candidate.selectSingleNode("metadata") 

    If Not metadata is Nothing Then 
     PassedCongressionalDistrict.Value = CInt(metadata.selectSingleNode("congressional_district").nodeTypedValue) 
    End If 

    PassedValidated.Value = True 

    '// ...end code snippet... 
+0

谢谢Brian。这解决了这个问题。建议将此更改传播到Github上的示例代码。 – KACJR

相关问题