Excel VBA中大约每10,000次迭代出现无法解释的类型不匹配错误

我有一个VBA宏,它使用Microsoft MapPoint计算电子表格中每条记录的两个位置之间的距离。我有大约120,000条记录需要处理。该程序平稳运行大约10,000次迭代然后返回类型不匹配错误,我在错误处理程序中定义MapPoint位置。此时,我选择“调试”,然后在不编辑任何代码的情况下继续执行,并且在再次发生同样的事情之前,它将成功运行另外10,000个左右的记录。 我检查了我的数据,我看不出为什么会出现类型不匹配,或者为什么代码会在一次记录中窒息,然后在没有重置任何内容的情况下,在恢复时处理相同的记录。知道为什么会这样吗? 以供参考,   - 列M包含“X County,ST”形式的位置   - 列AN包含一个单独的ZIP位置   - 列G包含与AN相同的位置数据,但格式为“X County,ST”
Sub distance_from_res()
Dim oApp As MapPoint.Application
Dim k As Long  
Dim count As Long 
Dim errors As Long 

k = 0
count = Sheets("i1_20041").Range("A2", Sheets("i1_20041").Range("A2").End(xlDown)).count
errors = 0

  Set oApp = CreateObject("MapPoint.Application.NA.11")
  oApp.Visible = False
  Set objMap = oApp.NewMap
  Dim objRes As MapPoint.Location
  Dim objFish As MapPoint.Location

'Error executes code at 'LocError' and then returns to point of error.
  On Error GoTo LocError
  Do While k < count
    If Sheets("i1_20041").Range("M2").Offset(k, 0) <> "" Then
        'Sets MapPoint locations as [County],[State] from Excel sheet columns "INT_CNTY_ST" and "ZIP".
          Set objRes = objMap.FindResults(Sheets("i1_20041").Range("AN2").Offset(k, 0)).Item(1)
          Set objFish = objMap.FindResults(Sheets("i1_20041").Range("M2").Offset(k, 0)).Item(1)
        'Calculates distance between two locations and prints it in appropriate cell in Column AO.
          Sheets("i1_20041").Range("AO2").Offset(k, 0) = objRes.DistanceTo(objFish)
    Else
        errors = errors + 1
    End If
      k = k + 1
  Loop
 'Displays appropriate message at termination of program.
  If errors = 0 Then
    MsgBox ("All distance calculations were successful!")
  Else
    MsgBox ("Complete! Distance could not be calculated for " & errors & " of " & count & " records.")
  End If

Exit Sub

LocError:
    If Sheets("i1_20041").Range("G2").Offset(k, 0) = "" Then
        errors = errors + 1
    Else
        'THIS IS WHERE THE ERROR OCCURS!
          Set objRes = objMap.FindResults(Sheets("i1_20041").Range("G2").Offset(k, 0)).Item(1)
          Set objFish = objMap.FindResults(Sheets("i1_20041").Range("M2").Offset(k, 0)).Item(1)
        'Calculates distance between two locations and prints it in appropriate cell in Column AO.
          Sheets("i1_20041").Range("AO2").Offset(k, 0) = objRes.DistanceTo(objFish)
    End If
      k = k + 1
    Resume


End Sub
更新: 我收录了@winwaed和@Mike D的大部分建议,我的代码现在更加准确,并且不会出现错误。然而,旧问题以新形式出现。现在,在大约10,000次迭代之后,代码继续,但之后打印每条记录的~10,000条记录的距离。我可以在故障点重新启动代码,它会找到这些记录的正常距离。为什么会这样?我在下面发布了我的更新代码。
Sub distance_from_res()

Dim oApp As MapPoint.Application
Dim k As Long 
Dim rc As Long 
Dim errors As Long

Dim dist As Double
Dim zipRes As Range
Dim coRes As Range
Dim coInt As Range
Dim distR As Range

Set zipRes = Sheets("Sheet1").Range("C2")
Set coRes = Sheets("Sheet1").Range("B2")
Set coInt = Sheets("Sheet1").Range("E2")
Set distR = Sheets("Sheet1").Range("G2")

k = 0
rc = Sheets("Sheet1").Range("F2", Sheets("Sheet1").Range("F2").End(xlDown)).Count
errors = 0

'Start MapPoint application.
Set oApp = CreateObject("MapPoint.Application.NA.11")
oApp.Visible = False
Set objMap = oApp.NewMap
Dim objResultsRes As MapPoint.FindResults
Dim objResultsInt As MapPoint.FindResults
Dim objRes As MapPoint.Location
Dim objInt As MapPoint.Location

Do While k < rc
    'Check results for Res Zip Code.  If good, set first result to objRes.  If not, check results for Res County,ST.  If good, set first result to objRes.  Else, set objRes to Nothing.
    Set objResultsRes = objMap.FindResults(zipRes.Offset(k, 0))
    If objResultsRes.ResultsQuality = geoFirstResultGood Then
        Set objRes = objResultsRes.Item(1)
    Else
        Set objResultsRes = Nothing
        Set objResultsRes = objMap.FindResults(coRes.Offset(k, 0))
        If objResultsRes.ResultsQuality = geoFirstResultGood Then
            Set objRes = objResultsRes.Item(1)
        Else
            If objResultsRes.ResultsQuality = geoAmbiguousResults Then
                Set objRes = objResultsRes.Item(1)
            Else
                Set objRes = Nothing
            End If
        End If
    End If

    Set objResultsInt = objMap.FindResults(coInt.Offset(k, 0))
    If objResultsInt.ResultsQuality = geoFirstResultGood Then
        Set objInt = objResultsInt.Item(1)
    Else
        If objResultsInt.ResultsQuality = geoAmbiguousResults Then
            Set objInt = objResultsInt.Item(1)
        Else
            Set objInt = Nothing
        End If
    End If

    On Error GoTo ErrDist
    distR.Offset(k, 0) = objRes.DistanceTo(objInt)

    k = k + 1
Loop

Exit Sub


ErrDist:
    errors = errors + 1
    Resume Next

End Sub
    
已邀请:
MikeD对你的危险FindResults()调用是正确的。但是,有一种更好的方法来检查结果。 “FindResults集合”不是纯粹的集合,但包含一个名为“ResultsQuality”的额外属性。文件在这里: http://msdn.microsoft.com/en-us/library/aa493061.aspx Resultsquality返回GeoFindResultsQuality枚举。您想要检查值geoAllResultsGood和geFirstResultGood。所有其他结果应该给出一些结果的错误。请注意,您现有的代码可以找到(例如)不明确的结果,即使第一个结果不太可能是正确的结果。它也可能匹配State或Zipcode(因为这是它能找到的最好的),它会给你一个错误的结果。使用ResultsQuality,您可以检测到这一点。 我仍然会检查Count的值作为额外的检查。 请注意,您的代码正在计算直线(Great Circle)距离。因此,瓶颈将是地理编码(FindResults)。如果您经常使用相同的位置,那么缓存机制可以大大加快速度。 如果你想计算行驶距离,那么市场上有很多产品(是的,我写了两个!)。     
您正在构建一个有点复杂的范围对象(Range - > Offset - > Item)。 DIM临时范围对象并按步骤执行,以便您可以查看问题发生的确切位置
tmpR1 = Sheets("i1_20041").Range("G2")
tmpR2 = tmpR1.Offset(k,0)
然后在尝试访问Item(1)之前检查.FindResult的.Count属性....也许这个项目不存在?!?
Debug.Print objMap.FindResult(tmpR2).Count
暗示: 看着你的代码,我发现你使用了一个变量“count”。此变量名称与第二行代码中的“Count”属性重叠 - 这就是语句末尾的“Count”关键字全部小写打印的原因。它与错误(我们假装;-))没有任何关系,但无论如何都是糟糕的风格。     

要回复问题请先登录注册