【问题标题】:Word VBA: Error "The requested member of the collection does not exist" for a table cell that really does existWord VBA:对于确实存在的表格单元格,出现错误“集合的请求成员不存在”
【发布时间】:2015-12-03 13:31:13
【问题描述】:

我有一个 Word VBA 脚本,它为当前选择添加了一些标题和一个表格。我现在正试图让它从下表中提取信息并将其放在正确的标题下。最终目标是使信息脱离表格格式以便更好地导航,因为 Word 的大纲无法识别表格内的标题。

在收到运行时错误 5941:集合的请求成员不存在之前,我只是将表格内容放入字符串变量。调试器转到这一行:

strChildren = rngSource.Tables(1).Cell(Row:=2, Column:=4).Range.Text

该表格远不止两行四列。为了确保集合的成员存在,我使用了另一个脚本来为我提供当前选择的行和列:

Sub CellRowColumn()
'For the current selection, shows a message box with the cell row and column.

With Selection.Cells(1)

        MsgBox ("Column = " & .ColumnIndex & vbCr & "Row = " & .RowIndex)

End With

End Sub

我在要从中复制的单元格中运行了这个,它确实显示了第 2 行和第 4 列。

这是我正在使用的代码:

Sub ElementHeadings()
'With the current selection, adds the headings for each element in the 
'Elements and Attribute List (Description, Parent(s), and Child(ren)) and
'a table for attributes, with 3 columns, headed "Attribute
'Name", "Attribute Required?" and "Attribute Content")

Dim rngSelection As Range
Dim rngTable As Range
Dim rngHeading As Range
Dim rngSource As Range
Dim strCaption As String
Dim lngCaptionLength As Long

Dim strDescr As String
Dim strParents As String
Dim strChildren As String
Dim strVol As String
Dim strUsedIn As String


Set rngSelection = Selection.Range
'msgBox (rngSelection.Text)


With rngSelection

    .InsertAfter ("Description")
    .InsertParagraphAfter
    .Expand unit:=wdParagraph

    .InsertAfter ("Parent(s)")
    .InsertParagraphAfter
    .Expand unit:=wdParagraph

    .InsertAfter ("Child(ren)")
    .InsertParagraphAfter
    .Expand unit:=wdParagraph

    .InsertParagraphAfter
    .InsertParagraphAfter

    Set rngTable = .Paragraphs(5).Range

    .InsertAfter ("Volume & Chapter")
    .InsertParagraphAfter
    .Expand unit:=wdParagraph

    .InsertAfter ("Used In")
    .Expand unit:=wdParagraph

    .Style = "Heading 4"

'MsgBox (rngSelection.Text)

End With

ActiveDocument.Tables.Add Range:=rngTable, NumRows:=3, NumColumns:=3

With rngTable

    .Tables(1).Cell(1, 1).Range.Text = "Attribute Name"
    .Tables(1).Cell(1, 2).Range.Text = "Attribute Required?"
    .Tables(1).Cell(1, 3).Range.Text = "Attribute Content"

    .Select

    GenericMacros.TableFormat

    .Move unit:=wdParagraph, Count:=-1
    .Select

End With

rngSelection.Select

Set rngHeading = Selection.GoTo(what:=wdGoToHeading, Which:=wdGoToPrevious)
rngHeading.Expand unit:=wdParagraph

'MsgBox (rngHeading.Text)

rngTable.Select

strCaption = rngHeading.Text
lngCaptionLength = Len(strCaption)
strCaption = Left(strCaption, lngCaptionLength - 1)

Selection.InsertCaption Label:=wdCaptionTable, Title:=". <" _
    & strCaption & "> Attribute Table"

rngSelection.Select

Set rngSource = Selection.GoTo(what:=wdGoToTable, Which:=wdGoToNext)

rngSource.Expand unit:=wdTable

strDescr = rngSource.Tables(1).Cell(Row:=2, Column:=2).Range.Text
strParents = rngSource.Tables(1).Cell(Row:=2, Column:=3).Range.Text
strChildren = rngSource.Tables(1).Cell(Row:=2, Column:=4).Range.Text
strVol = rngSource.Tables(1).Cell(Row:=2, Column:=8).Range.Text
strUsedIn = rngSource.Tables(1).Cell(Row:=2, Column:=9).Range.Text

MsgBox ("strDescr = " & strDescr & vbCr & "strParents = " & strParents & _
    vbCr & "strChildren =" & strChildren & vbCr & "str3001Vol = " _
    & str3001Vol & "strUsedIn = " & strUsedIn)

End Sub

(如果问题是文档而不是我的代码,这可能最终成为超级用户问题而不是堆栈溢出问题。以前,我在从表中复制和粘贴时遇到问题(复制文本但没有获得选项将其粘贴到上面),但这不再发生。因此,如果代码没有明显问题,则可能是文档损坏或其他 Word 异常。)

更新:我的源范围包含我刚刚创建的表,而不是我想从中提取的表,因此我修复了正在创建 rngSource 的 Selection.Goto。

【问题讨论】:

  • 自己发现了错误。我的源范围包含我刚刚创建的表,而不是我想从中提取的表,因此我修复了正在创建 rngSource 的 Selection.Goto。不确定这对其他人是否仍然是一个有用的问题,那么这里的礼仪是什么?我应该回答自己的问题并接受答案,还是应该有人将其标记为删除?
  • 就礼仪而言,这两种方式都可以。由于使用当前选择,我想解决您遇到的问题。正如您所发现的,这可能是不可靠的。尽可能使用 Word 的对象要好得多。例如,当您创建表时,将变量变暗,然后在创建表时分配给它。这为您在表格上提供了一个“句柄”,无论在它之前进行何种编辑,稍后:Set tbl = ActiveDocument.Tables.Add(Range:=rngTable, NumRows:=3, NumColumns:=3)。然后 tbl.Cell(1,1).Range.Text 等等...
  • 你是对的!我认为使用范围可以解决这个问题,但是当您编辑它们时范围也会发生变化。 (Selection.Goto 是一种解决方法,因为 Range 对象似乎没有类似的方法,除非我遗漏了一些东西。)我没想过要为表分配一个变量——这应该会更好。您列出的代码将适用于我作为脚本的一部分创建的表,但我需要针对预先存在的源信息表对其进行一些调整。
  • 我很乐意接受这个答案,因为它比我的“调整范围以使其包含正确的表格”更有用。

标签: vba ms-word


【解决方案1】:

很高兴您能够跟踪代码失败的位置。使用 Selection 对象往往是不可靠的,因为它可能不是您在编写代码时假设的位置(或它所在的位置)。

尽可能使用 Word 的对象会更好。例如,当您创建表时,将变量变暗,然后在创建表时分配给它。这给了你一个桌子上的“把手”,无论在它之前发生什么样的编辑,以后:

Dim tbl as Word.Table
Set tbl = ActiveDocument.Tables.Add(Range:=rngTable, NumRows:=3, NumColumns:=3). 
tbl.Cell(1,1).Range.Text = "Attribute Name"
'and so on...

要获取现有表,您需要能够识别它。如果你确定这个位置,那么:

Set tbl = ActiveDocument.Tables([index value])

如果这是您设置和重复使用的“模板”类型的文档,您可以为表格添加书签(选择表格并插入书签,或单击第一个单元格并插入书签),然后:

Set tbl = ActiveDocument.Bookmarks("BookmarkName").Range.Tables(1)

类似地,你可以替换这个:

rngHeading.Expand unit:=wdParagraph

如果您想明确地处理段落,请使用以下内容:

Dim para as Word.Paragraph
Set para = rngHeading.Paragraphs(1)

它还可以帮助您了解您可以将范围“折叠”到其起点或终点(类似于在选择时按下箭头键)。如果您想添加一些内容、对其进行格式化,然后添加其他应该具有不同格式的内容...(作为连续使用 InsertAfter 然后返回并以不同方式格式化内容的替代方法),这将非常有用。

【讨论】:

    【解决方案2】:

    我得到了类似 OP 的东西,运行下面的代码后:

    Dim tbl As Word.Table: Set tbl = doc.Tables(2)
    MsgBox tbl.Cell(1, 1).Range.Text
    

    它的工作原理是每个表都应该至少有一个单元格, 确实注意到我也访问了错误的表;-)

    所以,你可以先用它来确定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 2017-04-03
      相关资源
      最近更新 更多