I have the following code at the start of a routine:
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set ws1 = Workbooks.Open(ThisWorkbook.Sheets(1).[b4]).Sheets(1)
Set ws2 = Workbooks.Open(ThisWorkbook.Sheets(1).[b6]).Sheets(1)
Set ws3 = Workbooks.Open(ThisWorkbook.Sheets(1).[b8]).Sheets(1)
ws1.Move after:=ThisWorkbook.Sheets("MAIN")
ws2.Move after:=ThisWorkbook.Sheets("MAIN")
ws3.Move after:=ThisWorkbook.Sheets("MAIN")
'// remove redundant data
With ws1
With .Range("A2:A" & .Cells(.Rows.Count, 1).End(xlUp).Row)
...
Everything seems fine until the second With block, when I get an automation error:
Run-time error '-2147221080 (800401a8)':
Automation Error
Each of the files are CSV files with a single sheet, If I look in the locals window as they are being set they show as Worksheet/Sheet1 as I expect. Once I move the sheets to ThisWorkbook however, I notice that the type changes to Worksheet/Worksheet and I am no longer able to refer to ws1, ws2 or ws3 using the respective variables. The variables show as worksheet objects in the locals window and appear to be set to an object, but when I expand the variable's node it just states <No Variables>.
I haven't seen this behavior before in VBA so any explanations or suggestions would be greatly appreciated.
Thanks in advance.
The problem is that when you move a sheet from a 1 sheet workbook, it closes the workbook. would need to refer to the sheet in the current workbook not the one from the opened workbook. Code similar to below would work.
Sub tt()
Dim ws1 As Worksheet
Set ws1 = Workbooks.Open(ThisWorkbook.Sheets(1).[b1]).Sheets(1)
ws1_Name = ws1.Name
ws1.Move after:=ThisWorkbook.Sheets(1)
'// remove redundant data
With ThisWorkbook.Sheets(ws1_Name)
With .Range("A2:A" & .Cells(.Rows.Count, 1).End(xlUp).Row)
End With
End With
End Sub
You could also reset ws1 to the correct sheet
Set ws1 = ThisWorkBook.Sheets(ws1_Name)
Related
I am new to vba. I am trying to copy header row from one sheet to newly created another sheet. I am getting an out of range error when try to select new worksheet. Below is the code i am using.
With Sheets("Details Master")
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim rngsource As Range
Dim rngDest As Range
Set ws1 = Sheets("Details Master")
'Sheets("Details Master").Select
Set rngsource = ws1.Range("B2:L2")
rngsource.Copy
End With
With Sheets("Sh_name") **'Error on this line**
Set ws2 = Sheets("Sh_name") 'Sh_name is newly created sheet name
Set rngDest = ws2.Range("B2:L2")
rngDest.PasteSpecial
End With
Any idea what might be the issue.
You failed to add the new worksheet, as #Storax and # ashleedawg commented.
When using this basic code, please change the new worksheet name from "Temp" to what you want your worksheet name to be. Also make sure the name in the Destination line is the same name.
With ThisWorkbook
Sheets.Add(After:=Sheets(Sheets.Count)).Name = "Temp"
Sheets("Details Master").Range("B2:L2").Copy Destination:=Sheets("Temp").Range("B2")
End With
The goal here is to set a worksheet object, then move that worksheet to a new workbook and continue to use that worksheet object. However, by moving that worksheet it appears that the worksheet object previously associated with it is lost.
To test:
Lets say we have two excel workbooks in the same folder named Book1.xlsb and Book2.xlsb each with one sheet in them named Sheet1. When we open Book1 we put in the below sub and try to move a sheet from the other using a worksheet object.
Everything "works", but the worksheet object is lost in the process, and throws an error as soon as you try to use it again. Is it possible to move the worksheet to a new workbook and not lose that worksheet object association so that it can be referenced later?
Option Explicit
Sub test()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws As Worksheet
Set wb1 = ThisWorkbook
Set wb2 = Workbooks.Open("Book2.xlsb")
Set ws = wb2.Sheets(1)
ws.Name = "Sheet2" 'name changed to avoid conflict with the one already there
ws.Move wb1.Sheets(1)
MsgBox ws.Name 'this line throws an error, indicating that ws association has been lost
End Sub
Edit:
If this is not possible, how can we reliably re-set that worksheet object to the one that we just moved?
To reset the ws object:
Set ws = wb1.WorkSheets("Sheet2")
If you dont know the name, you know it was moved to the last position, right?
Set ws = wb1.WorkSheets(wb1.WorkSheets.Count)
If it was moved to the first position, then:
Set ws = wb1.WorkSheets(1)
In your code
ws.Move wb1.Sheets(1)
You alreay moved the sheet ws to the first sheet of the Book2.xlsb file
"Sheets(1)" means the first sheet of the file
So you can reset ws like this.
Set ws = wb1.Sheets(1)
I have a workbook named Test and wrote a macros with the code below. It worked fine, but when I added it to my personal workbook, the code gave an error on line Set ws = ThisWorkbook.Sheets("Sheet1").
Subscript out of range.
I moved the code from a module to the Sheet1 on the Personal Workbook and then to the ThisWorkbook. Nothing helped. If you could give any sort of advice of what I could try that would be greatly appreciated.
Sub KeepOnlyAtSymbolRows()
Dim ws As Worksheet
Dim rng As Range
Dim lastRow As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
lastRow = ws.Range("E" & ws.Rows.Count).End(xlUp).Row
Set rng = ws.Range("E1:E" & lastRow)
' filter and delete all but header row
With rng
.AutoFilter Field:=1, Criteria1:="<>*#*"
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
' turn off the filters
ws.AutoFilterMode = False
End Sub
Do you specifically wish to refer to the sheet "Sheet1" in the currently open workbook?
If so, use the line below
Set ws = ActiveWorkbook.Worksheets("Sheet1")
And if you simply wish to refer to the current sheet, use
Set ws = ActiveSheet
And if you wish to simply target the first sheet, whatever its name,
Set ws = ActiveWorkbook.Worksheets(1)
The way the code is currently written, it seems to be referring to "Sheet1" in the personal workbook and not necessarily the one currently active with the user.
I am trying to run a single macro which performs functions on multiple worksheets. Let's say I have assigned the macro button on worksheet 4. I have listed the functions I want it to perform step by step:
1) Select certain cells in worksheet 4 and copy to adjacent cells in worksheet 4.
2) delete range of cells in worksheet 3.
3) CUT range of cells in worksheet 2 then paste this range of cells into worksheet 3.
4) Take range of cells from a separate workbook and copy into worksheet 2. (I know this is an entirely different problem as the workbook is automatically published and I will have to find a way to link the two.)
5) Update pivot tables located within Worksheet 4 and Worksheet 3.
I would love help on the first 3 functions of this. I've pasted my current code below.
Sub START()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim sh4 As Worksheet
Set sh1 = ActiveWorkbook.Sheets("Brand")
Set sh2 = ActiveWorkbook.Sheets("CurrentWeek")
Set sh3 = ActiveWorkbook.Sheets("PriorWeek")
Set sh4 = ActiveWorkbook.Sheets("Pivot")
sh4.Range("B29:B30").Select
Selection.Copy
sh4.Range("C29").Select
ActiveSheet.Paste
sh3.Range("A4:AC1000").Select
Selection.Delete
sh2.Range("A4:AC1000").Select
Selection.Copy
sh3.Range("A4").Select
ActiveSheet.Paste
End Sub
It works... but it only works when I'm in the right worksheet to perform a specific function.
By removing the select, the selection and the activesheet, you will be able to make this sheet-independent
Sub START()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim sh4 As Worksheet
Set sh1 = ActiveWorkbook.Sheets("Brand")
Set sh2 = ActiveWorkbook.Sheets("CurrentWeek")
Set sh3 = ActiveWorkbook.Sheets("PriorWeek")
Set sh4 = ActiveWorkbook.Sheets("Pivot")
sh4.Range("B29:B30").Copy sh4.Range("C29")
sh3.Range("A4:AC1000").Delete
sh2.Range("A4:AC1000").Copy sh3.Range("A4")
End Sub
You are off to a great start. Just little more refinement and you'll have it.
Basically, there's no need to .Select your ranges (sheets, workbooks, etc), at least in this case. You can work directly with them and by using the Copy supply the destination where they will be copied.
See code below:
Sub START()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim sh4 As Worksheet
Dim wkb As Workbook
Set wkb = Workbooks("wkbName") '-> best to call workbooks by name, as opposed to "ActiveWorkbook", also best to set it to object
With wkb '-> now we can work with this object directly and succinctly
Set sh1 = .Sheets("Brand")
Set sh2 = .Sheets("CurrentWeek")
Set sh3 = .Sheets("PriorWeek")
Set sh4 = .Sheets("Pivot")
sh4.Range("B29:B30").Copy sh4.Range("C29")
'sh3.Range("A4:AC1000").Delete -> you don't need this if you are overwritting it
sh2.Range("A4:AC1000").Copy sh3.Range("A4")
End With
End Sub
sheets("name1").range("B29:B30").copy Destination:=sheets("name2").range("C29")
Will copy from one to another sheet assuming the sheet names are name1 and name2
Sub START()
Sheet("Pivot").Range("B29:B30").Copy Sheet("Pivot").Range("C29")
Sheet("CurrentWeek").Range("A4:AC1000").Copy Sheet("PriorWeek").Range("A4")
End Sub
I am opening 4 different xlsm files that ran a macro.
The macro reads data from the cells.
The macros work individually but together they get messed up.
because
Cells(1, 1).Value
is taken from the active sheet and not from the sheet I want .
Is there anyway to spicify a sheet like
workbook("example1").sheet("sheet1").Cells(1, 1).Value
workbook("example2").sheet("sheet1").Cells(1, 1).Value
?
Edit : (thanks Gimp)
I tried
Dim oWorkSheet As Worksheet
Set oWorkSheet = Workbooks("example1.xlsm").Sheets("sheet1")
oWorkSheet.Cells(1, 1).Value
and got a run time error
"Object doesn't support this property and method"
Yes this is a very common problem if you do not fully qualify your object. Let's take an example. If we have 4 workbooks and all four have Sheet called "Sheet1" then how should we ensure that the data is picked up from the right cell?
Cells(1, 1).Value
will always pick up the data from the current active sheet which might not be the sheet that you actually want.
If you are opening the 4 files via macro then this is the right way of doing it.
Sub Sample()
Dim wb1 As Workbook, wb2 As Workbook, wb3 As Workbook, wb4 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, ws4 As Worksheet
Set wb1 = Workbooks.Open("C:\File1.xlsx")
Set ws1 = wb1.Sheets("Sheet1")
Set wb2 = Workbooks.Open("C:\File2.xlsx")
Set ws2 = wb2.Sheets("Sheet1")
Set wb3 = Workbooks.Open("C:\File3.xlsx")
Set ws3 = wb3.Sheets("Sheet1")
Set wb4 = Workbooks.Open("C:\File4.xlsx")
Set ws4 = wb4.Sheets("Sheet1")
'~~> Now you can work with the relevant cells
Debug.Print ws1.Cells(1, 1).Value
Debug.Print ws2.Cells(1, 1).Value
Debug.Print ws3.Cells(1, 1).Value
Debug.Print ws4.Cells(1, 1).Value
End Sub
If you are not opening the four files via macro you can still set them to wb1, wb2 etc and then work as mentioned above.
Yes, use:
workbooks("example1.xlsm").sheets("sheet1").Cells(1, 1).Value
workbooks("example2.xlsm").sheets("sheet1").Cells(1, 1).Value
Update
Its either your workbook or sheet name that isnt working.
try msgbox Workbooks("example1.xlsm").name If that works then your problem is likely with the sheets() section. If it doesnt, then you may need to fully qualify the section like Workbooks("C:/Folder1/example1.xlsm")