【问题标题】:Why am I not able to change worksheet reference?为什么我无法更改工作表参考?
【发布时间】:2015-10-24 18:06:32
【问题描述】:

首先,如果这个问题太明显,我提前道歉。我只是几年没有使用过 VBA 和 Excel,在其他地方找不到我的问题的答案。

我希望我的 VBA 程序从工作表“ReportData”中获取数据,并使用它在新工作表“Report”上创建一些数据透视表。

我的问题是关于单元格引用。我认为,只要您激活或选择一个工作表,那么该工作表就会成为 VBA 的参考点。因此,像 Cells(1,1).Value 这样的语句将查看活动工作表第一个单元格中的值。但是,我不知道为什么它对我不起作用。

这是适合我的版本:

Dim PTCache As PivotCache
Dim PT As PivotTable
Dim ReportSheet As Worksheet
Dim ItemName As String
Dim Row As Long, Col As Long, i As Long
Application.ScreenUpdating = False

'Delete Report sheet if it exists
On Error Resume Next
Application.DisplayAlerts = False
Sheets("Report").Delete
On Error GoTo 0

'Add Report sheet
Set ReportSheet = Worksheets.Add
ActiveSheet.Name = "Report"

'Create Pivot Cache
Set PTCache = ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=Sheets("ReportData").Range("A1").CurrentRegion)

Row = 1
For i = 1 To 4
    For Col = 1 To 7
        ItemName = Sheets("ReportData").Cells(1, i + 2)

        With Sheets("Report").Cells(Row, Col)
            .Value = ItemName
            .Font.Size = 16
        End With
    .
    .
    .
    .
    Next Col    
Next i

我的问题是关于以下行:

With Sheets("Report").Cells(Row, Col)

为什么需要添加

“表格(“报告”)。”

?我以为最后一个激活的工作表是“报告”。因此,如果我使用:

使用单元格(行,列)

单独 - 不应该自动引用

Sheets("Report").Cells(Row, Col)

? (它没有)。

我也尝试在引用单元格之前激活“报告”工作表,但这也不起作用。例如,以下内容对我不起作用。它继续引用“ReportData”工作表中的单元格(这不是我要引用的工作表):

Dim PTCache As PivotCache
Dim PT As PivotTable
Dim ReportSheet As Worksheet
Dim ItemName As String
Dim Row As Long, Col As Long, i As Long
Application.ScreenUpdating = False

'Delete Report sheet if it exists
On Error Resume Next
Application.DisplayAlerts = False
Sheets("Report").Delete
On Error GoTo 0

'Add Report sheet
Set ReportSheet = Worksheets.Add
ActiveSheet.Name = "Report"

'Create Pivot Cache
Set PTCache = ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=Sheets("ReportData").Range("A1").CurrentRegion)

Row = 1
For i = 1 To 4
    For Col = 1 To 7
        ItemName = Sheets("ReportData").Cells(1, i + 2)

        Worksheets("Report").Activate

        With Cells(Row, Col)
            .Value = ItemName
            .Font.Size = 16
        End With
    .
    .
    .
    .
    Next Col    
Next i

第二个例子有什么问题?它快把我逼疯了。我认为您所要做的就是首先激活或选择一个工作表,然后您在此之后所做的任何单元格引用都将用于您已激活或选择的工作表中的单元格。我要疯了吗?

【问题讨论】:

  • 代码在这里按预期工作——即使没有明确的引用。 1. 在循环前插入Application.EnableEvents = False,检查是否有宏干扰。 2.在ItemName=...行和单步(F8)处设置断点,每步后在直接窗口中检查?activesheet.name
  • 试试Worksheets("Report").Activate,而不是ReportSheet.Activate。如果您仍需要工作表引用,请使用 ReportSheet 对象而不是 Sheets("Report")
  • user1016274 感谢您的帮助!

标签: excel vba


【解决方案1】:

这种类型的问题在这个网站上相当普遍......并且通常后面是来自愿意的受访者的 cmets 列表,询问您是否正在捕捉这个或那个事件、处理不同的工作簿、更改工作表名称、激活其他工作表,等等。关键是,没有人可以确定出了什么问题——我们或你——因为你无法控制你的对象。

VBA 就像一个蹒跚学步的孩子;你说的是不受控制的物体:

嘿,去甜品店,我五分钟后回来……哦,还有 那些来自淘气的OtherMacros 家庭的孩子可能也在那里。

尽管您的宝宝无疑很漂亮,但它会在顽皮的一步上花费大量时间!

我已经调整了您的代码,以便为您提供更多控制权,使其不依赖于活动工作簿和工作表、选择、默认属性等。它应该让您朝着正确的方向开始......甜品店叫Activate

哦,您不需要遍历Range 中的每个单元格来将其值复制到新的Range,您只需将其读入Variant 并将整个Variant 写入新的Range

Public Sub RunMe()
    Const DATA_SHEET_NAME As String = "ReportData"
    Const REPORT_SHEET_NAME As String = "Report"
    Dim dataSheet As Worksheet
    Dim reportSheet As Worksheet
    Dim ptCache As PivotCache
    Dim v As Variant
    Dim b As Boolean

    Application.ScreenUpdating = False

    Set dataSheet = ThisWorkbook.Worksheets(DATA_SHEET_NAME)

    'Delete Report sheet if it exists
    On Error Resume Next
    Set reportSheet = ThisWorkbook.Worksheets(REPORT_SHEET_NAME)
    On Error GoTo 0
    If Not reportSheet Is Nothing Then
        b = Application.DisplayAlerts
        Application.DisplayAlerts = False
        reportSheet.Delete
        Application.DisplayAlerts = b
    End If

    'Add Report sheet
    Set reportSheet = ThisWorkbook.Worksheets.Add
    reportSheet.Name = REPORT_SHEET_NAME

    'Create Pivot Cache
    Set ptCache = ThisWorkbook.PivotCaches.Create( _
                  SourceType:=xlDatabase, _
                  SourceData:=reportSheet.Range("A1").CurrentRegion)

    'Write the item names
    v = dataSheet.Range("C1").Resize(, 7).Value2
    With reportSheet.Range("A1").Resize(, UBound(v, 2))
        .Value = v
        .Font.Size = 16
    End With

    Application.ScreenUpdating = True

End Sub

【讨论】:

  • 安比,非常感谢您的帮助。从您的代码中,这些行对我帮助最大: Set reportSheet = ThisWorkbook.Worksheets.Add reportSheet.Name = REPORT_SHEET_NAME 一旦我开始使用 reportSheet 作为参考,一切都很好。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 2014-04-29
  • 1970-01-01
  • 2021-09-15
相关资源
最近更新 更多