
Hello,各位小伙伴们咱们好呀。我是Yogurt。不知道有没有从事电商职业或许往常触摸公司里需求收发邮件货品岗位的朋友,会不会都会碰到每天都要挂号物流信息、更新物流状况的状况?Yogurt从结业进入公司之后就一向担任公司产品的发货、物流盯梢等作业。其间每天都需求对宣布但未签收的产品进行物流盯梢,少的时分或许只要几个,多的时分或许会连着之前几天的物流信息一同查询,适当繁琐,非常的耗时刻。正好这两天有点时刻,就想着看看用Excel能不能承当这样的重担,幸而上天不负有心人,让Yogurt想到方法了。

上述是作用图,也便是咱么这次要讲的事例——用Excel来批量查询物流信息。
首要,咱们需求了解制造这样一个“高逼格”的小帮手的全体流程。

由于获取的信息都是最原始的代码信息,经Yogurt查询得知360查找所运用的文字编码为UNICODE编码。当查询不到物流信息时,会回来过错值[errormsg];而查到信息且为签收时会呈现[\u7b7e\u6536](UNICODE编码),转换成中文过来便是[签收];假如这两者都没有,则阐明查到了物流信息但没有签收——也便是运送中的状况。
大致了解了操作理论,那么下面就一同来实操一下吧。
这儿调用的是360查找的数据,因而咱们需求在360查找里获取信息(www.so.com)。

截止到Yogurt写推送,正好有三种不同状况的邮件,查询之后回来以下几种页面。
已签收
运送中
查询失利
这三种状况别离有其特色:
已签收:一切的文字中有且只要一个【签收】字样,网站js代码中有且只要一个【\u7b7e\u6536】。
查询失利:网站js代码中有且只要一个【errormsg】字样(接下来会讲到)。
运送中:既不呈现已签收中的特征,也不呈现查询失利中的特征。
因而咱们可以使用这些特征来获取js代码中的要害字眼,然后到达获取物流状况的意图。

首要,咱们随意拿一个单号复制张贴到360查找中查一下,弹出的窗口之后按键盘上的【F12】即可调出浏览器的【开发者东西】,Yogurt在这儿演示用的是360极速浏览器(一般来说,火狐浏览器、Chorme(谷歌)浏览器都是可以调出开发者东西的,360极速浏览器的内核是依据Chorme开发的,所以和Chorme差不多)。


翻开网页之后咱们会发现和往常看到的网页不同,这个网页是美丽的网页背面的数据,而咱们所需求的数据就在这儿面。
或许会有人说,一个中文都看不到我怎样知道是什么意思。网页数据的编码各不相同,有些用的是UTF-8,有些用的是ASCII,而这儿调用的数据是用UNICODE编码显现的。
经过查表,Yogurt知道了“签收”二字的编码别离是【7b7e】和【6536】,那么咱们只需求经过查询这一整段代码中是否含有这两个UNICODE编码即可得知是否签收。
以此类推,咱们经过查询暂时没有物流的快递单号时,在网页数据中有且只要一个【errormsg】字眼。也便是无法获取物流信息的状况。
最终咱们可以扫除签收状况和没有物流信息的状况,剩余的也就只要运送中的状况了。接着咱们就可以带着这个逻辑回到Excel中去。


然后张贴以下代码,再添加一个页面按钮即可。
Sub 创云物流查询模块()
Dim Url, Row1, i, Now1, AWSF, t
Row1 = Range("B" 2 ^ 20).End(xlUp).Row
Now1 = TimeValue(Now)
For i = 3 To Row1
Range("C" i).Select
If Range("C" i) "已签收" Then
Range("C" i) = ""
Range("D" i) = ""
Url = "https://open.onebox.so.com/api/getkuaidismart?callback=jQuery091220614_54com=nu="
Url = Url Range("B" i)
With CreateObject("msxml2.xmlhttp")
.Open "get", Url, False
.send
t = DateAdd("s", 0.5, Now)
Do Until Now t
DoEvents
Loop
If InStr(.responsetext, "errmsg") 0 Then
Range("C" i) = "暂无信息"
Range("D" i) = "-"
ElseIf InStr(Split(Split(.responsetext, "context"":""")(1), """")(0), "\u7b7e\u6536") 0 Then
Range("C" i) = "已签收"
Range("D" i) = Split(Split(.responsetext, "time"":""")(1), """")(0)
Else
Range("C" i) = "运送中"
Range("D" i) = Split(Split(.responsetext, "time"":""")(1), """")(0)
End If
End With
End If
Next
Set AWSF = Application.WorksheetFunction
MsgBox "查询单号:" AWSF.CountA(Range("C:C")) - 1 "条" vbCrLf _
"已签收共:" AWSF.CountIf(Range("C:C"), "已签收") "条" vbCrLf _
"运送中共:" AWSF.CountIf(Range("C:C"), "运送中") "条" vbCrLf _
"查询失利:" AWSF.CountIf(Range("C:C"), "暂无信息") "条" vbCrLf _
"共耗时:" Format(TimeValue(Now) - TimeValue(Now1), "hh:mm:ss") vbCrLf _
"物流信息来源于[360查找]及[菜鸟裹裹]" vbCrLf "查询代码由[大众号:创云规划]开发供给。", vbOKOnly, "创云物流查询模块 V1.0"
End Sub

在菜单栏中挑选【开发东西】,点击【刺进】中的表单控件中的第一个——【按钮(窗体控件)】。然后将控件制作到页面中,依照提示挑选编写好的代码模块即可。
接下来Yogurt为乐意研究而且想自己改善代码的朋友介绍一下Yogurt写的内容,便利咱们修正。
Yogurt写的代码首要分为三大部分——前期声明、赋值;中期抓包、循环;后期信息反应。

前期声明、赋值部分:界说Url为网址;Row1为获取单号行中最终一行不为空的单元格地点方位的行号;i为循环赋值;Now1为开端时刻赋值;AWSF为调用Excel函数的称号;t为延时时刻赋值。
首要经过获取单号地点列【B列】中最终一行不为空的单元格地点方位的行号并赋值给Row1。然后再获取代码履行开端时刻的值并赋值给Now1。
接下来就要进行循环部分了。
由于已签收的邮件自身不需求进行再次查询,因而需求判别【单号】对应【状况】列中的值是否为【已签收】,只要在不为【已签收】时才需求履行抓包查询。因而,这儿Yogurt加了If…Then…End If句子。
然后将咱们在第一步获取到的网址张贴到代码中并赋值给Url。网址中的最终两个参数中包括了单号和查询时刻。

赤色框中为单号,有必要存在才干查询;蓝色框中为提交时刻,疏忽即可(从往后删去)。
为了写代码愈加明晰,特将网址分隔来写,先写固定部分,再写单号。
接着就需求调用目标msxml2.xmlhttp来将网址提交服务器,并获取网页信息。
而在获取网页信息之前,咱们需求考虑服务器的延时问题,不然或许会由于代码履行太快而回来过错值。在第一步中Yogurt的电脑查询物流信息的页面加载时刻为500ms(毫秒)左右,往常加载时刻大概在350~700ms之间,因而干脆就定为500ms,也便是0.5秒。经过延时等候网页加载完结,然后削减查询的过错。
接着就需求对获取的网页进行查找及判别。这儿Yogurt用了InStr([start, ]string1, string2[, compare])函数(类似于Excel中的FIND函数)和Split(expression[, delimiter[, count[, compare]]])函数(一种可以对要害词进行分段获取的函数,规范称号为“指令读取指定文件”),来对获取的网页信息进行查询,便于If…Then…ElseIf…End If句子的判别。
依据前面拟定的流程,首要需求判别是否为暂无信息——也便是是否包括【errormsg】字样。
假如包括,则在对应的【状况】列中显现“暂无信息”,【时刻】列中为“-”。
同理,接下来判别是否【签收】,假如都不契合就在对应的【状况】列中显现“运送中”,【时刻】列中为最新的时刻。
然后就一向循环抓包获取物流信息。
咱们完结查询之后需求获取反应信息,证明代码现已运转结束了。因而需求履行一个对话框来获取反应信息。这儿为了便利,Yogurt直接经过调用Excel中的函数——Application.WorksheetFunction来进行相关的核算。用到了COUNTA函数(计算不为空的单元格的数量);COUNTIF函数(计算契合要求的单元格数量),并显现查询时刻。
最终测验一下,功德圆满!
以上Yogurt首要是以思路和逻辑为主,操作为辅进行解说,由于假如整个代码一字一句的翻译的话且不说文章篇幅问题,更会影响咱们的全体思路,Excel的函数、VBA的代码其实都很好把握,多用,多看,多测验即可。而规划函数公式和代码的逻辑思维,以及规划的全体思路才是最重要的。
他给Yogurt提的主张是:期望可以随意增减列的内容,让表愈加完好,比如说添加公司称号、补白之类的一起代码还可以履行。因而Yogurt改善后的作用和代码如下:

Sub 创云物流查询模块_改善()
Dim Url, Row1, Col_DH, Col_ZT, Col_SJ, i, Now1, AWSF, t
Set AWSF = Application.WorksheetFunction
Col_DH = AWSF.Match("单号", Rows("2:2"), 0)
Col_ZT = AWSF.Match("状况", Rows("2:2"), 0)
Col_SJ = AWSF.Match("更新时刻", Rows("2:2"), 0)
Row1 = Cells(2 ^ 20, Col_DH).End(xlUp).Row
Now1 = TimeValue(Now)
For i = 3 To Row1
Cells(i, Col_ZT).Select
If Cells(i, Col_ZT) "已签收" Then
Cells(i, Col_ZT) = ""
Cells(i, Col_SJ) = ""
Url = "https://open.onebox.so.com/api/getkuaidismart?callback=jQuery091220614_54com=nu="
Url = Url Cells(i, Col_DH)
With CreateObject("msxml2.xmlhttp")
.Open "get", Url, False
.send
t = DateAdd("s", 0.5, Now)
Do Until Now t
DoEvents
Loop
If InStr(.responsetext, "errmsg") 0 Then
Cells(i, Col_ZT) = "暂无信息"
Cells(i, Col_SJ) = "-"
ElseIf InStr(Split(Split(.responsetext, "context"":""")(1), """")(0), "\u7b7e\u6536") 0 Then
Cells(i, Col_ZT) = "已签收"
Cells(i, Col_SJ) = Split(Split(.responsetext, "time"":""")(1), """")(0)
Else
Cells(i, Col_ZT) = "运送中"
Cells(i, Col_SJ) = Split(Split(.responsetext, "time"":""")(1), """")(0)
End If
End With
End If
Next
MsgBox "查询单号:" AWSF.CountA(Range(Col_ZT ":" Col_ZT)) - 1 "条" vbCrLf _
"已签收共:" AWSF.CountIf(Range(Col_ZT ":" Col_ZT), "已签收") "条" vbCrLf _
"运送中共:" AWSF.CountIf(Range(Col_ZT ":" Col_ZT), "运送中") "条" vbCrLf _
"查询失利:" AWSF.CountIf(Range(Col_ZT ":" Col_ZT), "暂无信息") "条" vbCrLf _
"共耗时:" Format(TimeValue(Now) - TimeValue(Now1), "hh:mm:ss") vbCrLf _
"物流信息来源于[360查找]及[菜鸟裹裹]" vbCrLf "查询代码由[大众号:创云规划]开发供给。", vbOKOnly, "创云物流查询模块 V1.0"
End Sub
在原代码的基础上添加了获取含标题要害词的单元格的列方位来定位单号、状况、更新时刻地点列的方位,然后到达随意增减列内容的一起还能更新物流信息的意图,提高了表格的自由度。但是有一点需求留意,新增的列标题不能与本来的三个列标题相同——即不能独自呈现【单号】【状况】【更新时刻】这三个词。假如实在是要修正本来的列标题,那么需求按【Alt】+【F11】调出VBA代码模块,修正下图中红框部分相对应的标题姓名即可。

最终的最终,Yogurt再和洽朋友谈天过程中发现批量查询物流是许多从事电商或许企业内需求很多发货但没有专门的办理体系的朋友的痛点和难点,因而衷心期望咱们能用得高兴。
也期望咱们假如身边有从事相关职业的朋友无妨小手转发本文推荐给他们,从实际行动中协助他们。
好啦,以上便是本期推送的全部内容,我是Yogurt,下期见咯。
