起因

工作需要,为了简化一些数据的处理流程,于是乎我决定用VBA来做,没办法,谁让那些处理数据的模板都是xlsm呢!

原来的流程

  • 登录某个内网网站,其实就是个网盘,目录很多
  • 一级一级展开,找到要下载的数据文件
  • 更改模板文件名字与数据文件同名
  • 打开模板,执行处理相关宏
  • 检查处理结果

现在的流程

  • 打开模板文件,点击绑定宏的按钮,等待完成,目视检查即可。

简化关键点

  • 自动下载文件
  • 下载文件后自动执行处理数据的宏

相关库

  1. 为了现代化一点,登录网站和下载选择了WinHttpRequest
  2. 返回数据是字典形式的,选用了VBA-JSON/JsonConverter
  3. 写入文件选择的是Adodb.Stream这个库,写入的内容是IWinHttpRequest::ResponseBody

注意点

  1. WinHttpRequest默认保持cookie,不需要操心。一开始因为犯了一个小错误(以为登录失败,实际上登陆成功),我还一直在找原因,以为是要手动处理cookie,然后就把IWinHttpRequest.Option(WinHttpRequestOption_EnableRedirects) = False了,最后发现不是,算是踩了坑。
  2. 通过Open写入二进制数据(ResponseBody),文件的开头始终会多一些数据,没有找到原因,最后使用Adodb.Stream搞定。
  3. Function如果返回的是Object,那么形式应该是这样的,即赋值的时候要用Set,调用的地方也要用Set,如果是常规的类型则两个地方都不用Set,用了反而会错:
Function BeCallFunc(Param1 As String) As Object
    Dim res As Object
    ' ...
    Set BeCallFunc = res
End Function
Sub MainSub()
    Dim MainRes As Object
    Dim MainParam1 As Object
    Set MainRes = BeCallFunc(MainParam1)
End Sub
  1. As的大小写机制没有搞明白,似乎是在同一个函数里面同是一个模式,即都是As或都是as即可。
  2. 代码放到VBA是编辑器里面后,相关的代码大小写会自动调整,中文粘贴进去会正常,但是从VBA里复制出来会乱码,暂时没有查怎么避免。
  3. 有些函数的库需要提前在工具-引用里面选上,同系列(不同版本)的库只能用一个。
  4. base64的转换用的是Microsoft XML 3.0,这个网上一搜就能找到。
  5. 最好不要再VBA的编辑器里面敲代码,因为这是真的不好写,虽然有些代码提示是有帮助的。令人难受的点有什么呢,比如你回车选择它的提示,然后会给你多个换行出来,我也不知道这是怎么想的,可能需要系统性学习下才知道怎么操作可以避免这个。另外比如你选中剪切了一部分代码,会直接报错,说你代码格式/参数什么的不对,我知道不对呀!我这不是在改吗。。
  6. 运行时报错你找不到在哪里,它就是说你错了,貌似只有明显的语法错误才会标红,其他的BUG个人经验是先运行到指定的光标位置,然后F8逐语句比较好定位。
  7. 如果预先通过Dim定义了类型,那么赋值时,值会被转换到被赋值变量的类型。
  8. 如果想执行宏,但文件又不能是xlsm,那么请通过Open的方式,激活要操作的文件,然后跑VBA代码。

碎碎念

  • Mid函数用于截取字符串,值得注意的是,截取开始位置是1,而非编程中常常使用0作为开始,也许这是为了方便非编程人员吧,不过我是很难受。。
  • Shell command可以执行command命令,注意这里的command可以是其他exe,执行cmd的话一般就是 Shell "cmd /c ...",没错这里是一个字符串。
  • VBA中如果你要输出一个引号("),那么请把它写成两个即可,即两个引号代表一个引号,例如"""0"""实际上是"0"
  • 连接字符串可以用+也可以用&。
  • Object对象的函数传递参数,根据我目前的经验,如果要返回值,那么用res = obj.callfunc(param1, param2),不需要的话就是obj.callfunc param1, param2,否则报错是语法错误,没错就是这么神奇。。
  • WinHttpRequest要把请求头删掉的话SetRequestHeader传入header的值和NULL即可,不过由于抓包失败,没有验证到底是Null,还是”null“,还是"",网上也没搜到例子。。
  • 调试的时候,看变量相关属性和值,是在本地窗口,立即窗口是console,Debug.Print之类的输出会在这里显示,不过本地窗口的信息量有限。
  • 代码提示很渣。。

其他的想起来再补充。
有些数据方面的爬虫倒是可以基于Excel来做,就是写成VB代码不太方便。

标签: none

添加新评论