从另一个表更新表值 [英] Update table values from another Table

查看:94
本文介绍了从另一个表更新表值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个工作簿,其中的表大小约为20000行和52列.有时,我需要一次更新一定比例的选择行.我希望使用宏根据行中的值更新选择的单元格,该值由第二个较小的表映射出,并将更新后的值输入到表1中.几乎像VLOOKUP函数一样,但是没有如果找不到该条目,则不要擦除该单元格.例如,根据主机ID更改电话号码.

I have a workbook with a table that is roughly 20000 rows in size and 52 columns. At times, I need to update a percentage of select rows at once. I'm hoping to use a macro to update the select cells based on a value in the row, mapped out by a second smaller table with the updated values to be entered in to table 1. Almost like a VLOOKUP function, but one that doesn't erase the cell if the entry isn't found. For example, change the Phone Number according to the Host ID.

我尝试使用下面代码中的Array来完成表1中特定值的设置,但是我的值没有更新.我的VBA有点生锈,因此如果有人可以审查并帮助使其正常运行,将不胜感激.我想让它最终根据表头更新表中的任何条目.

I tried to do this with an Array in the code below for a specfic set of the values in Table 1, but my values didn't update. My VBA is a bit rusty, so if someone can review and assist with getting this to function, it would be appreciated. I would like to make it update any entry in the table based on the table headers eventually.

Sub NewNameandCostCenter()
Dim myList, myRange
Dim sht As Worksheet
Dim sht2 As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim LastRow2 As Long
Set sht = Worksheets("NewNameMacro")
Set sht2 = Worksheets("ALL")
Set StartCell = Range("A2")

'Find Last Row and Column
  LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
  LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column
'set myList array
Set myList = sht.Range(StartCell, sht.Cells(LastRow, LastColumn))
LastRow2 = sht.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'set myRange array
Set myRange = Sheets("ALL").Range("J2:M" & LastRow2)
'Update values of cells adjacent
For Each cel In myList.Columns(1).Cells
myRange.Replace What:=cel.Value, Replacement:=cel.Offset(0, 1).Value, LookAt:=xlWhole
myRange.Replace What:=cel.Value, Replacement:=cel.Offset(0, 2).Value, LookAt:=xlWhole
myRange.Replace What:=cel.Value, Replacement:=cel.Offset(0, 3).Value, LookAt:=xlWhole
Next cel
End Sub

谢谢, 京东

推荐答案

如果我正确理解了您的问题,那么您将根据映射表中的值有效地对数据运行UPDATE查询.

If I understand your question correctly, you're effectively running an UPDATE query against your data, based on the values in your mapping table.

我假设以下内容:

  • 键"列是数据表映射表中的第一列.

映射表中的列与数据表中的列具有相同的顺序和相对位置(尽管可以很容易地对其进行调整.

The columns in your mapping table are in the same order and relative position as the columns in the data table (although this could easily be adjusted.

映射表和数据表中键的顺序未排序.如果您可以确保对键进行排序(最好在两张纸上都进行排序),那么只需稍加修改就可以显着提高性能.

The order of the keys in the mapping table and the data table is unsorted. If you can ensure that the keys are sorted (ideally in both sheets), then you could achieve substantially better performance with some slight modifications.

我已经在示例中对范围进行了硬编码,但是如果需要,您可以恢复最后一行和最后一列的方法.

I've hard-coded the ranges in my example, but you can reinstate the last row and last column approach if you need to.

我已经完成了数组之间而不是范围之间的所有比较,并且不再使用查找"方法.您会发现这可行,并且工作效率更高.

I've done all of my comparisons between arrays instead of ranges, and I've done away with the Find approach. You'll find that this works, and works much more efficiently.

Option Explicit

Sub NewNameandCostCenter()

  Dim start As Double
  start = Timer

  Dim countOfChangedRows As Long

  'set rngMap array
  Dim rngMap As Range
  Set rngMap = Worksheets("Map").Range("A1:D51")

  'set rngData array
  Dim rngData As Range
  Set rngData = Worksheets("Data").Range("J2:M20001")

  Dim aMap As Variant
  aMap = rngMap.Value

  Dim aData As Variant
  aData = rngData.Value

  Dim mapRow As Long
  Dim datarow As Long
  Dim mapcol As Long

  For mapRow = LBound(aMap, 1) To UBound(aMap, 1)
    For datarow = LBound(aData) To UBound(aData)
      'Check the key matches in both tables
      If aData(datarow, 1) = aMap(mapRow, 1) Then
        countOfChangedRows = countOfChangedRows + 1
        'Assumes the columns in map and data match
        For mapcol = LBound(aMap, 2) + 1 To UBound(aMap, 2)
          aData(datarow, mapcol) = aMap(mapRow, mapcol)
        Next mapcol
      End If
    Next datarow
  Next mapRow

  rngData.Value = aData

  Debug.Print countOfChangedRows & " of "; UBound(aData, 1) & " rows updated in " & Timer - start & " seconds"

End Sub

对于50个更新的行,该性能是合理的:

The performance is reasonable for 50 updated rows:

50 of 20000 rows updated in 0.23828125 seconds

但是,如果您需要开始更新数千行,那么确保数据已排序并相应地调整代码将为您带来极大的好处.

But if you need to start updating thousands of rows, then you would benefit greatly from ensuring the data is sorted and tweaking the code accordingly.

这篇关于从另一个表更新表值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆