VBA: SaveAs method creates infinite csv file - vba

I am looping through several worksheets in a file, copying information to another sheet (called wsCSV, which is stored in ThisWorkbook) and then I want to create a CSV file from this worksheet. After creating the sheet, the loop should continue to the next sheet.
Here is part of the code which should create the CSV:
' Create CSV file
If iControl = 1 Then
Application.DisplayAlerts = False
wsCSV.Copy
ActiveWorkbook.SaveAs Filename:=sDestin & "\" & sShName & ".csv", FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close SaveChanges:=False
Application.DisplayAlerts = True
End If
Anyway, when I proceed the code, SaveAs method starts creating "infinite" file, till it consumes all my disk space. I don't know how is it possible, as the file has 6 rows and 3 columns, so it should have 1-2 kb. I have to stop the process manually. Any thoughts? I tried this code in another macro and it worked OK.
Thanks!

Make sure that your wsCSV worksheet is truly as empty as you think it is. Use Ctrl-End to see what the last used cell is and clean it up if necessary.

Related

Excel macro to open a folder of excel workbooks and copy 1 cell

I have a folder of .xlsx files, each identical in layout.
I need to write a macro in excel to open each file in turn (100+ files)
then get the data (a name) from a single cell, and drop it in a new excel worksheet, move on to the next and insert that below the last one etc.
Giving me basically a list of names from data not file names)
Here is (pretty much) exactly what you're trying to do. Next time do a little bit of googling before you ask! :)
http://www.excel-easy.com/vba/examples/files-in-a-directory.html
ROUGH CODE UNSURE IF IT WILL WORK: But here is the basic idea of what you need to modify in the example I sent you. If you look at the example again, it does everything you need and then some. Since you weren't interested in all worksheets, you don't have to loop through all worksheets in a workbook. You can just open it up, read your cell of interest, and then close it. The Do While loop will do this for every Excel file in your directory. AGAIN! Please modify this example accordingly before you use it.
Dim directory As String, fileName As String, sheet As Worksheet, i As Integer, j As Integer
Application.ScreenUpdating = False
directory = "c:\test\"
fileName = Dir(directory & "*.xl??")
Do While fileName <> ""
i = i + 1
Workbooks.Open (directory & fileName)
Workbooks("files-in-a-directory.xls").Worksheets(1).Cells(i, 1).Value = Workbooks(fileName).Worksheets(1).Cells(x, y) <-- whatever your cell of interest is
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True

Copy data from multiple excel sheets and append that to a single excel sheet using VBScript

The scenario is as follows:
I have an excel (.xls) file with data. (eg. A.xls)
The Data on this excel file are on a single worksheet (Sheet 1).
The number of columns in this file is fixed i.e. 8
However, the number of rows containing data may vary from time to time. (This file is updated by another program from time to time)
Now, I have another excel file (eg. B.xls) with similar type of data but not same as the contents of A.xls.
The number of columns in B.xls is 8 as well. However, the number of rows containing data are unknown.
I want to copy the contents of A.xls, 2nd row onwards (excluding the 1st row containing the column headers) and append/paste the same to the B.xls file, without over-writing the existing data on B.xls.
With all these details in mind, I want to write a vbscript to automate this task.
Please help.
Thanks a lot, in advance.
It needs a lot of cleanup, but something like this should work. I'll clean it up a bit and then make an edit.
Sub CopyRows()
' Choose the name of the Second Workbook and last column.
' It must be in the same directory as your First Workbook.
secondWorkbook = "B.xls"
lastColumn = "H"
' A couple more variables
currentWorkbook = ThisWorkbook.Name
Workbooks.Open ThisWorkbook.Path & "\" & secondWorkbook
' In the First Workbook, find and select the first empty
' cell in column A on the first Worksheet.
Windows(currentWorkbook).Activate
With Worksheets(1).Columns("A:A")
Set c = .Find("", LookIn:=xlValues)
If Not c Is Nothing Then
' Select and copy from A2 to the end.
secondAddress = Replace(c.Address, "$A$", "")
Range("A2:" & lastColumn & CStr(CInt(secondAddress) - 1)).Select
Selection.Copy
End If
End With
' Activate the Second Workbook
Windows(secondWorkbook).Activate
With Worksheets(1).Columns("A:A")
Set c = .Find("", LookIn:=xlValues)
If Not c Is Nothing Then
' Select and paste the data from First Workbook
Range(c.Address).Select
ActiveSheet.Paste
End If
End With
End Sub
Update: That should do the trick. I copied from the wrong workbook the first time around, too. Let me know if you have questions.
This is something the Macro Recoder could have written for you. You would come out with different approach.
Turn on recording. Open A.xls and B.xls. Move down one row on a. Press Shift+End then →, then Shift+End+↓. Then Ctrl+C to copy your data. Switch back to B. End+↓, ↓. Ctrl+V to paste. Turn off recording.
You can record in Excel.
Alt+T,M,R
then Home key then ↑. Stop recording.
Look what Excel wrote
Selection.End(xlUp).Select
or if you had of recorded Go To dialog
Application.Goto Reference:="R1C1"
or if you had of recorded Ctrl+Home
Range("A1").Select
To convert to vbscript
Record the steps in excel macro recorder. You have to rewrite it a bit because it uses a type of syntax that vbs doesn't.
This applies (I don't have a medium9) xlRangeAutoFormatAccounting4 in vba.
Selection.AutoFormat Format:=xlRangeAutoFormatAccounting4, Number:=True, _
Font:=True, Alignment:=True, Border:=True, Pattern:=True, Width:=True
So first look up constants in vba's object browser. xlRangeAutoFormatAccounting4 = 17
Then look the function up in object browser and look at the bottom for the function definition,.
Function AutoFormat([Format As XlRangeAutoFormat = xlRangeAutoFormatClassic1], [Number], [Font], [Alignment], [Border], [Pattern], [Width])
So the vba becomes in vbs (and vbs works in vba) (and as you can see you can work out the correct way without needing to look the function up usually)
Selection.AutoFormat 17, True, True, True,True, True, True
So your code becomes
objXLWs.Range("A3").CurrentRegion.Select.AutoFormat 17, True, True, True,True, True, True

Macro Produces Different Results If Clicking Screen While Running

I have two files (Microsoft Excel 97-2003 Worksheets) that contain multiple fields of data. A macro I have will open both files, copy the data (without headers) from one of them, and paste that data underneath the data in the other file. Once the data has been combined, I save the combined file as a new workbook. A somewhat stripped down version of the code I have is below (sorry it's inefficient; I had only just begun VBA when I wrote it):
Sub Combine()
' Combine Macro
' Turn some things off to speed things up
Application.ScreenUpdating = False
Application.StatusBar = False
Application.EnableEvents = False
' Set to directory where files to combine exist
ChDir "C:\Users\Me\Desktop\Macro Work"
' Variable Declarations
Dim EmptyRow As Long
Dim FileA, FileB As String
Dim Day as Integer
Day = 1
' Loop and combine the two files for each day of the month (if they exist)
Do Until (Day > 31)
' Get FileA and FileB names
FileA = "FileA" & Day & ".xls"
FileB = "FileB" & Day & ".xls"
' Open files A and B; handle error if file doesn't exist
On Error Resume Next
Workbooks.Open FileName:=FileA
If Err.Number = 1004 Then
GoTo NoFile
End If
Workbooks.Open FileName:=FileB
If Err.Number = 1004 Then
GoTo NoFile
End If
On Error GoTo 0
'Copy data from FileB and paste into FileA
EmptyRow = Workbooks(FileA).Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row + 1
Range(Range("A2"), Range("A2").End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy Workbooks(FileA).Worksheets(1).Range("A" & EmptyRow)
' Save combined workbook as FileName in Excel format
Workbooks(FileA).SaveAs FileName:="CombinedFile" & Day, FileFormat:=51
' Close the workbooks
Workbooks("CombinedFile" & Day).Close SaveChanges:=False
Workbooks(FileB).Close SaveChanges:=False
NoFile:
Day = Day + 1
Loop ' End of Loop
MsgBox "PAUSE - End of Macro"
End Sub
My problem isn't that that Macro won't run or throws an error. Rather if I run it and don't do anything else, I get one set of results. But if I run it and click on the VBA Editor Window while it's running, I get a different set of results.
Is it a known fact that you shouldn't do other things on your machine while your macro is running? Or have I neglected to add a piece of code that will keep the results of the macro consistent whether or not I sit and watch or am clicking the VBA Editor Window?
Thanks in advance, and let me know if I can provide further clarification.
Zachary
EDIT:
It's difficult to track down exactly what goes wrong with combining the files, but I can see that the number of lines differ. The combined file generated when I am clicking on the Editor Window has several thousand lines less than when I just watch it run. And I'll need to retract my earlier claim that I can consistently produce the same error. I can consistently reproduce an error, but the results may differ (i.e. maybe I'm missing only 4995 lines instead of 5000).
Liam, your response makes sense to me. However, I have a near identical Macro that skips this section:
'Copy data from FileB and paste into FileA
EmptyRow = Workbooks(FileA).Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row + 1
Range(Range("A2"), Range("A2").End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy Workbooks(FileA).Worksheets(1).Range("A" & EmptyRow)
Since sometimes the files I work with only have "FileA" I don't combine anything and instead use a Macro to open the file and SaveAs FileFormat=51 and with a new name. Obviously that removes sections in the code where I select data in the file. Yet I still receive different results when clicking. What might be causing this?
Lastly, in addition to removing sections of code where Selection is used, is there a way to help prevent the user from messing up the results of the macro in this way?
Thanks again.
its because you use:
Range(Range("A2"), Range("A2").End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Just because screenupdate is false, doesn't mean excel isn't executing your clicks. You can't reference a selection and expect it not to change if you select something else
Answers To Updated Question
You can easily remove the need to "select" cells by defining them in a range and referencing your new range. This will remove the possibility of users clicking and messing up the flow of your script
'Copy data from FileB and paste into FileA
Dim R1 as Range
Dim R2 as Range
EmptyRow = Workbooks(FileA).Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row + 1
Set R1 = Range(Range("A2"), Range("A2").End(xlDown))
Set R2 = Range(R1, R1.End(xlToRight))
R2.Copy Workbooks(FileA).Worksheets(1).Range("A" & EmptyRow)
This will do the same as your original code, without using select
One way to eliminate these problems is to reference the sheet in your calls (Sheets(1).Range(...)), and minimize selection (instead of .Select and then Selection., just put your Range.Copy or whatever you're doing). A little more code, but more robust.

Excel VBA code is causing my worksheets to appear as jargon

I currently am using a VBA macro that I found here on stack over flow. The problem is when I run it it saves all the data into a separate excel sheet but when i open it it appears as "jargon" in other words unreadable type. This is the "Save code"
'Save the new workbook, and close it
wb.SaveAs ThisWorkbook.Path & "\test" & WorkbookCounter
wb.Close
The way I am currently running the code is that it separates my excel sheets into different spread sheets by rows of 250. Everything works but when I open the saved documents it says that this file format is unacceptable to Excel. Then I try importing it and I get an error. Here is a snap shot of the way it appears in my screen. Also here is the file name: built.list\test.xls39
Your workbook counter always ends in a number, Windows and Excel use the file extension to determine file-type, so an '.xls39' file is unrecognisable. Try:
wb.SaveAs _
Filename:=ThisWorkbook.Path & "\test" & WorkbookCounter & ".xls" _
FileFormat:=XlFileFormat.xlExcel8
'Use xlOpenXMLWorkbook for the .xlsx format
(Use space followed by underscore to separate lines in VBA)
Or make sure WorkbookCounter ends in .xls and not a number.
(Edit: For other formats, please look in the References dialog in Excel VBA Editor)

Copy workbook containing macro to a workbook without macro

I am able to duplicate a workbook (copy to a desired location) which contains a macro in the background. This duplicate copy also contains the same macro.
My Problem is I do not want this duplicate workbook to have a macro with it. Can anyone tell how to do it?
Thank you in advance!!!
Save your workbook as macro-free, i.e. simply as Excel Workbook. For my Excel 2007 this is done using:
Application.DisplayAlerts = False
ThisWorkbook.CheckCompatibility = False
ThisWorkbook.SaveAs Filename:="D:\DOCUMENTS\Book1.xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = True
Correct path & name as you wish.
Read more about SaveAs method: http://msdn.microsoft.com/en-us/library/office/ff841185%28v=office.14%29.aspx
...and available File Formats: http://msdn.microsoft.com/en-us/library/office/ff198017%28v=office.14%29.aspx
Hope that was helpful)