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")
Related
I have three workbooks.
One workbook is a list I add to every month, of things I need to delete from a second workbook. I receive a second workbook every month. The second workbook I receive always contains extraneous entries (the number growing every month) and will not be fixed anytime soon. There is no general filter I can make without making the second workbook useless, so I need to be really specific and have a silly cleaning list.
My third workbook is where I run all of my workbook cleaning macros from.
The objective is to compare the entries in column A or B on the first workbook with the entries in column A or B of the second workbook I receive. If any of the entries match, delete the entire row on the second workbook.
I will be doing this once a month for a few hundred lines, and it will be run from a macro assigned to a shape on a third workbook.
Here I am posting some code that lets me open my two files and copy the contents of one of them, but what I need is code that will compare and delete rows on Workbook 2 that match with Workbook 1. My own code to do exactly that is terrible, not worth posting at all.
Code:
Sub test()
Dim strFileName As String
Dim wbTarget As Workbook
Dim wbSource As Workbook
Dim wsTarget As Worksheet
Dim wsSource As Worksheet
strFileName = Application.GetOpenFilename("Excel files (*.xls*),*.xl*", Title:="Open data")
Set wbSource = ThisWorkbook
Set wbTarget = Workbooks.Open(strFileName)
Set wsSource = wbSource.Worksheets("Sheet1")
Set wsTarget = wbTarget.Worksheets("Sheet1")
'to copy from Target - > Source
wsTarget.Range("B2").Resize(5, 5).Copy wsSource.Range("B2")
'etc.
End Sub
Code, comment and suggestion is greatly appreciated!
Cheers,
Christopher
CODE UPDATE 8:30 AM: This is a new way I am thinking of making things work. I am getting a type mismatch error on the code line Set Rng = Range("A1:B10000" & LR)
Sub test()
Dim strFileName As String
Dim strFileName2 As String
Dim wbTarget As Workbook
Dim wbSource As Workbook
Dim wsTarget As Worksheet
Dim wsSource As Worksheet
Dim LR
Dim Rng As Range
strFileName = Application.GetOpenFilename("Excel files (*.xls*),*.xl*", Title:="Open 'Things Which Have Been Removed'")
strFileName2 = Application.GetOpenFilename("Excel files (*.xls*),*.xl*", Title:="Open This Month's Purge List")
Set wbSource = ThisWorkbook
Set wbTarget = Workbooks.Open(strFileName)
Set wsSource = wbSource.Worksheets("Sheet1")
Set wsTarget = wbTarget.Worksheets("Sheet1")
Set LR = wsSource.UsedRange.Rows
With wbTarget.Sheets(1)
Set Rng = Range("A1:B10000" & LR)
Rng.RemoveDuplicates Columns:=Array(4), Header:=xlNo
End With
End Sub
To answer your specific question.
Set Rng = Range("A1:B10000" & LR)
Should be
Set Rng = Range("A1:B" & LR)
I would like to help with your other issues, but your description is confusing, this is what I understand; you identify bad information in the second workbook and copy that information from the second workbook to the first workbook, then you want a macro to match what is in the first workbook to the second workbook and delete the rows in the second workbook that match. Question, why don't you delete the rows in the second workbook instead of copying them to the first workbook?
You can use find method ; after open workbook u can use this code, findind the cell adress u can easily delete it clear command
Dim GCell As Range
Set GCell = ActiveSheet.Cells.Find("yourvariable")
I open two Workbooks that are part of the a 3D CAD file and have not real path.
Anyway, after I open them manually I want VBA to move, say, A1 from Workbook B To Workbook A.
In order for VBA to know the name of the source, I say the name of Workbook B is stored in B1 of Workbook A
I know how to move data if I have a path but since there is "none", how do I do that? Thank you!
Hope this help.
Dim FrmWorkbook As Workbook
Dim iCount As Integer
'Capture the source workbook
For i = 1 To ThisWorkbook.Application.Workbooks.Count
'change the name of your source Workbook below
If ThisWorkbook.Application.Workbooks(i).Name = "Book1.xlsx" Then
Set FrmWorkbook = ThisWorkbook.Application.Workbooks(i)
Exit For
End If
Next
'option 1: row by row or column by colum. (Column C)
Dim lRow As Long
For lRow = 1 To 100
ThisWorkbook.Sheets(1).Range("C" & lRow).Value = FrmWorkbook.Sheets(1).Range("C" & lRow).Value
Next
'option 2: copy the entire sheet (assuming Sheet1)
With FrmWorkbook.Sheets(1)
.Activate
.Select
.Copy before:=ThisWorkbook.Sheets(1)
End With
Set FrmWorkbook = Nothing
MsgBox "DONE"
After going back and forth i found out that this works too:
Private Sub import_Click()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set wb2 = ActiveWorkbook
Set ws2 = wb2.Sheets("sheet1")
Set wb1 = Workbooks(ActiveSheet.Range("n2").Value & ".xls")
Set ws1 = wb1.Sheets("input")
ws2.Range("a1") = ws1.Range("f90").Value
End Sub
Thank you for the good ideas
I am trying to combine numerous sheets into one new sheet. I would really appreciate any comments.
The issue is with the line:
wsSrc.Range("A1", wsSrc.Range("D", lastRow)).Copy Destination:=rngDest
Which causes the error when I try to run it. I have previously been using the code to combine all the sheets into the sheet Summary which is where the button for the macro is created which worked fine.
Sub mcrCombine()
ActiveWorkbook.Sheets.Add.Name = "Combined" 'Create new sheet
'Definitions
Dim wsSrc As Worksheet
Dim wsDest As Worksheet
Dim rngDest As Range
Dim lastRow As Long
Dim destRow As Long
Set wsDest = Worksheets("Combined") 'Destination sheet in same Workbook
Set rngDest = wsDest.Range("B1") 'Destination cell in Combined
Application.DisplayAlerts = False 'suppress prompt worksheet delete
'loop through all sheets
For Each wsSrc In ThisWorkbook.Sheets
If wsSrc.Name <> "Summary" And wsSrc.Name <> "Combined" Then 'all sheets except summary
lastRow = wsSrc.Cells.SpecialCells(xlCellTypeLastCell).Row 'define last row
wsSrc.Range("A1", wsSrc.Range("D", lastRow)).Copy Destination:=rngDest 'copy and paste data in range
Set rngDest = rngDest.Offset(lastRow - 1) 'update destination range
wsSrc.Delete 'delete source file
End If
Next
Application.DisplayAlerts = True 'prompts back on
End Sub
OK, I am not sure that this will get your code to achieve all what it is supposed to do, but since you corrected to issue pointed out by #Jeeped and specified your issue within this line:
wsSrc.Range("A1", wsSrc.Range("D", lastRow)).Copy Destination:=rngDest
The error in this line is because of the comma instead of the ampersand. You should change it into:
wsSrc.Range("A1", "D" & lastRow).Copy Destination:=rngDest
Hope this helps.
I have previously been using the code to combine all the sheets into the sheet Summary which is where the button for the macro is created which worked fine.
That's the clue as to what is occurring. As you cycle through each of the worksheets in the workbook you take care not to process the Summary worksheet; probably because a) it already holds aggregated information from the other worksheets and b) you do not want it deleted with the other worksheets that are processed.
If you have changed the central location to a Combined worksheet you are going to have to include that in the worksheet(s) to skip over. Failure to skip over the Combined worksheet will a) copy its content on top of itself and b) delete the Combined worksheet.
If wsSrc.Name <> "Summary" And wsSrc.Name <> "Combined" Then
If you delete the Combined worksheet, then there is Nothing in the way of a destination.
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)
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.