禁止“另存为”提示
我看了这个话题,发现了一些帮助,但build议似乎并没有工作。
- 我正在打开一个CSV文件到EXCEL中进行一些更改,然后想要将结果保存回相同的文件名和CSV格式。
- 我想这样做没有提示,我正在确保我想保存该文件。
- 我们正在使用一个macros启用Excel文件来导入数据进行更改,然后保存。
- 整个过程由一个batch file启动,这个batch file将会在一段时间内打开Excel应用程序和指定的文件,这就是为什么我们不希望提示停止进程。
这里是我在VBA中使用的代码来完成这项工作,以及我发现的其他潜艇,以帮助我压制提示。
此代码位于文件的TheWorkbook
中,而不是模块。
我错过了什么吗?
码
Sub fixfile() Const strFileName = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv" Dim wbkS As Workbook Dim wshS As Worksheet Dim wshT As Worksheet Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count)) Set wbkS = Workbooks.Open(Filename:=strFileName) Set wshS = wbkS.Worksheets(1) wshS.UsedRange.Copy Destination:=wshT.Range("A1") wbkS.Close SaveChanges:=False 'This is the area of work that we doing to the data 'Through here Application.DisplayAlerts = False 'IT WORKS TO DISABLE ALERT PROMPT ActiveWorkbook.SaveAs Filename:= _ "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat _ :=xlCSVMSDOS, CreateBackup:=False Application.DisplayAlerts = True 'RESETS DISPLAY ALERTS Application.Quit End Sub Private Sub Workbook_Open() fixfile End Sub Sub CloseandSave() ActiveWorkbook.Close SaveChanges:=True End Sub Private Sub Workbook_BeforeClose(Cancel As Boolean) ThisWorkbook.Save End Sub
你的代码中的问题是由于以下原因。
当您在启用macros的工作簿上调用SaveAs
时,您已经附加了一个工作表:
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
然后你试图将它保存为csv,这是一个只有一个工作表的文本文件,所以Excel抱怨说你会丢失信息。
而且,你正在对csv进行两次更新:一次在
ActiveWorkbook.SaveAs Filename:= ...
因此, 当前工作簿将成为保存的工作簿 ,然后再次放入Workbook_BeforeClose
。 在后者,你不会禁用警报,但无论如何不需要再次保存。
我得出的结论是,你想要的是使用启用macros的wb只是作为计算工具,而你只关心更新CSV
工作簿。
为了简单起见,我们将禁用整个会话的警报,因为启用macros的WB被用作实用程序,并且我们不希望批处理作业因任何原因而停止。 但是,如果你感觉更舒适,你可以用传统的方式,在保存前后进行。
' Code module ThisWorkbook Option Explicit Private Sub Workbook_Open() Application.DisplayAlerts = False Application.ScreenUpdating = False fixCSVFile ' Do the following only if you want the macro-enabled WB to keep ' a copy of the CSV worksheet. but my feeling is you dont want to ' ThisWorkbook.Save ''''''''''''''''''''' Application.Quit End Sub Sub fixCSVFile() Const strFileName = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv" Dim wbkS As Workbook, wshS As Worksheet, wshT As Worksheet Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count)) Set wbkS = Workbooks.Open(Filename:=strFileName) Set wshS = wbkS.Worksheets(1) wshS.UsedRange.Copy Destination:=wshT.Range("A1") wbkS.Close SaveChanges:=False 'This is the area of work that we doing to the data ' For purpose of testing: wshT.Range("A1").Value = wshT.Range("A1").Value + 1 ' Now we will export back the modified csv wshT.Move '<- Here we have a temporary workbook copy of the modified csv With ActiveWorkbook .SaveAs Filename:=strFileName, FileFormat:=xlCSVMSDOS, CreateBackup:=False .Close False End With End Sub
还有一件事情,启用macros的WB现在是这样的,它一打开就closures,所以编辑或修改将很困难(尽pipe有解决方法)。 因此,您应该保存它的备份副本,而不需要Application.Quit
作为testing/维护副本。 只有您为了批处理作业而投入生产的副本应具有Application.Quit
语句。
基于答案中的评论,即打开文件的原因,并立即保存它没有其他更改…
所以我们需要做我们正在做的事情,让文件编辑date改变,但不是实际的文件。
…这是一个完整的 XY问题 。 如果您需要更改文件的修改时间,只需更改文件的修改时间,而不是跳过所有打开和重新保存的循环:
Sub UpdateFileModifiedDate() Const filePath = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv" Dim handle As Integer handle = FreeFile Open filePath For Binary As #handle 'Read the first byte. Dim first As Byte Get #handle, 1, first 'Write it back Put #handle, 1, first Close #handle End Sub
这将比您当前的进程更加疯狂,只会将文件修改的date和时间设置为您运行Sub
的时间,并且不会冒任何其他可以通过Excel循环访问CSV文件的date(date格式和区域设置问题,截断小数,转换为指数表示法等等)。
既然你会有意识地覆盖现有的文件,你可以:
-
首先用一个
Kill
命令删除它 -
然后执行
SaveAs
所以改变这个代码部分:
'This is the area of work that we doing to the data 'Through here Application.DisplayAlerts = False 'IT WORKS TO DISABLE ALERT PROMPT ActiveWorkbook.SaveAs Filename:= _ "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat _ :=xlCSVMSDOS, CreateBackup:=False Application.DisplayAlerts = True 'RESETS DISPLAY ALERTS Application.Quit
对此:
'This is the area of work that we doing to the data 'Through here Kill strFileName '<-- delete the old file ActiveWorkbook.SaveAs Filename:= _ "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat _ :=xlCSVMSDOS, CreateBackup:=False Application.Quit
此外,可以通过正确处理ActiveWorkbook
和ActiveSheet
对象来重构代码,并减lessvariables和代码量,如下所示:
Sub fixfile() Const strFileName = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv" Workbooks.Open(Filename:=strFileName).Worksheets(1).UsedRange.Copy Destination:=Worksheets.Add(After:=Worksheets(Worksheets.Count)).Range("A1") '<--| open 'strFileName', reference and copy its 1st worksheet 'UsedRange' and paste it to a newly added worksheet in the macro workbook. After this statement we're left with the opened workbook as `ActiveWorkbook` ActiveWorkbook.Close SaveChanges:=False '<--| close `ActiveWorkbook`, ie the just opened one. We're left with macro workbook as `ActiveWorkbook` and its newly created worksheet as `ActiveSheet` 'This is the area of work that we doing to the data 'Through here ActiveSheet.Move '<--| move `ActiveSheet` (ie the newly created sheet in macro workbook) to a "new" workbook having that sheet as its only one. We're left with this "new" workbook as `ActiveWorkbook` Kill strFileName '<--| delete the "old" 'strFileName' ActiveWorkbook.SaveAs Filename:=strFileName, FileFormat:=xlCSVMSDOS, CreateBackup:=False '<--| save `ActiveWorkbook` (ie the "new" one) as the new 'strFileName' file ActiveWorkbook.Close SaveChanges:=False '<--| close `ActiveWorkbook` (ie the "new" one) without changes (we just "SavedA"s it) Application.Quit End Sub
看起来你正在对两个文件进行更改。 除了正在打开的csv文件之外,您似乎正在将一个工作表添加到使用以下行运行VBA代码的excel文件中:
Dim wshT As Worksheet Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
所以我的猜测是,你确实压制了csv文件的保存提示,但是当你尝试closures它时,你也得到了对excel工作簿进行的更改的保存提示。 所以我认为你也需要closures这个提示,同时closuresCloseAndSave子项中的DisplayAlerts,或者在实际closuresexcel工作簿的地方。
-
我不明白为什么要在启用macros的工作簿中将CSV表复制到新工作表中。 这是你的问题开始的地方!
- 你只需要处理
wshS
的数据并保存wbkS
。
完成了,没有更多的问题。
- 你只需要处理
-
你打电话时
ActiveWorkbook.SaveAs Filename:= _ "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat:=xlCSVMSDOS, CreateBackup:=False`
就像Excel所看到的那样,您将Excel中 当前启用macros的文件重命名为 CSV文件。
-
当调用
Application.Quit
,它将会调用Private Sub Workbook_BeforeClose(Cancel As Boolean) ThisWorkbook.Save End Sub
哪里是你抱怨的提示正在发生。
- 即使您删除它,在调用
Workbook_BeforeClose
之后, Excel仍将检查所有打开文件的.Saved
标志。 - Excel将提示您保存任何文件,其中
.Saved = False
- 即使您删除它,在调用
但是,如果您设置ThisWorkbook.Saved = True
然后Excel将closures该文件,而不要求保存。
解:
Private Sub Workbook_BeforeClose(Cancel As Boolean) ThisWorkbook.Saved = True End Sub