1

I'm automating a process to import data from a worksheet, though for data integrity (and to eventually append to a database), I do not want the identifier entered twice. My code works to import the data if the identifier (SHC_No) is not in column A, and to prompt if you would like to replace the entries because something has changed. It will delete the entries, and find the next blank row, but the .paste function will not operate. (Even though it is on the cell I want to paste into and I can see the data in the clipboard.)

I have gotten Run Time Error 1004 "Paste method of worksheet class failed," and "PasteSpecial Method of Range class failed," as well as 438 "Object doesn't support this property or method."

I'm relatively new to Excel VBA. I have tried different variations of .paste and .pastespecial and nothing seems to work. I have tried With statements, and defining the range. I'm at a loss.

Any ideas or suggestions, would be greatly appreciated.

Sub ImportAPDR()

Dim wbImport As Workbook
Dim wbCurrent As Workbook
Dim strSHC As String

Set wbImport = Workbooks("ImportPhase2.xlsm") 'Ensure name of the workbook... and don't change it.
Set wbCurrent = ActiveWorkbook

'On Error GoTo Handler:
Application.ScreenUpdating = False 'Prevents flickering screen.

'Activate Page 3 of the APDR

Worksheets("Page 3").Activate

strSHC = Range("A11").Value

Range("A11").Activate

Do

    If ActiveCell.Value = "" Then Exit Do
    ActiveCell.Offset(1, 0).Activate

Loop

'Selects All data from A11 until the EOR
ActiveCell.Offset(-1, 12).Activate
Range("A11", ActiveCell).Select

Selection.Copy

'Find the first blank cell in the Import workbook.

wbImport.Activate
Worksheets("Import").Activate

FindSHC (strSHC) 'Must send a variable or the other subroutine will not work.
Application.ScreenUpdating = True

Exit Sub

'Handler:
'MsgBox ("Ensure to run the macro on the APDR workbook, not the import workbook.")

End Sub

Sub FindSHC(strSHC As String)

    Dim foundSHC As String
    Dim Rng As Range
    Dim StartRange As Range
    Dim PasteRng As Range

    FindString = strSHC
    If Trim(strSHC) <> "" Then
        With Sheets("Import").Range("A:A")
            Set Rng = .Find(What:=FindString, _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlValues, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)
            If Rng Is Nothing Then
                Range("A1").Activate
                Do
                    If ActiveCell.Value = "" Then Exit Do
                    ActiveCell.Offset(1, 0).Activate
                Loop
                ActiveSheet.Paste
                Application.CutCopyMode = False
                MsgBox ("The Tenant/Unit Details have been copied for import.")
            Else
                Application.Goto Rng, True
                Set StartRange = ActiveCell
                Answer = MsgBox("This APDR looks like it has already been imported." & vbNewLine & "Do you want to reimport and replace?", vbYesNo)
                If Answer = vbYes Then
                    'Finds the values that have previously been entered and loops to select them all for deletion.
                    Do

                        If ActiveCell.Value <> strSHC Then Exit Do
                        ActiveCell.Offset(1, 0).Activate

                    Loop

                    ActiveCell.Offset(-1, 0).Activate
                    Range(StartRange, ActiveCell).Select
                    Selection.EntireRow.Delete Shift:=xlUp

                    'Find the next open row
                    Range("A1").Activate

                    Do

                        If ActiveCell.Value = "" Then Exit Do
                        ActiveCell.Offset(1, 0).Activate

                    Loop

                    ActiveSheet.Paste    '<-----This is where I get my error.
                    Application.CutCopyMode = False
                    MsgBox ("The Tenant/Unit Details have been replaced.")
                Else
                    Application.CutCopyMode = False
                    MsgBox ("Import has been cancelled.")
                End If
            End If
        End With
    End If

End Sub    
pnuts
  • 58,317
  • 11
  • 87
  • 139
Morgan
  • 26
  • 2
  • Do you need formatting? If not, just set one range to another. – findwindow Oct 28 '15 at 21:38
  • I'm not sure what you mean, formatting isn't the issue. I'm working in two separate workbooks, and the logic piece needs to work, or else this project is a bust. – Morgan Oct 28 '15 at 21:40
  • 1
    This makes my brain hurt...so many loops, if you have a lot of data it is going to take forever. But on the line you get the error change`activesheet` to `activecell`. Then do some research on finding the last row with data and how not to use select. These two items will greatly speed up your code and make it more robust. – Scott Craner Oct 28 '15 at 21:41
  • Copy/paste is very slow and... ugly. If you don't need formatting, you don't need to copy/paste which means you won't have the problem you have now. – findwindow Oct 28 '15 at 21:42
  • @ScottCraner I have tried using activecell, and it doesn't seem to work. Also, I will not be the only person importing data. It is to roll information to one central location. No more than 100 entries at a time. And the last cell will always be fluctuating. – Morgan Oct 28 '15 at 21:46
  • When Scott says last row, he means to use a variable which can handle fluctuations. – findwindow Oct 28 '15 at 21:47
  • @findwindow what is the non-copy/paste alternative? And how can I ensure its the first blank row, without loops? Sorry... This is my first project. – Morgan Oct 28 '15 at 21:48
  • As I said, you `set` one range to another. Edit: Scott's better than I. I will let him help you =P – findwindow Oct 28 '15 at 21:49
  • see [this](http://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-vba) for how to find the last row in a range of values. – Scott Craner Oct 28 '15 at 21:50
  • Okay, I will try that. Thank for the help. – Morgan Oct 28 '15 at 21:50
  • see [this](http://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba-macros) on how to avoid using select. – Scott Craner Oct 28 '15 at 21:51
  • In your first sub are you trying to get all data starting at A11 down and to column M? – Scott Craner Oct 28 '15 at 21:54
  • If that is the case I could do the whole select in one line `worksheets("Page 3").Range("A11").End(xldown).resize(,13).copy` – Scott Craner Oct 28 '15 at 21:57
  • Yes, that's what I'm trying to achieve in that sub, as that's where the form begins. You two are rockstars, I will have lots of ideas to work on tomorrow. Thank you so much! – Morgan Oct 28 '15 at 21:59
  • Try to do what has been pointed out and simplify the code some, then come back if you have problems. – Scott Craner Oct 28 '15 at 22:01
  • 1
    `Selection.EntireRow.Delete Shift:=xlUp` ..could be the issue, once you delete something, you would have nothing copied anymore. – Davesexcel Oct 28 '15 at 22:09

1 Answers1

0

Here are some tips to avoid getting stuck in such moments.

  1. Always try to emulate what macro does by manually performing all the actions, wherever it is possible to. In your case you can choose 2 identifiers for QA - one which is not present and another which is present. You won't have any trouble with the first one, but with the second - as soon as you delete any cell content after you have copied some range, your selection and copied range would be lost from clipboard. And that's actually what makes a trouble.

  2. Do proper debugging. As soon as you go into strange exception - debug what brought your code to this point. And again - in your case you can see that as soon as you delete contents the "dashed border" around copied range will disappear, meaning you have no copied range anymore which you could paste.

  3. This one goes directly to copy-paste combination. Whenever you are in need to use Copy & Paste build up your code so that these two go one after another. Avoid any range interaction between these two functions. If you need to do some calculations just save the range parameters(like range rectangle dimensions, starting row+column, ending row+column) to other variables and Copy only when you've done with everything using those saved parameters.

Good luck with this one.

GSazheniuk
  • 1,340
  • 10
  • 16