Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: wucj80

[已解决]工程明细数

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

    "车费", ...

那是另起一行的意思。
回复

使用道具 举报

发表于 2012-12-18 17:38 | 显示全部楼层
本帖最后由 hwc2ycy 于 2012-12-22 10:26 编辑
  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.     '结果数据写入Sheet2
  51.     With Worksheets("Sheet2")
  52.         i = .Cells(Rows.Count, 1).End(xlUp).Row '取最后一行数据位置
  53.         If i > 3 Then .Range("a4:aa" & i).Clear '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
复制代码
改回来,写入SHEET2里。我的SHEET是因为复制了表头。
回复

使用道具 举报

 楼主| 发表于 2012-12-18 19:55 | 显示全部楼层
再一次多谢老师的答案。这一个也是很好的
回复

使用道具 举报

 楼主| 发表于 2012-12-20 23:16 | 显示全部楼层
老师有一个问题就是怎么会出现运行时错误,下标越界
回复

使用道具 举报

 楼主| 发表于 2012-12-21 00:51 | 显示全部楼层
那个问题就是第35行不能有什么数据,一有数据就是下标越界,请问一下老师这个问题怎么改决
回复

使用道具 举报

 楼主| 发表于 2012-12-22 01:13 | 显示全部楼层
工程明细表20121220

工程明细表22.rar

13.41 KB, 下载次数: 5

回复

使用道具 举报

发表于 2012-12-22 10:46 | 显示全部楼层
  1. Sub 合并数据2()
  2. '字典+数组,字典只存位置
  3. '2012-12-22 by hwc2ycy
  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.             
  35.             If dicItem.exists(data(i, 3)) Then
  36.                 iPos = dicItem(data(i, 3))      '取列坐标
  37.                 Result(iPos, iCount) = data(i, 4)      '写入数据
  38.                 Result(1, iCount) = data(i, 1)          'A列
  39.                 Result(2, iCount) = data(i, 2)          'B列
  40.                 Result(27, iCount) = data(i, 5)         '备注
  41.                 dic(StrKey) = iCount                    '写回字典
  42.             Else
  43.                 MsgBox "字段名" & "'" & data(i, 3) & "'" & " 有误,此条数据被忽略" & vbCr & " 点 确定 继续"
  44.             End If
  45.         Else
  46.             k = dic(StrKey)                         '取数据列坐标
  47.             If dicItem.exists(data(i, 3)) Then
  48.                 iPos = dicItem(data(i, 3))              '行坐标
  49.                 Result(iPos, k) = Result(iPos, k) + data(i, 4)  '累加
  50.             Else
  51.                 MsgBox "字段名" & "'" & data(i, 3) & "'" & " 有误,此条数据被忽略"
  52.             End If
  53.         End If
  54.     Next
  55.    
  56.     '结果数据写入Sheet2
  57.     With Worksheets("Sheet2")
  58.         i = .Cells(Rows.Count, 1).End(xlUp).Row '取最后一行数据位置
  59.         If i > 3 Then .Range("a4:aa" & i).Clear '4为第一行数据位置
  60.         
  61.         '数组经转置后写回.
  62.         .Range("a4").Resize(iCount, 27) = WorksheetFunction.Transpose(Result)
  63.         
  64.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  65.         '添加边框
  66.         With .Range("a4:aa" & i).Borders
  67.             .LineStyle = xlContinuous
  68.         End With
  69.         .Range("b4:b" & i).NumberFormatLocal = "yyyy年m月d日"   '设置日期格式
  70.     End With
  71. End Sub
复制代码
回复

使用道具 举报

发表于 2012-12-22 10:47 | 显示全部楼层
  1. Option Explicit

  2. Sub 合并数据()
  3.     '字典装数组
  4.     '2012-12-22 by hwc2ycy
  5.     Dim data
  6.     With Worksheets("Sheet1")
  7.         data = .Range("a1").CurrentRegion
  8.     End With

  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.     Dim t, i&
  15.     For Each t In arr1
  16.         i = i + 1
  17.         dicItem(t) = i
  18.     Next
  19.     Dim StrKey$
  20.     Dim Result(), iPos&
  21.     For i = LBound(data) + 1 To UBound(data)
  22.         StrKey = data(i, 1) & "|" & data(i, 2)
  23.         If Not dic.exists(StrKey) Then
  24.             ReDim Result(1 To dicItem.Count)
  25.             If dicItem.exists(data(i, 3)) Then
  26.                 iPos = dicItem(data(i, 3))
  27.                 Result(iPos) = data(i, 4)
  28.                 'If iPos > 1 And iPos < 6 Then Result(1) = data(i, 4)
  29.                 Result(dicItem.Count) = data(i, 5)
  30.                 dic(StrKey) = Result
  31.             Else
  32.                 MsgBox "字段名" & "'" & data(i, 3) & "'" & " 有误,此条数据被忽略" & "点 确定继续"
  33.             End If
  34.         Else
  35.             Result = dic(StrKey)
  36.             If dicItem.exists(data(i, 3)) Then
  37.                 iPos = dicItem(data(i, 3))
  38.                 Result(iPos) = Result(iPos) + data(i, 4)
  39.                 'If iPos > 1 And iPos < 6 Then Result(1) = Result(1) + data(i, 4)
  40.                 Result(dicItem.Count) = data(i, 5)
  41.                 dic(StrKey) = Result
  42.             
  43.             Else
  44.                 MsgBox "字段名" & "'" & data(i, 3) & "'" & " 有误,此条数据被忽略" & vbCr & "点 确定 继续"
  45.             End If
  46.         End If
  47.     Next

  48.     With Worksheets("sheet2")
  49.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  50.         If i > 3 Then .Range("a4:aa" & i).ClearContents
  51.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))
  52.         .Range("h4").Resize(UBound(Result), UBound(Result, 2)) = Result
  53.         For Each t In dic.keys
  54.             dic(t) = Split(t, "|")
  55.         Next
  56.         Result = WorksheetFunction.Transpose(WorksheetFunction.Transpose(dic.items))
  57.         .Range("a4").Resize(UBound(Result), UBound(Result, 2)) = Result
  58.         i = .Cells(Rows.Count, 1).End(xlUp).Row
  59.         With .Range("a4:aa" & i).Borders
  60.             .LineStyle = xlContinuous
  61.         End With
  62.     End With
  63. End Sub
复制代码
回复

使用道具 举报

发表于 2012-12-22 10:48 | 显示全部楼层
原来的代码中“午餐”前面多加了个空格,所以没有测出来。
代码重新改了,多谢。
回复

使用道具 举报

发表于 2012-12-22 10:49 | 显示全部楼层
工程明细表22.rar (20.49 KB, 下载次数: 7)
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-4 00:17 , Processed in 0.457081 second(s), 9 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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