递归连接路径和文件名

Concatenate path and filename recursively

我将输出导出到 Excel,其中列出了路径和文件名。

然而,路径和文件名位于不同的行中。如果路径一致,文件名将简单地列在下一行。然后下一个路径在下一行,后跟文件名等。

C:\
file1.doc
C:\Windows\
file2.doc
file3.doc
file4.doc
C:\Windows\Folder\
file5.doc

我需要将所有路径与文件名连接起来。所有路径都以 c:\(或可以定义的其他驱动器号)开头。对于上面的示例,需要以下输出:

C:\file1.doc
C:\Windows\file2.doc
C:\Windows\file3.doc
C:\Windows\file4.doc
C:\Windows\Folder\file2.doc

很高兴有空格,因为可以在 Excel 中过滤掉这些空格。

谢谢,

乔诺

使用列 A​​ 中的数据,此宏会将结果放入列 B:

Sub dural()
    Dim s As String, J As Long, r As Range
    J = 1

    For Each r In Intersect(ActiveSheet.UsedRange, Range("A:A"))
        s = r.Text
        If s = "" Then Exit Sub
        If Right(s, 1) = "\" Then
            pref = s
        Else
            Cells(J, 2).Value = pref & s
            J = J + 1
        End If
    Next r
End Sub

Non-VBA解决方案,这将需要一些辅助列:

假设您的数据在 A 列中,并且您不关心结果的排序/结果中是否有空格:

将其放入单元格 B2 并向下复制[我建议您为第 1 行设置一个 header 行]

=if(mid(A2,2,2)=":/",A2,B1) This puts the new file path in column B, and if it's not a new file path (doesn't start with "x:/"), it takes the file path from column the previous cell.

在单元格 C2 中,向下复制:

=if(mid(A2,2,2)=":/","",B2&A2) This checks if the line you're on is a file path or a file name. If it's a file name, it adds the file name to the file path and displays as a single string. If it's a filepath, it returns a blank.

或者,您可以使用列 B-D 而不是 B-C 来节省一点点处理时间。这里浪费了一些计算,因为我们在做同样的检查("does cell A2 include ':/'?")两次,所以excel需要计算两次。像这样:

将其放入单元格 B2:

=mid(a2,2,2)=":/" Returns TRUE if the cell in column A is a filepath; returns FALSE if the cell in column A is a filename. Then put this in cell C2 and copy down: =if(B2,A2,B1) Works same as above, but uses the test already defined in cell B2. Put this in cell D2 and copy down: =if(B2,"",B2&A2)

如果您确实想对结果列进行排序,只需执行 2 个额外步骤(这是不必要的,但如果您想以某种格式呈现/打印数据,则需要执行此操作或手动操作复制 + 粘贴值):

在我上述回复的最后一列右侧添加一个额外的列。在这里,您要检查当前行是新文件路径 + 文件名,还是空白(意味着 A 列是文件路径)。我假设您使用了上面的第二个选项,使用列 B-D.

在 E 列中,从 E2 开始向下复制:

=if(B2,B1,B1+1) If B2 is TRUE, the row is a filepath, and doesn't create a new filename + filepath. Therefore, we can keep the last counter. Otherwise, add a new counter.

在 F 列中,从 F2 开始向下复制: =if(row()-1>max(E:E),"",index(D:D,匹配(row()-1,E:E,0)))

这会查看您的结果列 D 列,该列未排序且包含空白。如果 F 列中的当前行号(header 行减 1)不大于 D 列中最大的计数器,则它 returns 是 D 列中该行号的匹配项。

希望这对您以后遇到类似情况有所帮助。

VBA 做法:

Sub test()
    Dim ws As Worksheet
    Dim iRow As Long
    Dim i As Integer
    Dim strFirstValue, strScndValue, strNewValue, strValue As String
    Dim startFlag, endFlag As Boolean

    Set ws = Sheets(1)

    iRow = ws.Range("A1048576").End(xlUp).Row
    strFirstValue = ws.Range("A2:A2")
    strFirstValue = "": strScndValue = ""
    startFlag = False
    strFirstValue = ws.Range("A2:A2")
    For i = 2 To iRow   'Assuming you have header, otherwise change 2 to 1
        If endFlag Then
            strFirstValue = ws.Range("A" & i & ":A" & i)
        End If
        strValue = strFirstValue

        strScndValue = ws.Range("A" & i + 1 & ":A" & i + 1)
        If InStr(strValue, ":") > 0 Then
            startFlag = True
            If Not strScndValue = "" Then
                If Not InStr(strScndValue, ":") > 0 Then
                    strNewValue = strFirstValue & strScndValue
                    ws.Range("B" & i + 1 & ":B" & i + 1) = strNewValue
                    endFlag = False
                Else
                    endFlag = True
                End If
            End If
        End If
    Next i

    'To remove the row with drive info
    For i = 2 To iRow
        strValue = ws.Range("B" & i & ":B" & i)
        If strValue = "" Then
            ws.Range("B" & i & ":B" & i).EntireRow.Delete
        End If
    Next i

    Set ws = Nothing
End Sub  

之前:

之后: