遍历两个数组以检查值是否匹配,如果不匹配则更改

时间:2018-09-10 13:33:04

标签: excel vba excel-vba

已更新问题以使其清楚我要问的内容,并根据评论的帮助更新了代码。

我有两个表,每个表都有一个人员ID,姓名,团队和经理。

表1包含以前保存的数据,表2包含每天都会更新的实时数据。

我现在创建了一个数组,这些数组循环成功地存储了两个表中的数据,并更改了VBA监视窗口中的值以进行匹配。问题是在输出期间我遇到类型数据不匹配的情况。

这是我到目前为止的代码:

Function UpdateReports(rName, srcSheet)

  Dim Counter As Long
  Dim rr As Long
  Dim zz As Long
  Dim x As Long

  Dim aPID() As String
  Dim aName() As String
  Dim aTeam() As String
  Dim aOps() As String
  Dim aRole() As String


  Application.ScreenUpdating = False
  rPath = "%systemdrive%\users\%username%\Desktop\"
  Creator = rPath & "Test Workbook.xlsm"
  RepDest = rPath & rName & ".xlsx"
  Set sWbk = Nothing
  Set sWbk = Workbooks.Open(RepDest, True, True)

  'Store tList into Array
  Workbooks(Creator).Worksheets("tList").Visible = True
  Workbooks(Creator).Worksheets("tList").Activate
  Range("A1").CurrentRegion.Select
  zz = Selection.Rows.Count - 1
  rr = 1
  x = 0

  Do Until rr > zz ' repeat until end of Staff
    rr = rr + 1
    x = x + 1
    ReDim Preserve aID(1 To x) As String
    ReDim Preserve aName(1 To x) As String
    ReDim Preserve aTeam(1 To x) As String
    ReDim Preserve aManager(1 To x) As String


    aID(x) = Int(Cells(rr, 1).Value) ' Store ID
    aName(x) = Cells(rr, 2).Value ' Store Name
    aTeam(x) = Cells(rr, 3).Value ' Store Team
    aManager(x) = Cells(rr, 6).Value ' Store Manager

  Loop

'Compare tList to data sheet in report
  Workbooks(RepDest).Worksheets(srcSheet).Activate
  Range("A1").CurrentRegion.Select
  XY = Selection.Rows.Count
  For y = 3 To XY
    bID = Cells(y, 1).Value
    bName = Cells(y, 2).Value
    bTeam = Cells(y, 3).Value
    bManager = Cells(y, 4).Value
    For Z = 1 To zz
      If bID = aID(Z) Then
        bName = aName(Z)
        bTeam = aTeam(Z)
        bManager = aManager(Z)
      End If
    Next z
  Next y


'  Dim vArray As Variant
'    ReDim vArray(LR)
'    For x = 8 To LR
'      vArray(x) = Cells(x, 3).Value
'    Next x
'    Worksheets("Breaks Overuse").Activate
'    Range("B2").CurrentRegion.Select
'    XY = Selection.Rows.Count
'    For y = 2 To XY
'      PID = Cells(y, 2).Value
'      For Z = 8 To LR
'        If ID = vArray(Z) Then
'          Rows(y).Delete
'          y = y - 1
'          XY = XY - 1
'        End If
'      Next Z
'    Next y

  Sheets(srcSheet).Select
  Counter = 0
  yy = 1
  With Sheets(srcSheet).Range("A1")
    For Counter = 1 To x
        .Offset([yy], [0]).Value = Format(bID(Counter), "0") 'This is where I get type mismatch, the value for bID is <type mismatch> but in the part above this the value is the ID number 123456
        .Offset([yy], [1]).Value = Format(bName(Counter), "@")
        .Offset([yy], [2]).Value = Format(bTeam(Counter), "@")
        .Offset([yy], [3]).Value = Format(bManager(Counter), "@")

        yy = yy + 1
    Next
  End With
  Set sWbk = Nothing

End Function

1 个答案:

答案 0 :(得分:1)

您正试图为属性Creator分配一个值为只读的值。 (我相信它也包含对Application对象的隐式引用。因此,您实际上是在使用Application.Creator。)

我不确定您使用此属性的意图是什么。您检查了它的价值吗?根据{{​​3}},它是一个恒定值。据我了解,在Mac环境中创建文档时,其值可能会有所不同。无论如何,以它命名工作簿对我来说似乎不是很有用。

就建立一个新的工作簿名称而言,您确实应该为此使用一个新变量。应用程序/文档属性(即使可写)也不是存储脚本运行时信息的地方。


正如@QHarr在评论中已经提到的那样,您将从不想在循环中ReDim数组(除非您可以提供帮助,但要注意:这闻起来... )。
对于您而言,绝对没有必要这样做:

zz = Selection.Rows.Count - 1
rr = 1
x = 0
Do Until rr > zz ' repeat until end of Staff
    rr = rr + 1
    x = x + 1
    ReDim Preserve aID(1 To x) As String
    ReDim Preserve aName(1 To x) As String
    ReDim Preserve aTeam(1 To x) As String
    ReDim Preserve aManager(1 To x) As String

    ' assignments removed for brevity
Loop

当循环开始时,退出条件是已知的(您可能还应该将此循环重写为For ... Next循环)。值zz在循环中是已知的并且是常量。 rr的起始值以及增量都是已知的。因此,从一开始您就知道rr的值将是结尾。因此,您还知道最后的x是什么,从而知道数组的最终大小是什么。

该循环从rr = 2(以r = 1开始,然后立即递增1)到rr = zz(以rr > zz停止),循环为{{ 1}}。由于Step 1同时以相同的增量递增,但从0而不是1开始,x的最终值为x。有了这些知识,我们便可以重构为:

x = zz - 1

关于您的类型不匹配错误:由于您没有向我们显示所有zz = Selection.Rows.Count - 1 ' First dimension arrays outside of the loop Dim xMax as Long xMax = zz - 1 ReDim Preserve aID(1 To xMax) As String ReDim Preserve aName(1 To xMax) As String ReDim Preserve aTeam(1 To xMax) As String ReDim Preserve aManager(1 To xMax) As String ' Proceed with filling the arrays in a For ... Next loop ' the index x has been replaced by rr-1 For rr = 2 to zz aID(rr-1) = Int(Cells(rr, 1).Value) ' Store ID aName(rr-1) = Cells(rr, 2).Value ' Store Name aTeam(rr-1) = Cells(rr, 3).Value ' Store Team aManager(rr-1) = Cells(rr, 6).Value ' Store Manager Next rr 变量的声明,所以我不能说为什么会发生。而且您对这些变量的用法不一致。刚开始,您似乎在bbID = Cells(y, 1).Value中将它们用作标量,但是后来您进行了If bID = aID(Z) Then,它被用作数组。当您不得不在一个月的时间内审视这些界限时,您不仅会为此而感到困惑,还会使您未来的自我困惑。

通常:您是否将Format(bID(Counter), "0")放在代码模块的顶部?如果没有,请尽快。我觉得这可能会解决您的大多数问题。 (如果不存在,请转到VBE选项并在第一页上启用Option Explicit。此后,该代码会自动在您创建的每个模块中写入Require variable declaration。)