以递归方式连接路径和文件名

时间:2015-07-07 15:10:52

标签: excel excel-vba path excel-formula concat vba

我有一个导出到Excel的输出,其中列出了路径和文件名。

然而,路径和文件名位于不同的行上。如果路径一致,则文件名只列在下一行。然后下一个路径在下一行,然后是文件名ect。

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中过滤掉。

谢谢,

城野

3 个答案:

答案 0 :(得分:0)

对于 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

enter image description here

答案 1 :(得分:0)

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

假设您的数据位于A列,并且您不关心对结果进行排序/在结果中包含空格:

将它放在单元格B2中并复制下来[我建议你有第1行的标题行]

  

=如果(MID(A2,2,2)= “:/”,A2,B1)   这会将新文件路径放在B列中,如果它不是新文件路径(不以“x:/”开头),则从前一个单元格的列中获取文件路径。

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

  

=如果(MID(A2,2,2)= “:/”, “”,B2&安培; A2)   这将检查您所在的行是文件路径还是文件名。如果它是文件名,则将文件名添加到文件路径并显示为单个字符串。如果是文件路径,则返回空白。

或者,您可以使用B-D列而不是B-C来节省一点处理时间。这里浪费了一些计算,因为我们正在进行两次相同的检查(“单元格A2包括':/'?”),因此excel需要计算两次。像这样:

把它放在Cell B2中:

  

= MID(a2,2,2)= “:/”   如果A列中的单元格是文件路径,则返回TRUE;如果A列中的单元格是文件名,则返回FALSE。然后把它放在单元格C2中并复制下来:   = IF(B2,A2,B1)   与上面相同,但使用已在单元格B2中定义的测试。把它放在单元格D2中并复制下来:   = IF(B2 “”,B2&安培; A2)

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

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

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

  

=如果(B2,B1,B1 + 1)   如果B2为TRUE,则该行是文件路径,并且不会创建新的文件名+文件路径。因此,我们可以保留最后一个计数器。否则,添加一个新计数器。

在F栏中,从F2开始并向下复制: = IF(行() - 1>最大(E:E), “”,指数(d:d,匹配(行() - 1,E:E,0)))

这将查看结果列D列,该列未排序且包含空格。如果列F中的当前行号(标题行的减1)不大于列D中的最大计数器,则返回列D中该行号的匹配项。

希望这可以帮助你在将来的类似情况。

答案 2 :(得分:0)

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  

<强>之前:
enter image description here

<强>后:
enter image description here