【问题标题】:How to extract file name from path?如何从路径中提取文件名?
【发布时间】:2009-11-16 16:39:21
【问题描述】:

如何在 VBA 中从 C:\Documents\myfile.pdf 中提取文件名 myfile.pdf?

【问题讨论】:

  • 尝试使用split函数从路径获取文件名:MSDN link

标签: string vba


【解决方案1】:

在 VBA for Office 2000/2003 中处理文件和目录的最佳方式是使用脚本库。

创建一个文件系统对象并使用它执行所有操作。

早期绑定:

添加对 Microsoft 脚本运行时的引用(IDE 中的工具 > 引用)。

Dim fso as new FileSystemObject
Dim fileName As String
fileName = fso.GetFileName("c:\any path\file.txt")

Late binding(更多信息请参见 cmets)

With CreateObject("Scripting.FileSystemObject")
    fileName = .GetFileName(FilePath)
    extName = .GetExtensionName(FilePath)
    baseName = .GetBaseName(FilePath)
    parentName = .GetParentFolderName(FilePath)
End With

FileSystemObject 很棒。它提供了许多功能,例如获取特殊文件夹(我的文档等),以面向对象的方式创建、移动、复制、删除文件和目录。

【讨论】:

  • 在 Excel VBA 中,Dim fileName As String; Dim fso as Object; Set fso = CreateObject("Scripting.FileSystemObject"); fileName = fso.GetFilename(path);
  • 一句警告,如果您收到“未定义用户定义类型”错误,您需要设置对 VB 脚本运行时库的引用。加载 VB 编辑器 (ALT+F11),从下拉菜单中选择工具 > 引用,然后从可用引用列表中勾选“Microsoft 脚本运行时”旁边的复选框,然后单击确定。
  • 不是一个好的解决方案:它需要对 VBA 的外部依赖。代码仍然不能在所有 VBA 环境中工作。
  • @Skrol29 世界上每个 Windows 机器都包含该库。没什么可担心的。接受的答案也不适用于 Mac。系统地后期绑定脚本运行时的人不知道他们在做什么,也不知道为什么。这个答案是完全可以接受的,并且 确实 比接受的答案高出一英里。或者两个。
  • @IceArdor 后期绑定脚本运行时不会给您带来任何好处。你会因为在运行时解决调用而受到性能损失,并且编译时检查为零,这意味着你打错了,在你运行代码之前你不会知道它,这将愉快地编译。不要后期绑定自 Win98 以来每台 Windows 机器上标准交付的库。
【解决方案2】:
Dir("C:\Documents\myfile.pdf")

将返回文件名,但前提是它存在。

【讨论】:

  • 错误,因为它假定路径是程序可以读取的物理文件。
  • 嗨@Skrol29,你能帮忙解释一下吗?
  • @HarryDuong Dir 返回文件名,但前提是该文件实际存在于该位置。如果文件不存在,Dir 返回一个空字符串。如果您知道文件存在,例如当您提示用户选择文件时,那么这是获取文件名的快速简便的方法。如果您不知道该文件是否存在,来自@ArturPiwkowski 的Split 更好。两个Splits 将比任何字符串操作都快。
  • @Harry Duong:函数 Dir() 确实在计算机上执行扫描以检查给定的掩码。在此示例中,掩码是预期文件的名称。如果该文件在计算机上不存在,则 Dir() 返回一个空值。但是在很多情况下,当您从物理上不存在的路径中提取名称时。例如要创建的文件的路径,或者之前刚刚删除的文件。
【解决方案3】:

这取自snippets.dzone.com:

Function GetFilenameFromPath(ByVal strPath As String) As String
' Returns the rightmost characters of a string upto but not including the rightmost '\'
' e.g. 'c:\winnt\win.ini' returns 'win.ini'

    If Right$(strPath, 1) <> "\" And Len(strPath) > 0 Then
        GetFilenameFromPath = GetFilenameFromPath(Left$(strPath, Len(strPath) - 1)) + Right$(strPath, 1)
    End If
End Function

【讨论】:

  • 正确,但是如果您使用的是 Mac 怎么办?不幸的是,这不是一个跨平台的解决方案..
  • 那么它在windows上坏了,对吧?我已经想办法使用Application.PathSeparator,但不幸的是,在 OSX VBA 上,甚至返回旧的:-notation 中的路径。我必须编写一个函数来转换这些路径。
  • 这可行,但是是不必要的递归,特别是对于 VBA(它不会自动将尾递归转换为循环)。
  • 恕我直言,stackoverflow.com/a/1755577/481207 by Zen 是一个更好的答案。代码重用,无递归,无嵌入常量。
  • @ThomasFankhauser 这是一条旧评论,但我很困惑:您为什么期望跨平台解决方案? (加上目前less than 1 in 5Stack Overflow 用户在 Mac 上)
【解决方案4】:

我已经阅读了所有答案,我想再添加一个我认为由于其简单性而胜出的答案。与公认的答案不同,这不需要递归。它也不需要引用 FileSystemObject。

Function FileNameFromPath(strFullPath As String) As String

    FileNameFromPath = Right(strFullPath, Len(strFullPath) - InStrRev(strFullPath, "\"))

End Function

http://vba-tutorial.com/parsing-a-file-string-into-path-filename-and-extension/ 具有此代码以及其他用于解析文件路径、扩展名甚至不带扩展名的文件名的功能。

【讨论】:

  • 对我来说最好的:聪明、矮小、越野。
  • +1 为简单起见 - 甚至可以放弃该功能,并按原样或循环使用“=”行来处理多个文件。
  • 我更喜欢这个而不是其他任何答案。它可以很容易地在任何其他子或函数中重用,并且不需要对引用进行任何摆弄
  • 这很棒,因为您可以在受限的脚本环境中使用它(在我的例子中是 RPA)。
【解决方案5】:

我无法相信其中一些答案是多么复杂......(没有冒犯!)

这是一个可以完成工作的单行函数:


Function getFName(pf)As String:getFName=Mid(pf,InStrRev(pf,"\")+1):End Function

Function getPath(pf)As String:getPath=Left(pf,InStrRev(pf,"\")):End Function

示例:

【讨论】:

  • 我不喜欢单行函数的风格,除非你正在尝试 Code Golf。我正在寻找一种可以嵌入到 SQL 查询中的方法,而您的代码(没有该函数)是最简单的:Left(pf,InStrRev(pf,"\")) 这利用了mid() 的第三个参数是可选的。
【解决方案6】:
Dim sFilePath$, sFileName$
sFileName = Split(sFilePath, "\")(UBound(Split(sFilePath, "\")))

【讨论】:

  • 不太聪明,因为它运行了两次Split(sFilePath, "\")。
【解决方案7】:

如果您想要一个更强大的解决方案,可以同时为您提供完整文件夹的路径和文件名,这里是:

Dim strFileName As String, strFolderPath As String
Dim lngIndex As Long
Dim strPath() As String

strPath() = Split(OpenArgs, "\")   'Put the Parts of our path into an array
lngIndex = UBound(strPath)
strFileName = strPath(lngIndex)    'Get the File Name from our array
strPath(lngIndex) = ""             'Remove the File Name from our array
strFolderPath = Join(strPath, "\") 'Rebuild our path from our array

或作为子/功能:

Private Sub SeparatePathAndFile(ByRef io_strFolderPath As String, ByRef o_strFileName As String)    
    Dim strPath() As String
    Dim lngIndex As Long

    strPath() = Split(io_strFolderPath, "\")  'Put the Parts of our path into an array
    lngIndex = UBound(strPath)
    o_strFileName = strPath(lngIndex)   'Get the File Name from our array
    strPath(lngIndex) = ""              'Remove the File Name from our array
    io_strFolderPath = Join(strPath, "\")     'Rebuild our path from our array  
End Sub

您将第一个参数与文件的完整路径一起传递,它将被设置为文件夹的路径,而第二个参数将被设置为文件的名称。

【讨论】:

    【解决方案8】:

    这是我编写的一个简单的 VBA 解决方案,适用于 Windows、Unix、Mac 和 URL 路径。

    sFileName = Mid(Mid(sPath, InStrRev(sPath, "/") + 1), InStrRev(sPath, "\") + 1)
    
    sFolderName = Left(sPath, Len(sPath) - Len(sFileName))
    

    您可以使用以下代码测试输出:

    'Visual Basic for Applications 
    http = "https://www.server.com/docs/Letter.txt"
    unix = "/home/user/docs/Letter.txt"
    dos = "C:\user\docs\Letter.txt"
    win = "\\Server01\user\docs\Letter.txt"
    blank = ""
    
    sPath = unix 
    sFileName = Mid(Mid(sPath, InStrRev(sPath, "/") + 1), InStrRev(sPath, "\") + 1)
    sFolderName = Left(sPath, Len(sPath) - Len(sFileName))
    
    Debug.print "Folder: " & sFolderName & " File: " & sFileName
    

    另见:Wikipedia - Path (computing)

    【讨论】:

      【解决方案9】:

      在excel宏中获取文件名是:

      filname = Mid(spth, InStrRev(spth, "\", Len(spth)) + 1, Len(spth))
      MsgBox Mid(filname, 1, InStr(filname, ".") - 1)
      

      【讨论】:

        【解决方案10】:

        如果您确定文件实际存在于磁盘上,最简单的方法是:

        Dim fileName, filePath As String
        filePath = "C:\Documents\myfile.pdf"
        fileName = Dir(filePath)
        

        如果您不确定文件是否存在或只是想从给定路径中提取文件名,那么最简单的方法是:

        fileName = Mid(filePath, InStrRev(filePath, "\") + 1)
        

        【讨论】:

          【解决方案11】:
          函数 file_name_only(file_path As String) As String 昏暗温度作为变体 temp = Split(file_path, Application.PathSeparator) file_name_only = temp(UBound(temp)) 结束功能
          1. 在此输入文件名作为函数的输入
          2. VBA 的 split 函数通过使用“\”作为路径分隔符将路径拆分为不同部分,并将它们存储在名为“temp”的数组中
          3. UBound() 查找数组的最大项数,最后将结果分配给“file_name_only”函数

          希望这会有所帮助。

          【讨论】:

            【解决方案12】:

            这是一个没有代码的替代解决方案。此 VBA 在 Excel 公式栏中工作:

            提取文件名:

            =RIGHT(A1,LEN(A1)-FIND("~",SUBSTITUTE(A1,"\","~",LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))))
            

            提取文件路径:

            =MID(A1,1,LEN(A1)-LEN(MID(A1,FIND(CHAR(1),SUBSTITUTE(A1,"\",CHAR(1),LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))))
            

            【讨论】:

              【解决方案13】:

              我正在使用这个功能... VBA 函数:

              Function FunctionGetFileName(FullPath As String) As String
              'Update 20140210
              Dim splitList As Variant
              splitList = VBA.Split(FullPath, "\")
              FunctionGetFileName = splitList(UBound(splitList, 1))
              End Function
              

              现在输入

              =FunctionGetFileName(A1) in youe required cell.
              

              或者您可以使用这些...

              =MID(A1,FIND("*",SUBSTITUTE(A1,"\","*",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))
              

              【讨论】:

                【解决方案14】:

                我需要的是路径,而不是文件名。

                所以要提取代码中的文件路径:

                JustPath = Left(sFileP, Len(sFileP) - Len(Split(sFileP, "\")(UBound(Split(sFileP, "\"))))) 
                

                【讨论】:

                  【解决方案15】:

                  这是从 Twiggy @http://archive.atomicmpc.com.au 和其他地方收集到的:

                  'since the file name and path were used several times in code
                  'variables were made public
                  
                  Public FName As Variant, Filename As String, Path As String
                  
                  Sub xxx()
                     ...
                     If Not GetFileName = 1 Then Exit Sub '
                     ...
                  End Sub
                  
                  Private Function GetFileName()
                     GetFileName = 0 'used for error handling at call point in case user cancels
                     FName = Application.GetOpenFilename("Ramp log file (*.txt), *.txt")
                     If Not VarType(FName) = vbBoolean Then GetFileName = 1 'to assure selection was made
                     Filename = Split(FName, "\")(UBound(Split(FName, "\"))) 'results in file name
                     Path = Left(FName, InStrRev(FName, "\")) 'results in path
                  End Function
                  

                  【讨论】:

                    【解决方案16】:
                    Dim nme As String = My.Computer.FileSystem.GetFileInfo(pathFicheiro).Name
                    Dim dirc As String = My.Computer.FileSystem.GetFileInfo(nomeFicheiro).Directory
                    

                    【讨论】:

                    • 虽然您的回答可能适用于该问题,但能否请您添加一些关于正在做什么的解释?
                    • 这是更好的解决方案。它从给定的路径 pathFicheiro 中提取文件名和目录。不需要 nomeFicheiro,因为您可以使用 pathFicheiro。 pathFicheiro = 文件名变量
                    • 抱歉,除非我遗漏了什么,否则这里是.net,所以它不能回答vba 的问题。
                    猜你喜欢
                    • 2011-04-28
                    • 1970-01-01
                    • 2010-10-01
                    • 2016-06-19
                    • 2013-08-19
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多