2017-08-07 108 views
1

我正在尝试使用变量整数分配工作表引用。为了提供上下文,我导入了数据,根据日期标准将数据拆分到不同的工作表中,然后使用月份和年份命名工作表。将变量分配给工作表:VBA

我后来希望能够比较不同工作表内的数据,但诀窍是我将永远不会知道日期范围是什么,直到数据导入。唯一的区别是我创建工作表时的整数变量。下面我已经复制了与我的问题相关的部分代码。

Dim WS, WS1, WS2, WS3 As Worksheets 
Dim Sheetname As String 
Dim p, q, y As Integer 

p = Worksheets.Count 
For q = 1 To p 
    With Worksheets(q) 
     Sheetname = Format(st_date, "yyyy-mmm") 
     ActiveSheet.Name = Sheetname 
    End With 
    If q = 1 Then 
     Set WS1 = ThisWorkbook.Sheets(Sheetname) 
    End If 
    If q = 2 Then 
     Set WS2 = ThisWorkbook.Sheets(Sheetname) 
    End If 
    If q = 3 Then 
     Set WS3 = ThisWorkbook.Sheets(Sheetname) 
    End If 
Next q 

当我运行程序我得到一个“类型不匹配”的错误时,它必须设置WS3。我真的不知道为什么它只做当它到达3

+3

'昏暗的WS,WS1,WS2,WS3作为Worksheets'是一个错误,你需要定义每个对象的工作表。正确的定义语法是'Dim WS As Worksheet,WS1 As Worksheet,WS2 As Worksheet,WS3 As Worksheet'。同样,'Dim p,q,y As Integer', –

+1

您的代码中的活动工作表永远不会改变(至少是您发布的位),'st_date'也不会,并且您的With子句毫无意义。 – SJR

回答

0

试试这样说:

Sub TestMe() 

    Dim WS   As Worksheets, WS1 As Worksheets, WS2 As Worksheets, WS3 As Worksheets 
    Dim Sheetname As String 
    Dim p&, q&, y& 'shortwriting for dim q as long 

    For q = 1 To Worksheets.Count    
     With Worksheets(q) 
      .name = Format(st_date, "yyyy-mmm") & q 
     End With    
     If q = 1 Then 
      Set WS1 = ThisWorkbook.Worksheets(Sheetname) 
     End If    
     If q = 2 Then 
      Set WS2 = ThisWorkbook.Worksheets(Sheetname) 
     End If    
     If q = 3 Then 
      Set WS3 = ThisWorkbook.Worksheets(Sheetname) 
     End If    
    Next q    
End Sub 

我已经改变With Worksheet.name,因此它是有用的。我已经添加了&q,只是为了确保名称总是不同的。 Dims根据评论中的想法而改变。

3

你只得到WS3类型不匹配错误的原因是因为你是如何定义WS1WS2WS3。该生产线

Dim WS, WS1, WS2, WS3 As Worksheets 

相当于线

Dim WS As Variant, WS1 As Variant, WS2 As Variant, WS3 As Worksheets 

问题:

  1. 你不是故意的申报大多数这些对象的其变
  2. 因为它们被声明为变种,他们可以愉快地分配到您的循环中的工作表对象,没有错误
  3. Worksheets是错误的对象类型,您想使用Worksheet对象。
  4. 因为(仅)WS3是错误的对象类型,所以会引发类型不匹配错误!

的代码应该是:

' Declare variable types individually 
Dim WS As Worksheet, WS1 As Worksheet, WS2 As Worksheet, WS3 As Worksheet 
Dim Sheetname As String 
' Longs can be bigger than Integers, unless memory is a big issue can use Longs by default 
' Also declare individually 
Dim p As Long, q As Long, y As Long 

' Fully qualifying the sheets by using a workbook object 
p = ThisWorkbook.Worksheets.Count 
For q = 1 To p 
    ' You never changed st_date, so are trying to name all sheets the same 
    ' st_date = ... 
    Sheetname = Format(st_date, "yyyy-mmm") 
    ' The active sheet doesn't change, no need for With block for single statement 
    ThisWorkbook.Worksheets(q).Name = Sheetname 
    ' Use ElseIf statements for quicker evaluation and neater code 
    If q = 1 Then 
     Set WS1 = ThisWorkbook.Sheets(Sheetname) 
    ElseIf q = 2 Then 
     Set WS2 = ThisWorkbook.Sheets(Sheetname) 
    ElseIf q = 3 Then 
     Set WS3 = ThisWorkbook.Sheets(Sheetname) 
    End If 
Next q 

改进

我真的不知道为什么你根据表q分配表名称,但随后用If逻辑来分配相关工作表由名称。你也许可以用一些替换代码像

Dim WS1 As Worksheet, WS2 As Worksheet, WS3 As Worksheet 
Dim Sheetname As String 
Dim p As Long, q As Long, 
p = ThisWorkbook.Worksheets.Count 
For q = 1 To p 
    ' You never changed st_date, so are trying to name all sheets the same 
    ' st_date = ... 
    Sheetname = Format(st_date, "yyyy-mmm") 
    ThisWorkbook.Worksheets(q).Name = Sheetname 
Next q 
Set WS1 = ThisWorkbook.Sheets(1) 
Set WS2 = ThisWorkbook.Sheets(2) 
Set WS3 = ThisWorkbook.Sheets(3) 
+0

花了我一段时间才弄清楚为什么它只会在WS3上导致错误 - 正在想'Variants'会接受工作表对象......当然,Worksheet ** s **不会接受工作表,因为这是工作表集合,而不是单个工作表。小错别字,周一早上 - 不是很好的组合。 –

+0

当试图声明多个工作表** s **时,易于滑倒! – Wolfie