感谢黎培兴老师为我开启编程世界的大门
(呵呵……千万别去百度搜啊)
作为一名学过C/C++的统计狗
编程?”识条铁咩“
本文不适合编程小白食用
欢迎各大编程高手留言赐教&指正
last but not least
我不生产代码
我只是代码的搬运工
从前有个业务系统,我想把里面的某个清单抓出来。然而我并没有导出权限,也不想去开权限。(因为那个账号根本不是我的,我不想惊动到账号的主人……糟了,暴露了)
所以要想办法绕过权限把数据抓出来。
然后,我偶然发现,那个网页可以保存到本地。
所以斗胆地认为,存到本地的文件里面,一定有我要的数据。
【Step1】点击进入审批清单的界面
【Step2】把单页可显示的数据条数调到最大(我这里只能调到100)
举例如下:把红色箭头所示的数据改成100或更大
【Step3】按Ctrl+S,跳出“保存网页”的界面
(通常情况下,右键功能会被屏蔽,但不会屏蔽快捷键……)
每刷一页数据,就把网页存一次,个人不建议直接存桌面
(假设有每页100条,一共10页,那就存10遍……非常无脑的机械重复操作)
正常情况下,一个网页保存下来,会有1个htm文件+1个数据文件夹(里面有超多文件)
这是我的存放结构,不是这种结构的,我不知道要不要改代码
【敲黑板!!!】
保存网页的编码默认是简体中文GB2312,请必须选择为Unicode
用简体中文GB2312保存的话,页面数据文件(htm格式)用excel打开,只能看到源代码
用Unicode保存的话,才能看到数据
天知道我在这里卡了多久
显然,我要的表单数据,均储存在一个叫做”griddata.htm“的文件,这个文件就在数据文件夹里,存储路径不一定都一致,但至少文件名称是不会变的。(一点都不显然好吗!)
“griddata.htm”可以直接用excel打开,并且打开之后能直接看到我要的数据。(用Unicode编码储存才有这样的效果!)
所以,可以分解步骤如下:
1.把每个网页对应的griddata.htm找到
2.用excel逐一打开这些griddata.htm,然后一个接一个的往下复制粘贴
这样就能获得完整的清单数据
(我擅长的就是这种机械重复的VBA)
再次重申
我不生产代码
我只是代码的搬运工
干货开始
第一步
找到所有gridata.htm
这个代码直接搬人家的
本机运行竟然也不报错,真的很优秀了
作者的思路是,先编个函数,把目标文件的地址存放在一个数组里头,然后再编一个宏,去调用这个函数,把函数得出的数组输出到指定表格的指定位置。
作者心机有点重啊……把函数单独写一页再加个密码,绝了
我们先来看看函数
我尽量解释一下哈~~
【第1行】定义一个叫做ListFile函数
这个函数有3个自变量,分别为
Mulu:就是个地址,函数会遍历这个地址下的文件
Zi:布尔型参数,只有两个值,真&假
LeiXing:目标文件的描述,比如我要找所有叫做griddata.htm的文件,我就直接输入griddata.htm(我没有试过只写扩展名,哪位勇士有兴趣的可以去试试,告诉我是啥情况)
【第2~5行】老传统,把要用的东西全部定义一遍
Scripting.Dictionary是VBA本身封装好的一个东西,我还没翻到Dictionary的描述文档,所以也不太清楚到底是啥
所以d很多可以直接用的属性&方法,我都不懂是啥
欢迎广大编程爱好者帮我找找~~
【第6行】判断Mulu这个参数是不是空值,假如不是空值,就探索它的下一层
【第7行】不懂
【第8行】给i赋初始值0
【第9~20行】是一个完整的Do While循环(简称循环①)
【第12~17行】是嵌套在循环①里面的Do While循环(简称循环②)
【第9行】如果i比d.Count小,则执行第10~20行,否则跳出循环①(飞去第21行)
【第10、11行】不懂
【第12行】如果myFile的值不为空,则执行第13~17行,否则跳出循环②(飞去第18行)
【第13行】假如myFile不等于“.”而且不等于“..”,则执行第14行
【第14行】不懂,我猜是把满足条件的地址放到数组里面
【第15行】if结束,注意,这是第13行if语句的结束,而不是第14行的
【第16行】寻找此目录下的下一个文件
【第17行】回到第12行
【第18行】假如Zi这个参数的值是False,则跳出循环①(飞去第21行)
【第19行】i累加
【第20行】回到第9行
【第21行】假如LeiXing这个参数是空值,则执行第22行
【第22行】不懂
【第23行】假如LeiXing不是空值,则执行第24~34行
【第24~31】是一个完整的For循环(简称循环③)
【第26~29行】是嵌套在循环③里面的Do While循环(简称循环④)
【第24行】对于每个在d.keys里面的x,执行第25~31行
【第25行】不懂
【第26行】假如myFile不是空值,执行第27~29行,否则跳出循环④(飞去第30行)
【第27行】不懂
【第28行】寻找此目录下的下一个文件
【第29行】返回第26行
【第30行】假如Zi这个参数的值是False,就跳出循环③(飞去第32行)
【第31行】回到第24行
【第32行】假如ms是空值,则把“没有符合要求的文件”赋给ms
【第33行】把ms(数组)中每一个元素,以“,”为标记进行划分(类似于“分列”功能),再对数组进行转置(把横向排列变为纵向排列)
【第34行】if结束,注意这是第21行if语句的结束
【第35行】Listfile这个函数的编码到此结束
好了函数搞完了,终于轮到宏了
是的,只有6行
因为所有关键代码全在函数里头了
【第1行】建立一个宏,叫做getalist
【第2行】定义a,不指定数据类型(其实就是个数组)
【第3行】调用ListFile函数,并且把3个自变量填上
【第4、5行】这两行要一起看;从表List的A2单元格开始,把a(数组)的元素逐一往下填到单元格里(注意,要事先建一个叫做“List"的工作表,不然代码会出错的)
【第6行】宏结束
第一步到此结束
第二步
打开每个griddata.htm,把数据都粘贴在同一张表里面
首先,我们要新建一个工作表
不能在表List里面直接运行下面这个宏!!!
否则会直接把地址列表覆盖掉&代码报错
继续
【第1行】宏代码开始
【第2~6行】老传统,不解释了
【第7行】给b一个初始值2(为啥是2?看第10行)
【第8行】赋值,让Tb这个参数代表宏所在的工作簿
【第9行】因为接下来要反复打开/关闭表格,为了防止屏幕抖动,直接不让屏幕刷新
【第10行】把表List的A2单元格的值赋给MyPath(第一步获得的地址列表,是从单元格A2开始往下填的;而A2用Cells函数的表达就是Cells(2,1);通过b的累加,就可以遍历这个地址列表了)
【第11行】Num这个参数是计算一共合并了多少个文件,个人觉得可有可无
【第12~23行】是一个完整的Do While循环(简称循环⑤)
【第15~20行】是嵌套在循环⑤里面的With语句
【第16~18行】是嵌套在With语句里面的For循环(简称循环⑥)
【第12行】当MyPath的值不为空时,执行第13~23行;为空值就代表地址列表已经读取完了,可以跳出这个循环(飞去第24行)
【第13行】要用excel打开一个文件,这个文件的地址就是MyPath,然后再把这个文件用Wb去表示
【第14行】成功打开文件,Num累加
【第15行】激活宏所在工作簿的活动工作表,第16~19行都是在这个情况下去操作
【第16行】Sheet.Count表示打开的这个工作簿一共有多少个工作表;从第一到最后一张工作表,执行第17~18行语句(遍历当前工作簿的每个工作表)
【第17行】把第G张工作表的内容,全部粘贴到宏所在的工作表里面(因为这句话,所以事先一定要新建工作表再运行这个宏,否则会直接把地址列表覆盖掉)
这句话非常有意思,我真的控制不住要给大家讲讲:
通常情况下,复制粘贴的语句,可以看到Copy和Paste成对出现
然而,这句话是没有Paste的!!!
所以我当初为了校正粘贴位置,瞎忙活的好几天
Wb.Sheet(G).UsedRange.Copy
懂英文的应该都能看到
然后
!!空一格再写!!
.Cells(.Range("A65536").End(xlUp).Row+1,1)
必须要空一格再写,也不能另起一行写
这句话,就是粘贴的意思了
粘贴到宏所在工作簿的活动工作簿的指定位置
而且是接着上一个粘贴数据的后面去粘贴
不会把前面的数据覆盖掉的哟
建议大家抽空去了解一下xlUp、xlDown
这是非常实用的两个参数
【第18行】跳到Wb的下一个工作表,再执行第17行
【第19行】Wb所有的工作表都已经粘贴合并好了,就把Wb关闭,不保存
【第20行】With结束
【第21、22行】b累加,把地址列表的下一个地址赋给MyPath
【第23行】回到第12行
【第24行】(现在应该已经回到宏所在的工作簿,并且活动工作表显示的就是合并之后的数据)选中活动工作表的B1单元格
【第25行】屏幕可以更新了
【第26行】跳出弹窗,告诉你一共合并了多少个工作簿
【第27行】宏结束
要累垮了……
让我的手指歇一歇
1.对于第一步
其实可以搞个窗体,把要抓的文件参数输在窗体里面,即便往后要抓的文件变了,也不需要回去代码里面慢慢改
2.对于第二步
我一直想搞个无格式粘贴,但是问度娘也没有找到运用.Copy的无格式粘贴办法;现在这个有格式粘贴,单元格会自动换行变宽,搞得表格看上去很长(虽然可以再合并之后统一刷格式,但是无形中又多了几行代码,所以最好是在粘贴的时候直接无格式地粘)
3.关于两步合并
其实可以再多编一个宏,直接按顺序运行第一步&第二步的程序,更省事(这个根本不用自己敲代码,录制宏就能解决)But我个人也不太建议两步合并,毕竟与合并后过万条的数据相比,看地址列表更容易发现有没有错漏,也可以对地址列表进行再加工
本期内容到此结束
欢迎各大高手留言赐教&指正
我不生产代码
我只是代码的搬运工
但是代码解释真的是我手把手写的
所以厚颜无耻地声明原创
大家有任何VBA需求都可以来找我
我可是活雷锋哟
but还是祝大家永远都用不着VBA
领取专属 10元无门槛券
私享最新 技术干货