ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 727|回复: 3

[求助] 数据汇总的代码不够完善,希望有老师能帮帮忙

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-11-29 09:14 | 显示全部楼层 |阅读模式
本帖最后由 Glazes 于 2019-11-29 09:16 编辑

因为工作需要,在网上东拼西凑了一个用于多账簿多表格汇总的代码,但有些功能没办法实现,希望有老师能帮我改进代码。

希望改进的地方:
1.目前只能忽略每个表的表头,希望能忽略每张表的表头和表尾,比如:表格的前一行和最后两行不需要。
2.目前只能默认从A1单元格开始粘贴,希望能自主选择粘贴位置,因为前三列有别的数据,比如说从C1开始粘贴。
3.希望能在粘贴原表数据时,在原始数据前面三列添加其他的原创数据,比如,序号,公司名称,时间等,不过不能实现也没关系,可以后期手动添加。

如果老师在修改代码的时候能在改进的地方加上备注就更好了。
  1. <p><p>Sub 多簿多表合并()
  2.      Dim MyPath, MyName, AWbName
  3.      Dim Wb As Workbook, WbN As String
  4.      Dim G As Long
  5.      Dim Num As Long
  6.      Dim BOX As String
  7.      zdm = Application.InputBox("请输入汇总要匹配的列字段名:")
  8.      Application.ScreenUpdating = False '关闭屏幕更新
  9.      MyPath = ThisWorkbook.Path
  10.      MyName = Dir(MyPath & "" & "*.xls*")
  11.      AWbName = ThisWorkbook.Name
  12.      
  13.      For Each CXrng In ActiveSheet.UsedRange '取消合并单元格
  14.         If CXrng.MergeCells Then
  15.             Set XRrng = CXrng.MergeArea
  16.             A = CXrng.MergeArea(1).Value
  17.             CXrng.UnMerge
  18.             XRrng.Value = A
  19.         End If
  20.      Next     </p><p>
  21. </p><p>     Sheet1.UsedRange.Offset(0, 3).Clear '清除*行*列之外的所有内容
  22.      'Columns.Clear '表单清除
  23.      
  24.      Num = 0
  25.      Do While MyName <> ""
  26.          If MyName <> AWbName Then
  27.              Set Wb = Workbooks.Open(MyPath & "" & MyName)
  28.              Num = Num + 1
  29.              With Workbooks(1).ActiveSheet
  30.                  
  31.                  For G = 1 To Wb.Sheets.Count
  32.                      Wb.Sheets(G).UsedRange.Offset(1, 0).Copy .Cells(.Range("a65536").End(xlUp).Row + n, 1)
  33.                      n = (n + 1) ^ 0
  34.                  Next
  35.                  Wb.Close False '关闭工作簿且不保存
  36.              End With
  37.          End If
  38.          MyName = Dir '寻找下一个工作簿
  39.      Loop
  40.      Myr = Cells(Rows.Count, 1).End(xlUp).Row
  41.      Set Rng = ActiveSheet.UsedRange.Find(What:=zdm)
  42.      l = Rng.Column
  43.      For I = Myr To 2 Step -1
  44.          If Cells(I, l) = zdm Then Rows(I).Delete
  45.      Next
  46.      Application.ScreenUpdating = True '恢复屏幕更新
  47.    
  48. End Sub</p>
复制代码


TA的精华主题

TA的得分主题

发表于 2019-11-29 09:43 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-11-29 11:54 | 显示全部楼层
有老师能帮帮忙吗?实在是搞不定了

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-11-29 15:12 | 显示全部楼层
microyip 发表于 2019-11-29 09:43
http://club.excelhome.net/thread-1310803-1-1.html 多表多工作簿汇总,参考变通一下

老师你好,我按照您的代码修改了一下,但是实在是完成不了,又是工作任务,能帮我看一下吗?
我修改后的数组查找,提示下标越界了

  1. Sub 数组查找工作簿汇总()
  2.     Dim vReadData As Variant '定义读取工作簿中表的数据的数组变量
  3.     Dim vData As Variant '定义读取工作簿中表的规范格式数据的数组变量
  4.     Dim wWB As Workbook '定义工作簿变量
  5.     Dim sPath As String '定义文件夹变量
  6.     Dim sFile As String '定义文件名变量
  7.     Dim nRow As Double '定义行数变量
  8.     Dim nCol As Integer '定义列数变量
  9.     Dim bAdd As Boolean '定义是否需要作为新记录添加的逻辑变量
  10.     Dim vFill As Variant '定义将要作为查询结果的数组变量
  11.     Dim nFill As Double '定义查询结果数组的行数的变量
  12.     Dim sName As String, sGas As Variant, sWater As Variant, sPliers As Variant, sGrab As Variant, sElectric As Variant, sCold As Variant, sSpray As Variant, sClip As Variant, sSilk As Variant, sKnife As Variant, sBall As Variant, sNet As Variant, sPipe As Variant, sOther As Variant, sTotal As Variant '*
  13.     Dim vTitle As Variant '定义标题变量
  14.    
  15.     Application.ScreenUpdating = False '禁止数据更新,避免因数据更新时引起闪屏,提高运行速度
  16.     vTitle = Split("采购商品名称|送气|送水|活检钳|抓钳|电圈套器|冷圈套器|喷洒管|夹子|导丝|切开刀|球囊|网篮|引流管|其他|合计", "|") '将所有标题用|隔开的字符串根据|分离成数组'*
  17.     sName = Trim([B1]) '获取查询商品名称的条件
  18.     sGas = Trim([B2])
  19.     sWater = Trim([B3])
  20.     sPliers = Trim([B4])
  21.     sGrab = Trim([B5])
  22.     sElectric = Trim([B6])
  23.     sCold = Trim([B7])
  24.     sSpray = Trim([B8])
  25.     sClip = Trim([B9])
  26.     sSilk = Trim([B10])
  27.     sKnife = Trim([B11])
  28.     sBall = Trim([B12])
  29.     sNet = Trim([B13])
  30.     sPipe = Trim([B14])
  31.     sOther = Trim([B15])
  32.     sTotal = [B16].Value
  33.    
  34.     ReDim vFill(1 To 16, 1 To 1) '定义一个4列1行的数组
  35.     '注意:正常填到表格内的数组是按(行,列)来定义的,因为考虑到行数将不断增加,而且数组只能是最后一个维度上进行变化,所以先将行定义在后面
  36.     Set wWB = ThisWorkbook '设置本工作簿的变量
  37.     sPath = wWB.Path & "" '获取本工作簿所在文件夹
  38.     sFile = Dir(sPath & "*.xls*") '查找sPath文件夹内的与xls有关后缀名的文件
  39.     Do While sFile <> "" '如果查找不到相关文件将会返回空字符串,找到的话,将返回文件名的全名
  40.         If sFile <> ThisWorkbook.Name Then '如果找到的文件名不等于本工作簿的文件名
  41.             With Workbooks.Open(sPath & sFile)  '打开工作簿sFile
  42.                 vReadData = .Sheets(1).UsedRange.Value '将第一个表的所有已用单元格的数值赋值给数组
  43.                 .Close False '关闭工作簿sFile
  44.             End With
  45.             vData = 规范数据格式(vReadData, vTitle) '如果所有工作簿内数据格式一致,可以跳过本步,上一步的赋值给vReadData的时候直接赋值给vData即可
  46.             For nRow = 4 To UBound(vData) 'vData中,第1行是标题,故从2行开始读取数据
  47.                 bAdd = True '初始化变量为真
  48.                 If sName <> "" Then bAdd = bAdd And (vData(nRow, 1) = sName)
  49.                 '假如存在姓名条件,且姓名类似条件形式,为真,并跟bAdd进行与运算,例如:条件是”张“,那么”张三“就类似”*张*“
  50.                 If sGas <> "" Then bAdd = bAdd And (vData(nRow, 1) = sGas)
  51.                 'If sGas(1, 2) <> "" Then bAdd = bAdd And Application.Evaluate(vData(nRow, 2) & IIf(sGas(1, 1) = "", "=", sGas(1, 1)) & sGas(1, 2))
  52.                 'Evaluate是计算一个字符串形式的式子的值
  53.                 'IIf(vAge(1, 1) = "", "=", vAge(1, 1)) ,如果年龄的比较符号vAge(1, 1)没有被选择,默认使用等于号
  54.                 '整个语句就是当条件中有年龄条件数值,对比数据中年龄vData(nRow, 2)是否符合条件
  55.                 If sWater <> "" Then bAdd = bAdd And (vData(nRow, 1) = sWater)
  56.                 '假如存在籍贯条件,且籍贯与条件相同,为真,并跟bAdd进行与运算
  57.                 If sPliers <> "" Then bAdd = bAdd And (vData(nRow, 1) = sPliers)
  58.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  59.                 If sGrab <> "" Then bAdd = bAdd And (vData(nRow, 1) = sGrab)
  60.                 '假如存在籍贯条件,且籍贯与条件相同,为真,并跟bAdd进行与运算
  61.                 If sElectric <> "" Then bAdd = bAdd And (vData(nRow, 1) = sElectric)
  62.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  63.                 If sCold <> "" Then bAdd = bAdd And (vData(nRow, 1) = sCold)
  64.                 '假如存在籍贯条件,且籍贯与条件相同,为真,并跟bAdd进行与运算
  65.                 If sSpray <> "" Then bAdd = bAdd And (vData(nRow, 1) = sSpray)
  66.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  67.                 If sClip <> "" Then bAdd = bAdd And (vData(nRow, 1) = sClip)
  68.                 '假如存在籍贯条件,且籍贯与条件相同,为真,并跟bAdd进行与运算
  69.                 If sSilk <> "" Then bAdd = bAdd And (vData(nRow, 1) = sSilk)
  70.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  71.                 If sKnife <> "" Then bAdd = bAdd And (vData(nRow, 1) = sKnife)
  72.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  73.                 If sBall <> "" Then bAdd = bAdd And (vData(nRow, 1) = sBall)
  74.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  75.                 If sNet <> "" Then bAdd = bAdd And (vData(nRow, 1) = sNet)
  76.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  77.                 If sPipe <> "" Then bAdd = bAdd And (vData(nRow, 1) = sPipe)
  78.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  79.                 If sOther <> "" Then bAdd = bAdd And (vData(nRow, 1) = sOther)
  80.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  81.                 If sTotal <> "" Then bAdd = bAdd And (vData(nRow, 1) = sTotal)
  82.                 '假如存在区域条件,且区域与条件相同,为真,并跟bAdd进行与运算
  83.                 If bAdd Then '假如条件符合判断逻辑变量bAdd为真时
  84.                     nFill = nFill + 1 '为查询数据数组的行数增加一行
  85.                     ReDim Preserve vFill(1 To 4, 1 To nFill) '为增加一行的查询数据数组重定义
  86.                     For nCol = 1 To 4
  87.                         vFill(nCol, nFill) = vData(nRow, nCol) '复制符合条件的一行数据到查询数据数组最后一行上
  88.                     Next
  89.                 End If
  90.             Next
  91.         End If
  92.         sFile = Dir '查询一个符合条件的文件
  93.     Loop
  94.     ThisWorkbook.Activate '本工作簿激活为使用状态
  95.     With Sheets("sheet1") '对”汇总“表进行操作
  96.         .[F:U].ClearContents '清空汇总表内的F:I列数据
  97.         .[F1:U1] = Split("采购商品名称,送气,送水,活检钳,抓钳,电圈套器,冷圈套器,喷洒管,夹子,导丝,切开刀,球囊,网篮,引流管,其他,合计", ",") '通过以逗号为拆分词来拆分字符串所得数组赋值给F1:I1单元格作为标题
  98.         If nFill > 0 Then '假如查询数据数组的记录行数大于0,即表示有数据
  99.             .[F2].Resize(nFill, 4) = Application.WorksheetFunction.Transpose(vFill)
  100.             '因为前面定义vFill时按(列,行)定义的,需要通过系统的转置函数Transpose转置为(行,列)数组
  101.             '赋值给由F2开始变形为nFill行,4列的单元格区域
  102.         End If
  103.     End With '结束对”汇总“表进行操作
  104.     Application.ScreenUpdating = True
  105. End Sub

  106. Function 规范数据格式(vReadData As Variant, vTitle As Variant) As Variant
  107. '将数据规范为一定格式,本例中的格式是:姓名、年龄、籍贯、区域
  108.     Dim oDic As Object '定义字典对象变量
  109.     Dim nRow As Double, nCol As Integer, nNewCol As Integer
  110.     Dim vData As Variant '定义数据规范的数组
  111.    
  112.     Set oDic = CreateObject("Scripting.Dictionary") '定义oDic为字典变量
  113.     '注意:标题的数量要与vReadData数组对应
  114.     For nRow = LBound(vTitle) To UBound(vTitle) '从数组的最低标号到最高标号循环
  115.         oDic(vTitle(nRow)) = nRow + 1 '以标题为关键字的字典,赋值对应于标题数组的标号
  116.     Next
  117.     vData = vReadData '令vData与vReadData具有同样容量的数组
  118.     For nCol = 1 To UBound(vReadData, 2) '列号从1到vReadData第二维最高标号,即最右的列号
  119.         nNewCol = oDic(vReadData(1, nCol)) '从vReadData标题行的标题获取数据规范的所在列
  120.         For nRow = 2 To UBound(vReadData) '列号从2到vReadData第一维最高标号,即最下的行号
  121.             vData(nRow, nNewCol) = vReadData(nRow, nCol) '把vReadData赋值到数据规范的数组
  122.         Next
  123.     Next
  124.     规范数据格式 = vData '返回规范数据的数组
  125. End Function
复制代码
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-24 07:14 , Processed in 0.036876 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表