布尔值未根据for循环

时间:2016-06-15 15:39:17

标签: excel vba excel-vba loops

我是编程和VBA的新手,但我一直在使用堆栈溢出的大量帮助问题和答案来学习!我正在尝试创建一个循环,用于确定“预览”工作表中是否缺少“任务”工作表中的值,如果是,则将数字和行添加到“任务”工作表中的“预览”工作表中。有关每张纸上数据的示例:

任务表

TASK VALUE  description 
11      task 1
12      task 2
13      task 3

预览表

PREVIEW VALUE       Description
1111                preview 1
2222                preview 2
11                  task 1
3333                preview 3
13                  task 3

目的是将预览表中的每个数字与任务表中的每个值进行比较。如果在预览表中找不到任务表中的值,则应将该值和整行添加到任务表的预览表中。

我的主要方法是创建一个for循环,将“预览”工作表上的每个数字与“任务”工作表上的每个值进行比较。如果发现两个值匹配,则将设置变量newTask = False,然后退出嵌套for循环以继续下一个比较。如果它发现数据表中的值不在主表中,则会设置newTask = True并运行直到没有更多值要比较。然后,如果newTask = True,它会将数据表中的值和行复制并粘贴到主工作表中。这是我尝试编码:

Dim newTask As Boolean

iP = (Worksheets("parents").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) - 1 'count of parent workorders
iC = (Worksheets("child").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) - 1 ' count of child workorders
iT = (Worksheets("task").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) - 1 ' count of task workorders
iPr = (Worksheets("preview").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) + 1 ' this will set iPr one row below the last row on the preview page
nT = 0
Set prRng = Sheets("Preview").Range(Sheets("Preview").Cells(iPr, 1), Sheets("Preview").Cells(iPr, 11))

     For n = 1 To iPr

        taskWO = Worksheets("task").Cells(n + 1, 1).Value

        For nT = 1 To iT
            previewWO = Worksheets("preview").Cells(nT + 1, 1).Value

            If previewWO = taskWO Then
                newTask = False
                Exit For

            ElseIf previewWO <> taskWO Then
                newTask = True
                End If

        Next nT


        If newTask = True Then

            Set tRng = Sheets("task").Range(Sheets("task").Cells(n + 1, 1), Sheets("task").Cells(n + 1, 11))
            Sheets("Preview").Range(Sheets("Preview").Cells(iPr, 1), Sheets("Preview").Cells(iPr, 11)) = tRng.Value
            Sheets("Preview").Cells(iPr, 12) = Sheets("task").Cells(n + 1, 13).Value
            iPr = (Worksheets("preview").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) + 1

        End If
    Next n

但是,当我运行此代码时,它会保持newTask = True,即使这些值在预览和任务表中都匹配。调试确认了这一点,如果它遇到类似的值,它只会继续在它上面,好像它们彼此不相等。这会导致任务表中的所有值都复制到预览表,添加许多重复项。我还尝试了Do Until循环,但得到了相同的结果:这是我的尝试:

Dim newTask As Boolean

iP = (Worksheets("parents").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) - 1 'count of parent workorders
iC = (Worksheets("child").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) - 1 ' count of child workorders
iT = (Worksheets("task").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) - 1 ' count of task workorders
iPr = (Worksheets("preview").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) + 1 ' this will set iPr one row below the last row on the preview page
nT = 0
taskWO = Worksheets("task").Cells(n + 1, 1).Value
Set prRng = Sheets("Preview").Range(Sheets("Preview").Cells(iPr, 1), Sheets("Preview").Cells(iPr, 11))

For n = 1 To iPr
taskWO = Worksheets("task").Cells(n + 1, 1).Value
    Do Until taskWO = previewWO Or nT = iT
        previewWO = Worksheets("preview").Cells(nT + 1, 1).Value
        nT = nT + 1
        If nT = iT Then
            Set tRng = Sheets("task").Range(Sheets("task").Cells(n + 1, 1), Sheets("task").Cells(n + 1, 11))
            Sheets("Preview").Range(Sheets("Preview").Cells(iPr, 1), Sheets("Preview").Cells(iPr, 11)) = tRng.Value
            Sheets("Preview").Cells(iPr, 12) = Sheets("task").Cells(n + 1, 13).Value
            iPr = (Worksheets("preview").Columns("a").Cells.SpecialCells(xlCellTypeConstants).Count) + 1
        End If
    Loop

Next n

我已经做了很多搜索,但我找不到任何方法来阻止重复值......但是如果我错过了一个有这些信息或帮助的帖子,我会道歉。我觉得这很简单,但我无法理解。我能帮忙解决一下这个问题吗?如果这不是正确的方法,你还可以提一下为什么循环不起作用或出了什么问题所以我将来可以知道吗?感谢您提供的任何帮助!如果您需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

Kyle,如果没有对代码进行全面的重新设计,请参阅我认为可能会帮助您的一些代码。如果我正确理解您的问题,您遇到的主要问题是您无法正确判断另一个范围内的值是否存在。当我遇到这个问题时,我通常会使用字典对象,因为它速度很快,并且提供了一种检查列表中是否有值的简单方法。但是,要使用字典,您可能必须先添加对它的引用。要执行此操作,请转到工具菜单,然后选择&#34;参考&#34;。向下滚动,直到找到&#34; Microsoft Scripting Runtime&#34;并选择该项目。之后,以下代码应该运行得很好。

Sub Testq()
        Set Dict = New Dictionary

        For Each Cel In Worksheets("preview").Columns(1).SpecialCells(xlCellTypeConstants)
            'Add the "Preview Values" of all the cells into your dictionary as Keys.
            'Set the value of each key to the "Description" which is in the row next to it.
            Dict(Trim(Cel.Value)) = Trim(Cells(Cel.Row(), 2))
        Next
        'Lets add in the header row of the task worksheet to prevent it from getting coppied over.
        Dict(Worksheets("task").Cells(1, 1).Value) = Worksheets("task").Cells(1, 2).Value
        'Now loop through all of the values in your "Task" table, checking them against the Dictionary
        'to see if there are any new ones.
        For Each Cel In Worksheets("Task").Columns(1).SpecialCells(xlCellTypeConstants)
            If Not Dict.Exists(Trim(Cel.Value)) Then 'We have a new value.
                TaskValue = Trim(Cel.Value)
                Description = Trim(Worksheets("Task").Cells(Cel.Row(), 2))
                Debug.Print "Yup, I found one that's missing: " & Trim(TaskValue)

                'Now add the missing value to the end of your "preview" sheet.
                LastRow = Worksheets("preview").Cells(Range("A:A").Rows.Count, "A").End(xlUp).Row
                Worksheets("preview").Cells(LastRow + 1, 1) = Trim(TaskValue)
                Worksheets("preview").Cells(LastRow + 1, 2) = Trim(Description)
            End If
        Next
    End Sub

由于您提到您是VBA的新手,我指出要查看Debug.Print语句的输出,您需要显示&#34;立即&# 34;窗口。通过从“视图”菜单中选择它来执行此操作。当我更清楚地了解您的项目时,我会根据需要补充这个答案,但现在我希望这可以帮助您解决您遇到的大部分问题。