Arrays VBA匹配2组数据
我这里有个问题。我想匹配并突出显示表1和表2中的这两个数据。标准是合同代码必须匹配,表2中该合同代码的总批次数量也必须匹配 例如,在表1中,375应与表2中的三个数据项相匹配并突出显示Arrays VBA匹配2组数据,arrays,vba,excel,Arrays,Vba,Excel,我这里有个问题。我想匹配并突出显示表1和表2中的这两个数据。标准是合同代码必须匹配,表2中该合同代码的总批次数量也必须匹配 例如,在表1中,375应与表2中的三个数据项相匹配并突出显示50 ZBZ8125 ZBZ8200 ZBZ8 Table 1 CONTRACT LOTS ZBZ8 375 ZBU8 339 ZBM8 -250 ZBH8 -75 Table 2 Qty Co
50 ZBZ8
125 ZBZ8
200 ZBZ8
Table 1
CONTRACT LOTS
ZBZ8 375
ZBU8 339
ZBM8 -250
ZBH8 -75
Table 2
Qty Contract
40 TYZ7
200 TYZ7C
-400 TYZ7C
100 EDZ7
100 EDZ7
100 EDZ7
100 EDH8
-100 EDZ8
-100 EDZ8
-100 EDH9
-25 ZBH8
-50 ZBH8
-250 ZBM8
114 ZBU8
200 ZBU8
25 ZBU8
50 ZBZ8
125 ZBZ8
200 ZBZ8
25 XMZ7
-115 YMZ7
-200 YMZ7
我是VBA新手,请耐心等待。正如托马斯在下面提到的,字典似乎是解决这个问题的方法
我尝试了下面答案中的代码,但似乎不起作用。使用数组的代码实际上看起来是一个不错的开始 下面是我将如何解决它:
Dim x AS Long, y AS Long
For x = DATA2_STARTING_ROW to 0 ' infinite loop (through data set 2)
Dim code AS String
code = Cells(x, DATA2_CODE_COLUMN)
If code = "" Then Exit For ' no more data
Dim total AS Integer
total = 0
For y = DATA1_STARTING_ROW to 0 ' (through data set 1)
If Cells(y, DATA1_CODE_COLUMN) = "" Then Exit For
If Cells(y, DATA1_CODE_COLUMN) = code Then ' found a match
total = total + Cells(y, DATA1_QUANTITY_COLUMN)
End If
Next
If total = Cells(x, DATA2_QUANTITY_COLUMN) Then ' the totals match
Cells(x, DATA2_QUANTITY_COLUMN).Interior.Color = RGB(50, 100, 50)
Cells(x, DATA2_CODE_COLUMN).Interior.Color = RGB(50, 100, 50)
End If
Next
只需替换DATA2\u QUANTITY\u列。。。变量与数据集开始位置的实际值。下面是一个使用注释中建议的字典的示例 我已经包括了几个循环,以突出显示源行和总行,其中没有代码将单个行与总和匹配 这是基于根据以下图像设置的数据: 要验证的总数: 要求和的行数: 请注意,在这种情况下,仅突出显示了
TYZ7C
。它实际上只存在于一张表中,而不存在于另一张表中(没有要核对的金额)。总数与其他总数相当。您可能会考虑用不同的颜色强调缺失的代码。
负数的红色字体是由于已经应用的格式类型,与代码的功能无关
Option Explicit
'Tools > References > Add reference to Microsoft Scripting Runtime
Public Sub CheckTotal()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws1 As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Futures - DB") ' change as appropriate e.g. "Futures - DB"
Set ws1 = wb.Worksheets("Futures - FNZC")
Dim totalsDict As Scripting.Dictionary 'set reference to microsoft scripting runtime
Set totalsDict = New Scripting.Dictionary
Dim valuesArr()
Dim valuesSource As Range
Dim lastRowInM As Long
lastRowInM = ws.Cells(ws.Rows.Count, "M").End(xlUp).Row
Set valuesSource = ws.Range("M3:N" & lastRowInM) 'range containing values to sum
valuesSource.Cells.Interior.PatternColorIndex = xlAutomatic
valuesArr = valuesSource.Value
AddToDict valuesArr, totalsDict
' PrintDict totalsDict
Dim currCell As Range
Dim loopRange As Range
Set loopRange = ws1.Range("C9:D37") 'range containing codes whose sums are to be checked
loopRange.Cells.Interior.PatternColorIndex = xlAutomatic
Dim colourCodesArr()
ReDim colourCodesArr(0 To 1000) 'change this number to a number greater than the expected number of totals to be checked.
Dim counter As Long
counter = 0
For Each currCell In loopRange.Columns(1).Rows
If Not IsEmpty(currCell) And currCell <> "CONTRACT" Then 'ignore cells in range that don't qualify for consideration
If currCell.Offset(, 1) = totalsDict(currCell.Value2) Then
colourCodesArr(counter) = currCell 'store codes whose totals match summing of rows match in array
counter = counter + 1
Else
currCell.Offset(, 1).Interior.ColorIndex = 6 'colour yellow
End If
End If
Next currCell
ReDim Preserve colourCodesArr(0 To counter - 1)
For Each currCell In valuesSource.Columns(2).Rows 'Loop the codes in the source range checking if a no match was registered
If UBound(Filter(colourCodesArr, currCell.Value2)) = -1 Then 'if code not found in array highlight in yellow
currCell.Offset(, -1).Interior.ColorIndex = 6
End If
Next currCell
End Sub
Private Sub AddToDict(ByVal valuesArr As Variant, ByRef totalsDict As Dictionary)
Dim code As Long
For code = LBound(valuesArr, 1) To UBound(valuesArr, 1)
If totalsDict.Exists(valuesArr(code, 2)) Then 'if code exists add new value to existing value otherwise add code and value to the dictionary e.g. TYZ7C ,200
totalsDict(valuesArr(code, 2)) = totalsDict(valuesArr(code, 2)) + valuesArr(code, 1)
Else
totalsDict.Add valuesArr(code, 2), valuesArr(code, 1)
End If
Next code
End Sub
Private Sub PrintDict(ByVal totalsDict As Dictionary)
Dim key As Variant
For Each key In totalsDict.Keys
Debug.Print "Key: " & key & " Value: " & totalsDict(key)
Next
End Sub
选项显式
'工具>引用>添加对Microsoft脚本运行时的引用
公共子检查总计()
将wb设置为工作簿
将ws设置为工作表
将ws1设置为工作表
设置wb=ThisWorkbook
设置ws=wb。工作表(“Futures-DB”)根据需要更改,例如“Futures-DB”
设置ws1=wb.工作表(“期货-FNZC”)
Dim totalsDict作为脚本。Dictionary设置对microsoft脚本运行时的引用
Set totalsDict=New Scripting.Dictionary
Dim估价师()
尺寸值来源为范围
暗淡的最后一行
lastRowInM=ws.Cells(ws.Rows.Count,“M”).End(xlUp).Row
设置值source=ws.Range(“M3:N”和lastRowInM)包含要求和的值的范围
值source.Cells.Interior.PatternColorIndex=xlAutomatic
valuesArr=valuesSource.Value
AddToDict估价师,totalsDict
“PrintDict totalsDict
Dim Curr单元格作为范围
变暗范围作为范围
Set loopRange=ws1.Range(“C9:D37”)“包含要检查其总和的代码的范围
loopRange.Cells.Interior.PatternColorIndex=xlAutomatic
暗色编码器()
ReDim COLORCODESAR(0到1000)'将此数字更改为大于要检查的预期总数的数字。
昏暗的柜台一样长
计数器=0
对于loopRange.Columns(1.Rows)中的每个currCell
如果不是IsEmpty(currCell)和currCell“CONTRACT”,则“忽略范围内不符合考虑条件的单元格”
如果currCell.Offset(,1)=totalsDict(currCell.Value2),则
COLORCODESAR(计数器)=currCell'存储其总数与数组中行的总和相匹配的代码
计数器=计数器+1
其他的
currCell.Offset(,1).Interior.ColorIndex=6'颜色黄色
如果结束
如果结束
下一个电池
ReDim保留彩色编码器(0到计数器-1)
对于valuesSource.Columns(2).Rows中的每个currCell,循环源范围中的代码,检查是否注册了不匹配项
如果UBound(Filter(colorcodesarr,currCell.Value2))=-1,则“如果在数组中未找到代码,则以黄色突出显示”
currCell.Offset(,-1).Interior.ColorIndex=6
如果结束
下一个电池
端接头
私有子AddToDict(ByVal valuesArr作为变体,ByRef totalsDict作为字典)
长码
对于代码=LBound(估价师,1)到UBound(估价师,1)
如果totalsDict.存在(valuesArr(代码,2)),则“如果存在代码,则向现有值添加新值,否则向字典添加代码和值,例如TYZ7C,200
totalsDict(估价师(代码,2))=totalsDict(估价师(代码,2))+估价师(代码,1)
其他的
总计信息。添加估价师(代码2),估价师(代码1)
如果结束
下一个代码
端接头
专用子打印目录(ByVal totalsDict作为字典)
变暗键作为变量
对于totalsDict.Keys中的每个键
调试。打印“键:”&键和“值:”&总计信息(键)
下一个
端接头
您应该使用集合。脚本字典是此任务的首选集合。手表:太棒了!我将尝试一下。您需要转到visual basic编辑器(alt+F11),然后转到工具>引用>添加对microsoft脚本运行时的引用(向下滚动以在列表中查找,然后选中此框)。查看此选项后,如果要求和的数据量未知,我将如何设置范围。“Set valuesSource=ws.Range(“A2:B6”)”是否有指定的起始单元格和列号(字母如a列和B列)?M列中的值是否有空白单元格?