【问题标题】:ActiveWorkbook.SaveAS filename:= using special charactersActiveWorkbook.SaveAS 文件名:= 使用特殊字符
【发布时间】:2015-08-02 08:02:45
【问题描述】:

诚然,我不擅长理解行话,所以虽然我认为我对此进行了彻底的研究,但在某个地方可能会有完美的答案。这是我的困境,我正在开发这个 Excel VBA 宏来备份和恢复工作表(基本上给我无限的撤消到我指定的点以及保存和重新打开的捷径):

Public BULast As String

Sub Backup()

'This macro imitates videogame save-states. It will save a backup that can replace to current workbook later if you've made an irreversible mistake.

'Step 1: Agree to run away if things go wrong (establish an error handler)
On Error GoTo BackupError

'Step 2: Create some variables
    Dim OriginalFile As String
    Dim BUDir As String
    Dim BUXAr() As String
    Dim BUExt As String
    Dim BUNam As String
    Dim BackupFile As String

'Step 3: Define those variables
    OriginalFile = ActiveWorkbook.FullName
    BUDir = ActiveWorkbook.Path
    BUXAr = Split(ActiveWorkbook.FullName, ".")
    BUExt = BUXAr(UBound(BUXAr))
    BUNam = Replace(ActiveWorkbook.Name, "." & BUExt, "") & " (Back-Up)"
    BackupFile = BUDir & "\" & BUNam & "." & BUExt

'Step 4: Hide the truth
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

'Step 5(A): If there is no backup file, create one using the same file name as the one you're working with and throw a " (Back-up)" on it.
    If Dir(BackupFile) = "" Then

        ActiveWorkbook.SaveAs filename:=BackupFile

        ActiveWorkbook.Close

        Workbooks.Open filename:=OriginalFile

        BUYoN = vbNo

        BULast = Date & ", " & Time

        MsgBox "A Backup has been created!"

    Else

        BUYoN = MsgBox("This will restore the " & BULast & " backup and undo all changes made to this project. Continue?" _
            , vbYesNo, "Revert to Backup?")

    End If

'Step 5(B): If a backup has been created, restore it over the current workbook and delete the backup.
    If BUYoN = vbYes Then

        ActiveWorkbook.Close

        Workbooks.Open filename:=BackupFile

        ActiveWorkbook.SaveAs filename:=OriginalFile

        Kill (BackupFile)

        BUCheck = "Dead"

    End If

'Step 6: Put things back to the way you found them, you're done!
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    Exit Sub

'Step 1 (Continued): If nothing went wrong, stop worrying about it, if something did, say it didn't work and go away.

On Error GoTo 0

BackupError:

    MsgBox "Attempt to Backup or Restore was unsuccessful"

End Sub

通常它可以按预期工作,但就在昨天它开始无法正常工作,在玩弄它之后我意识到这是因为我在文件名中有 Ω 符号的文件上尝试它。

基本过程是在当前目录中查找活动工作簿的文件名,但在末尾添加(备份)。它要么创建一个,要么用它找到的替换打开的。然而,当在 Ω 文件上完成时,它会用 O 替换该字符。当再次运行时,它显然 搜索 Ω 正确,因为它找不到任何(即使使用 O-substitute 文件正确就在眼前)。

我知道最简单的解决方案是确保人们将他们的文件名保留在您在键盘上可以看到的内容,但这对我不起作用;我几乎热衷于将适应性放在代码而不是用户中。所以有了这个冗长的背景故事,这是我的具体问题:

VBA 中是否有可以处理指定文件名中的特殊字符的 SaveAs 函数或实用解决方法?

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    问题在于 Dir() 函数,因为它在检查文件之前将特殊字符转换为 ANSI,因此在这些情况下失败。请改用 FileSystemObject 对象:

    Sub Backup()
    
    On Error GoTo BackupError
    
        Dim OriginalFile As String
        OriginalFile = ActiveWorkbook.FullName
    
        ' get back up file name
        Dim BackupFile As String
        Dim pos As Integer
        pos = InStrRev(OriginalFile, ".")
        BackupFile = Mid$(OriginalFile, 1, pos - 1) & " (Back-Up)." & Mid$(OriginalFile, pos + 1)
    
        Application.ScreenUpdating = False
        Application.DisplayAlerts = False
    
    'Step 5(A): If there is no backup file, create one using the same file name as the one you're working with and throw a " (Back-up)" on it.
        Dim BUYoN As VbMsgBoxResult
        Dim BULast As String
        Dim fs As Object
        Set fs = CreateObject("Scripting.FileSystemObject")
        With fs
            If Not .FileExists(BackupFile) Then
    
                ActiveWorkbook.SaveAs Filename:=BackupFile
                ActiveWorkbook.Close
                Workbooks.Open Filename:=OriginalFile
                BUYoN = vbNo
                BULast = Date & ", " & Time
                MsgBox "A Backup has been created!"
    
            Else
                BUYoN = MsgBox("This will restore the " & BULast & " backup and undo all changes made to this project. Continue?" _
                    , vbYesNo, "Revert to Backup?")
    
            End If
        End With
    
    
    'Step 5(B): If a backup has been created, restore it over the current workbook and delete the backup.
        If BUYoN = vbYes Then
            ActiveWorkbook.Close
            Workbooks.Open Filename:=BackupFile
            ActiveWorkbook.SaveAs Filename:=OriginalFile
            'Kill (BackupFile)
            fs.Delete BackupFile
            Dim BUCheck As String
            BUCheck = "Dead"
    
        End If
    
    'Step 6: Put things back to the way you found them, you're done!
        Application.ScreenUpdating = True
        Application.DisplayAlerts = True
    
        Exit Sub
    
    
    On Error GoTo 0
    
    BackupError:
        MsgBox "Attempt to Backup or Restore was unsuccessful"
    End Sub
    

    【讨论】:

    • 注意:我重新编写了构建新文件名的部分,因为我认为这可能是问题的根源,但我现在不太确定。
    • 嗨,Rachel,感谢您抽出宝贵时间来解决这个问题!我使用名为“Bαckup Tεster Ω.xlsm”的文件对您的代码进行了测试。您的代码能够确认该文件存在,这比我的更进一步。它在 Kill 命令处出错,调试器将变量显示为“Backup Tester O.xlsm”。是否有替代 Kill 删除文件的方法?
    • 我更新了代码以使用fs.Delete 命令而不是Kill 命令。 Kill 可能与 Dir 有相同的问题,所以这应该适合你。
    • 谢谢瑞秋!这会很棒!我也很喜欢你建立新文件名的方式;它是如此简单和高效!如果我不是这样的新成员,我会向上箭头你。
    【解决方案2】:

    我知道我们不应该发表意见,但我认为 Rachel 是个天才!我不知道 FileSystemObject,但这最终成为了关键。它不仅能够搜索和识别带有特殊字符的文件,而且它似乎也可以删除它。将其合并到代码中可以使其在有或没有特殊字符的情况下完美运行:

    Public BULast As String
    
    Sub Backup()
    
    'This macro imitates videogame save-states. It will save a backup that can replace the
    'current workbook later if you've made an irreversible mistake.
    
    'Step 1: Agree to run away if things go wrong (establish an error handler)
        On Error GoTo BackupError
    
    'Step 2: Create some variables
        Dim OriginalFile As String
        Dim BUDir As String
        Dim BUXAr() As String
        Dim BUExt As String
        Dim BUNam As String
        Dim BackupFile As String
        Dim BUfs As Object
    
    'Step 3: Define those variables
        OriginalFile = ActiveWorkbook.FullName
        BUDir = ActiveWorkbook.Path
        BUXAr = Split(ActiveWorkbook.FullName, ".")
        BUExt = BUXAr(UBound(BUXAr))
        BUNam = Replace(ActiveWorkbook.Name, "." & BUExt, "") & " (Back-Up)"
        BackupFile = BUDir & "\" & BUNam & "." & BUExt
        Set BUfs = CreateObject("Scripting.FileSystemObject")
    
    
    'Step 4: Hide the truth
        Application.ScreenUpdating = False
        Application.DisplayAlerts = False
    
    'Step 5(A): If there is no backup file, create one using the same file name as the one
    'you're working with and throw a " (Back-up)" on it.
    
        With BUfs
            If Not .FileExists(BackupFile) Then
    
                ActiveWorkbook.Save
                ActiveWorkbook.SaveAs filename:=BackupFile
    
                ActiveWorkbook.Close
    
                Workbooks.Open filename:=OriginalFile
    
                BUYoN = vbNo
    
                BULast = Date & ", " & Time
    
                MsgBox "A Backup has been created!"
    
            Else
    
                BUYoN = MsgBox("This will restore the " & BULast & " backup and undo all changes made to this project. Continue?" _
                    , vbYesNo, "Revert to Backup?")
    
            End If
        End With
    
    'Step 5(B): If a backup has been created, restore it over the current workbook and
    'delete the backup.
        If BUYoN = vbYes Then
    
            ActiveWorkbook.Close
    
            Workbooks.Open filename:=BackupFile
    
            ActiveWorkbook.SaveAs filename:=OriginalFile
    
            BUfs.DeleteFile BackupFile, True
    
        End If
    
    'Step 6: Put things back to the way you found them, you're done!
        Application.ScreenUpdating = True
        Application.DisplayAlerts = True
    
        Exit Sub
    
    
    'Step 1 (Continued): If nothing went wrong, stop worrying about it, if something did,
    'say it didn't work and go away.
    
    On Error GoTo 0
    
    BackupError:
    
        MsgBox "Attempt to Backup or Restore was unsuccessful"
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-17
      • 2016-02-04
      • 2011-12-19
      • 2017-04-06
      • 1970-01-01
      相关资源
      最近更新 更多