简体   繁体   English

为什么会出现“类型不匹配”错误?

[英]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. 但是,当它尝试将信息粘贴到表中的下一个可用行时,出现错误13。我对vba还是很陌生,似乎找不到解决方案,因此不胜感激。

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) . @QHarr 正确地识别Range(N & "A") ,并提出了针对您在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: Sheet1Worksheet类型的隐式声明的对象变量,其编译时标识符由工作表的(Name)属性确定:

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). 如果将此属性值更改为SummarySheet ,则Sheet1不再是有效的标识符,并且SummarySheet成为一个标识符-这就是为什么在每个模块的顶部指定Option Explicit很重要的部分原因,因为没有它,VBA会很高兴编译并运行,除了现在不是Sheet1是非法的,它现在是一个未定义的Variant/Empty值,可以意外地愉快地传递它,这会使事情很难调试(对于任何未声明的变量,这同样适用,而不仅仅是工作表代码名称)。

So Sheet1 is a Worksheet object reference. 因此Sheet1是一个Worksheet对象引用。 If Worksheet had a default member that returned the value of its Name property, your code would work. 如果Worksheet具有返回其Name属性值的默认成员 ,则您的代码将起作用。

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 ). 但是Worksheet没有默认成员 ,因此Worksheets(Sheet1)Worksheet对象引用作为参数传递给Worksheets.Item索引器(这是隐式的-因为Worksheets确实具有默认成员,其Item属性),即期待Variant工作表(持在该名称Variant/String ),或一个数字索引( Variant/IntegerVariant/Long )。

Passing a Worksheet object to Worksheets.Item is what's throwing the type mismatch error. Worksheet对象传递给WorksheetWorksheets.Item 类型不匹配错误。

Therefore, assuming that Sheet1 worksheet is the intended destination, this would fix it (making abstraction of the Range parameter bug identified earlier by QHarr): 因此,假设Sheet1工作表是预期的目标,这将对其进行修复(对QHarr先前确定的Range参数错误进行抽象化):

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. 永远不需要从Worksheets集合中检索ThisWorkbook编译时存在的Worksheets

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 . 由于Worksheets不合格,因此它所属的Workbook是模棱两可的:如果该代码是在ThisWorkbook编写的,则Worksheets是针对Me的成员调用,即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应该是"Sheet1"Worksheets("Sheet1") Sheet1 by itself, unquoted, will be seen as a variable. Sheet1本身(未加引号)将被视为变量。 Unless you have a string variable by that name? 除非您有该名称的字符串变量? Use Option Explicit at the top of your module to check for variable declarations. 使用模块顶部的Option Explicit检查变量声明。


Additional comment from @MathieuGuidon: @MathieuGuidon的其他评论:

I'll add that Sheet1 is the default code name of the "Sheet1" worksheet in a new workbook; 我将添加Sheet1是新工作簿中“ Sheet1”工作表的默认代码名称; 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 这是VBA免费创建的项目范围标识符,为您提供了对该特定Worksheet对象的编译时引用-因此,从Worksheets集合中检索该对象完全是多余的:Sheet1.Range(...)更可取-理想情况下,应将该工作表的(Name)属性修改为有意义的标识符,例如SummarySheet,它使SummarySheet.Range(...)合法,而无需声明任何SummarySheet变量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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