简体   繁体   中英

Why am I getting a 'type mismatch' error?

I am trying to copy a range from one workbook to a table in another workbook to capture production data. I am able to copy the correct range and open the workbook with the table successfully. However, when it tries to paste the information into the next available row in the table I get the error 13. I am rather new to vba and can't seem to find a solution, any help would be greatly appreciated.

Dim wbTime As Workbook
   Set wbTime = ThisWorkbook

   Dim wbData As Workbook

   Dim N As Long
   N = Cells(Rows.Count, "A").End(xlUp).Row + 1

   Dim UsdRws As Long
   UsdRws = Cells.Find("*", After:=Range("A32"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

   wbTime.ActiveSheet.Range("A6:O" & UsdRws).Copy

   Set wbData = Workbooks.Open("S:\Lean Carrollton Initiative\Allen\Buffering Interrupters\1st Shift\B10\Data.xlsx")

   wbData.ActiveSheet.Paste Destination:=Worksheets(Sheet1).Range(N & "A")

   wbData.Close SaveChanges:=True
End Sub
 Destination1:=Worksheets(Sheet1).Range(N & "A") 

@QHarr correctly identified the problem with Range(N & "A") , and proposed a fix for the type mismatch error you're getting at Worksheets(Sheet1) .

I just wanted to explain what's going on in more details than can fit a little comment box.

Sheet1 is an implicitly declared object variable of type Worksheet , whose compile-time identifier is determined by the (Name) property of the worksheet:

Sheet1属性工具窗口显示(Name)属性

If you change this property value to, say, SummarySheet , then Sheet1 is no longer a valid identifier, and SummarySheet becomes one - and this is part of why specifying Option Explicit at the top of every module is important, because without it VBA will happily compile and run, except now instead of Sheet1 being illegal, it's now an undefined Variant/Empty value that can merrily passed around accidentally, which can make things very hard to debug (the same holds true for any undeclared variable, not just worksheet code names).

So Sheet1 is a Worksheet object reference. If Worksheet had a default member that returned the value of its Name property, your code would work.

But Worksheet doesn't have a default member , so Worksheets(Sheet1) is passing the Worksheet object reference as an argument to the Worksheets.Item indexer (implicitly - because the Worksheets class does have a default member, its Item property), which is expecting a Variant holding either the name of a worksheet ( Variant/String ), or a numeric index ( Variant/Integer or Variant/Long ).

Passing a Worksheet object to Worksheets.Item is what's throwing the type mismatch error.

Therefore, assuming that Sheet1 worksheet is the intended destination, this would fix it (making abstraction of the Range parameter bug identified earlier by QHarr):

wbData.ActiveSheet.Paste Destination:=Sheet1.Range(...)

There is never a need to retrieve a worksheet that exists at compile-time in ThisWorkbook , from the Worksheets collection.

Note that in the original code:

 Destination1:=Worksheets(Sheet1).Range(N & "A") 

Since Worksheets isn't qualified, the Workbook it belongs to is ambiguous: if that code is written in ThisWorkbook , then Worksheets is a member call against Me , ie ThisWorkbook.Worksheets . Otherwise, it "conveniently" implicitly refers to whatever workbook happens to be currently active , and that's often a risky assumption for code to be making.

Your range needs to be for correct syntax

Range("A" & N)

You could also use

Cells(N, "A")

And sheet1 should be "Sheet1" ie Worksheets("Sheet1") . Sheet1 by itself, unquoted, will be seen as a variable. Unless you have a string variable by that name? Use Option Explicit at the top of your module to check for variable declarations.


Additional comment from @MathieuGuidon:

I'll add that Sheet1 is the default code name of the "Sheet1" worksheet in a new workbook; it's a project-scoped identifier VBA creates for free, giving you a compile-time reference to that specific Worksheet object - thus, retrieving that object from the Worksheets collection is redundant altogether: Sheet1.Range(...) would be preferable -- and ideally, that sheet's (Name) property should be modified to a meaningful identifier, eg SummarySheet, which makes SummarySheet.Range(...) legal, without needing to declare any SummarySheet variable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM