View Full Version : Solved: New to VBA - Help me in making this code shorter and better
vicks
02-06-2009, 07:49 AM
Hi All
Thanks for this great Forum. I have written first code in life :) . It is for a simple activity , opening 4 files (Euro, GBP, USD, in one folder copying the active sheets in a new workbook (Consolidated) in other location. So that this new workbook has four sheets. I am sure there must be a better way to do this, like using a list box to store file name). Also I want to give name to sheets same as file names from where they are copies (to difficult for me :think:)
The code is as follows. Please help...This will help me in learning a lot.
Sub Copy_Data()
Workbooks.Open FileName:=("C:/VBA Source/Euro.xls")
Workbooks("Euro.xls").Sheets(1).Copy _
After:=Workbooks("Consolidated.xls").Sheets(1)
Workbooks("Euro.xls").Close
Workbooks.Open FileName:=("C:/VBA Source/USD.xls")
Workbooks("USD.xls").Sheets(1).Copy _
After:=Workbooks("Consolidated.xls").Sheets(1)
Workbooks("USD.xls").Close
Workbooks.Open FileName:=("C:/VBA Source/JPY.xls")
Workbooks("JPY.xls").Sheets(1).Copy _
After:=Workbooks("Consolidated.xls").Sheets(1)
Workbooks("JPY.xls").Close
Workbooks.Open FileName:=("C:/VBA Source/GBP.xls")
Workbooks("GBP.xls").Sheets(1).Copy _
After:=Workbooks("Consolidated.xls").Sheets(1)
Workbooks("GBP.xls").Close
MsgBox ("Copying worksheets completed")
End Sub
Bob Phillips
02-06-2009, 08:12 AM
I cannot see what possible purpose trying to shorten this code or using a listbox will serve.
Sub Copy_Data()
Dim ThisWb As Workbook
Dim wb As Workbook
Set ThisWb = Workbooks("Consolidated.xls")
Set wb = Workbooks.Open(Filename:=("C:/VBA Source/Euro.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Workbooks.Open Filename:=("C:/VBA Source/USD.xls")
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Workbooks.Open Filename:=("C:/VBA Source/JPY.xls")
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Workbooks.Open Filename:=("C:/VBA Source/GBP.xls")
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
MsgBox ("Copying worksheets completed")
End Sub
vicks
02-06-2009, 08:27 AM
Hi
Thanks a lot for your reply. I am getting error on the following line. The first step is getting completed properly
Workbooks.Open FileName:=("C:/VBA Source/USD.xls")
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Regards
Bob Phillips
02-06-2009, 08:34 AM
Works okay for me. What error do you get?
vicks
02-06-2009, 08:39 AM
After opening the second file , i get the error on line [saying Run time error'-2147221080 (800401a8)
Automation errror]
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
vicks
02-06-2009, 09:09 AM
Hi I did some trial and error and could solve it. Here is the code which i used. Apprantely Set Wb = was missing from the second loop. Can you tell me what does Set do?
Sub Copy_Data()
Dim ThisWb As Workbook
Dim wb As Workbook
Set ThisWb = Workbooks("Consolidated.xls")
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/Euro.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/USD.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/JPY.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/GBP.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
MsgBox ("Copying worksheets completed")
End Sub
vicks
02-06-2009, 10:02 AM
If I want to run above Macro in the same file again How to first delete existing sheets in the file with name USD, Euro, JPY and GBP (Or to say other way round delete all sheets except for Sheet1), so that programme runs properly.
Bob Phillips
02-06-2009, 10:12 AM
Hi I did some trial and error and could solve it. Here is the code which i used. Apprantely Set Wb = was missing from the second loop. Can you tell me what does Set do?
It assigns an object to an object variable.
Most variables such as
myvar = 10
are really saying
Let myvar = 10
Set is used to distinguish objects from data types.
Greetings vicks,
I noticed that you just joined and your noting that this was your first efforts. Boy Howdy(!), yours sure looked better than my first attempts. Shucks, my poor computer thought there was only two modes for a while: off or BOOM!
Anyways, you asked about 'resetting' (so-to-speak) your workbook (wb) so the code could be re-run. This would be one way:
Option Explicit
Sub ThisWB_Reset()
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
If Not wks.Name = "Sheet1" Then
Application.DisplayAlerts = False
wks.Delete
Application.DisplayAlerts = True
End If
Next
End Sub
Hope that helps,
Mark
vicks
02-06-2009, 11:04 AM
Hi GTO
Thanks for your reply and morale boosting reply. Certainly there is long way to go. :friends:
Well tell me one thing in this case I had only 4 files. If I have 20 files, can i not store the list somewhere and write the code in such a way that I can pick up name from that list? So that I dont have to write 4 lines for each file?
Vicks
vicks
02-06-2009, 11:29 AM
Hi
Also Mark, Can you tell me how and where to put code given by you in my code? It has to be subroutine or i can put it inside? :think:
Please post entire code.
Thanks
Vicks
Hi Vicks,
Sure there is. First I need to ask a question, as I think I totally missed something, and goobered up that last answer.
What is the name of the workbook that your code is stored in? I ask because my answer assumed the code is in "Consolidated.xls" and in re-reading your and Bob's (XLD) posts, I think I was wrong.
Mark
vicks
02-06-2009, 11:37 AM
Hi
My code is stored in Consolidated.xls and i am consolidating 4 worksheets in this file.
Vicks
vicks
02-06-2009, 12:32 PM
Hi Mark
I could use your code in subroutine, only thing is added following addtional line in your codeOnly thing i did not use Option Explicit anywhere...I dont know how to use it
Set ThisWb = Workbooks("Consolidated.xls")
I also added additional subrouitne to delete few columns from all the sheets in Consolidated.xls.
Here is my new code which worked fine
Sub Copy_Data()
Dim ThisWb As Workbook
Dim wb As Workbook
Set ThisWb = Workbooks("Consolidated.xls")
'to reset workbook
Call Resetting
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/Euro.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ActiveSheet.Name = wb.Name
'ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/USD.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ActiveSheet.Name = wb.Name
'ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/JPY.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ActiveSheet.Name = wb.Name
'ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/GBP.xls"))
wb.Sheets(1).Copy After:=ThisWb.Sheets(1)
ActiveSheet.Name = wb.Name
'ThisWb.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
'For Deleting Colums
Call Deletecolumn
MsgBox ("Copying worksheets completed")
End Sub
Sub Resetting()
Dim wks As Worksheet
Set ThisWb = Workbooks("Consolidated.xls")
For Each wks In ThisWb.Worksheets
If Not wks.Name = "Sheet1" Then
Application.DisplayAlerts = False
wks.Delete
Application.DisplayAlerts = True
End If
Next
End Sub
Sub Deletecolumn()
ActiveWorkbook.Sheets.Select
Columns("B:AG").Select
Selection.Delete Shift:=xlToLeft
Columns("C:BF").Select
Selection.Delete Shift:=xlToLeft
'ActiveCell.FormulaR1C1 = "RECEIVE_CCY"
Columns("E:F").Select
Selection.Delete Shift:=xlToLeft
Columns("G:AC").Select
Selection.Delete Shift:=xlToLeft
Columns("H:H").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
End Sub
Do suggest changes if any
Well firstly, "Phew!", I got lucky on that one. As the code is in Consolidated, we can skip a 'Set' and just use ThisWorkbook, which always refers to the workbook it resides within.
Also - I've gotta get to work, but here's an "untested but I think okay" example. I'm sure you'll get any more questions answered, as there are some great folks here and Bob (XLD) was already helping you. He is just plain skads more knowledgeable than me; I just happened to notice your question on deleting the 'old' sheets.
Hope this helps,
Mark
Sub Copy_Data()
'// Skip this. As the code resides in Consolidated, we can just use ThisWorkbook. //
'Dim ThisWb As Workbook
Dim wb As Workbook
Dim wks As Worksheet
Dim lLastRow As Long
Dim rCell As Range
'// This will loop thru ea worksheet in ThisWorkbook (Consolidated)... //
For Each wks In ThisWorkbook.Worksheets
'// ...and if the sheet is not named (the name on the tab) "Sheet1"... //
If Not wks.Name = "Sheet1" Then
'// ...after first turning off .DisplayAlerts (so that it doesn't stop and //
'// ask us "Are you sure...?" before deleting ea sheet... //
Application.DisplayAlerts = False
'//...it then deletes the sheet... //
wks.Delete
'// ... and then turns DisplayAlerts back on, so that we don't later bash //
'// thru and do something we didn't intend to. //
Application.DisplayAlerts = True
End If
Next
'// Now, this presumes that on "Sheet1", Column A is blank, excepting for your list //
'// of workbook (wb) names that you wish to open and copy a sheet from. PLease //
'// note that there can not be other stuff farther down in Col A below your list //
'// of wb names. //
'// So, start your list of names in cell A1, then A2 and so on. Also, I left the //
'// extension in below, so it is not needed in the cell. i.e. - in cell A1, you //
'// could list "Euro", not "Euro.xls" //
lLastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For Each rCell In ThisWorkbook.Worksheets("Sheet1").Range("A1:A" & lLastRow)
Set wb = Workbooks.Open(Filename:=("C:/VBA Source/" & rCell.Value & ".xls"))
wb.Sheets(1).Copy After:=ThisWorkbook.Sheets(1)
ThisWorkbook.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Next
End Sub
Hey there,
ieexplorer crashed and you got a bit ahead on me. Read #15 in response to your #13.
Sorry 'bout the delay, I'm out for a bit,
Mark
vicks
02-06-2009, 01:17 PM
Hey Mark,
Thanks...doesnt matter , late reply is better than no reply :yes
And boss...your code worked :yes (Although i didnt understand it fully)
I am pasting the revised code, just to be on same lines.
Can you explain me how does these two lines work and what those actually do?
lLastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For Each rCell In ThisWorkbook.Worksheets("Sheet1").Range("A1:A" & lLastRow)
Here is the code
Sub Copy_data()
Dim wb As Workbook
Dim wks As Worksheet
Dim lLastRow As Long
Dim rCell As Range
For Each wks In ThisWorkbook.Worksheets
If Not wks.Name = "Sheet1" Then
Application.DisplayAlerts = False
wks.Delete
Application.DisplayAlerts = True
End If
Next
lLastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For Each rCell In ThisWorkbook.Worksheets("Sheet1").Range("A1:A" & lLastRow)
Set wb = Workbooks.Open(FileName:=("C:/VBA Source/" & rCell.Value & ".xls"))
wb.Sheets(1).Copy After:=ThisWorkbook.Sheets(1)
ThisWorkbook.Worksheets(2).Name = Replace(Replace(wb.Name, ".xls", ""), "C:/VBA Source/", "")
wb.Close
Next
'For Deleting Colums
Call Deletecolumn
MsgBox ("Copying worksheets completed")
End Sub
Sub Deletecolumn()
ActiveWorkbook.Sheets.Select
Columns("B:AG").Select
Selection.Delete Shift:=xlToLeft
Columns("C:BF").Select
Selection.Delete Shift:=xlToLeft
ActiveCell.FormulaR1C1 = "RECEIVE_CCY"
Columns("E:F").Select
Selection.Delete Shift:=xlToLeft
Columns("G:AC").Select
Selection.Delete Shift:=xlToLeft
Columns("H:H").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
End Sub
mdmackillop
02-06-2009, 05:21 PM
lLastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Like going to the bottom cell in Column 1 and pressing Control + Up arrow and getting the row number of the selected cell
For Each rCell In ThisWorkbook.Worksheets("Sheet1").Range("A1:A" & lLastRow)
If ILastRow returned 30, this will loop through each cell from A1:A30
Delete column can be tidied up to
Sub Deletecolumn()
ActiveWorkbook.Sheets.Select
Columns("B:AG").Delete
Columns("C:BF").Delete
Range("C1") = "RECEIVE_CCY"
Columns("E:F").Delete
Columns("G:AC").Delete
Columns("H:H").Select
Range(Columns("H:H"), Columns("H:H").End(xlToRight)).Delete
End Sub
Do you really mean to run this on all sheets? see first line of code.
vicks
02-09-2009, 03:17 AM
Hi mdmac
Thanks for your explaination and suggestion. Yes I want to perform the operation on all the sheets.
Thanks indeed. If I want to store the name of the files in the code itself rather than excel sheet, how can I do it and will it be more efficient?
Further assuming that all the files in the source folder go through this operation, is there any way out to shorten the code, knowing that i have to select all the files.
Regards
Vicks
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.