找到并合并指定文件

感谢黎培兴老师为我开启编程世界的大门

(呵呵……千万别去百度搜啊)

作为一名学过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

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181214G0MA6000?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券