从不完整的数据集创建列表

时间:2013-10-01 15:31:41

标签: excel excel-vba vba

我有一个连接地点的电子表格。每个地方都有一个相应的数字,并放置在一个区域(区域)。

我想要一个列表Node,其中包含相应的NameArea。由于缺少某些数据,我假设从PARIS开始的一行也将在PARIS中结束。

From    To          From    To      AreaF   AreaT
51191   51190       BARUM   OVERL   PARIS   PARIS
51191   60000       BARUM   BARDU   PARIS   0
51059   51074       FOLLO   DYRLO   #N/A    #N/A
51059   51070       FOLLO   DYRLO   #N/A    BERG
51059   50795       FOLLO   NYSTU   #N/A    #N/A
51059   59001       FOLLO   VEVEL   #N/A    #N/A
51059   50362       FOLLO   MYRVO   #N/A    #N/A
51059   50363       FOLLO   MYRVO   #N/A    #N/A
51059   50812       FOLLO   NORDB   #N/A    #N/A

我想要的是什么:

Node    Name    Area
50362   MYRVO   BERG
50363   MYRVO   BERG
50795   NYSTU   BERG
50812   NORDB   BERG
51059   FOLLO   BERG
51070   DYRLO   BERG
51074   DYRLO   BERG
51190   OVERL   PARIS
51191   BARUM   PARIS
59001   VEVEL   BERG
60000   BARDU   PARIS

有关如何在Excel中完成此操作的任何提示?任何可能派上用场的有用功能?

我能想到的最好的逻辑是:

(例如第3行)

  1. 检查AreaF是否包含有效的区域名称,而不是#N / A或0(False)
  2. 检查AreaT是否包含有效的区域名称(False)
  3. 检查列A为51059的其他行是否包含valie区域名称(True,第4行)
  4. 在新列表中使用该区域
  5. 我的问题主要是第3点。我无法弄清楚我必须使用哪些功能等来实现这一目标。

    这似乎适用于第1点和第2点:

    =IF(ISNA(F2);IF(ISNA(G2);$M$2;IF(G2=0;$M$2;G2));IF(F2=0;IF(ISNA(G2);$M$2;IF(G2=0;$M$2;G2));F2))
    

    谢谢!

2 个答案:

答案 0 :(得分:1)

对于第一个问题,“有关如何在Excel中完成此操作的任何提示?可能派上用场的任何有用功能吗?”:
你的逻辑可行。但是,您可能需要考虑在VBA中对此进行编码,而不是在每个单元格中使用长公式。格式类似于:

  1. 浏览所有节点
    • 使用 For ... Next 循环遍历节点。
  2. 如果尚未看到该节点,请将其添加到列表中。
    • 例如,使用 Range.Find 方法检查是否已找到该节点。 (有关 .Find COUNTIF 等)的详细讨论,请参阅here
  3. 在该节点上进行计算。
    • 检查区域T或区域F是否包含有效名称。
    • 将该区域用于节点。

  4. 回答关于第3点可以使用哪些功能的第二个问题:对于不使用VBA的内容,您可以考虑 VLOOKUP 功能,以及 COUNTIF ,要记住好的功能。但同样,请参阅here,以便对 .Find COUNTIF 等进行良好讨论。

答案 1 :(得分:1)

这是一个循环范围的VBA方法,基本上是用强力进行评估。

我确信它可以清理并提高效率。应该让你开始。

Sub NodeList()
    Dim sheet As Worksheet
    Set sheet = ActiveWorkbook.Sheets("Sheet1")

    'First Column
    Dim rngA As Range
    Set rngA = [A2:A10]
    Dim datA As Variant
    datA = rngA
    Dim i As Long
    Dim j As Long

    'Results
    Dim myarray()
    ReDim myarray(100, 100)
    Dim datR As Variant
    Dim store As Boolean
    Dim duplicate As Boolean
    store = False
    duplicate = False
    Dim cntr As Integer
    cntr = 0

    'Range Column loop
    For i = LBound(datA, 1) To UBound(datA, 1)
        'Find first result
        If IsEmpty(myarray(0, 0)) Then
            'Is Col E valid?
            If Not IsError(rngA(i, 5)) Then
                If rngA(i, 5) <> 0 Or rngA(i, 5) <> "#N/A" Or Not IsEmpty(rngA(i, 5)) Then
                    'Col E is valid
                    store = True
                    col = 5
                End If
            End If
            'Is Col F valid?
            If store = False And Not IsError(rngA(i, 6)) Then
                If rngA(i, 6) <> 0 Or rngA(i, 6) <> "#N/A" Or Not IsEmpty(rngA(i, 6)) Then
                    'Col E is valid
                    store = True
                    col = 6
                End If
            End If

            'Store value to results
            If store = True Then
                myarray(0, 0) = rngA(i, 1)
                myarray(0, 1) = rngA(i, col)
                store = False
            End If
        Else
            'Results has at least one value check for duplicate
            'Loop thru results
            For k = LBound(myarray) To UBound(myarray)
                If datA(i, 1) = myarray(k, 0) Then
                    ' duplicate found
                    duplicate = True
                    Exit For
                End If
            Next

            If duplicate = False Then
                'validate data
                If Not IsError(rngA(i, 5)) Then
                    If rngA(i, 5) <> 0 Or rngA(i, 5) <> "#N/A" Or Not IsEmpty(rngA(i, 5)) Then
                        'Col E is valid
                        store = True
                        col = 5
                    End If
                End If
                'Is Col F valid?
                If store = False And Not IsError(rngA(i, 6)) Then
                    If rngA(i, 6) <> 0 Or rngA(i, 6) <> "#N/A" Or Not IsEmpty(rngA(i, 6)) Then
                        'Col E is valid
                        store = True
                        col = 6
                    End If
                End If

                'Store value to results
                If store = True Then
                    cntr = cntr + 1
                    myarray(cntr, 0) = rngA(i, 1)
                    myarray(cntr, 1) = rngA(i, col)
                    store = False
                End If
            End If
            duplicate = False
        End If
    Next


    Dim rngB As Range
    Set rngB = [B2:B10]
    datA = rngB

    'Range Column loop
    For i = LBound(datA, 1) To UBound(datA, 1)
        'Find first result
        If IsEmpty(myarray(0, 0)) Then
            'Is Col E valid?
            If Not IsError(rngA(i, 5)) Then
                If rngA(i, 5) <> 0 Or rngA(i, 5) <> "#N/A" Or Not IsEmpty(rngA(i, 5)) Then
                    'Col E is valid
                    store = True
                    col = 5
                End If
            End If
            'Is Col F valid?
            If store = False And Not IsError(rngA(i, 6)) Then
                If rngA(i, 6) <> 0 Or rngA(i, 6) <> "#N/A" Or Not IsEmpty(rngA(i, 6)) Then
                    'Col E is valid
                    store = True
                    col = 6
                End If
            End If

            'Store value to results
            If store = True Then
                myarray(0, 0) = rngA(i, 2)
                myarray(0, 1) = rngA(i, col)
                store = False
            End If
        Else
            'Results has at least one value check for duplicate
            'Loop thru results
            For k = LBound(myarray) To UBound(myarray)
                If datA(i, 1) = myarray(k, 0) Then
                    ' duplicate found
                    duplicate = True
                    Exit For
                End If
            Next

            If duplicate = False Then
                'validate data
                If Not IsError(rngA(i, 5)) Then
                    If rngA(i, 5) <> 0 Or rngA(i, 5) <> "#N/A" Or Not IsEmpty(rngA(i, 5)) Then
                        'Col E is valid
                        store = True
                        col = 5
                    End If
                End If
                'Is Col F valid?
                If store = False And Not IsError(rngA(i, 6)) Then
                    If rngA(i, 6) <> 0 Or rngA(i, 6) <> "#N/A" Or Not IsEmpty(rngA(i, 6)) Then
                        'Col E is valid
                        store = True
                        col = 6
                    End If
                End If

                If store = False Then
                    'Both are invalid
                    'look in col 'A' and reloop thru value to find another match

                    For p = LBound(myarray) To UBound(myarray)
                        If rngA(i, 1) = myarray(p, 0) Then
                            cntr = cntr + 1
                            myarray(cntr, 0) = rngA(i, 2)
                            myarray(cntr, 1) = myarray(p, 1)
                            store = False
                            Exit For
                        End If
                    Next

                End If

                'Store value to results
                If store = True Then
                    cntr = cntr + 1
                    myarray(cntr, 0) = rngA(i, 2)
                    myarray(cntr, 1) = rngA(i, col)
                    store = False
                End If
            End If
            duplicate = False
        End If
    Next

    For i = LBound(myarray) To UBound(myarray)
        Range("H" & i + 1).Value = myarray(i, 0)
        Range("I" & i + 1).Value = myarray(i, 1)
    Next
End Sub

输出如下:

enter image description here

我没有添加名称,但您可以通过修改数组来实现。