Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 6762|回复: 21

[已解决]工程明细数

[复制链接]
发表于 2012-12-18 13:59 | 显示全部楼层 |阅读模式
10学分
老师们,谢谢了,sheet2是我想要的表
最佳答案
2012-12-18 16:31
  1. Option Explicit

  2. Sub 合并数据()
  3.     Dim data
  4.     '读源数据
  5.     With Worksheets("Sheet1")
  6.         data = .Range("a1").CurrentRegion
  7.     End With

  8.     '字典,装数据和列类别
  9.     Dim dic As Object, dicItem As Object
  10.     Set dic = CreateObject("scripting.dictionary")
  11.     Set dicItem = CreateObject("scripting.dictionary")

  12.     Dim arr1
  13.     arr1 = Array("餐费", "早餐", " 午餐", "晚餐", "夜宵", "生活用品", "煤气", "宽带费", _
  14.     "车费", "住宿费", "修理费", "工具费", "招待费", "水电", "项目检查费", "人情费", "合计", "联系人姓名", "联系人电话", "备注")
  15.    
  16.     '定义列坐标
  17.     Dim t, i&
  18.     For Each t In arr1
  19.         i = i + 1
  20.         dicItem(t) = i
  21.     Next
  22.     '以A|B列数据为KEY
  23.     Dim StrKey$
  24.     Dim Result(), iPos&
  25.     For i = LBound(data) + 1 To UBound(data)    '第一行为标题
  26.         StrKey = data(i, 1) & "|" & data(i, 2)
  27.         If Not dic.exists(StrKey) Then      '检测字典中是否存在Strkey
  28.             ReDim Result(1 To dicItem.Count)
  29.             iPos = dicItem(data(i, 3))      '取列坐标
  30.             Result(iPos) = data(i, 4)       '写入数据
  31.             'If iPos > 1 And iPos < 6 Then Result(1) = data(i, 4)
  32.             Result(dicItem.Count) = data(i, 5)  '备注
  33.             dic(StrKey) = Result                '写入字典
  34.         Else
  35.             Result = dic(StrKey)                '取数组
  36.             iPos = dicItem(data(i, 3))          '坐标
  37.             Result(iPos) = Result(iPos) + data(i, 4)    '累加
  38.             'If iPos > 1 And iPos < 6 Then Result(1) = Result(1) + data(i, 4)
  39.             Result(dicItem.Count) = data(i, 5)  '备注
  40.             dic(StrKey) = Result                '写回字典
  41.         End If
  42.     Next
  43.    
  44.     '结果数据写入Sheet3
  45.     With Worksheets("Sheet3")
  46.         i = .Cells(Rows.Count, 1).End(xlUp).Row '取最后一行数据位置
  47.         If i > 3 Then .Range("a4:aa" & i).ClearContents '4为第一行数据位置
  48.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))    '数据经过2次转置变成2维数组
  49.         .Range("h4").Resize(UBound(Result), UBound(Result, 2)) = Result                 '写入到H4
  50.         
  51.         '把KEY转变成一维数组,存入对应的ITEM
  52.         For Each t In dic.keys
  53.             dic(t) = Split(t, "|")
  54.         Next
  55.         
  56.         'Items经过2次转换变成2维数组
  57.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))
  58.         .Range("a4").Resize(UBound(Result), UBound(Result, 2)) = Result '写入A4
  59.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  60.         '添加边框
  61.         With .Range("a4:aa" & i).Borders
  62.             .LineStyle = xlContinuous
  63.         End With
  64.     End With
  65. End Sub
复制代码

工程明细表.rar

3.79 KB, 下载次数: 32

发表于 2012-12-18 16:22 | 显示全部楼层
  1. Sub 合并数据()
  2.     Dim data
  3.     With Worksheets("Sheet1")
  4.         data = .Range("a1").CurrentRegion
  5.     End With

  6.     Dim dic As Object, dicItem As Object
  7.     Set dic = CreateObject("scripting.dictionary")
  8.     Set dicItem = CreateObject("scripting.dictionary")

  9.     Dim arr1

  10.     arr1 = Array("餐费", "早餐", " 午餐", "晚餐", "夜宵", "生活用品", "煤气", "宽带费", "车费", "住宿费", "修理费", "工具费", "招待费", "水电", "项目检查费", "人情费", "合计", "联系人姓名", "联系人电话", "备注")
  11.     Dim t, i&
  12.     For Each t In arr1
  13.         i = i + 1
  14.         dicItem(t) = i
  15.     Next
  16.     Dim StrKey$
  17.     Dim Result(), iPos&
  18.     For i = LBound(data) + 1 To UBound(data)
  19.         StrKey = data(i, 1) & "|" & data(i, 2)
  20.         If Not dic.exists(StrKey) Then
  21.             ReDim Result(1 To dicItem.Count)
  22.             iPos = dicItem(data(i, 3))
  23.             Result(iPos) = data(i, 4)
  24.             'If iPos > 1 And iPos < 6 Then Result(1) = data(i, 4)
  25.             Result(dicItem.Count) = data(i, 5)
  26.             dic(StrKey) = Result
  27.         Else
  28.             Result = dic(StrKey)
  29.             iPos = dicItem(data(i, 3))
  30.             Result(iPos) = Result(iPos) + data(i, 4)
  31.             'If iPos > 1 And iPos < 6 Then Result(1) = Result(1) + data(i, 4)
  32.             Result(dicItem.Count) = data(i, 5)
  33.             dic(StrKey) = Result
  34.         End If
  35.     Next

  36.     With Worksheets("sheet3")
  37.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  38.         If i > 3 Then .Range("a4:aa" & i).ClearContents
  39.         '.Range("a1").ClearContents
  40.         '.Range("c1").Resize(, UBound(arr1) + 1) = arr1
  41.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))
  42.         .Range("h4").Resize(UBound(Result), UBound(Result, 2)) = Result
  43.         For Each t In dic.keys
  44.             dic(t) = Split(t, "|")
  45.         Next
  46.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))
  47.         .Range("a4").Resize(UBound(Result), UBound(Result, 2)) = Result
  48.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  49.         With .Range("a4:aa" & i).Borders
  50.             .LineStyle = xlContinuous
  51.         End With
  52.     End With
  53. End Sub
复制代码
回复

使用道具 举报

发表于 2012-12-18 16:23 | 显示全部楼层
工程明细表.rar (22.57 KB, 下载次数: 5)
回复

使用道具 举报

发表于 2012-12-18 16:23 | 显示全部楼层
楼主,数据录入时候还是规范点,不要在数据前面加上空格之类的。
回复

使用道具 举报

发表于 2012-12-18 16:31 | 显示全部楼层    本楼为最佳答案   
  1. Option Explicit

  2. Sub 合并数据()
  3.     Dim data
  4.     '读源数据
  5.     With Worksheets("Sheet1")
  6.         data = .Range("a1").CurrentRegion
  7.     End With

  8.     '字典,装数据和列类别
  9.     Dim dic As Object, dicItem As Object
  10.     Set dic = CreateObject("scripting.dictionary")
  11.     Set dicItem = CreateObject("scripting.dictionary")

  12.     Dim arr1
  13.     arr1 = Array("餐费", "早餐", " 午餐", "晚餐", "夜宵", "生活用品", "煤气", "宽带费", _
  14.     "车费", "住宿费", "修理费", "工具费", "招待费", "水电", "项目检查费", "人情费", "合计", "联系人姓名", "联系人电话", "备注")
  15.    
  16.     '定义列坐标
  17.     Dim t, i&
  18.     For Each t In arr1
  19.         i = i + 1
  20.         dicItem(t) = i
  21.     Next
  22.     '以A|B列数据为KEY
  23.     Dim StrKey$
  24.     Dim Result(), iPos&
  25.     For i = LBound(data) + 1 To UBound(data)    '第一行为标题
  26.         StrKey = data(i, 1) & "|" & data(i, 2)
  27.         If Not dic.exists(StrKey) Then      '检测字典中是否存在Strkey
  28.             ReDim Result(1 To dicItem.Count)
  29.             iPos = dicItem(data(i, 3))      '取列坐标
  30.             Result(iPos) = data(i, 4)       '写入数据
  31.             'If iPos > 1 And iPos < 6 Then Result(1) = data(i, 4)
  32.             Result(dicItem.Count) = data(i, 5)  '备注
  33.             dic(StrKey) = Result                '写入字典
  34.         Else
  35.             Result = dic(StrKey)                '取数组
  36.             iPos = dicItem(data(i, 3))          '坐标
  37.             Result(iPos) = Result(iPos) + data(i, 4)    '累加
  38.             'If iPos > 1 And iPos < 6 Then Result(1) = Result(1) + data(i, 4)
  39.             Result(dicItem.Count) = data(i, 5)  '备注
  40.             dic(StrKey) = Result                '写回字典
  41.         End If
  42.     Next
  43.    
  44.     '结果数据写入Sheet3
  45.     With Worksheets("Sheet3")
  46.         i = .Cells(Rows.Count, 1).End(xlUp).Row '取最后一行数据位置
  47.         If i > 3 Then .Range("a4:aa" & i).ClearContents '4为第一行数据位置
  48.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))    '数据经过2次转置变成2维数组
  49.         .Range("h4").Resize(UBound(Result), UBound(Result, 2)) = Result                 '写入到H4
  50.         
  51.         '把KEY转变成一维数组,存入对应的ITEM
  52.         For Each t In dic.keys
  53.             dic(t) = Split(t, "|")
  54.         Next
  55.         
  56.         'Items经过2次转换变成2维数组
  57.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))
  58.         .Range("a4").Resize(UBound(Result), UBound(Result, 2)) = Result '写入A4
  59.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  60.         '添加边框
  61.         With .Range("a4:aa" & i).Borders
  62.             .LineStyle = xlContinuous
  63.         End With
  64.     End With
  65. End Sub
复制代码
回复

使用道具 举报

发表于 2012-12-18 16:32 | 显示全部楼层
工程明细表.rar (23.18 KB, 下载次数: 8)
回复

使用道具 举报

发表于 2012-12-18 17:05 | 显示全部楼层
再来个数组的方法,效率应该比这高。
回复

使用道具 举报

 楼主| 发表于 2012-12-18 17:23 | 显示全部楼层
这个已经很好了,老师,学习了,谢谢
回复

使用道具 举报

 楼主| 发表于 2012-12-18 17:27 | 显示全部楼层
arr1 = Array("餐费", "早餐", " 午餐", "晚餐", "夜宵", "生活用品", "煤气", "宽带费", _

    "车费", "住宿费", "修理费", "工具费", "招待费", "水电", "项目检查费", "人情费", "合计", "联系人姓名", "联系人电话", "备注")

这一句中“宽带费", _   改成“宽带费", 这样可以吧,要不老是说这一句有问题
回复

使用道具 举报

发表于 2012-12-18 17:35 | 显示全部楼层
  1. Sub 合并数据2()
  2. '数组+字典解法
  3. '2012-12-18 hwc2ycy 17:33修改
  4.    
  5.     Dim data
  6.     '读源数据
  7.     With Worksheets("Sheet1")
  8.         data = .Range("a1").CurrentRegion
  9.     End With

  10.     '字典,装数据和列类别
  11.     Dim dic As Object, dicItem As Object
  12.     Set dic = CreateObject("scripting.dictionary")
  13.     Set dicItem = CreateObject("scripting.dictionary")

  14.     Dim arr1
  15.     arr1 = Array("餐费", "早餐", " 午餐", "晚餐", "夜宵", "生活用品", "煤气", "宽带费", _
  16.     "车费", "住宿费", "修理费", "工具费", "招待费", "水电", "项目检查费", "人情费", "合计", "联系人姓名", "联系人电话", "备注信息")
  17.    
  18.     '定义列坐标
  19.     Dim t, i&
  20.     i = 7
  21.     For Each t In arr1
  22.         i = i + 1
  23.         dicItem(t) = i
  24.     Next
  25.     '以A|B列数据为KEY
  26.     Dim StrKey$
  27.     Dim Result(), iPos&, iCount&, k&
  28.     ReDim Result(1 To 27, 1 To 1)
  29.     For i = LBound(data) + 1 To UBound(data)    '第一行为标题
  30.         StrKey = data(i, 1) & "|" & data(i, 2)
  31.         If Not dic.exists(StrKey) Then      '检测字典中是否存在Strkey
  32.             iCount = iCount + 1
  33.             ReDim Preserve Result(1 To 27, 1 To iCount)
  34.             iPos = dicItem(data(i, 3))      '取列坐标
  35.             Result(iPos, iCount) = data(i, 4)      '写入数据
  36.             Result(1, iCount) = data(i, 1)          'A列
  37.             Result(2, iCount) = data(i, 2)          'B列
  38.             'If iPos > 1 And iPos < 6 Then Result(1) = data(i, 4)
  39.             Result(27, iCount) = data(i, 5)         '备注
  40.             dic(StrKey) = iCount                    '写回字典
  41.         Else
  42.             k = dic(StrKey)                         '取数据列坐标
  43.             iPos = dicItem(data(i, 3))              '行坐标
  44.             Result(iPos, k) = Result(iPos, k) + data(i, 4)  '累加
  45.             'If iPos > 1 And iPos < 6 Then Result(1) = Result(1) + data(i, 4)
  46.             'Result(27, k) = data(i, 5)              '备注

  47.         End If
  48.     Next
  49.    
  50.     '结果数据写入Sheet3
  51.     With Worksheets("Sheet3")
  52.         i = .Cells(Rows.Count, 1).End(xlUp).Row '取最后一行数据位置
  53.         If i > 3 Then .Range("a4:aa" & i).ClearContents '4为第一行数据位置
  54.         
  55.         '数组经转置后写回.
  56.         .Range("a4").Resize(iCount, 27) = WorksheetFunction.Transpose(Result)
  57.         
  58.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  59.         '添加边框
  60.         With .Range("a4:aa" & i).Borders
  61.             .LineStyle = xlContinuous
  62.         End With
  63.         .Range("b4:b" & i).NumberFormatLocal = "yyyy年m月d日"   '设置日期格式
  64.     End With
  65. End Sub
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-24 00:31 , Processed in 0.519002 second(s), 12 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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