【问题标题】:Get Value and Position of Checkbox in Word Table to Copy Entire Table to Excel获取Word表格中复选框的值和位置以将整个表格复制到Excel
【发布时间】:2020-03-31 17:47:00
【问题描述】:

我有一个大约 10 页和 20 个表格的 Word 文件。其中一些表格有复选框。我想将这些表复制到 Excel 文件中。

以下代码将我的 Word 文件中的所有表格复制到我的 Excel 文件中:

Sub Import()
    Option Explicit
    
    Dim wb As Workbook
    Dim sh As Worksheet
    Dim sheet As Worksheet
    Dim lzeile As Integer
    Set wb = ActiveWorkbook
    Set sh = wb.ActiveSheet
    Set sheet = wb.Worksheets("Tabelle1")
        
    Dim Btxt As Object
    Set Btxt = CreateObject("Word.Application")
    
    Btxt.Visible = True
    Btxt.documents.Open "C:\Users\*.doc"          '*=path
    lzeile = 0
    
    For i = 1 To 20
        Btxt.ActiveDocument.Tables(i).Range.Copy
            
        Application.Goto sheet.Cells(1 + lzeile, 1)
        sheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:=False
        
        lzeile = sheet.Cells(Rows.Count, 1).End(xlUp).Row
        lzeile = lzeile + 1
        sheet.Cells(lzeile, 1) = "Tabelle" & i
    Next i
    
    Btxt.Quit
    Set Btxt = Nothing
    Set wb = Nothing
    Set sh = Nothing
    
End Sub

它不会复制复选框或复选框的值(0 = 未选中 / 1 = 选中)。
我可以使用以下行将复选框的值写入我的 Excel 工作表中的单元格:

sheet.Cells(j, 10) = Btxt.ActiveDocument.Tables(i).FormFields.Item("Kontrollkästchen" & j).Result

在所有“Kontrollkästchen”(内容控件或表单字段项的德语翻译)上都有一个循环 j,因此基本上是此 Word 文件中所有表单字段项的名称。
如何获取这些表单域项的位置或识别哪个表单域项/ContentControl 在哪个表中?

我试图遍历每个表中的所有行和列,因为它们都不大于 10x10。但是我找不到一种方法来检查一个复选框是否可能在第 5 列第 5 行的表 3 中,然后将该复选框的名称读取到相同位置的 Excel 单元格中的安全值 (0 / 1)我复制的表格。

【问题讨论】:

  • 这需要您提供更多信息和想法。根据最后的代码sn-p,这些是遗留表单字段;这意味着文档被作为表单保护,这可能会影响代码的工作方式。是这样吗?如果是,是否有密码保护?最直接的方法是在复制表格之前将复选框转换为您要在 Excel 中使用的值。
  • 感谢您的回答。我认为是您描述的情况,但 word 文件没有密码保护。正如下面的macropod评论的那样,我会尝试用数值替换复选框,但我遇到了下面提到的“.Range”和“.Delete”命令的问题。

标签: excel vba ms-word


【解决方案1】:

解决方案取决于它们是表单域还是内容控件。

假设它们是表单域:

Sub Demo()
Dim i As Long, j As Long, Rng As Range
With ActiveDocument
  For i = .FormFields.Count To 1 Step -1
    With .FormFields(i)
      If .Type = wdFieldFormCheckBox Then
        j = Abs(.CheckBox.Value)
        Set Rng = .Range
        .Delete
        Rng.Text = j
      End If
    End With
  Next
End With
End Sub

假设它们是内容控件:

Sub Demo()
Dim i As Long, j As Long, Rng As Range
With ActiveDocument
  For i = .ContentControls.Count To 1 Step -1
    With .ContentControls(i)
      If .Type = wdContentControlCheckBox Then
        j = Abs(.Checked)
        Set Rng = .Range
        .Delete
        Rng.Text = j
      End If
    End With
  Next
End With
End Sub

【讨论】:

  • 感谢您的回复,但我真的不明白。此代码如何识别例如内容控件 8 是否是位置第 4 列 - 第 5 列的表 3 的一部分?我看到的是您遍历所有内容控制复选框并将它们的范围设置为“Rng”变量,但是这个 .delete 是什么?
  • 尝试代码了吗?它不需要知道复选框在哪些单元格中;它只是用数值替换它们。
  • 现在我确定使用了表单域。只是为了澄清代码应该做的是循环遍历所有表单字段复选框,复制数值并将 Word 文件中的复选框替换为完全相同位置上的数值。我对么?因为我逐行检查了代码,“.Range”和“.Delete”部分似乎有问题。如果我为每个表单域打印出“.Range”部分,它只会打印这个符号“┴”。你知道这意味着什么吗?而且我还需要使用 .Type = 71 而不是 .Type = wdContentControlCheckBox。
【解决方案2】:

为了简单明了,下面的示例代码省略了与 Excel 相关的部分,以及创建 Word 应用程序的实例。它仅显示如何访问 Word 文档的复选框并将其转换为静态值。

最后,文档也被关闭不保存更改,这意味着表单保护和复选框应该保持不变 - 宏不会影响它们。

注意:Option Explicit 应该位于代码页的顶部,而不是“Sub”中。

工作原理

要处理的文档被打开并在此时设置为一个对象 (doc)。使用它而不是ActiveDocument,因为它会更清晰,并且在用户尝试做某事时不会影响宏的执行。

如果文档具有表单保护,则必须将其关闭才能删除复选框并插入静态值。

然后所有的表单域都被循环。如果它们是复选框,则确定值,删除复选框并将值分配给复选框占用的范围。

完成后,代码将数据传输到 Excel。然后关闭文档而不保存更改。

Sub ConvertCheckBoxesToValues()
    Dim ff As Object    ' Word.FormField
    Dim doc As Object   ' Word.Document
    Dim cbValue As String
    Dim rngFF As Object ' Word.Range

    Set doc = Btxt.Documents.Open("C:\Users\*.doc")         '*=path
    If doc.ProtectionType <> -1 Then   'wdNoProtection
        doc.Unprotect
    End If

    For Each ff In doc.FormFields
        If ff.Type = 71 Then  'wdFieldFormCheckBox 
            If ff.CheckBox.value = True Then
                cbValue = "1"
            Else
                cbValue = "0"
            End If
            Set rngFF = ff.Range
            ff.Delete
            rngFF = cbValue
        End If
    Next

    'Transfer the information to Excel, then

    doc.Close 0  'wdDoNotSaveChanges
End Sub

【讨论】:

  • 非常感谢辛迪!该代码完美运行,并且解释得也很好!这对我帮助很大。
  • 很高兴它有帮助,@DataHustle。由于您是该站点的新手:“感谢”回答您问题的贡献的公认方式是单击其左侧的复选标记。如果您发现它们有用/有帮助,任何贡献(问题和答案)都可以投票。稍后,一旦您积累了一些声誉积分,您还可以对您认为无用或不属于该网站的贡献投反对票(help center 中的规则/指南)。享受吧!
猜你喜欢
  • 2021-03-14
  • 2023-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
相关资源
最近更新 更多