SO IWARE DEVEL0PMENT AND D ̄ESIGq 3N 软件开发与设计 利用VBA编程实现生产日报表的自动生成 杨廷福,王会梅 (中原油田钻井工程技术研究院技术信息研究所,河南濮阳457001) 摘要:利用VBA语句编程,实现固定报表合并、动态报表合并、删除重复行空白行、打印报表上传情况及VBA 与报表分离,结合Windows任务计划程序,分步、分模块直到实现生产日报表的定时自动生成。 关键词:VBA编程;报表合并;任务计划程序;自动生成 Automatic Generation of Achieve Daily Production Reports with VBA Programming YANG Ting-fu,WANG Hui-mei (InstituteforTechnologyinformaitonoftheDrillingTechnologyResearchInstituteofZhongYuanOilfield,He'nanPuyang457001,China) Abstract:Fixed report amalgamation ,dynamic report amalgamation,deleting repeated and blank line printing report uploading ,status and separation of VBA and report are achieved with VBA language programming.Combined with Windows task plan program,taking steps and making module blocks are carried out until the daily production reports are timing automaticly generated. Key words:VBA programming;report amalgamation;task lan prpogram;automatic generation l 引言 一21.xls,一公司的命名为lgs2012—3—21.xls,同理命名其它三个 公司的。在钻井院当天13报完成复制粘贴后即将当前文件最 小化但不退出,然后打开下一个分公司当天报表,直到完成5 个分公司的当天报表的合并,当前的Excel工作簿中包含了5 个分公司当天的报表。 DimwbAsWorkbook 家水平井技术公司分别由钻井院水平井公司、一公司 水平井公司、二公司水平井公司、三公司水平井公司和四公 司水平井公司等5家分公司组成,而每个分公司又有若干个 水平井服务队组成。水平井技术公司指定专人每天固定时间 把各个分公司通过FTP方式上传到服务器中当天的Excel生产 报表(格式均一样),复制粘贴合并到一个汇总表中,然后再 把汇总表存放到汇总表文件夹下所属当月的子文件夹中,以 定义wb为工作簿变量 Application.WindowState=xlMinimized 当天的日期命名,然后再以FrrP的方式提供给水平井技术公 司的领导、技术人员共享使用。管理员每天要逐一进入到每 个分公司当月子文件中打开Excel文档进行复制粘贴,这是一 将当前的汇总表(空白的)窗口最小化 Set wb=Workbooks,.Open C i:\定向井报表\钻井院水平井 日报表 ̄2012-一3\z_iy2012-.-3-.-21.xls”) 打开钻井院2012年3月21日的报表并赋给变量wb Range(”b6:aal4”).Select 种重复、琐碎(将来可能增加到7家分公司)、容易出错(比 如粘贴位置)的工作,而且当各个分公司的定向井服务队没 有工作量时,当天的汇总表中会出现很多空白行,影响报表 的美观及浏览效率。 通过Excel VBA编程,则能有效地解决上述问题,而且 选择单元格区间 Selection.Copy 对选择的内容进行复制 Application.WindowState=xlMinimized 结合Windows的任务计划程序,实现了水平井生产日报表的 自动、高效、准确的生成。 当前工作表:zjy2012—3-21.xls最小化 Windows C中原油田定向井水平井技术公司生产情况日报 表1.xls”).Activate 2设计开发过程 2.1思路 将汇总表激活为当前工作表 Range C B6”).Select 选择粘贴的位置 设计思路如图1所示。 ActiveSheet.Paste 完成工作表粘贴 Application.WindowState=xlMinimized I固定日期报表合并卜÷}动态日期报表合并卜—刮删除重复内容 L———————————————————————. — . ..~r—————————————]‘---------------—-—-—-.---.-.—-—-——--.--—---.-—-—-—--一r—————————————]r——————————] l删除空白行及排序卜÷l打印报表上传情况卜 l VBA源程序分I 图1设计思路 将包含了钻井院当天报表内容的汇总表最小化 Set wb=Nothing 将变量清零 Set wb=Workbooks.Open(”iA定向井报表、一公司定向 2.2固定日期报表的合并 作者简介:杨廷福(1966一),男,工程师,研究方向:编程、 网络维护及应用;王会梅(1967一),女,助理工程师,研究 分别进入到钻井院、一公司等5个分公司2012年3月份 文件夹下,打开当天(2012年3月21日)的报表,为保证同 时打开的文件不能同名,钻井院当天的日报命名为zjy2012—3— 方向:图书管理。 收稿日期:2012—08—10 |_ 电脑编程技巧与维护 井水平井生产日报表 ̄2012—3\1gs2012—3—21.xls”) 打开一公司当天的报表:lgs2012—3—21.xls并赋给变量wb 一一 完成一公司当天的报表复制粘贴、最小化,同理 完成其他3个分公司的当天的报表复制粘贴,需要注意的: 一是复制的单元格区间因各分公司包含的定向队多少不同而 不同,二是在汇总表上粘贴的位置是不同的:既不能重复粘 贴也不能漏粘贴,粘贴内容要一一衔接好。 ActiveSheet.Range(”b2”).Select ActiveWorkbook.SaveAs”i:\定向井报表\汇总表 ̄2012— 3\2012-3-21.xls” 将包含了5个分公司当天报表的汇总表以文件名:2012一 3-21.xls另存在汇总表的2012—3子文件夹下。 Workbooks.Close 所有工作簿关闭 2.3当前日期的提取 通过工作簿打开事件,来提取当前日期,并获得当前日 期为星期几,代码如下: Private Sub WorkbookOpen 0 通过工作簿打开事件实现日期的提取 Dim today As Date,WeekdayC As Integer,WeekdayS As String 定义变量 today=Date WeekdayC=Weekday(today,vbMonday) WeekdayS=WeekdayName(WeekdayC,False,vbMonday) 上述语句为变量赋值 MsgBox”当前日期If1&Date&”,当前时间:”&Time 在当前屏幕显示当前日期及当前时间对话框 Range(”c2”)=Year(Date)&”年” Range(”d2”)=Month(Date)&”月”&Day(Date) &”日” Range C e2”、=WeekdayS 在汇总表相关位置填入日期及星期几 End Sub 如图2所示生成水平井生产情况日报表。 ¨ 4粕g静 * 虢 * 张| ∞∞ g强%懒 }I【 h . }I t ㈣ 图2水平井生产情况日报表(空白表) 2.4动态日期报表的合并 为实现生产日报表的合并,在用户端5个分公司必须将 当天的生产报表上传到FTP服务器的指定目录下、相关单位、 对应月份的子文件夹下,并且以分公司名称前三字汉字拼音 的声母加上当日日期组成。比如钻井院分公司2012年3月23 日的报表上传的路径为:钻井院水平井生产日报表k2012— 3 y2012—3—23.xls;一公司2012年3月23日的报表上传的路 径为:一公司定向井水平井生产日报表L2012—3\1gs2012—3— 23.xls;其他3个公司依此类推。在服务器端,则必须分别到所 属5个分公司当月子文件夹中打开当天的Excel文件,进行复 制粘贴。要实现动态日期报表的合并,服务器端就必须能够 打开含有动态路径及动态文件名(均是日期的函数)的Excel 文档,自然地想到利用Format函数,代码如下: DimwbAsWorkbook On Error Resume Next 错误忽略语句 Dim dt As String,dtl As String Dim mypath As String,mywb As String 定义4个字符串变量 dt=Format(Date,”yyyy-m”) dtl=Format(Date,”YYYY—m—d”) mypath:”\It&dt&”、’’ mywb=dtl&”.xls” 分别为4个变量赋值 Application.WindowState=xlMinimized Set wb=Workbooks.Open C i:\定向井报表\钻井院水平 井日报表”&mypath&”zjy”&mywb) Range C b6:aal4”).Select Selection.Copy Application.WindowState=xlMinimized Windows C中原油田定向井水平井技术公司生产情况日报 表4.xls”).Activate Range C B6”).Select ActiveSheet.Paste Application.WindowState=xlMinimized Set wb=Nothing Set wb=Workbooks.Open C i:\定向井报表、一公司定向 井水平井生产日报表”&mypath&”lgs”&mywb) 以同样的方式完成其他3家分公司的报表 复制粘贴 ActiveSheet.Range C b2”).Select ActiveWorkbook.SaveAs”i:\定向井报表\汇总表”& mypath&mywb 将5个分公司合并后的报表以当前动态的文件名存放在: 汇总表\动态月份的路径中。 Workbooks.Close 2.5解决重复行问题 复制粘贴时Excel重复行(重复内容)的出现的根源在于 当一个Excel文档不存在时,系统会把上一个Excel文档粘贴 在不存在文档应该粘贴的位置,当有n家分公司没有上传报 表时,系统会将前一家的数据重复粘贴n次。以下语句解决 此问题: Dim d As Object Dim an",alTn Dim k&.temp 在程序开头位置加上新定义的5个变量 Application.ScreenUpdating=False 在5家分公司报表完成复制粘贴后加入这些语句 arr=ActiveSheet.UsedRange.Value Set d=CreateObject C scripting.dictionary”1 For k=2ToUBound(art) l temp=Join(Application.Index(all7,k),” Tf d.Exists(temp)Then d(temp&k)=”1..&k Else S0 rWARE DEVEL0PMENT AND DESIGN d(temp)=… EndIf Next k arm=Filter(d.Items,” For k=UBound(arm)To 0 Step一1 Rows(Replace(arm(k),” ,…’)).Delete Next k Application.ScreenUpdating=True 2.6删除空白行及排序 由于各分公司的定向队不可能总是有工作量,或者整个 分公司某日就没有工作量,甚至几个分公司均没有工作量, 反映在汇总表上则是有很多空白行,既影响美观也影响浏览 效率,为此,用以下语句: Dim xh As Integer 在程序开头加入此语句 Range(”d6:d35”).SpecialCells(xlCellTypeBlanks).En— tireROW.Delete 在上述2.5完成重复内容删除后,删除d6:d35实质数据区 内空白单元格所在行 Range C a6:a35”)=”” 序号所在列清除为空白 For xh=6 To Range C d65536”) End(xlUp).Row Cells(xh,1)=xh一5 Next xh 实现报表合并且清除重复内容、清除空白行后的排序 2.7在汇总表中显示报表递送情况 为了在汇总表中合适位置显示当日哪些分公司传递了报 表,哪些分公司没有上传报表,用以下语句: Dim wbs As Integer,XXX As Integer 在程序开始位置定义两个整型变量 在上述2.6实现排序后,加入以下语句 XXX=Range(”d65536”).End(xlUp).Row+2 XXX为d列数据区下第2个空白单元格所在行数 For wbs=l To Workbooks.Count If Workbooks(wbs).Name=”zjy”&mywb Then Cells(XXX,”b”)=”钻井院”&Date&”已上报” Elself Workbooks(wbs).Name=”lgs”&mywb Then Cells(xxx,”e”)=”一公司”&Date&”已上报” Elself Workbooks(wbs).Name=”2gs”&mywb Then Cells(xxx,”h”)=”二公司”&Date&”已上报” Elself Workbooks(wbs).Name=”3gs”&mywb Then Cells(XXX,”l”)=”三公司”&Date&”已上报” Elself Workbooks(wbs).Name:”4gs”&mywb Then Cells(xxx,”P”)=”四公司”&Date&”已上报” Else 增加此语句让程序更严谨 Cells(XXX,”b”)=”钻井院”&Date&”未上报” Cells(xxx,”e”)=”一公司”&Date&”未上报” Cells(XXX,”h”)=”二公司”&Date&”未上报” Cells(xxx,”l”)=”三公司”&Date&”未上报” Ceils(xxx,”P”)=”四公司”&Date&”未上报” EndIf Nextwbs 2.8实现VBA源程序与汇总表(纯数据)的分离 为了完全及规范,提供给用户使用的应该是不包含VBA 源程序的纯数据报表。只要将经过报表合并等系列处理过的 软件开发与设计 文档另存为纯数据格式的Excel文档,而原文档仍然是包含有 VBA程序的只有空白表格的Excel文档,供下次继续使用。 Application.DisplayAlerts=False ActiveWorkbook.SaveAs”i:\定向井报表\汇总表”& mypath&mywb.FileFormat:=xlOpenXMLWorkbook 另存为纯数据格式的Excel文档 Application.DisplayAlerts=True 3 实现水平井生产日报表的定时自动生成 利用Excel工作簿打开事件及Windows的任务计划程序可 实现生产日报表的定时自动生成功能。 3.1水平井生产日报表的合并 要完成生产日报表合并的顺利执行,程序运行中间不能 产生对话框,比如要去掉这样的语句:MsgBox”当前日期:” &Date&”,当前时间:”&Time对于此问题只要在程序中该 语句前加上西文单引号(’)即可;然后把上面讨论的报表合 并程序名,比如aa 0(此前放在一模块中)输入到在上文2. 3中讨论的工作簿打开事件中动态日期提取语句的后面,也就 是程序结束语句end之前,在程序完全调试好后,这样在工作 簿打开时,就会自动进行报表的合并。 3.2实现生产日报表的定时自动生成 VBA本身是没有自动打开、执行功能的,利用Windows 的任务计划程序则可以。在Win7中,启动任务计划程序,在 新建任务的常规对话框的“名称”位置输入“水平井生产日 报表自动生成”,在新建触发器对话框中选择“每天”,开始 时间为2012年3月21日10:00:00,在新建操作对话框中, “操作”位置选“启动程序”,在“程序或脚本”位置选择 “定向井水平井生产日报表合并.xls”Excel文档,确定后输入 有管理员权限的的用户的密码即可。这样,系统每天1O点就 会自动打开“定向井水平井生产日报表合并.x 文档,从而 自动进行报表生成。 4 结语 以上利用VBA语句编程,结合Windows任务计划程序实 现了生产日报表的自动生成,迅速、高效、准确、人性化, 节省了专人的劳动。从固定日期报表合成一动态日期报表合 成一删除重复内容一删除空白行及排序一报表传送情况打 印一最后是实现VBA源程序与汇总表的分离,分步,分模块 进行直到最终完成,其编程思路可作借鉴。 参考文献 【1】赵志东.Excel VBA基础入门,第2版.北京:人民邮电 出版社,2011. 【2】Excel精英培训.WWW.excelpx.com. 【3]ExcelHOME论坛.W- ̄rW.excelhome.net. ,