Code has error. When I debug, it shows the error of last line.
Sub test()
WB_Master = ActiveWorkbook.Name
Dim ra As Range
open file
Workbooks.Open FileName:="X:\Projects\RPOC\Comparison\book1.xlsx"
WB_Source = ActiveWorkbook.Name
Workbooks(WB_Source).Activate
Worksheets("sheet1").Activate
' set value to ra. Is it correct?
Set ra = Range("c2")
Workbooks(WB_Source).Close SaveChanges:=False
Workbooks(WB_Master).Activate
Worksheets("sheet1").Activate
Set Range("k2").Value = ra.Value
End Sub
You can't Set a Value - you should only use the Set keyword when assigning an object reference. (E.g. your Set ra = Range("c2") is assigning a reference to Range("c2") to your object ra.)
So change
Set Range("k2").Value = ra.Value
to
Range("k2").Value = ra.Value
Because you are also closing the workbook that contains the range referred to by your ra variable before you use it, you will also have problems. I have refactored your code to get around that issue:
Sub test()
Dim WB_Source As Workbook
Dim WB_Master As Workbook
Set WB_Master = ActiveWorkbook
Set WB_Source = Workbooks.Open(FileName:="X:\Projects\RPOC\Comparison\book1.xlsx")
WB_Master.Worksheets("sheet1").Range("k2").Value = _
WB_Source.Worksheets("sheet1").Range("c2").Value
WB_Source.Close SaveChanges:=False
End Sub
(Note: I changed your WB_Source and WB_Master variables from being Variant/String to being Workbook.)
Related
I want below code to open a closed workbook and copy the values from the range StartRow and EndRow to active workbook.
I get
error 1004 "No such interface supported".
on line "xlBook.Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select"
When I run this code directly in the workbook I want to copy the data from, it works.
Sub GetDataFromClosedBook()
'copy data from closed workbook to active workbook
Dim xlApp As Application
Dim xlBook As Workbook
Dim sh As Object
Set xlApp = CreateObject("Excel.Application")
'Path source Wokrbook
Set xlBook = xlApp.Workbooks.Open("C:\Users\name\Desktop\EXCEL USEFUL DOSC\Missing Data Check New Process\Missing Data Reports\" & Sheets("Data Check").Range("C3").Value & ".xlsx")
xlApp.Visible = True
ShName = Sheets("Data Check").Range("C3").Value
With xlBook.Sheets(ShName)
StartRow = .Range("E:E").Find(what:="January-2020", after:=.Range("E1")).Row
EndRow = .Range("E:E").Find(what:="January-2020", after:=.Range("E1"), searchdirection:=xlPrevious).Row
'ThisWorkbook.Activate
xlBook.Sheets(ShName).Range("A2").Value = ShName
xlBook.Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select
'Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select
End With
xlApp.DisplayAlerts = False
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
Set xlBook = ActiveWorkbook
Set sh = Sheets("Dealer_ID Check")
sh.Activate
Range("A1").Select
sh.Paste
End Sub
Putting all the comments together, your code so far could be refactoed as
Option Explicit
Sub GetDataFromClosedBook()
'copy data from closed workbook to active workbook
Dim wbData As Workbook
Dim wbDest As Workbook
Dim wsDataCheck As Worksheet
Dim wsDealerIDCheck As Worksheet
Dim wsReports As Worksheet
Dim ShName As String
Dim PthName As String
Dim FlName As String
Dim rStartRow As Range, rEndRow As Range
Dim rng As Range
Set wbDest = ActiveWorkbook ' not prefered, better to be explicit
Set wsDataCheck = wbDest.Worksheets("Data Check")
'Path source Wokrbook
PthName = "C:\Users\name\Desktop\EXCEL USEFUL DOSC\Missing Data Check New Process\Missing Data Reports\"
FlName = wsDataCheck.Range("C3").Value
ShName = wsDataCheck.Range("C3").Value
On Error Resume Next
Set wbData = Workbooks.Open(PthName & FlName & ".xlsx")
On Error GoTo 0
If wbData Is Nothing Then
' File didn't open
Exit Sub
End If
Set wsReports = Nothing
On Error Resume Next
Set wsReports = wbData.Worksheets(ShName)
On Error GoTo 0
If wsReports Is Nothing Then
' No such sheet
GoTo CleanUp
End If
With wsReports
Set rStartRow = .Range("E:E").Find(What:="January-2020", After:=.Range("E1"), LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext)
Set rEndRow = .Range("E:E").Find(What:="January-2020", After:=.Range("E1"), SearchDirection:=xlPrevious)
If rStartRow Is Nothing Or rEndRow Is Nothing Then
' Search term not found, What Now?
GoTo CleanUp
End If
.Range("A2").Value = ShName
Set rng = .Range(rStartRow, rEndRow)
' For debug purposes only
.Activate ' the worksheet
rng.Select ' the range
End With
Application.DisplayAlerts = False
' do you want to save the change you made to wbData?
wbData.Close True ' or wbData.Save False
Set wsDealerIDCheck = wbDest.Worksheets("Dealer_ID Check")
' continue ...
Exit Sub
CleanUp:
If Not wbData Is Nothing Then wbData.Close False
End Sub
The comments have pointed out the disassociation in your code many times. Your code uses implicit and explicit references to worksheets without performing any of the necessary checks to prevent errors.
The commenters we're being polite and didn't use strong terms, but I am not polite: ActiveSheet is not what you think it is.
What you think ActiveSheet is during design is practically never guaranteed to be ActiveSheet during run time. There are certainly times when they are but such certainties are rare unless you make the effort to code then into reality. All other times you should explicitly reference your ranges. Consider it a life saving skill
Let's assume you set a pointer to a workbook and you open it, whatever sheet it opens to becomes the ActiveSheet. Typically this is the sheet that was last viewed when the workbook was saved, but that is by no means guaranteed.
What is even less guaranteed, is your assumption that it will open to the "Data Check" sheet.
You can read from and write to the "Data Check" sheet all day long without caring if it is the ActiveSheet or not, but you can only Select a cell on it when it is the ActiveSheet.
The worksheet variableShName is set to the "Data Check" worksheet. At no point have you validated ShName as the ActiveSheet, but ShName must be the ActiveSheet to prevent an error on this line:
xlBook.Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select
So I had this error in word but as was pointed out "ActiveDocument" was the issue even though I only had one word application open. By changing to wdApp.ActiveDocument it resolved it. wdApp being my word.application object.
I want to copy the value from current sheet to another workbooks with auto filter by creating new one, once I run the code I got the error:
Object variable or with block variable not set
Here's the code:
Sub copyvaluetoanothersheet()
Dim selectrange As Range
Dim wb As Workbook
Dim Dsheet As Worksheet
Dim Lastrow As Long
Application.ScreenUpdating = False
Set wb = Workbooks.Add
Set Dsheet = wb.Worksheets(1)
Lastrow = Sheet2.Range("A" & Rows.Count).End(xlUp).Row
selectrange = Sheet2.Range("A2:BP" & Lastrow)
With Worksheets("Production data")
.AutoFilterMode = False
selectrange.AutoFilter field:="Branch", Criteria1:="Direct Response"
selectrange.SpecialCells(xlCellTypeVisible).EntireRow.Copy
End With
Dsheet.PasteSpecial xlPasteValues
Application.ScreenUpdating = True
End Sub
Many thanks
You must use Set when assigning object variables (you've done it elsewhere).
Set selectrange = Sheet2.Range("A2:BP" & Lastrow)
Note too that your mixture of sheet code names, tab names, and indexes is confusing, and that your code will error if nothing is visible.
Try following
Sub cpVisible()
Dim MyProdName As String
Dim FilteredRange As Range
Dim myArr As Variant
Sheets("Production Data").Range("$A$2:$BP$50000").AutoFilter Field:="Branch", Criteria1:="Direct Response"
Set FilteredRange = Sheets("Production Data").Range("$A$2:$BP$50000").SpecialCells(xlCellTypeVisible)
FilteredRange.Copy Sheets("Dsheet").Range("A1")
End Sub
My macro is going through a folder and picking each Excel file and deleting the first tab which is named some_Accounts and then copy pasting data to the master workbook where the worksheet names match.
Getting the following error Method 'Name' of object '_Worksheet' on the following line of code
Set wsDst = wbDst.Worksheets(wsSrc.Name)
I made sure that the worksheet names are equal.
Sub ProjectMacro()
Dim wbDst As Workbook
Dim wsDst As Worksheet
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim MyPath As String
Dim strFilename As String
Dim lLastRow As Long
Dim LC As Long
Dim s As Worksheet, t As String
Dim i As Long, K As Long
K = Sheets.Count
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
Set wbDst = ThisWorkbook
MyPath = "C:\Users\Adam\Desktop\some files\"
strFilename = Dir(MyPath & "*.xls*", vbNormal)
Do While strFilename <> ""
Set wbSrc = Workbooks.Open(MyPath & strFilename)
'loop through each worksheet in the source file
For Each wsSrc In wbSrc.Worksheets
'Find the corresponding worksheet in the destination with the same
name as the source
For i = K To 1 Step -1
t = Sheets(i).Name
If t = "some_Accounts" Then
Application.DisplayAlerts = False
Sheets(i).Delete
Application.DisplayAlerts = True
End If
Next i
Set wsDst = wbDst.Worksheets(wsSrc.Name)
On Error GoTo 0
If wsDst.Name = wsSrc.Name Then
lLastRow = wsDst.UsedRange.Rows(wsDst.UsedRange.Rows.Count).Row + 1
wsSrc.UsedRange.Copy
wsDst.Range("A" & lLastRow).PasteSpecial xlPasteValues
End If
Next wsSrc
wbSrc.Close False
strFilename = Dir()
Loop
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Right now, you are looping through all the Worksheets in wbSrc. When wsSrc is the "some_Accounts" sheet, right after you've deleted it within For i = K to 1... End For, it no longer exists, and thus wsSrc has no Name and will throw an error later on. If you're deleting a sheet, do so before you loop through all the sheets in a workbook.
But since you are closing wbSrc without saving changes, I assume that you don't really need to delete that sheet; you can just skip it as you're looping.
That would look something like this:
For Each wsSrc In wbSrc.Worksheets
If wsSrc.Name <> "some_Accounts" Then
'... copy and pasting code here
End If
Next wsSrc
Note that you can incorporate a WorksheetExists function into your code to make sure that there is a matching sheet in wbDst. That's already been provided in another answer.
Try to put this in your code to see if the worksheet exists:
If worksheetExists(wbDst, wsDst.Name) = true then
MsgBox "Exists!"
else
MsgBox "Does not exist!"
end if
Public Function worksheetExists(ByVal wb As Workbook, ByVal sheetNameStr As String) As Boolean
On Error Resume Next
worksheetExists = (wb.Worksheets(sheetNameStr).Name <> "")
Err.Clear: On Error GoTo 0
End Function
I am trying to create For Each loop for a several workbooks; however I am not able to set the workbook name in the array and thus resulted into this. I'm stuck in trying to concatenate the workbook name.
Here's my code:
'Open all .csv file in folder location
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(ThisWorkbook.Path)
For Each objFile In objFolder.Files
If InStr(objFile, ".csv") Then
Workbooks.Open (objFile)
End If
Next
' Declare variables
Dim WrkBkPrm As Workbook
Dim WrkBkSrc As Workbook
Dim WrkShtPrm As Worksheet
Dim WrkShtSrc As Worksheet
Dim TextSrc(4) As String
Dim SrcRng As Range
Dim DRng As Range
' Assign values to TextSrc() Array
TextSrc(0) = Cable
TextSrc(1) = Care
TextSrc(2) = MSD
TextSrc(3) = Business
'Set WrkBkPrm and WrkShtPrm values
Set WrkBkPrm = Workbooks("MasterFile" & ".xlsm")
Set WrkShtPrm = WrkBkPrm.Worksheets("Canvas")
'Activate Canvas Sheet
WrkBkPrm.Activate
WrkShtPrm.Select
Application.ScreenUpdating = False
'Start For Each Loop
For Each Src In TextSrc()
Set WrkBkSrc = Workbooks(Src & ".csv")
Set WrkShtSrc = WrkBkSrc.Worksheets(Src)
'Copy loop for 1st section
For i = 2 To 49
For j = 7 To 25
Set SrcRng = WrkShtSrc.Cells(i, j)
Set DRng = WrkShtPrm.Cells(i, j)
If SrcRng <> "" Then
DRng.Value = SrcRng.Value
End If
Next j
Next i
Next Src
Application.ScreenUpdating = True
I'd suggest you work on the file as soon as you get hold of the relevant info you need.
Something like:
Dim wb As Workbook
For Each objFile In objFolder.Files
If InStr(objFile.Name, ".csv") <> 0 Then
Set wb = Workbooks.Open(Thisworkbook.Path & "\" & objFile.Name)
'~~> Do your cool stuff with the opened CSV File
wb.Close False '~~> Close without saving
Set wb = Nothing '~~> Clean up although most of the time not necessary
End If
Next
As for the route you took, for you to use For Each Loop on TxtSrc, you need to declare it as variant.
Something like:
Dim TxtSrc As Variant, Src As Variant
TxtSrc = Array("Cable", "Care", "MSD", "Business")
For Each Src In TxtSrc
Set wb = Workbooks.Open(Thisworkbook.Path & "\" & Src & ".csv")
'~~> More cool stuff here
wb.Close False
Set wb = Nothing
Next
It is important that provide the correct argument for the Workbook Open Method.
You should always include the complete path in string format. HTH.
I have some VBA code within an Access 2007 database that exports data to an Excel 2007 file. I have a problem with this piece of the code:
Sub GetLastRow(strSheet, strColum)
Dim MyRange As Range
Dim lngLastRow As Long
Set MyRange = Worksheets(strSheet).Range(strColum & "1")
lngLastRow = Cells(65536, MyRange.Column).End(xlUp).Row
lngLastRow = lngLastRow + 1
Rows(lngLastRow & ":1048576").Select
Selection.Delete Shift:=xlUp
End Sub
The issue is the variable lngLastRow does not count belong the header rows (these are already in the excel file) in excel file unless I manually open the Excel session and then continue running the code. I would like to solve this correctly, but as a minimum if I could include some code to display the excel file so it appears automatically that would solve the issue anyway. But can't see where/how I could do this.
The following is the function that calls the above function.
Function CreateExcelData()
'Copies data to be exported to an Excel workbook
Dim objExcel As Excel.Application
Dim strTemplate As String
Dim strPathFile As String
Dim RowCount As Integer
Dim wbExported As Workbook 'The initial exported data
Dim wbAllData As Workbook 'Workbook to copy exported data to
Dim rngUsed As Range 'Used range in exported data
Dim Sheet As Worksheet
'Try GetObject first in case Excel Application is already open.
On Error Resume Next
Set objExcel = GetObject(, "excel.Application")
If Err.Number <> 0 Then
'GetObject returns error if not already open
'so use CreateObject
On Error GoTo 0 'Turnoff ASAP so error trapping is available
Set objExcel = CreateObject("Excel.Application")
End If
strTemplate = "TEMPLATE.xlsm"
strPathFile = strPath & strTemplate
strPathFileFinal = strPath & strReportName & "_" & Mydat & ".xlsm"
FileCopy strPathFile, strPathFileFinal
'Open the exported data workbook and assign to a variable
Set wbExported = objExcel.Workbooks.Open(strFilePath)
'Open the data workbook to receive the exported data and assign to a variable.
Set wbAllData = objExcel.Workbooks.Open(strPathFileFinal)
'Exported data
With wbExported.Sheets(1).UsedRange
Set rngUsed = .Offset(1, 0) _
.Resize(.Rows.Count - 1, .Columns.Count)
End With
With wbAllData.Sheets("MainSheet")
'Copy exported data and paste to first empty cell of MainSheet in File
rngUsed.Copy
.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
End With
Call GetLastRow("MainSheet", "A")
wbExported.Close
wbAllData.Save
wbAllData.Close
Set rngUsed = Nothing
Set wbExported = Nothing
Set wbAllData = Nothing
Set objExcel = Nothing
Kill strFilePath
End Function
Your code has a number of unqualified and partially qualified references to Worksheets and Ranges. These will refer to the ActiveWorkbook or ActiveSheet, probably not wjhat you want, and will cause unpredictable results.
Try this refactor
Sub GetLastRow(MyRange As Excel.Range)
Dim lngLastRow As Long
With MyRange.Worksheet
lngLastRow = .Cells(.Rows.Count, MyRange.Column).End(xlUp).Row
.Range(.Cells(lngLastRow + 1, 1), .Cells(.Rows.Count, 1)).EntireRow.Delete
End With
End Sub
Call it like this
GetLastRow wbAllData.Worksheets("MainSheet").Columns("A")