Here is my code, it s simple! but i have an error
at this line "wb.Sheets("Sheet1").Range(Cells(3, j), Cells(10, j)).Select"
Private Sub CommandButton1_Click()
Dim fd As Office.FileDialog
Dim wb As Workbook
Dim ms As Workbook
Dim Path As String
Dim i As Integer
Dim j As Integer
Set ms = ThisWorkbook
Path = "D:\SYSTEM DATA\\EVT.xlsx"
Set wb = Workbooks.Open(Path)
wb.Activate
For i = 2 To 12 Step 1
If wb.Sheets(1).Cells(1, i).Value = "EVT006" Then
j = i
Exit For
End If
Next i
wb.Sheets("Sheet1").Range(Cells(3, j), Cells(10, j)).Select 'the error line
Selection.Copy
ms.Activate
With ms
Sheets(1).Cells(1, 1).PasteSpecial Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
End With
wb.Close True
End Sub
i dont know why ?
Please help
Be sure to declare your wb on your cells within the range as well.
Private Sub CommandButton1_Click()
Dim fd As Office.FileDialog
Dim wb As Workbook
Dim ms As Workbook
Dim Path As String
Dim i As Integer
Dim j As Integer
Set ms = ThisWorkbook
Path = "D:\SYSTEM DATA\\EVT.xlsx"
Set wb = Workbooks.Open(Path)
wb.Activate
For i = 2 To 12 Step 1
If wb.Sheets(1).Cells(1, i).Value = "EVT006" Then
j = i
Exit For
End If
Next i
wb.Sheets("Sheet1").Range(wb.Sheets("Sheet1").Cells(3, j), wb.Sheets("Sheet1").Cells(10, j)).Select 'the error line
Selection.Copy
ms.Activate
With ms
Sheets(1).Cells(1, 1).PasteSpecial Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
End With
wb.Close True
End Sub
in
wb.Sheets("Sheet1").Range(Cells(3, j), Cells(10, j)).Select
you have wb.Sheets("Sheet1").Range( referencing worksheet "Sheet1" of workbook wb, while Cells(3, j) and Cells(10, j) are referencing active sheet of active workbook, where this latter is still wb (due to preceeding wb.Activate) while the former is the worksheet wb is opening with (i.e. the active sheet at the time it was last saved) which is not assured in any way to be "Sheet1"
furthemore you should avoid Activate/Select/ActiveXXX/Selection pattern and use fully qualified range references
finally you wouldn't need any wb.Activate statement after Set wb = Workbooks.Open(Path) one, since at any workbook opening it becomes the Active one
so substitute
wb.Sheets("Sheet1").Range(Cells(3, j), Cells(10, j)).Select 'the error line
Selection.Copy
ms.Activate
With ms
Sheets(1).Cells(1, 1).PasteSpecial Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
End With
with
With Wb.Sheets("Sheet1")
.Range(.Cells(3, j), .Cells(10, j)).Copy
ms.Sheets(1).Cells(1, 1).PasteSpecial Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
End With
Related
I am using the following code:
Sub CSVParser()
Dim i As Integer
Dim x As Integer
Dim values As Range
Sheets("CSV Paste").Select
Range("A3").Select
For i = 1 To Range("A3", Range("A3").End(xlDown)).Rows.Count
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Sheets("Working Sheet 1").Select
Range("A1").Select 'problem code
Do Until ActiveCell.Value = ""
If ActiveCell.Value = "" Then
Exit Do
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
ActiveSheet.Paste
Sheets("CSV Paste").Select
ActiveCell.Offset(1, 0).Select
Next
End Sub
However, the line Range("A1").Select just after Sheets("Working Sheet 1").Select is kicking up a run-time error '1004'
Does anyone know why? I have rearranged this in every way I can think of an have typed it out from scratch again.
Give this version of your code a try:
Sub CSVParser()
Dim wb As Workbook
Dim wsCSV As Worksheet
Dim wsWork As Worksheet
Set wb = ActiveWorkbook
Set wsCSV = wb.Sheets("CSV Paste")
Set wsWork = wb.Sheets("Working Sheet 1")
wsCSV.Range("A3").CurrentRegion.Copy wsWork.Cells(wsWork.Cells.Count, "A").End(xlUp).Offset(1)
End Sub
Using .Select and .Activate is not considered 'best practice'. See How to avoid using Select in Excel VBA macros. Yes, using the code from the macro recorder is a good place to start but you have to get away from the practice at some point.
Performing bulk operations is preferred to looping through an indeterminate number of rows or columns.
Option Explicit
Sub CSVParser()
Dim lastCol As Long
With Worksheets("CSV Paste")
With .Range(.Cells(3, "A"), .Cells(.Rows.Count, "A").End(xlUp))
lastCol = .CurrentRegion.Columns.Count
With .Resize(.Rows.Count, lastCol)
.Copy Destination:=Sheets("Working Sheet 1").Range("A1")
End With
End With
End With
End Sub
I think this is what you are trying to achieve (without all the unnecessary Select):
Option Explicit
Sub CSVParser()
Dim i As Long
Dim x As Long
Dim LastRow As Long
Dim PasteRow As Long
With Sheets("CSV Paste")
LastRow = .Range("A3").End(xlDown).Row
For i = 3 To LastRow
PasteRow = Sheets("Working Sheet 1").Cells(Sheets("Working Sheet 1").Rows.Count, "A").End(xlUp).Row
.Range(.Range("A" & i), .Range("A" & i).End(xlToRight)).Copy Destination:=Sheets("Working Sheet 1").Range("A" & PasteRow + 1)
Next i
End With
End Sub
I use vba to import data from one wb to another - but it seems like the data is not overwriten.
ex.
wb 1 cell A2 contains the number "2" and is copied to wb 2 cell A2.
But if I delete cell A2 from wb 2, and run the vba again - there is no data entered in wb 2 cell A2...
Can anyone see why this is?
Regards
Brian
Sorry forgot to add code :o)
Sub GetData()
Dim strWhereToCopy As String, strStartCellColName As String
Dim strListSheet As String
Application.ScreenUpdating = False
strListSheet = "List"
On Error GoTo ErrH
Sheets(strListSheet).Select
Range("B2").Select
'this is the main loop, we will open the files one by one and copy their data into the masterdata sheet
Set currentWB = ActiveWorkbook
Do While ActiveCell.Value <> ""
strFileName = ActiveCell.Offset(0, 1) & ActiveCell.Value
strCopyRange = ActiveCell.Offset(0, 2) & ":" & ActiveCell.Offset(0, 3)
strWhereToCopy = ActiveCell.Offset(0, 4).Value
strStartCellColName = Mid(ActiveCell.Offset(0, 5), 2, 1)
Application.Workbooks.Open strFileName, UpdateLinks:=False, ReadOnly:=True
Set dataWB = ActiveWorkbook
Range(strCopyRange).Select
Selection.Copy
currentWB.Activate
Sheets(strWhereToCopy).Select
lastRow = LastRowInOneColumn(strStartCellColName)
Cells(lastRow + 1, 1).Select
Selection.PasteSpecial xlPasteValues, xlPasteSpecialOperationNone
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
dataWB.Close False
Sheets(strListSheet).Select
ActiveCell.Offset(1, 0).Select
Loop
Sheets(strListSheet).Select
Range("B2").Select
Exit Sub
ErrH:
MsgBox "It seems some file was missing. The data copy operation is not complete."
Exit Sub
'Application.ScreenUpdating = True
End Sub
you can copy wb1 and past it as wb2
Sub Copy_One_File()
Dim wb1, wb2 As String
wb1 = ActiveWorkbook.Path & "wb1.xlsm"
wb2 = ActiveWorkbook.Path & "wb2.xlsm"
FileCopy wb1, wb2
End Sub
this is the simplest method
you should avoid Select/Selection/Activate/ActiveXXXpattern in favour of a fully qualified range reference
like in the following (commented) code:
Option Explicit
Sub GetData()
Dim strWhereToCopy As String, strStartCellColName As String
Dim strFileName As String
Dim strCopyRange As Range, cell As Range
Dim LastRow As Long
With Sheets("List") '<--| reference your "List" worksheet
For Each cell In .Range("B2", .Cells(.Rows.count, "B").End(xlUp)).SpecialCells(xlCellTypeConstants) '<--| loop through its column "B" not empty cells form row 2 down to last not empty one
With cell '<--| reference current cell
strFileName = .Offset(0, 1) & .Value
strCopyRange = .Offset(0, 2) & ":" & .Offset(0, 3)
strWhereToCopy = .Offset(0, 4).Value
strStartCellColName = Mid(.Offset(0, 5), 2, 1)
End With
On Error GoTo ErrH '<--| activate error handler for subsequent file open statement
Workbooks.Open strFileName, UpdateLinks:=False, ReadOnly:=True
On Error GoTo 0 '<--| resume "default" error handling
Range(strCopyRange).Copy '<-- without a leading dot (.) the range referes to the currently active worksheet, which is the active one in the just opened workbook
With .Parent '<--| reference workbook where currently referenced Sheet "List" resides in
LastRow = LastRowInOneColumn(.Worksheets(strWhereToCopy), strStartCellColName) '<--| your 'LastRowInOneColumn' function must be passed a worksheet reference, too
With .Worksheets(strWhereToCopy).Cells(LastRow + 1, 1) '<--| reference 'strWhereToCopy' named worksheet in the referenced workbook
.PasteSpecial xlPasteValues, xlPasteSpecialOperationNone
.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
End With
End With
ActiveWorkbook.Close False
Next cell
.Activate
.Range("B2").Select
End With
Exit Sub
ErrH:
MsgBox "It seems some file was missing. The data copy operation is not complete."
End Sub
as per comments, your LastRowInOneColumn function must be passed a worksheet object reference too and fully qualify the column range reference to search the last row in
the function signature and its pseudocode is:
Function LastRowInOneColumn(sht As Worksheet, strStartCellColName As String) As Long
With sht
'here goes your actual 'LastRowInOneColumn' code
' only you have to put a dot (.) before each range reference
End With
End Function
I recorded a macro, What I'm trying to obtain is creating a code that will copy the following range in the code on each worksheet and paste it in rows underneath each other on sheet "Master".
I have the following code:
Sub Macro1()
'
' Macro1 Macro
'
'
Dim rng As Range
Sheets("AL-Jackson Hospital-Fvar").Select
Set rng = Range( _
"K50:M50,K58:M58,K59:M59,K55:M55,K12:M12,K14:M14,K24:L24,K28:L28,K29:L29,K35:L35,K62:L62,K32:L32,K30:L30,K31:L31,K63:L63,K33:L33,K34:L34,K37:L37,K40:L40,K41:L41,K42:L42,K46:L46" _
)
rng.Select
Selection.Copy
Sheets("Master").Select
Range("B4").Select
Range("B4").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveWindow.ScrollWorkbookTabs Position:=xlFirst
End Sub
For example:
On sheet 1, 2 ,3 Copy the following range on each sheet and paste as values in sheet Master starting in Cell B1. So sheet 1 data range should be in B1, sheet 2 data range should be in b2, and sheet 3 data range should be in b3 and etc....
Guys my workbook has over 50 sheets
Something like should work for you:
Sub tgr()
Dim wb As Workbook
Dim ws As Worksheet
Dim wsDest As Worksheet
Dim rCell As Range
Dim aData() As Variant
Dim sCells As String
Dim i As Long, j As Long
Set wb = ActiveWorkbook
Set wsDest = wb.Sheets("Master")
sCells = "K50:M50,K58:M58,K59:M59,K55:M55,K12:M12,K14:M14,K24:L24,K28:L28,K29:L29,K35:L35,K62:L62,K32:L32,K30:L30,K31:L31,K63:L63,K33:L33,K34:L34,K37:L37,K40:L40,K41:L41,K42:L42,K46:L46"
ReDim aData(1 To wb.Sheets.Count - 1, 1 To wsDest.Range(sCells).Cells.Count)
i = 0
For Each ws In wb.Sheets
If ws.Name <> wsDest.Name Then
i = i + 1
j = 0
For Each rCell In ws.Range(sCells).Cells
j = j + 1
aData(i, j) = rCell.Value
Next rCell
End If
Next ws
wsDest.Range("B1").Resize(UBound(aData, 1), UBound(aData, 2)).Value = aData
End Sub
here's an alternative "formula" approach
other than putting in an alternative approach, it also reduces the number of iterations from (nsheets-1)*ncells (as per tigeravatar's solution) to (nsheets-1) + ncells, should it ever be a relevant issue
Option Explicit
Sub main()
Dim ws As Worksheet
Dim cell As Range, refCell As Range
With ActiveWorkbook.Sheets("Master")
For Each ws In wb.Sheets
.Cells(.Rows.Count, 1).End(xlUp).Offset(1) = IIf(ws.Name <> .Name, ws.Name, "")
Next ws
Set refCell = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
For Each cell In Range("K50:M50,K58:M58,K59:M59,K55:M55,K12:M12,K14:M14,K24:L24,K28:L28,K29:L29,K35:L35,K62:L62,K32:L32,K30:L30,K31:L31,K63:L63,K33:L33,K34:L34,K37:L37,K40:L40,K41:L41,K42:L42,K46:L46")
.Cells(refCell.Row, .Columns.Count).End(xlToLeft).Offset(, 1).Value = cell.Address ' set the reference for INDIRECT() function
Next cell
With .Range("B2", .Cells(refCell.Row, .Columns.Count).End(xlToLeft).Offset(-1))
.FormulaR1C1 = "=INDIRECT(ADDRESS(ROW(INDIRECT(R" & refCell.Row & "C)),COLUMN(INDIRECT(R" & refCell.Row & "C)),,,RC1))"
.Value = .Value
.Offset(.Rows.Count).Resize(1).ClearContents
End With
End With
End Sub
it leaves the sheets name in column "A": they can be removed
I am trying to copy the last row and paste special at the next row. When I try the following code for an individual worksheet it works fine:
Sub Macro1()
Dim LR As Long
LR = Range("E" & Rows.Count).End(xlUp).Row
Rows(LR).Select
Selection.Copy
Rows(LR + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
But when I am trying to loop through all worksheets, it is only pasting special in one of the worksheets the same copied row number of times instead of repeating to each worksheet. Could you please advise what I am doing wrong on the following for loop?
Sub Macro1()
Dim ws As Worksheet
Dim wb As Workbook
Dim LR As Long
Set wb = ActiveWorkbook
For Each ws In wb.Worksheets
If ws3.Name Like "*.plt" Then
LR = Range("E" & Rows.Count).End(xlUp).Row
Rows(LR).Select
Selection.Copy
Rows(LR + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
Next ws
End Sub
Thanks in advance!
To save some overhead, you should first refrain from using .Select and .Selection.*. If you anyways want to copy just the value you should do so via the .Value property of the cell. Secondly, you should use the With statement to make sure that you are referencing the target sheet. Finally, you should set unused objects to Nothing in the end. The following code should do the trick.
Code
Sub Macro1()
Dim ws As Worksheet
Dim wb As Workbook
Dim rng As Range
Set wb = ActiveWorkbook
For Each ws In wb.Worksheets
With ws
If .Name Like "*.plt" Then
Set rng = .Range("E" & Rows.Count).End(xlUp).EntireRow
rng.Offset(1).Value = rng.Value
End If
End With
Next ws
Set ws = Nothing
Set rng = Nothing
Set wb = Nothing
End Sub
I think that this
If ws3.Name Like "*.plt" Then
might be your issue. You need to enable Option Explicit so that you do not use undefined names.
Also, make
Set wb = ActiveWorkbook
to
Set wb = ThisWorkbook
I have the following VBA code that takes a single row from Sheet "Tabled data", copies the data, then pastes the data into the next available row in Sheet "Running list". However the original row has formulas and I need the values to paste, not the formulas. I've seen numerous ways to do it with Range.PasteSpecial but this code didn't use Range and I'm not sure how to incorporate it.
Note: I modified this code from here: http://msdn.microsoft.com/en-us/library/office/ff837760(v=office.15).aspx. It originally had an IF statement to match content in a cell then paste it in a certain sheet according to the content in the cell. I only had one sheet to copy to and didn't need the IF. I don't really need to find the last row of data to copy either as it will only ever be one row with range of A2:N2. But if I take out the FinalRow section and the For and replace with Range("A2:N2") it doesn't work so I left those in.
Any guidance on how to add in the PasteValues property without making this more complicated? I'm also open to simplification of the For or FinalRow variable such as using Range. I'm only sort of familiar with VBA, having done a few things with it, but usually after much searching and modifying code.
Public Sub CopyData()
Sheets("Tabled data").Select
' Find the last row of data
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
' Loop through each row
For x = 2 To FinalRow
ThisValue = Cells(x, 1).Value
Cells(x, 1).Resize(1, 14).Copy
Sheets("Running list").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
ActiveSheet.Paste
Sheets("Tabled data").Select
Next x
End Sub
Hopefully we can actually make this more simple.
Public Sub CopyRows()
Sheets("Sheet1").UsedRange.Copy
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'check if the last cell found is empty
If IsEmpty(ActiveSheet.Cells(lastrow, 1)) = True Then
'if it is empty, then we should fill it
nextrow = lastrow
Else
'if it is not empty, then we should not overwrite it
nextrow = lastrow + 1
End If
ActiveSheet.Cells(nextrow, 1).Select
ActiveSheet.Paste
End Sub
edit: I expanded it a little so that there won't be a blank line at the top
I found a working solution. I recorded a macro to get the paste special in there and added the extra code to find the next empty row:
Sub Save_Results()
' Save_Results Macro
Sheets("Summary").Select 'renamed sheets for clarification, this was 'Tabled data'
'copy the row
Range("Table1[Dataset Name]").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
' paste values into the next empty row
Sheets("Assessment Results").Select
Range("A2").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' Return to main sheet
Sheets("Data Assessment Tool").Select
End Sub
Just copy the data all at once, no need to do it a row at a time.
Sub CopyData()
With ThisWorkbook.Sheets("Tabled data")
Dim sourceRange As Range
Set sourceRange = .Range(.Cells(2, 1), .Cells(getLastRow(.Range("A1").Parent), 14))
End With
With ThisWorkbook.Sheets("Running list")
Dim pasteRow As Long
Dim pasteRange As Range
pasteRow = getLastRow(.Range("A1").Parent) + 1
Set pasteRange = .Range(.Cells(pasteRow, 1), .Cells(pasteRow + sourceRange.Rows.Count, 14))
End With
pasteRange.Value = sourceRange.Value
End Sub
Function getLastRow(ws As Worksheet, Optional colNum As Long = 1) As Long
getLastRow = ws.Cells(ws.Rows.Count, colNum).End(xlUp).Row
End Function
Private Sub Load_Click()
Call ImportInfo
End Sub
Sub ImportInfo()
Dim FileName As String
Dim WS1 As Worksheet
Dim WS2 As Worksheet
Dim ActiveListWB As Workbook
Dim check As Integer
'Application.ScreenUpdating = False
Set WS2 = ActiveWorkbook.Sheets("KE_RAW")
confirm = MsgBox("Select (.xlsx) Excel file for Data transfer." & vbNewLine & "Please ensure the sheets are named Sort List, Second and Third.", vbOKCancel)
If confirm = 1 Then
FileName = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xls*", _
Title:="Select Active List to Import", MultiSelect:=False)
If FileName = "False" Then
MsgBox "Import procedure was canceled"
Exit Sub
Else
Call CleanRaw
Set ActiveListWB = Workbooks.Open(FileName)
End If
Set WS1 = ActiveListWB.Sheets("Sort List")
WS1.UsedRange.Copy 'WS2.Range("A1")
' WS2.Range("A1").Select
WS2.UsedRange.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'WS2.Range ("A1")
ActiveWorkbook.Close False
'Call ClearFormulas
' Call RefreshAllPivotTables
Sheets("Key Entry Data").Select
'Sheets("Raw").Visible = False
'Application.ScreenUpdating = True
MsgBox "Data has been imported to workbook"
Else
MsgBox "Import procedure was canceled"
End If
Application.ScreenUpdating = True
End Sub
Sub CleanRaw()
Sheets("KE_RAW").Visible = True
Sheets("KE_RAW").Activate
ActiveSheet.Cells.Select
Selection.ClearContents
End Sub