excel - 如何在 VBA 中制作名称搜索功能?
问题描述
我有一个 Excel 文件,它允许我通过指定目标城市所在的国家/地区来计算两个城市之间的距离,以便它在正确的国家/地区进行搜索,并避免在不同国家/地区使用相同的城市名称出错。
我注意到一个问题是
- 有时它找不到某些城市,尤其是在法国,所以
663 km
每次都输入“”,因为它只查找“FR
”。 - 对于罗马、巴黎和马赛等一些城市,它什么也找不到。对于罗马,这也是由于拼写(
Roma
) 而对于巴黎和马赛,这是因为它没有考虑添加的区号:
City of departure City of destination Destination country code Distance (km) Correct names
Soorts-Hossegor PONT L ABBE FR 663 Pont-l'Abbé
Soorts-Hossegor PONT L ABBE FR 663 Dolus-D'Oléron
Soorts-Hossegor DOLUS D OLERON FR 663 Saint-Pierre-d'Oléron
Soorts-Hossegor PONT L ABBE FR 663 Rome
Soorts-Hossegor DOLUS D OLERON FR 663 Paris
Soorts-Hossegor ST PIERRE D OLERON FR 663 Marseille
Soorts-Hossegor NAPLES IT 1740
Soorts-Hossegor ST PIERRE D OLERON FR 663
Soorts-Hossegor DAX FR 40
Soorts-Hossegor ST PIERRE D OLERON FR 663
Soorts-Hossegor PONT L ABBE FR 663
Soorts-Hossegor BREST FR 817
Soorts-Hossegor ST PIERRE D OLERON FR 663
Soorts-Hossegor PONT L ABBE FR 663
Soorts-Hossegor ST PIERRE D OLERON FR 663
Soorts-Hossegor ST JEAN D AULPS FR 663
Soorts-Hossegor ROMA TRIGORIA IT
Soorts-Hossegor PARIS 11 FR
Soorts-Hossegor MARSEILLE 03 FR
我在文件中添加了一个列,其中包含有问题的城市名称,拼写正确。
我想知道是否可以通过运行我的脚本在此列中搜索并纠正导致问题的城市?当我找到导致问题的城市名称时,可以更改最后一列。
Option Explicit
Sub Distance()
Const DIST1 As String = "http://www.distance2villes.com/recherche?source="
Const DIST2 As String = "&destination="
Const DIST3 As String = "distanciaRuta"
Const wsName As String = "Feuil1"
'Dim w As Object: Set w = CreateObject("WINHTTP.WinHTTPRequest.5.1")
Dim w As Object: Set w = CreateObject("MSXML2.XMLHTTP")
Dim h As Object: Set h = CreateObject("htmlfile")
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets(wsName)
Dim rg As Range
Set rg = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(, 2))
Dim Data As Variant: Data = rg.Value
Dim isFound As Boolean: isFound = True
Dim i As Long
Dim Url As String
Dim S As String
For i = 1 To UBound(Data, 1)
If Len(Data(i, 1)) > 0 And Len(Data(i, 2)) > 0 Then
Url = DIST1 & Data(i, 1) & DIST2 & Data(i, 2) & "%20" & Data(i, 3)
w.Open "GET", Url, False
w.Send
h.body.innerHTML = w.responseText
On Error GoTo NotFoundError
S = h.getElementById(DIST3).innerText
On Error GoTo 0
If isFound Then
Data(i, 1) = Replace(Left(S, Len(S) - 3), ",", "")
Else
Data(i, 1) = ""
isFound = True
End If
Else
Data(i, 1) = ""
End If
Next
rg.Columns(1).Offset(, 3).Value = Data
Exit Sub
NotFoundError:
isFound = False
Resume Next
End Sub
解决方案
改进城市名称搜索-
您的代码使用具有一些特殊性的法国网站的结果。对数据库中的拼写进行一些修改,可以通过 url request 找到城市(至少大多数城市)。
最典型的更正可以通过帮助功能解决correct()
:
- 该网站对一些城市使用法语拼写,例如 ROMA ~~> Rome
Marseille 11
必须删除额外的数字区后缀- 必须用连接部分字符串的连字符替换空格
-
- 单曲
l
或d
在人声添加撇号之前'
- 所有重音符号都必须替换为基本字符。
将主子中的URL分配更改为
Url = DIST1 & Data(i, 1) & DIST2 & correct(Data(i, 2)) & "%20" & Data(i, 3)
调用帮助函数correct()
:
Function correct(ByVal city As String) As String
Dim i As Long
'a) change special cities to French spelling
Dim cities: cities = Split("Roma,Wien", ",")
Dim cities2: cities2 = Split("Rome,Vienne", ",")
For i = 0 To UBound(cities)
city = Replace(city, cities(i), cities2(i))
Next
'b)remove numeric district suffixes
Dim tmp: tmp = Split(city, " ")
If IsNumeric(tmp(UBound(tmp))) Then
tmp(UBound(tmp)) = "DELETE"
city = Join(Filter(tmp, "DELETE", False))
End If
'c) insert hyphens and apostrophs
city = Replace(Replace(Replace(UCase(city), " L ", " L'"), " D ", " D'"), " ", "-")
'd) remove all accents
Dim chars: chars = Split("Á À Â Ç É È Ê Î Ï")
Dim chars2: chars2 = Split("A A A C E E E I I")
For i = 0 To UBound(chars)
city = Replace(city, chars(i), chars2(i))
Next
'e) return function result
correct = city
End Function
请注意,上述功能仅涵盖最典型的情况,因此需要进一步补充。
玩得开心 / Beaucoup de plaisir :-)
推荐阅读
- reference - (Anylogic)如何从另一个代理引用 Main
- python - Discord bot 在语音聊天中断开随机用户的连接
- mapping - 从括号切换到 Visual Studio Code
- c# - OnTriggerEnter2D 仅在 Unity 中触发它的对象上更改 int
- python - Selenium 页面源
- c++ - extern "C" 是将 C 代码转换为 C++ 代码,还是只允许编译器将 C 代码编译为 C++ 代码?
- r - geom_smooth 没有回归线
- excel - 在 TEXTJOIN 函数中崩溃 VBA 代码和不需要的“@”符号
- elasticsearch - 弹性:子聚合中直方图聚合的参考桶键?
- sql - IF 在 Where 中具有多个条件