【VBA】通过VBA自动解析指定工作薄,生成自己需要的数据表
2015-05-16 00:25
453 查看
最近使用VBA自动处理EXCEL的数据,用着用着觉得很方便,于是写了一些小脚本,不过水平有限,代码很冗余。
个人使用的脚本一般都是符合个人使用的特定场景,不像高手写的有很强的复用性。
不过既然写了,方便了个人的同时,我还是抛砖引玉分享一下,万一能帮到人呢!同时自己也留个备忘。
这里主要是:传播一种使用脚本解决重复性、简单、单调工作时,主动去寻找使用脚本解决的思想。
本案例需求是将图2中的数据按照图四的样式展开,同时生成一个目录页,所以写了这个脚本用来一键生成。
附上脚本的一部分:
需要同步数据的表格式如图2:
同步过来生成的结果如图3:
映射标的模板如图4:
个人使用的脚本一般都是符合个人使用的特定场景,不像高手写的有很强的复用性。
不过既然写了,方便了个人的同时,我还是抛砖引玉分享一下,万一能帮到人呢!同时自己也留个备忘。
这里主要是:传播一种使用脚本解决重复性、简单、单调工作时,主动去寻找使用脚本解决的思想。
本案例需求是将图2中的数据按照图四的样式展开,同时生成一个目录页,所以写了这个脚本用来一键生成。
附上脚本的一部分:
Sub lianjie() '在首页生成每个sheet页的超链接 Dim x As Long x = 0 For x = 5 To Sheets.Count Sheets(3).Select '我的首页设在第三页,所以选中第三页 Sheets(3).Hyperlinks.Add Anchor:=Cells(9 + x, 4), Address:=ActiveWorkbook.Name, SubAddress:=Sheets(x).Name & "!A1", TextToDisplay:=Sheets(x).Name Next End Sub '写入表名,这里说一下使用场景,我需要从另个工作薄中获取每个sheet页(sheet页模板在我的<span style="font-size:12px;"><span class="link_title"><a target=_blank href="http://blog.csdn.net/zutsoft/article/details/45441343">EXCEL通过VBA生成SQL,自动生成创建表结构SQL</a></span></span> 博文里给出了) '存在指定位置的数据库表名,每次手工一页一页复制很累,所以写个脚本同步过来 Sub Write_Tablename() Dim x As Long '声明变量x,用来循环 str_source = "" x = 0 For x = 5 To Sheets.Count str_source = Trim(Sheets(3).Cells(9 + x, 5)) '获取源表名,源表名位于从第9行开始的第五列。 If str_source <> "" Then '如果源标记不为空 '截取前四位和元标记+‘_’对比 If Left(str_source, 4) = Trim(Sheets(3).Cells(11, 2)) & "_" Then '从左边截取4位 str_temp = Mid(str_source, 5) '截取第5位到字符串尾 Else str_temp = str_source End If str_target = "TS_" & Trim(Sheets(3).Cells(11, 2)) & "_" & str_temp '去除空格,生成“TS_源标记_表名”格式的ts层表名 str_mapping = LCase("m_" & Trim(Sheets(3).Cells(11, 2)) & "_ts_" & str_temp) '生成 “m_源标记_ts_表名” 格式的infamatica使用的mapping 名 Sheets(3).Cells(9 + x, 6) = str_target Sheets(3).Cells(9 + x, 7) = str_mapping Sheets(x).Cells(7, 3) = str_source Sheets(x).Cells(7, 10) = str_target End If Next End Sub '生成序号,图三中的序号 Sub create_index() Dim line As Integer, sheet_index As Integer, index As Integer For sheet_index = 5 To Sheets.Count index = 1 For i = 0 To 200 If Trim(Sheets(sheet_index).Cells(10 + index, 9)) <> "" Then Sheets(sheet_index).Select Sheets(sheet_index).Cells(10 + index, 1) = index Sheets(sheet_index).Cells(10 + index, 1).HorizontalAlignment = xlCenter '设置水平方向居中对齐 Sheets(sheet_index).Cells(10 + index, 1).VerticalAlignment = xlCenter '垂直方向居中对齐 ActiveSheet.Range(Cells(11, 1), Cells(10 + index, 16)).Borders.LineStyle = 1 '将有数据的范围画上边框 ActiveSheet.Range(Cells(11, 8), Cells(10 + index, 8)).Merge '中间的列作为分割线,做合并处理 index = index + 1 End If Next Next End Sub '插入etl 使用的字段 Sub insert_etl_row() Dim sheet_index As Integer, index As Integer For sheet_index = 5 To Sheets.Count index=0 For i = 0 To 200 If Trim(Sheets(sheet_index).Cells(10 + index, 9)) <> "" Then index = index + 1 End If Next If Sheets(sheet_index).Cells(7 + index, 9) <> "C_SOURCENO" Then '如果倒数第三行已经是C_SOURCENO,则不需要插入etl字段 Sheets(sheet_index).Cells(10 + index, 9) = "C_SOURCENO" Sheets(sheet_index).Cells(10 + index, 10) = "采集源代码" Sheets(sheet_index).Cells(10 + index, 11) = "N" Sheets(sheet_index).Cells(10 + index, 12) = "C" Sheets(sheet_index).Cells(10 + index, 13) = "2" Sheets(sheet_index).Cells(11 + index, 9) = "D_DATADATE" Sheets(sheet_index).Cells(11 + index, 10) = "数据日期" Sheets(sheet_index).Cells(11 + index, 11) = "N" Sheets(sheet_index).Cells(11 + index, 12) = "D" Sheets(sheet_index).Cells(11 + index, 13) = "8" Sheets(sheet_index).Cells(12 + index, 9) = "C_ROWFLAG" Sheets(sheet_index).Cells(12 + index, 10) = "行标志" Sheets(sheet_index).Cells(12 + index, 11) = "N" Sheets(sheet_index).Cells(12 + index, 12) = "C" Sheets(sheet_index).Cells(12 + index, 13) = "1" End If Next End Sub '一键同步源表数据,做一定的转换,生成我需要的数据表格式 Sub Create_TableFrame() Dim x As Long str_temp = "" x = 0 worksheetname = "平台表结构设计.xls" If WorkbookOpen(worksheetname) Then '判断需要读取的工作薄是否打开,未打开则提示需要打开。 For x = 2 To Workbooks(worksheetname).Sheets.Count '源表工作表循环 '获取表名 str_temp = Workbooks(worksheetname).Sheets(x).Cells(3, 3) '获取另一个数据表的sheet页的第3行第3列 Sheets(3).Cells(12 + x, 5) = str_temp '将值付给当前活动sheet页里的指定位置 str_sheet_name = Workbooks(worksheetname).Sheets(x).Name '获取另一个数据表的sheet页的名字 If str_sheet_name <> "" Then '如果sheet名不为空 '生成sheet页 Sheets("模板").Copy After:=Worksheets(Worksheets.Count) '复制并新建sheet页,将sheet排在当前工作表的最后面(实质是一个接一个的排列在后面) ActiveSheet.Name = str_sheet_name '重命名复制的sheet页 '填写接口名称 ActiveSheet.Cells(2, 3) = str_sheet_name str_sheet_name = "" '获取主键 ActiveSheet.Cells(8, 3) = Workbooks(worksheetname).Sheets(x).Cells(5, 3) ActiveSheet.Cells(8, 10) = Workbooks(worksheetname).Sheets(x).Cells(5, 3) For i = 2 To 100 '获取字段 line_temp = Workbooks(worksheetname).Sheets(x).Cells(13 + i, 2) If line_temp <> "" Then ActiveSheet.Cells(9 + i, 2) = line_temp ActiveSheet.Cells(9 + i, 9) = line_temp '获取类型 type_temp = Workbooks(worksheetname).Sheets(x).Cells(13 + i, 3) '数据类型的处理 pos1 = 0 data_temp = UCase(Trim(type_temp)) If data_temp <> "" Then pos1 = InStr(1, data_temp, "(") If pos1 = 0 Then str_type = "DATE" Else str_type = Left(data_temp, pos1 - 1) str_num = Mid(data_temp, pos1 + 1) str_num = Replace(str_num, ")", "") End If Select Case str_type Case "VARCHAR2" ActiveSheet.Cells(9 + i, 5) = "VC" ActiveSheet.Cells(9 + i, 6) = str_num Case "NUMBER" ActiveSheet.Cells(9 + i, 5) = "N" pos2 = InStr(1, str_num, ",") If pos2 = 0 Then ActiveSheet.Cells(9 + i, 6) = str_num Else ActiveSheet.Cells(9 + i, 6) = Left(str_num, pos2 - 1) ActiveSheet.Cells(9 + i, 7) = Mid(str_num, pos2 + 1) End If Case "CHAR" ActiveSheet.Cells(9 + i, 5) = "C" ActiveSheet.Cells(9 + i, 6) = str_num Case "DATE" ActiveSheet.Cells(9 + i, 5) = "D" Case Default data_temp = "error" '只要上面未匹配就认为错误 End Select End If '数据类型处理完毕 '是否为空 ActiveSheet.Cells(9 + i, 4) = Workbooks(worksheetname).Sheets(x).Cells(13 + i, 4) '获取中文解释 ActiveSheet.Cells(9 + i, 3) = Workbooks(worksheetname).Sheets(x).Cells(13 + i, 6) ActiveCell.EntireRow.AutoFit ActiveSheet.Cells(9 + i, 10) = Workbooks(worksheetname).Sheets(x).Cells(13 + i, 6) ActiveCell.EntireRow.AutoFit '是源表的字段复制到映射的目标表字段同步 ActiveSheet.Cells(9 + i, 11) = ActiveSheet.Cells(9 + i, 4) ActiveSheet.Cells(9 + i, 12) = ActiveSheet.Cells(9 + i, 5) ActiveSheet.Cells(9 + i, 13) = ActiveSheet.Cells(9 + i, 6) ActiveSheet.Cells(9 + i, 14) = ActiveSheet.Cells(9 + i, 7) End If '字段名不为空 Next '循环1 to 100 每页假设有100个字段 End If '如果sheet名不为空 Next '源表工作表循环 '调用之前的函数,达到一键生成的目的 Call VBAProject.模块3.insert_etl_row Call VBAProject.模块3.create_index '生成超链接时,是页面回到目录页,我的工作表的第三页 Sheets(3).Select Call VBAProject.模块3.Write_Tablename Call VBAProject.模块3.lianjie '提示信息 MsgBox "同步成功" Else MsgBox "请打开" & worksheetname & "!" End If End Sub Function WorkbookOpen(ByVal WorkBookName As String) As Boolean '如果该工作簿已打开则返回真 WorkbookOpen = False On Error GoTo WorkBookNotOpen If Len(Application.Workbooks(WorkBookName).Name) > 0 Then WorkbookOpen = True 'MsgBox "该工作簿已打开" Exit Function End If WorkBookNotOpen: End Function目录页格式如图1:
需要同步数据的表格式如图2:
同步过来生成的结果如图3:
映射标的模板如图4:
相关文章推荐
- python从共享目录读取考勤数据,通过openpyxl解析excel2007,查询出自己考勤记录
- 通过数据库表自动生成POJO(JavaBean)对象
- form表单通过GET提交的数据自动生成的链接地址如何伪静态化处理
- xfire框架构建webservice应用(通过myeclipse自动生成代码,自动导入xfire jar包,需要用jdk5.0)
- shell 抓取网页解析网页 自动读取poj测试数据——V2生成 pku poj acm编程模版
- JEECG t:autocomplete 自动补全, 生成自己需要展示格式
- ElasticSearch5:Document id的手动指定和自动生成两种解析
- 【VBA】EXCEL通过VBA生成SQL,自动生成创建表结构SQL
- linux上mysql数据备份并自动通过附件发送到指定邮箱
- Django学习笔记(二)--通过model自动生成数据表
- Greendao 简单实现增删改查使用过GreenDao的同学都知道,3.0之前需要通过新建GreenDaoGenerator工程生成Java数据对象(实体)和DAO对象,非常的繁琐而且也加大了使用成
- 通过数据自动生成流程图(前端)
- 将表中的数据自动生成INSERT语句的存储过程,自己收藏一下
- 利用动软代码生成器 自动生成LINQ需要用的数据实体类
- 使用GSON来解析和生成JSON基础,通过传入List集合自动生成json字符串(一)
- 编程实现用户名和密码自动生成【可以自己指定长度】
- 减少重复工作,通过 Annotation Processor 自动完成源码的生成
- Windows下通过FTP自动备份数据到服务器并删除指定天数前的备份
- VOC数据提取自己需要的类生成XML标签