VBA Saving single sheet as CSV (not whole workbook) - vba

I appreciate there are lots of entries like save individual excel sheets as csv
and Export each sheet to a separate csv file - But I want to save a single worksheet in a workbook.
My code in my xlsm file has a params and data sheet. I create a worksheet copy of the data with pasted values and then want to save it as csv. Currently my whole workbook changes name and becomes a csv.
How do I "save as csv" a single sheet in an Excel workbook?
Is there a Worksheet.SaveAs or do I have to move my data sheet to another workbook and save it that way?
CODE SAMPLE
' [Sample so some DIMs and parameters passed in left out]
Dim s1 as Worksheet
Dim s2 as Worksheet
Set s1 = ThisWorkbook.Sheets(strSourceSheet)
' copy across
s1.Range(s1.Cells(1, 1), s1.Cells(lastrow, lastcol)).Copy
' Create new empty worksheet for holding values
Set s2 = Worksheets.Add
s2.Range("A1").PasteSpecial Paste:=xlPasteValuesAndNumberFormats
' save sheet
s2.Activate
strFullname = strPath & strFilename
' >>> BIT THAT NEEDS FIXIN'
s2.SaveAs Filename:=strFullname, _
FileFormat:=xlCSV, CreateBackup:=True
' Can I do Worksheets.SaveAs?
Using Windows 10 and Office 365

This code works fine for me.
Sub test()
Application.DisplayAlerts = False
ThisWorkbook.Sheets(strSourceSheet).Copy
ActiveWorkbook.SaveAs Filename:=strFullname, FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Sub
It's making a copy of the entire strSourceSheet sheet, which opens a new workbook, which we can then save as a .csv file, then it closes the newly saved .csv file, not messing up file name on your original file.

This is fairly generic
Sub WriteCSVs()
Dim mySheet As Worksheet
Dim myPath As String
'Application.DisplayAlerts = False
For Each mySheet In ActiveWorkbook.Worksheets
myPath = "\\myserver\myfolder\"
ActiveWorkbook.Sheets(mySheet.Index).Copy
ActiveWorkbook.SaveAs Filename:=myPath & mySheet.Name, FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close
Next mySheet
'Application.DisplayAlerts = True
End Sub

You just need to save the workbook as a CSV file.
Excel will pop up a dialog warning that you are saving to a single sheet, but you can suppress the warning with Application.DisplayAlerts = False.
Don't forget to put it back to true though.

Coming to this question several years later, I have found a method that works much better for myself. This is because the worksheet(s) I'm trying to save are large and full of calculations, and they take an inconvenient amount of time to copy to a new sheet.
In order to speed up the process, it saves the current worksheet and then simply reopens it, closing the unwanted .csv window:
Sub SaveThisSheetInParticular()
Dim path As String
path = ThisWorkbook.FullName
Application.DisplayAlerts = False
Worksheets("<Sheet Name>").SaveAs Filename:=ThisWorkbook.path & "\<File Name>", FileFormat:=xlCSV
Application.Workbooks.Open (path)
Application.DisplayAlerts = True
Workbooks("<File Name>.csv").Close
End Sub
Here the Sheet and csv filename are hardcoded, since nobody but the macro creator (me) should be messing with them. However, it could just as easily be changed to store and use the Active Sheet name in order to export the current sheet whenever the macro is called.
Note that you can do this with multiple sheets, you simply have to use the last filename in the close statement:
Worksheets("<Sheet 1>").SaveAs Filename:=ThisWorkbook.path & "\<File 1>", FileFormat:=xlCSV
Worksheets("<Sheet 2>").SaveAs Filename:=ThisWorkbook.path & "\<File 2>", FileFormat:=xlCSV
[...]
Workbooks("<File 2>.csv").Close

Related

after run macro to save as xlsx file, the macro file convert to xlsx file

I want the macro to backup my xlsm file as xlsx format, still remain there after save as xlsx type. However, below coding will convert the existing xlsm file to xlsx file, causing my macro file dissapear. Any suggestion to avoid this, I want xlsx file save and close while xlsm file remain?
Sub backup()
Application.DisplayAlerts = False
ThisWorkbook.saveas "C:\Users\Documents\Book1.xlsx", xlOpenXMLWorkbook
Application.DisplayAlerts = True
End Sub
Use SaveCopyAs.
Sub Test()
Dim wb As Workbook, wb2 As Workbook
Dim Path As String
Application.DisplayAlerts = False
Path = "C:\Users\" & Environ("Username") & "\Desktop\"
Set wb = ThisWorkbook
wb.SaveCopyAs (Path & "File.xlsm")
Set wb2 = Workbooks.Open(Path & "File.xlsm")
wb2.SaveAs Path & "File1.xlsx", xlOpenXMLWorkbook
wb2.Close
Application.DisplayAlerts = True
End Sub
This would save a copy to your desktop, but does not affect the Workbook you are working in.
ThisWorkbook addresses the workbook in which the code is located. If you wish to save the ActiveWorkbook you must address it either as ActiveWorkbook or by its name.
Once you save ThisWorkbook in xlsx format the code can't continue to run. To do what you intend to do you might place the code in a third file, like an add-in, and manipulate your workbooks from there.

How can I export usedrange of values without exporting formulas in Visual Basic Excel

I have tried multiple variations, and keep getting the same result. The most recent iteration is this:
Sub CopyToCSV()
' Copy and Paste Active Sheet
ActiveSheet.Copy
With ActiveSheet.UsedRange
.Value = .Value
End With
'The new workbook becomes Activeworkbook:
With ActiveWorkbook
'Saves the new workbook to given folder / filename:
.SaveAs Filename:= _
"C:\upload\19meat-kl.csv", _
FileFormat:=xlCSV, _
CreateBackup:=False
'Closes the file
.Close False
End With
End Sub
My output keeps looking like this:
Store,Department,Date,Category,Item Count,Retail Price,Dollars,Reduced Retail,Total Loss,Reason for loss
18,90,2017-04-04,Meat,2,3,6,1,4,Out of Date
18,90,2017-04-04,Pork,2,1.5,3,0.99,1.02,Other
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
The reason is that my Excel file contains some formulas like this:
=IF(D5>0,TODAY(),"")
This auto fills some of the cells if they enter anything into certain cells. This causes Excel to think that the cells are "used" and includes them. I attempted several variations of Worksheet.usedrange.values and I either get the same output or I get a debug prompt due to bad code. How can I remove the commas from the output?
edited to include the whole code
just Clear the nearly-blank cells
Sub CopyToCSV()
' Copy and Paste Active Sheet
ActiveSheet.Copy
With ActiveSheet.UsedRange
.Value = .Value
.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End With
'The new workbook becomes Activeworkbook:
With ActiveWorkbook
'Saves the new workbook to given folder / filename:
.SaveAs Filename:="C:\upload\19meat-kl.csv", FileFormat:=xlCSV, CreateBackup:=False
'Closes the file and discard changes (no needed any more)
.Close False
End With
End Sub
Instead of copying and pasting the entire used range, you can copy from your starting row to the last row that doesn't have a formula in it. That last row can be found by using this:
Dim i As Integer
With Sheets(1).Columns("A").SpecialCells(xlCellTypeConstants)
i = .Cells(.Cells.Count).row
End With

Suppress "Save As" prompt

I looked this topic up and found some help but the suggestions do not seem to be working.
I am opening a CSV file into EXCEL make some changes and then want to save the results back to the same file name and the CSV format.
I want to do this without the prompt that I am getting to make sure I want to save the file.
We are using a macro enabled excel file to import the data make changes and then save.
This whole process with initiated by a batch file that will open the Excel application and the designated file at regular period of time so that is why we do not want the prompt to stop the process.
Here is the code I am using in VBA to do the work, as well as the other subs I found that were suppose to help me suppress the prompt.
This code is in the TheWorkbook of the file and not a module.
Am I missing something?
code
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
The problems in your code are due to the following.
When you call SaveAs on the macro-enabled workbook, you had already appended a worksheet to it:
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
and then you're trying to save it as csv, which is a text file with only one worksheet, so Excel complains that you will loose information.
Moreover, you're doing the update to the csv twice: once in the
ActiveWorkbook.SaveAs Filename:= ...
Where, as a result, the current workbook becomes the saved workbook, and then again in the Workbook_BeforeClose. In the latter you dont disable the alerts, but anyway there's no need to save again.
I have come to the conclusion that what you want is to use the macro-enabled wb just as a utility for calculation, and you care only for updating the CSV workbook.
For simplicity, we will disable the alerts for the whole session, because the macro-enabled WB is used as a utility and we dont want the batch job to stop for any reason. However you can do it the traditional way, before and after saving, if you feel more comfortable with it.
' 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
One more thing, the macro-enabled WB is now such that it closes as soon as it opens so it will be difficult to edit or modify (although there are workarounds). Therefore you should save a back-up copy of it without the Application.Quit, as a testing/maintenance copy. Only the copy that you put in production for the sake of the batch job should have the Application.Quit statement.
Based on the comment in the answers that the reason for opening the file and immediately saving it with no other changes...
So we needed to do what we were doing to get the file edit date to
change but not the actual file.
...this is a complete X-Y problem. If you need to change a file's modified time, just change the file's modified time instead of jumping through all of the opening and re-saving hoops:
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
This will be insanely faster than your current process, will only set the file modified date and time to the time that you run the Sub, and doesn't risk any of the other issues you can run into cycling a CSV file through Excel (date formats and locale issues, truncating decimals, conversions to exponential notation, etc., etc.).
since you're going to consciously overwrite an existing file you can just:
first delete it with a Kill command
then do the SaveAs
so change this code section:
'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
to this:
'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
furthermore your code can be refactored by properly handling the ActiveWorkbook and ActiveSheet objects and reduce the variables and code amount, like follows:
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`, i.e. 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` (i.e. 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` (i.e the "new" one) as the new 'strFileName' file
ActiveWorkbook.Close SaveChanges:=False '<--| close `ActiveWorkbook` (i.e the "new" one) without changes (we just "SavedA"s it)
Application.Quit
End Sub
It seems like you are making changes to two files. In addition to the csv file that you are opening, you appear to be adding a sheet to the excel file that is running the VBA code with these lines:
Dim wshT As Worksheet
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
So my guess is that you are indeed suppressing the save prompt for the csv file but you are also getting a save prompt for the changes you made to the excel workbook when you attempt to close it. So I think you need to suppress that prompt as well by also turning off DisplayAlerts in the CloseAndSave sub, or wherever the excel workbook is actually being closed.
I don't get why you are copying the CSV sheet into a new sheet in the macro enabled workbook. This is where your problem starts!
You should just be dealing with the data in wshS and saving wbkS instead.
Done, no more problems.
When you call
ActiveWorkbook.SaveAs Filename:= _
"W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv",
FileFormat:=xlCSVMSDOS, CreateBackup:=False`
you're renaming the current macro enabled file within excel to the CSV file as far as Excel sees it.
When Application.Quit is called, it is going to call
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Save
End Sub
Which is where the prompt that you are complaining about is happening.
Even if you remove it, after Workbook_BeforeClose is called, Excel is still going to check all the open files' .Saved flag.
Excel will prompt you to save any files where .Saved = False
But if you set ThisWorkbook.Saved = True then Excel will close the file without asking to save.
Solution:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Saved = True
End Sub

Excel VBA execute code in newly created workbook

I'm trying to save one worksheet in my excel file to a new file, but without the formula's.
I have this code that is working to get the file saved:
Sub SaveInvoice()
'Create a filename based on invoicenumber
Dim FileName As String
FileName = Sheets("Sale").Range("C3").Value
'Copy the "Print" sheet
Worksheets("Print").Copy
With ActiveWorkbook
'Save the file as new
.SaveAs FileName:="C:\" & FileName
End With
End Sub
This works like a charm, however I need to strip out the formula's so I googled and fount this piece of code:
ActiveSheet.Copy
Cells.Copy
Range("A1").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
And this works as well, however once I merge the two pieces of code together the whole function breaks.
With ActiveWorkbook
'Transform cells to values
ActiveSheet.Copy
Cells.Copy
Range("A1").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
'Save the file as new
.SaveAs FileName:="C:\" & FileName
End With
This results in my base worksheet beeing stripped from formula's.
I need to know how I can call the function on the newle created workbook.
When copying a worksheet with no Destination excel creates a New Workbook, and the New Workbook with its only Worksheet are active.
EDIT: I just realized that in the final code these lines from the original code:
'Copy the "Print" sheet
Worksheets("Print").Copy
Were moved inside the
With ActiveWorkbook
That was previously referring to the New Workbook created by the Worksheet.Copy and that now refers to the Source Workbook
So let see what the Op's final code is actually doing:
Here the ActiveWorkbook is the [Source Workbook] and the ActiveSheet must be [Print]
With ActiveWorkbook
This copies the ActiveSheet creating a New Workbook with only one sheet
ActiveSheet.Copy
These lines are affecting the ActiveSheet [Print] in the [Source Workbook].
Not because of the With statement but because it's the one active
Cells.Copy
Range("A1").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
The commands within a With intended to affect object that it refers to must start with a dot [.]; however these lines are invalid because Cells and Range are not Methods nor Properties of the Workbook Object, thus en error would have been triggered.
With Statement
Executes a series of statements on a single object or a user-defined type.
(from the msdn.microsoft.com help)
This saves the Workbook referred by the With statement, which still has the formulas
'Save the file as new
.SaveAs FileName:="C:\" & FileName
End With
Try this code:
Sub SaveInvoice_TEST_1()
'Create a filename based on invoicenumber
Dim FileName As String
With ThisWorkbook
FileName = .Sheets("Sale").Range("C3").Value
'Copy the "Print" sheet
.Worksheets("Print").Copy
End With
With ActiveWorkbook
Rem Replace Formulas with Values
.Sheets(1).UsedRange.Value = .Sheets(1).UsedRange.Value2
'Save the file as new
.SaveAs FileName:="C:\" & FileName
End With
End Sub
Suggest to read the following pages to gain a deeper understanding of the resources used:
With Statement
Try something like the following. Read the help page for 'ActiveSheet.Copy' - note that it creates a new workbook and activates it
Dim MyWkbk as workbook
set MyWkbk = ActiveWorkbook
ActiveSheet.Copy
With ActiveWorkbook
Cells.Copy
Range("A1").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
'Save the file as new
.SaveAs FileName:="C:\" & FileName
'.close
End With
MyWkBk.activate
Thanks to #EEM the solution was found.
Here's the code I used:
Sub SaveInvoice()
Dim FileName As String
With ThisWorkbook
'Create a filename based on invoicenumber
FileName = .Sheets("Sale").Range("C3").Value
'Copy the "Print" sheet
.Worksheets("Print").Copy
End With
With ActiveWorkbook
'Replace Formulas with Values
.Sheets(1).UsedRange.Value = .Sheets(1).UsedRange.Value2
'Save the file as new
.SaveAs FileName:="C:\" & FileName
End With
End Sub

Save Specific single sheet as .csv

I have a very similar question as this post:
Save individual Excel sheets as CSV
My question differs in that I only need one sheet to be saved
This is the answer from that post
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.SaveAs "C:\docs\" & ws.Name & ".csv", xlCSV
Next
This code saves each worksheet to a specific folder and names the file the same as the worksheet. 2 problems I see:
1- The workbook you were currently working on becomes the very last worksheet the code saved. If you want to keep working on your workbook you have to open the original file. It would work better if a new workbook was opened and saved separately from the one that is being worked on.
2- It saves each worksheet. I only need to save one specific worksheet, i.e Sheet2
I found this other code but I am VERY new to VBA and only know how to create a macro, copy & paste code into it. I get error when I run the code.
Sub test()
Application.DisplayAlerts = False
ThisWorkbook.Sheets(strSourceSheet).Copy
ActiveWorkbook.SaveAs Filename:=strFullname, FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Sub
Hopefully I can get pushed in the right direction. Thanks!
strSourceSheet is the sheet which has the name/number of the sheet which you want to export
strFullname is the filename with path of the csv. As simple as that.
Now see this code
ThisWorkbook.Sheets(strSourceSheet).Copy
ActiveWorkbook.SaveAs Filename:=strFullname, _
FileFormat:=xlCSV, _
CreateBackup:=True
ActiveWorkbook.Close
Let's say I want to copy Sheet2 then I would write it as
Dim strSourceSheet As String
Dim strFullname As String
'~~> Change the below two lines as per your requirements
strSourceSheet = "Sheet2"
strFullname = "C:\Temp\MyCsv.Csv"
ThisWorkbook.Sheets(strSourceSheet).Copy
ActiveWorkbook.SaveAs Filename:=strFullname, _
FileFormat:=xlCSV, _
CreateBackup:=True
ActiveWorkbook.Close
Did you notice how we switch between ThisWorkbook and ActiveWorkbook. When you copy the sheet a new workbook is created and becomes active and hence to close that we use ActiveWorkbook
Hope this helps.