2

我是新手。我有一个包含 10 张工作表的 excel 文件,其中 6 张工作表以 6 名员工姓名命名,接下来的 3 张工作表包含一些信息(与我的代码无关),第 10 张工作表名为 Temp。

员工表的每一列都有以下数据(D&E 为空白):

| A         | B                | C | D | E | F                          |
| 17-Sep-13 | ProjectA         | 6 |   |   | Report updated on this day |
| 18-Sep-13 | CBL Ideas - HMF  | 7 |   |   |                            |
| 18-Sep-13 | CBL Ideas - HMF  | 1 |   |   |                            |

我希望将所有这些数据整理到名为 Temp 的工作表中,如下所示:

| A         | B         | C | D   |
| 17-Sep-13 | Project A | 6 | foo |
| 18-Sep-13 | Project A | 7 | foo |
| 18-Sep-13 | Project B | 1 | foo |
| 17-Sep-13 | Project A | 6 | bar |
| 18-Sep-13 | Project A | 7 | bar |
| 18-Sep-13 | Project B | 1 | bar |

下面是我的代码:

Sub ListRelevantEntries()
  Dim s As Integer
  Dim C As Range

  For s = 1 To Worksheets.Count - 4  
    If Sheets(s).Cells(Rows.Count, "F").End(xlUp) _
          .Value = "Report last updated on this day" Then
      'Execution stops on the below line with an
      ' "Application-defined or object defined error"
      Sheets(s).Range(Cells(Rows.Count, "F").End(xlUp) _
          .Offset(1, 0), Cells(Rows.Count, _ "A").End(xlUp)) _
          .Copy(Sheets("Temp").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0))

      Sheets("Temp").Select
      Sheets("Temp").Cells(Rows.Count, "C").End(xlUp).Offset(0, 1).Select
      For Each C In Sheets("Temp").Range(Cells(Rows.Count,"C").End(xlUp). _
        Offset(0, 1), Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)).Cells
        C = Sheets(s).Name
      Next
    ElseIf Not Sheets(s).Cells(Rows.Count, "F").End(xlUp) _
          .Value = "Report last updated on this day" _
          And Not Sheets(s).Cells(Rows.Count, "F").End(xlUp).Value = "" Then
  MsgBox "Extra Words entered " & ActiveSheet.Cells(Rows.Count, "F") _
      .End(xlUp).Offset(1, 0).Value & " in " & Sheets(s).Name
    End If
  Next

  Sheets("Temp").Range("1:1").Delete  
End Sub

抱歉问了这么长的问题。我想不出任何其他方式来解释!

4

3 回答 3

2

如果您清理代码,错误会容易得多。在开始处添加工作表变量

Dim ws As Worksheet

然后在第一个 For 语句之后将目标表分配给它

  Set ws = Worksheets(s)

注意我用Worksheets(s)not Sheets(s)。它们是不同的,不要混合它们。该Sheets集合可以包括图表和工作表,它代表每个选项卡。Worksheets 集合仅包含 Worksheet 对象。在你For使用的循环中Worksheets,然后你Sheets在循环中使用。如果工作簿中有任何图表,这将中断。

好的,现在你有了这个ws包含对工作表的引用的变量,继续用 for 循环体内的所有内容替换你Sheets(s)ws。当你在它的时候,修复你对Cellsand的所有调用Rows。任何地方你写的东西就像ws.Range(Cells(1, "F"))你犯了一个错误。Cells单独指向ActiveSheet.Cells你想要的地方ws.Cellsws否则,您试图在任何时候都不是创建跨工作表范围ActiveSheet。范围的其他属性也是如此,例如Rows. 所以现在你要停止的代码行应该更像这样:

ws.Range(ws.Cells(ws.Rows.Count, "F").End(xlUp) _
      .Offset(1, 0), ws.Cells(ws.Rows.Count, "A").End(xlUp)) _
      .Copy Sheets("Temp").Cells(Sheets("Temp").Rows.Count, "A") _
      .End(xlUp).Offset(1, 0)

请注意,我还删除了您传递给的参数周围的括号.Copy。在 VBA 中,您调用不带括号的方法,除非它返回一个值。如此MyMethod "Value to pass"result = MyMethod("Value to pass")但不是MyMethod("Value to pass")

在修复所有这些之后,如果它仍然产生错误,我建议使用调试器。打开监视窗口,开始将有问题的行分成几段,检查它们,找出问题所在。

所以首先你可以创建一个手表ws并确保它是正确的表。然后也许编辑那个手表ws.Cells(ws.Rows.Count, "F").End(xlUp),看看它是否得到了正确的单元格。

哦,另外,如果你做得正确,你不应该调用任何类似的东西Worksheet.Selector .Activate。事实上,建议您在绝大多数情况下避免使用这些,除非您通过更改视图与用户进行交互。

于 2013-11-13T07:09:07.607 回答
0

用类似的东西替换

With Sheets(s)
        .Range(.Cells(.Rows.Count, "F").End(xlUp).Offset(1, 0), .Cells(.Rows.Count, "A").End(xlUp)).Copy Sheets("Temp").Cells(Sheets("Temp").Rows.Count, "A").End(xlUp).Offset(1, 0)
End With
于 2013-11-13T06:57:17.083 回答
0

您收到错误,因为您没有返回对工作表的引用。一个快速的解决方法是添加这个:

Sheets(s).Select

在第 6 行之前或在第 4 行之后。

但为了更好的编码,请尝试使用This Thread中看到的内容。
该链接讨论了如何通过声明和设置所有对象来避免使用 select。

于 2013-11-13T06:59:32.177 回答