VBA: Paste ceases to work (suddenly) in specific macro - excel

I'm a very new, self-taught programmer, so please keep this in mind in your responses. I have extensively searched this and other forums and can't seem to find a similar question.
The following code has been working for weeks and has not been changed. (My macro includes more variables and code, but I know from taking it apart that those pieces work, so I've left them out for clarity). From what I can tell the PasteSpecial function is specifically not working.
Dim StimSheet As String
ActiveCell.Rows("1:290").EntireRow.Select
Selection.Copy
'Copies the data for the current stimulus
StimSheet = Application.InputBox("Enter the name of the stimulus")
'asks name of the stimulus
Sheets.Add After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = StimSheet
'adds new sheet at the end and names whatever you input as stimulus name
Sheets(StimSheet).Select
Selection.PasteSpecial Paste:=xlPasteValues
'pastes data into new sheet
At this point there is no error, the macro simply stops after copying and creating the new sheet.
Here's what I know / have tried:
The macro is successfully making and naming the new sheet and copying the selection to the clipboard, because I can manually paste it after running the macro. It seems to be getting stuck at the paste piece.
Other macros that use the exact same format of copy / paste special are still working correctly.
Another forum with a similar program suggested typing "Application.EnableEvents=True" into the immediate window. This did not change anything.
This macro has worked for several weeks with no errors. I have made new macros using previously saved code in case something inadvertently was changed in the current one, but this did not work either.
The paste option will work one time on a new file and then ceases to work again.
Thank you in advance for your suggestions.

You might find the problem is that you don't have much control over which workbook and worksheet this code applies to. It's better to avoid ActiveSheet, Select, and Sheet with no parent as much as you can.
If you only need to copy the values of cells without any formatting, then Paste isn't needed either.
Try changing your code to the following and see if you have any better luck:
Const BOOK_NAME As String = "Book1.xlsm" 'change this to your workbook name
Const SOURCE_SHEET_NAME As String = "Sheet1" 'change this to your sheet name
Dim wb As Workbook
Dim sourceSheet As Worksheet
Dim newSheet As Worksheet
Dim newSheetName As String
Dim validName As Boolean
Dim rng As Range
' Set the book, sheet and range objects
Set wb = Workbooks(BOOK_NAME)
Set sourceSheet = wb.Worksheets(SOURCE_SHEET_NAME)
Set newSheet = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
' Acquire the new sheet name and check it's valid.
Do
newSheetName = InputBox("Enter the name of the stimulus")
On Error Resume Next
newSheet.Name = newSheetName
validName = (Err.Number = 0)
On Error GoTo 0
If Not validName Then MsgBox "Sheet name isn't valid. Try again."
Loop Until validName
' Write the values into the new sheet
Set rng = sourceSheet.Cells(1, 1).Resize(290, sourceSheet.UsedRange.Columns.Count)
newSheet.Range(rng.Address).value = rng.Value2

I moved this line:
StimSheet = Application.InputBox("Enter the name of the stimulus")
to the top of the method and it seems to work reliably. I wish I could tell you exactly why, but at least you can proceed. Perhaps it has something to do with the focus changing.
Also, when it failed for me (Office 2013) I got the following error:
Run-time error 1004:
Application-defined or object-defined error.
When the Sub was in a Sheet code behind, and this:
Run-time error '1004'
PasteSpecial method of Range class failed.
When pasted in a Module.

Related

Visual Basic 438 Error When Assigning String to Cell

I copied this text from the "Introduction to Excel VBA Programming" textbook by Guojun Guo:
Sub AccessObject()
Application.ActiveWorkbook.Sheets(1).Cells(1,2).Value = "A String"
End Sub
I get a 438 Error. When I get rid of the Application.ActiveWorkbook.Sheets(1) prefix the code runs. I do not know why this prefix gives the 438 Error. Is this just deprecated or are my settings wrong?
Thanks!
edit: see additional material at the end in response to this comment
It's possible to have sheets in a workbook which aren't worksheets and thus don't have cells. Chart sheets are an example of this. You can check which type of sheet that Sheets(1) is by adding this to your code:
MsgBox Application.ActiveWorkbook.Sheets(1).Type
If the value displayed in the message box is -4167, then Sheets(1) is a worksheet. For anything else, consult the values for xlSheetType
But the simpler solution is to change to using Worksheets(1) instead, because that will only look at worksheets. You can also remove Application.ActiveWorkbook (edit: but see below) because that is the default, which leaves you with:
Worksheets(1).Cells(1, 2).Value = "A String"
edit: As pointed out in this comment, Application.ActiveWorkbook is not the default when the code in question is in a ThisWorkbook module. So, either specify ActiveWorkbook if you want your macro to affect whichever workbook is currently active (there shouldn't be any need to specify Application though):
ActiveWorkbook.Worksheets(1).Cells(1, 2).Value = "A String"
Or, if you want your macro to affect the same workbook that the macro code is in, either specify ThisWorkbook in a normal module:
ThisWorkbook.Worksheets(1).Cells(1, 2).Value = "A String"
Or put the code in the ThisWorkbook module and don't specify anything about the workbook:
Worksheets(1).Cells(1, 2).Value = "A String"
Or, if you want the code to affect a specific workbook that isn't the one which contains the macro and isn't necessarily the active workbook, then capture a reference to that other workbook in a variable and refer to that. A common way to do this is when you open that other workbook:
Dim wb As Workbook
Set wb = Workbooks.Open("filename goes here")
' do stuff
wb.Sheets(1).Cells(1, 2).Value = "A String"
' do other stuff - including potentially saving the workbook
wb.Close
Set wb = Nothing

Vba code works at times, and at times fails miserably

I have written a pretty elaborate code to automate 2 hours of work into less than 1 min. It works, on most days, somedays like today, the code wont work, or parts of the code wont work.
Its the most obviously simple parts of the code that doesn't work.
This is frustrating me.
To get the code to work, what I have to do would be to restart the system.
Please understand, I dont change the code at all. either before or after the error happens.
the is the code, where the error happens.
Range("Table1_2[[#Headers],[Bag No]:[Batch Making]]").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Batch Making").Delete
Sheets.Add(After:=Sheets("Sheet1")).Name = "Batch Making"
Range("A1").Select
ActiveSheet.Paste
Cells.Select
Cells.EntireColumn.AutoFit
Today the error was that it would not paste what the code had selected.
please note:
It selected the set of rows and columns
It created the new sheet and selected the first cell
It tried pasting the value also, but nothing happened.
After restarting the system, code worked like a dream.
Why does this happen?? any clue ??
EDIT: Biggest issue is replicating the error, as I mentioned on some days, the code will crash, else it will run smoothly.
Every day new data is fed to the program, and its cleaned to ensure that only what the program can take is given to it and this involves removing #N/A's, #VALUE's and #Ref (this was done today also, I double checked the data after the crash)
Yet at times it fails.
I'll remove the Error Handlers and have separate code to check for availability of sheet, incase the error pop's up again, then I'll update here.
You can try below code. Using select is not the best idea in 99% of time. Also, when referencing a cell it is always good to precisely tell VBA which worksheet to use.
I would suggest to replace on error resume next clause - it disables all errors in your code and you will not be notified if something went wrong.In this case you can write a bit more code to check whether the specific worksheet exist and then remove/add it.
Sub copytable()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("worksheet_with_table_you_want_to_copy")
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("Batch Making").Delete
ThisWorkbook.Sheets.Add(After:=Sheets("Sheet1")).Name = "Batch Making"
Application.DisplayAlerts = True
ws.ListObjects(1).Range.Copy
With ThisWorkbook.Worksheets("Batch Making")
.Range("a1").PasteSpecial xlPasteAll
.Cells.EntireColumn.AutoFit
End With
End Sub
edit: Code without on error but with check wheather worksheet "Batch Making" exists and delete it if it's true
Sub copytable()
Dim wsTable As Worksheet
Set wsTable = ThisWorkbook.Worksheets("worksheet_with_table_you_want_to_copy")
Dim ws As Worksheet
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
If ws.Name = "Batch Making" Then ThisWorkbook.Worksheets("Batch Making").Delete
Next ws
Application.DisplayAlerts = True
ThisWorkbook.Sheets.Add(After:=Sheets("Sheet1")).Name = "Batch Making"
ws.ListObjects(1).Range.Copy
With ThisWorkbook.Worksheets("Batch Making")
.Range("a1").PasteSpecial xlPasteAll
.Cells.EntireColumn.AutoFit
End With
End Sub
Unfortunately, you don't say what your code is supposed to do but it seems that you have a template and try to create a new worksheet with a table from this template.
The problem is that the source isn't qualified. Your code copies a "Table_2" from an unspecified source sheet, then deletes the "Batch Making" tab, creates a new sheet by that name and pastes the clipboard to this new sheet. The process is slightly illogical because if the source is a sheet by the name of "Batch Making" then it takes a lot of confidence to delete the original before the copy is safely in place. But I think you have a template. Therefore there is no danger of losing data but the question arises why you make the copy before you need it. Either way, if the copy on the clipboard is lost while deleting and inserting sheets "nothing will happen", as you say.
But what should happen? I presume that you just get a fresh copy of the template, and that means that you retain the structure of the table. Therefore my code below takes a radically different approach. It doesn't delete a sheet (with the table in it) and doesn't create a new sheet. Instead it simply deletes the content of the table in the existing sheet.
Sub Snippet()
' 295
Const WsName As String = "Batch Making"
Dim Ws As Worksheet ' Sheets(WsName)
Dim Tbl As ListObject
On Error Resume Next
Set Ws = Worksheets(WsName)
If Err Then
MsgBox "Sorry, there is no tab """ & WsName & """ in this workbook.", _
vbInformation, "Missing worksheet"
Else
Set Tbl = Ws.ListObjects(1)
If Err Then
MsgBox "Sorry, there is no table on the specified worksheet.", _
vbInformation, "Missing table"
Else
Tbl.DataBodyRange.ClearContents
End If
End If
End Sub
This is done by a single line of code, to wit, Tbl.DataBodyRange.ClearContents. You could take more or different action at that point. For example, you could delete unwanted rows or add default cell content. If there is a lot of such default you might get those data (or formulas) from a template. Otherwise just add it to the code. Headers and totals aren't deleted. The table's structure remains unchanged.
Before that, in the above code, the sheet is qualified and the table. In place of the error messages you could insert code to create the tab and/or create the table.
Please observe the name of the worksheet at the top of the code. You can change that string to any other name. The code doesn't specify the name of the table. Instead, it presumes that there is only one table on that sheet and clears that one.

In This Excel VBA Could some body tells me Why it refuses to take after parameter in the add method in worksheets object?

The code is:
Sub Copy_Filtered_Table()
Dim aSheet As Worksheet
Dim i As Long
i = ActiveSheet.Index
ActiveSheet.AutoFilter.Range.Copy
-> Set aSheet = ActiveWorkbook.Worksheets.Add(After:=i)
aSheet.Range("A1").PasteSpecial
End Sub
The workbook format is .xlsm Excel 2016
it has sheets after and before the active sheet
Also I Have tried doing it with out the aSheet variable like this
ActiveWorkbook.Worksheets.Add After:=i
It did not work too. both cases gives error 1004 Method 'Add' of object 'Sheet' faild.
If I ommited the After parameter it works but putting the result new sheet before the active sheet which exactly I am avoiding.
In order to insert relative to an existing sheet, you need to provide the actual sheet rather than its index, using one of:
Set aSheet = ActiveWorkbook.Sheets.Add(After:=ActiveWorkbook.Worksheets(i))
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Worksheets(i)
Which one you choose depends on whether you immediately want to do something with the sheet without searching for it again but I suspect you already know that, given your question.
As an aside (though I haven't tried), I suspect getting the index of the current sheets then turning that back into the current sheet object is a bit unnecessary. You may want to just try:
Set aSheet = ActiveWorkbook.Sheets.Add(After:=ActiveWorkbook.ActiveSheet)

Excel 2013 VBA: Subscript out of Range (Error 9)

So I have this code:
Sub CopyItems()
Dim Source As String
Dim Target As String
'Dim SourceSheet As String
'Dim TargetSheet As String
Source = "Source.xlsm"
Target = "needChange.xlsm"
'SourceSheet = "Sprint backlog"
'TargetSheet = "Sheet1"
Workbooks(Source).Sheets("Sprint backlog").Range("B6:B15").Copy
Workbooks(Target).Sheets("Sheet1").Range("A14:A23").Paste '<-ERROR here
End Sub
And it's giving me the Run-time error '9' as expressed in the title. The code is so simple that I am completely stumped.
I read around the net and it seems it's because of names that don't exist, however both the sheets and workbooks exist, with identical names. There is no space or weird char between any of the code.
Basically I want to Copy a column ranging from B6 to B15 from the sheet "Sprint backlog" in Source.xlsm to the range A14 to A23 in Sheet1 of needChange.xlsm
I tried, without any luck:
Workbooks(Source).Sheets("Sprint backlog").Range("B6:B15").Copy _
Workbooks(Target).Sheets("Sheet1").Range("A14:A23").PasteSpecial
And also modified code with what's now commented out.
I suspect the Macro can't access the target file (needChange.xlsm) because it can't find it or can't access it and therefore return the problem, but i cannot figure out how to fix it with code..
If it helps, while running the macro, both of the Workbooks in this code were open and accessible for me.
I am turning to you for help.
Big thanks.
Best Regards.
This was trickier than expected. I borrowed heavily from this web page http://ccm.net/faq/24666-excel-vba-copy-data-to-another-workbook.
I had to add references to the sheets for the copy and paste to get it to work.
The code as posted requires both workbooks to be open, but you can have wbTarget get opened if you give it a pathname. In that case you could comment out the two lines that appear after the -OR-.
The code can also save and close the target workbook as well.
Sub CopyOpenItems()
'
' CopyOpenItems Macro
' Copy open items to sheet.
'
' Keyboard Shortcut: Ctrl+Shift+O
'
Dim wbTarget As Workbook 'workbook where the data is to be pasted
Dim wbThis As Workbook 'workbook from where the data is to copied
Dim strName As String 'name of the source sheet/ target workbook
'set to the current active workbook (the source book)
Set wbThis = ActiveWorkbook
'get the active sheetname of the book
strName = ActiveSheet.Name
'open a workbook that has same name as the sheet name
'Set wbTarget = Workbooks.Open("C:\YourPath\needChange.xlsm")
' - OR -
Workbooks("needChange.xlsm").Activate
Set wbTarget = ActiveWorkbook
'select cell A1 on the target book
'wbTarget.Range("A1").Select
'clear existing values form target book
'wbTarget.Range("A1:M51").ClearContents
'activate the source book
wbThis.Activate
'clear any thing on clipboard to maximize available memory
Application.CutCopyMode = False
'copy the range from source book
wbThis.Sheets("Sprint backlog").Range("B6:B15").Copy
'paste the data on the target book
wbTarget.Sheets("Sheet1").Range("A14").PasteSpecial
'clear any thing on clipboard to maximize available memory
Application.CutCopyMode = False
'save the target book
'wbTarget.Save
'close the workbook
'wbTarget.Close
'activate the source book again
wbThis.Activate
'clear memory
Set wbTarget = Nothing
Set wbThis = Nothing
End Sub
if you copy only values (and no formula, picture, formating), a simple
Workbooks(Target).Sheets("Sheet1").Range("A14:A23").value = Workbooks(Source).Sheets("Sprint backlog").Range("B6:B15").value is good.
(in one same code line, only the size of the window here makes it look beeing on 2).
for more than values :
Workbooks(Source).Sheets("Sprint backlog").Range("B6:B15").Copy _
Workbooks(Target).Sheets("Sheet1").Range("A14:A23").
(in 2 lines)
note : the _ means that the folowing line is meant to be on the same line , and is only there for reading the code more easily purpose . (you made that error in your second code)
note 2 : range().paste does not exist , only sheets().paste , or range().pastespecial.
note 3 : of course, all worbooks, and sheets, must exist and have the same exact name than those used...
note 4 : copy/paste works ONLY if both workbooks are already opened. for closed files it's a different story.
To make it short, you made 2 mistakes : _, and range().paste.

Copy a Worksheet and Place it after all other worksheets and rename it as cell reference in another worksheet in the same workbook

I am new to this site, I have a workbook, (Costing-Calculator) and in the workbook, I have many worksheets, but the sheets I am concerned with are named (Tour_Fare_&_Analysis) and (RoutePlanner).
What I want to do is Copy the Route Planner and place it after all other worksheets with values only (Without original formulas) and rename this new copy with value from Cell ("G2") in worksheet (Tour_Fare_&_Analysis).
In my searches I have found a code that did work initially, but later when I tried to change the code to make copy values only, i dont know what went wrong and even the original code is brining back error msg. The code I am using is as below and i have put the error ms too following the code.
Dim Test As Worksheet
Sheets("RoutePlanner").Copy After:=Sheets(Sheets.Count)
Set Test = ActiveSheet
ActiveSheet.Name = Sheets("Costing Summery").Range("G2").Value
Error Msg:
Run-Time error'1004':
Cannot rename a sheet to the same name as another sheet, a referenced object library or a workbook referenced by Visual Basic.
Please can anyone help me solve this issue, I will really appreciate any help as I have turned the google serches up-side down to try and find the answer to the error msg i am getting.
Been a while since the question, but here is how I solved a similar problem. I allow it to use the same name, but add a sequence number to the name.
(I also gotten into the habit of inserting stuff first or at the top, since I rearly need to look at the things I created a year ago, saves me the time of going to the end/bottom of everything.)
Sub OrderConfirmation()
Dim newsheet As Worksheet
Dim i As Integer
Dim OCNO As String
OCNO = "OC #" & ' adding the order number from a different sheet/row that Im working with
Worksheets("Template").Copy before:=Worksheets(1)
Set newsheet = ActiveSheet
On Error Resume Next
newsheet.Name = OCNO
If Err.Number = "1004" Then
For i = 1 To 10
On Error Resume Next
newsheet.Name = OCNO & "(" & i & ")"
If Not Err.Number = "1004" Then i = 10
Next i
End If
End Sub

Resources