I am trying to paste a manually copied sheet into a sheet named "Digital - Input".
I sometimes get the error
Pastespecial method of Range class failed
This is my paste statement:
Worksheets("Digital - Input").range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
This is my complete code:
Sub pasteDigitalInput()
Application.ScreenUpdating = False
'open the source sheet
Call unlockAll
'show the input sheet
Call showerfunc("Digital - Input")
'paste values
'On Error GoTo feilmeld
Worksheets("Digital - Input").range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Update cell references
Call getTotals
'Set the start of ukestrykk for digital
showerfunc ("Kilder")
Sheets("Kilder").Select
range("J2").Select
Call findAnd("Netto spend pr uke:", "Kilder", "Digital - Input", 2, 0, , , True)
hiderfunc ("Kilder")
'Hide sheet
Call hiderfunc("Digital - Input")
Sheets("Digital").Select
Application.ScreenUpdating = True
'locks the sheet again
Call lockAll
Exit Sub
feilmeld:
'hiderfunc ("Digital - Input")
Sheets("Digital").Select
Call lockAll
Application.ScreenUpdating = True
MsgBox ("Du må kopiere planen fra excel utskriften til Adform før du bruker denne knappen. OBS! kopier planen på nytt og lås opp Digital arket før du prøver igjen.")
End Sub
Edit:
It seems to work right after opening the two workbooks. However if I use any other macro especially the macro that cleans the input sheet, I get the error.
Clean input sheet macro:
Sub clearInputDigital()
Call ClearInput("Digital - Input", "Digital")
End Sub
Sub ClearInput(inputsheet As String, sourceSheet As String)
Application.ScreenUpdating = False
'Show the sheet
showerfunc (inputsheet)
Sheets(inputsheet).Select
Cells.Select
Selection.ClearContents
'Hide the sheet
hiderfunc (inputsheet)
Sheets(sourceSheet).Select
Application.ScreenUpdating = True
End Sub
(obviously I'm unsure what is happening in the subs and functions that you are calling)
I don't always trust the excel VBA compiler to reference the objects that I'm coding it to reference, so I always try to fully qualify my code like the following
Sub pasteDigitalInput()
Excel.Application.ScreenUpdating = False
'open the source sheet
Call unlockAll
'show the input sheet
Call showerfunc("Digital - Input")
'paste values
'On Error GoTo feilmeld
Excel.ThisWorkbook.Worksheets("Digital - Input").Range("A1").PasteSpecial Paste:=Excel.xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
'Update cell references
Call getTotals
'Set the start of ukestrykk for digital
showerfunc ("Kilder")
With Excel.ThisWorkbook.Sheets("Kilder")
.Activate
.Range("J2").Select
End With
Call findAnd("Netto spend pr uke:", "Kilder", "Digital - Input", 2, 0, , , True)
hiderfunc ("Kilder")
'Hide sheet
Call hiderfunc("Digital - Input")
Excel.ThisWorkbook.Sheets("Digital").Activate
Excel.Application.ScreenUpdating = True
'locks the sheet again
Call lockAll
Exit Sub
feilmeld:
'hiderfunc ("Digital - Input")
Excel.ThisWorkbook.Sheets("Digital").Activate
Call lockAll
Excel.Application.ScreenUpdating = True
MsgBox ("Du må kopiere planen fra excel utskriften til Adform før du bruker denne knappen. OBS! kopier planen på nytt og lås opp Digital arket før du prøver igjen.")
End Sub
If you're only moving values maybe you could try avoiding using the clipboard altogether with a structure more like this :
Sub WithoutPastespecial()
'WORKING EAXAMPLE
Dim firstRange As Excel.Range
Dim secondRange As Excel.Range
Set firstRange = Excel.ThisWorkbook.Worksheets("Cut Sheet").Range("S4:S2000")
With Excel.ThisWorkbook.Worksheets("Cutsheets")
Set secondRange = .Range("A" & .Rows.Count).End(Excel.xlUp).Offset(1)
End With
With firstRange
Set secondRange = secondRange.Resize(.Rows.Count, .Columns.Count)
End With
secondRange.Value = firstRange.Value
End Sub
Generally this error shows up when the current window(sheet) that is open is not the same one in which you are pasting something. Excel is very strict about it. When you do it manually, the sheet is selected obviously before pasting, so you will never see the error.
So before pasting into the worksheet "Digital - Input", just insert a line, above that to select the sheet that you would like to paste in and then paste. Also, I would recommend using 'Thisworkbook' if you are handling multiple files so that...you know...excel doesn't get confused which workbook you're referring to. So your code would be
Thisworkbook.Worksheets("Digital - Input").Select
Worksheets("Digital - Input").range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Hope this helps.
Related
I have a text box and a combo box in an excel sheet that are dependent on each other. Sometimes the code for the text box starts running before it should be, after inputting just one character instead of waiting until I click out of it, ending up with an error result. See Below code and a screenshot of the textbox properties.
Private Sub TextBox1_Lostfocus()
Range("p5").Value = TextBox1.Value
With Range("P5")
.NumberFormat = "0"
.Value = .Value
End With
Range("Q5").FormulaR1C1 = "=IFNA(VLOOKUP(RC[-1],[ShevgenII.xlsb]Sheet1!R1C1:R60C2,2,FALSE),""Error"")"
End Sub
Private Sub ComboBox1_Change()
On Error Resume Next
Sheets("Calculator").Range("q5").Copy
Sheets("Calculator").Range("q5").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Sheets("Calculator").Range("P5").FormulaR1C1 = "=IF(RC[1]=""Fee Class"",""Enter"",LEFT(RC[1],3))"
TextBox1.Value = Range("P5")
Sheets("Calculator").Range("A1").Copy
Sheets("Calculator").Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
End Sub
I know my code is amateurish, I'm still learning...
The problem happens when for example I want to enter the numbers "524" but I only got to enter "5" the Vlookup will return an error because there is no match for "5".
Note that "q5" is the linked cell for the combo-box, so changes to the textbox automatically trigger the combo-box code.
In a previous version of this excel file I also had this code on the same codesheet:
Private Sub TextBox1_Change()
End Sub
I added it back now and its working fine.
I initially removed it when I was cleaning up all the extra code before publishing this document for my teammates; which is when I started having the above issue. However it seems like its not extra even though it is a blank procedure. I guess it is kind of telling VBA not to do anything just from a change, rather it should wait till the text box lost focus.
I recorded a macro to better understand my process. This macro is shown below in the first part. The second part is my attempt to make this thing faster.
Current Sequence of Events
Insert asset name in cell D3, in a tab titled "Live" (cell D3 is a dropdown list with 50+ assets - more on this in next section titled "Steps We Can Improve")
Calculate new asset by using Application.CalculateFull
Wait until the "Live" tab is done calculating to move to next line of code
Wait 15 seconds (more on this in next section)
Copy the newly iterated data in the "Live" tab
Create a new worksheet titled with the asset's name
Paste the data from the "Live" tab as values into the newly created worksheet
Repeat steps 1-7 until all assets have been calculated
Steps to Improve
instead of inserting an asset name in cell D3, which requires a lot of code, I would like to loop through the list found within cell D3 (a data validation list which sources asset names from a master list on another worksheet).
I added time to the code because I thought the model was not fully iterating for certain assets. This was wrong - it never iterated correctly with the addition of time. So, it is likely a formula error? The formula is listed below, and it is showing a #VALUE error for roughly 20 assets - but only when I run the macro. Outside of the macro, this formula populates correctly.
Sub SlowMACROv3()
' Turns off screen updating and auto calcs which helps to speed macro
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Turns off screen updating and auto calcs which helps to speed macro
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Sheets("Live").Select
Range("D3").Select
ActiveCell.FormulaR1C1 = "309"
Application.Calculate
If Not Application.CalculationState = xlDone Then DoEvents
Application.Wait (Now + TimeValue("0:00:15"))
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Sheets("Live").Select
Sheets("Live").Copy Before:=Sheets(1)
Range("D3").Select
ActiveCell.FormulaR1C1 = "310"
Application.Calculate
If Not Application.CalculationState = xlDone Then DoEvents
Application.Wait (Now + TimeValue("0:00:15"))
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
' Turns on screen updating and auto calcs
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
My second attempt works, but the code is just as long. Also a formula throws an error for some assets and can be found at the very bottom.
Sub SlowishMACROv1()
' Turns off screen updating and auto calcs which helps to speed macro
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Cycle all assets and create new worksheets as values macro
Sheets("Live").Copy Before:=Sheets(1)
Range("D3").FormulaR1C1 = "309"
Application.Calculate
If Not Application.CalculationState = xlDone Then DoEvents
Range("A1:XFD1000").Value = Range("A1:XFD1000").Value
Sheets("Live").Copy Before:=Sheets(1)
Range("D3").FormulaR1C1 = "310"
Application.Calculate
If Not Application.CalculationState = xlDone Then DoEvents
Range("A1:XFD1000").Value = Range("A1:XFD1000").Value
' Turns on screen updating and auto calcs
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Formula: =+IF(INDEX('Reversion Dashboard'!$I:$I,MATCH($D$3,'Reversion Dashboard'!$C:$C,0))=1,I331*(1+(RATE($E$325,,$I331,-('Reversion Schedule'!$K$19)))),"")
This formula works in the "Live" tab except for assets that trigger the =1 portion within the IF True section, whenever the macro is run. Why does this formula work every time we switch to a different asset, but not when I run the macro?
Am tempted to suggest you close this question and start again as the comments are long. Read [ask] and [mcve] and perhaps post a screenshot as remember that none of us know anything about your set up.
However, see if this code broadly does what you want - it's not entirely clear as Ibo says.
Sub x()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim r As Range, ws As Worksheet
For Each r In Worksheets("Asset Dashboard").Range("C6:C570") 'go through each cell in DV list
If Len(r) > 0 Then 'only do something if cell not empty
Worksheets("Live").Range("D3").Value = r.Value 'transfer value to D3 of Live
Application.Calculate
Set ws = Worksheets.Add 'add new sheet
Worksheets("Live").UsedRange.Copy
ws.Range("A1").PasteSpecial xlValues 'copy values only from Live to new sheet
End if
Next r
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
I have a checkbox which copies 5 cells of a address into 5 cells below if the project address is the same as the correspondence address.
here is the code I have:
Sub copy_address()
'
' copy_address Macro
'
Range("D5:G5").Select
Selection.Copy
Range("D11:G11").Select
ActiveSheet.Paste
Range("D6:G6").Select
Application.CutCopyMode = False
Selection.Copy
Range("D12:G12").Select
ActiveSheet.Paste
Range("D7:G7").Select
Application.CutCopyMode = False
Selection.Copy
Range("D13:G13").Select
ActiveSheet.Paste
Range("D8:G8").Select
Application.CutCopyMode = False
Selection.Copy
Range("D14:G14").Select
ActiveSheet.Paste
Range("F9:G9").Select
Application.CutCopyMode = False
Selection.Copy
Range("F15:G15").Select
ActiveSheet.Paste
SendKeys "{ESC}"
ActiveSheet.Range("D17").Select
End Sub
But what it does not do is undo the copy and paste when de-selected. In fact it carries out the copy and paste operation weather the box is ticked or un-ticked.
There is no mention in your code of any checkbox or its current state (aka .Value). Typically, after putting an ActiveX checkbox on the worksheet, you would use Design Mode and right-click it for the View Code command.
Once on the worksheet's code sheet in the VBE, modify the on-click handler to something like this.
Private Sub CheckBox1_Click()
If CheckBox1.Value Then
Range("D5:G8").Copy Destination:=Range("D11")
Range("F9:G9").Copy Destination:=Range("F15")
Else
Range("D11:G14").ClearContents
Range("F15:G15").ClearContents
End If
End Sub
Or you can try this if you want to keep the already assigned copy_address sub.
Sub copy_address()
'
' copy_address Macro
If ActiveSheet.Shapes("Check Box 1").ControlFormat.Value = 1 Then
ActiveSheet.Range("D5:G8").Copy Destination:=ActiveSheet.Range("D11:G14")
ActiveSheet.Range("F9:G9").Copy Destination:=ActiveSheet.Range("F15:G15")
Else
ActiveSheet.Range("D11:G15").ClearContents
End If
End Sub
I have used an Excel macro that automatically pastes all data as values, by undoing the pasting and pasting it as value.
This is the code:
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim UndoList As String
Application.ScreenUpdating = False
Application.EnableEvents = False
On Error GoTo Whoa
'~~> Get the undo List to capture the last action performed by user
UndoList = Application.CommandBars("Standard").Controls("&Undo").List(1)
'~~> Check if the last action was not a paste nor an autofill
If Left(UndoList, 5) <> "Paste" And UndoList <> "Auto Fill" _
Then GoTo LetsContinue
'~~> Undo the paste that the user did but we are not clearing
'~~> the clipboard so the copied data is still in memory
Application.Undo
If UndoList = "Auto Fill" Then Selection.Copy
'~~> Do a pastespecial to preserve formats
On Error Resume Next
'~~> Handle text data copied from a website
Target.Select
ActiveSheet.PasteSpecial Format:="Text", _
Link:=False, DisplayAsIcon:=False
Target.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
On Error GoTo 0
'~~> Retain selection of the pasted data
Union(Target, Selection).Select
LetsContinue:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
I am using the English Excel version where it works fine, however when other users, who e.g. have a German Excel version paste something, they get a procedure error in this line:
UndoList = Application.CommandBars("Standard").Controls("&Undo").List(1)
I guess the Undo command is named differently in German.
Is there a way to define the Undo list independent of the language the user is using?
Use the Control's Id number instead.
debug.Print Application.CommandBars("Standard").Controls("&Undo").Id
=> 128
debug.Print Application.CommandBars("Standard").FindControl(Id:=128).caption
=> &Undo
You should also substitute in the code the words "Paste", "Auto fill" and "Text" for your local language words.
Use the index as name:
undoname = Application.CommandBars("Standard").FindControl(ID:=128).Index
UndoList = Application.CommandBars("Standard").Controls(undoname).List(i)
Very useful code. Thank you.
Can do this also:
UndoList = Application.CommandBars("Standard").FindControl(ID:=128).List(1)
I have a group of cells B32 till R32 length and B32 to B51 breadth. I want to keep this block hidden at the start when the sheet is opened. I have named this block as 'Analysis'.
There is a button in the sheet. When the button is pressed, I want to unhide that block. I am new to Excel Vba. I would like to know the syntax/code for doing this operation.
Thanks in advance.
Ananda
You cant just hide an area like MattCrum has mentioned.
You have 3 choices as far as I am concerned
Now, just make sure you have something(data - not empty cells) in the Range 32:51 and your main sheet is either called Sheet1 or change Sheet1 in the code to suit your worksheets name
1)
in VBE ( Visual Basic Editor ) double click ThisWorkbook in the project explorer and paste this code
Private Sub Workbook_Open()
ThisWorkbook.Sheets("Sheet1").Rows(32 & ":" & 51).hidden = True
End Sub
Right click on the folder Modules and Insert a new Module, then paste this code
Sub unhide()
ThisWorkbook.Sheets("Sheet1").Rows(32 & ":" & 51).hidden = False
End Sub
Now, add a button on the spreadsheet, right click and assign macro called unhide to it.
Save changes and save your workbook as *.xlsm file
Notice when you open the workbook now, rows 32 to 51 are hidden. Clicking the button will unhide them.
2) You can change the font color to white to "hide" the contents.
Follow step 1, and replace
ThisWorkbook.Sheets("Sheet1").Rows(32 & ":" & 51).hidden = True
with this
ThisWorkbook.Sheets("Sheet1").Range("B32:R51").Font.Color = RGB(255, 255, 255)
and the code in the Module ( the unhide subroutine )with
ThisWorkbook.Sheets("Sheet1").Range("B32:R51").Font.Color = RGB(0, 0, 0)
Now, everything works similar to step 1 except your are "hiding"(changing) the font color instead of hiding rows. Not a great approach, but if it works for you then cool
3) Follow step 1 and replace the code under ThisWorkbook with
Option Explicit
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Set ws = ThisWorkbook.Sheets("Sheet1")
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "hiddenSheet"
Set hs = ThisWorkbook.Sheets(Worksheets.Count)
hs.Visible = xlSheetHidden
ws.Range("B32:R51").Select
Selection.Copy
With hs
.Activate
.Range("B32").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
End With
ws.Activate
ws.Rows(32 & ":" & 51).Delete
Application.ScreenUpdating = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call deleteHidden(Worksheets.Count)
End Sub
And the code in the Module1 with
Option Explicit
Public ws As Worksheet, hs As Worksheet
Sub unhide()
With hs
.Activate
.Rows("32:51").Select
Selection.Copy
End With
With ws
.Activate
.Rows("32:32").Select
Selection.Insert Shift:=xlDown
End With
End Sub
Sub deleteHidden(num&)
Application.DisplayAlerts = False
Worksheets(num).Delete
Application.DisplayAlerts = True
Set hs = Nothing
End Sub