ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

vba 如何用数组把新数据导入已有的数据库

[复制链接]

TA的精华主题

TA的得分主题

发表于 2020-6-3 09:00 | 显示全部楼层 |阅读模式
我经常需要把最新的数据更新到已有的数据中。最新的数据经过编辑后,如果有编号的,说明是要更新的数据(原有数据已有),没有编号的是新增的数据。请问如何用数组的方式实现?如果有更快的方式也可以。我现在用的是用程序逐条读取Excel的方式,稍微多点数据,效率就很慢,电脑还容易卡。
示例如下
1、需要更新的数据(跟新的数量不确定,可能4条,也可能几十上百条),每一条根据编号,把更新数据覆盖和已有数据编号相同的数据
image.png
2、更新到已有的数据表,直接导入到已有数据,并自动添加编号
image.png
详见示例文件,请各位大神帮忙。我用数组的时候,老是出错,但是逐条读取的时候又效率太低。
image.png

示例.rar

7.56 KB, 下载次数: 16

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-6-3 11:40 来自手机 | 显示全部楼层
字典记录已有数据编号,然后匹配,能匹配则更新,不匹配则写入

TA的精华主题

TA的得分主题

发表于 2020-6-3 15:06 | 显示全部楼层
Sub test()
ar = Sheets("已有").[a1].CurrentRegion
xh = Sheets("已有").Cells(Rows.Count, 1).End(xlUp)
Set d = CreateObject("scripting.dictionary")
For i = 2 To UBound(ar)
    If Trim(ar(i, 1)) <> "" Then
        d(Trim(ar(i, 1))) = i
    End If
Next i
br = Sheets("原始").[a1].CurrentRegion
ReDim cr(1 To UBound(br), 1 To UBound(br, 2))
For i = 2 To UBound(br)
    If Trim(br(i, 1)) <> "" Then
        m = d(Trim(br(i, 1)))
        If m <> "" Then
            For j = 1 To UBound(br, 2)
                ar(m, j) = br(i, j)
            Next j
        End If
    End If
    If Trim(br(i, 1)) = "" Then
        n = n + 1
        xh = xh + 1
        cr(n, 1) = xh
        For j = 2 To UBound(br, 2)
            cr(n, j) = br(i, j)
        Next j
        
    End If
Next i
Sheets("已有").[a1].CurrentRegion = ar
r = Sheets("已有").Cells(Rows.Count, 1).End(xlUp).Row + 1
If n <> "" Then
    Sheets("已有").Cells(r, 1).Resize(n, UBound(cr, 2)) = cr
End If

End Sub

TA的精华主题

TA的得分主题

发表于 2020-6-3 15:08 | 显示全部楼层
示例.rar (14.7 KB, 下载次数: 21)

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-6-7 12:27 | 显示全部楼层
3190496160 发表于 2020-6-3 15:06
Sub test()
ar = Sheets("已有").[a1].CurrentRegion
xh = Sheets("已有").Cells(Rows.Count, 1).End(xlU ...

谢谢大神,帮我大忙了,比直接读取单元格进行判断高效了很多。

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-6-7 12:28 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

谢谢大神,效率很高,谢谢,谢谢

TA的精华主题

TA的得分主题

发表于 2020-8-19 09:28 | 显示全部楼层
看这个表有一点楼主我有点疑惑没看懂,就是“原始”表里的编号是你自己添加的吗?你原始表里的新增数据没有编号,但是你要在“已有”数据中自动添加编号,那么“原始”表里前面的数据编号到底根据什么编写的呢

TA的精华主题

TA的得分主题

发表于 2020-8-27 20:26 | 显示全部楼层
本帖最后由 kokokeke001 于 2020-8-27 21:20 编辑
  1. Sub test()
  2.     ar = Sheets("已有").[a1].CurrentRegion
  3.     xh = Sheets("已有").Cells(Rows.Count, 1).End(xlUp)
  4.     Set d = CreateObject("scripting.dictionary")
  5.     For i = 2 To UBound(ar)
  6.         If Trim(ar(i, 1)) <> "" Then 'Trim函数删除给定输入字符串的前导空格和尾随空格。
  7.             d(Trim(ar(i, 1))) = i '字典非空a列i行(a列编号即用于判断新增还是更新的依据)
  8.         End If
  9.     Next i
  10.     br = Sheets("原始").[a1].CurrentRegion
  11.     '[a1].CurrentRegion由a1向四周找单元格,遇到整空行空列停止,的范围(不包含遇到的空行列)
  12.     'aa=[a1].CurrentRegion
  13.     'UBound(aa) 取范围的最大值,参数1为行(默认可省略,参数2为列)
  14.     'MsgBox UBound(br) & Chr(13) & UBound(br, 2)
  15.     ReDim cr(1 To UBound(br), 1 To UBound(br, 2))
  16.     '这里cr是个数组(很可能猜错)表示每个br范围内单元格的行列(的值?)。
  17.     For i = 2 To UBound(br)
  18.         If Trim(br(i, 1)) <> "" Then
  19.             m = d(Trim(br(i, 1))) '从字典d里按原始表行取a列数据(编号),不为空时
  20.             If m <> "" Then
  21.                 For j = 1 To UBound(br, 2) '从表原始向表已有赋值,
  22.                     ar(m, j) = br(i, j)  'm是已有表的行,i是原始表内需要更新数据的行,j相同的列
  23.                 Next j
  24.             End If
  25.         End If
  26. '以上把需要更新的数据放到ar里面了。
  27.         If Trim(br(i, 1)) = "" Then  '(编号)为空时,需要新增行
  28.             n = n + 1 'n第一次用=1,每次+1
  29.             xh = xh + 1 '编号+1
  30.             cr(n, 1) = xh 'n,1就是n行1列,cr(n,1)就是这个单元格的值,新增数据的1行1列单元格的值等于xh(原来的最大编号)+1
  31.             For j = 2 To UBound(br, 2)
  32.                 cr(n, j) = br(i, j)  '这里赋值和上面一样
  33.             Next j
  34.         End If
  35.     Next i
  36.     Sheets("已有").[a1].CurrentRegion = ar '这里更新数据
  37.     r = Sheets("已有").Cells(Rows.Count, 1).End(xlUp).Row + 1  '这里r用来过渡一个新行
  38.     If n <> "" Then
  39.         Sheets("已有").Cells(r, 1).Resize(n, UBound(cr, 2)) = cr '这里新增数据'把cells().resize()代替range使变量更简单的参与。
  40.     End If
  41. End Sub

复制代码

学习了。看了好久,越发觉得优雅。
ar(3,1)可以同时传递行、列、行列(单元格)的值,而且还是个范围,要好好学习数组了。
这是个数组吧。
一直都只会用cells,觉得比range好用。觉得变量好参与,现在看来要升级一下了。

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

本版积分规则

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

GMT+8, 2024-11-23 10:25 , Processed in 0.045511 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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