【问题标题】:Excel macro - running through cells on the same levelExcel 宏 - 在同一级别的单元格中运行
【发布时间】:2011-04-01 05:48:21
【问题描述】:

所以我想运行 A1-C200 并将所有内容粘贴到 Word 文档中。问题是,我有两种方法可以将它粘贴到 Word 中,但每种方法都有其缺点。

目标:将 A1-C200 复制到 Word 中并保持列布局,不复制空白。

示例 1:

下面的代码将所有内容复制到 Word 中,但从 A1 -> A200、B1 -> B200、C1 -> C200 运行。因为它以这种方式读取我的文件,所以我丢失了列布局。我更喜欢这个例子的解决方案,因为这段代码对我来说看起来更清晰。

iMaxRow = 200

" Loop through columns and rows"
For iCol = 1 To 3
    For iRow = 1 To iMaxRow

    With Worksheets("GreatIdea").Cells(iRow, iCol)
        " Check that cell is not empty."
        If .Value = "" Then
            "Nothing in this cell."
            "Do nothing."
        Else
            " Copy the cell to the destination"
            .Copy
            appWD.Selection.PasteSpecial
        End If
    End With

    Next iRow
Next iCol

示例 2:

下面的代码复制了正确的列布局,但也插入了空白。所以如果 A1-A5 和 A80-A90 都填好了,我的 Word 文档里会有 75 个空白。

a1 = Range("A1").End(xlDown).Address
lastcell = Range("C1").Address
Range(a1, lastcell).Copy
With Range("A1") 
Range(.Cells(1, 1), .End(xlDown).Cells(2, 3)).Copy
End With
Range("A1:C50").Copy
appWD.Selection.PasteSpecial

【问题讨论】:

  • 空白会发生什么?是否要将 A80-A90 的内容上移到 A1-A5 旁边?或者保留 Word 表中已有的值,以免它们被空白覆盖?假设它是一个 Word 表?请澄清。
  • 另外,您的第二个代码示例真是一团糟!前7行互为冗余;您正在复制 3​​ 个不同的范围,而不是将它们粘贴到任何地方。
  • 哦,示例 2 是我的第一次编码。但是,是的,我希望 A80-A90 的内容向上移动,以便它们位于 A1-A5 之下。

标签: excel vba ms-word selection


【解决方案1】:

有多种方法可以做到这一点,不知道哪种方法最快,但这里有一些我为您快速编写的代码。在变体中一次获取所有范围是从 excel 中获取数据的最快方法。

Sub test()

        Dim i As Long, j As Long
        Dim wd As Word.Document
        Dim wdTable As Word.Table
        Dim wks As Excel.Worksheet
        Dim v1 As Variant
        Set wd = GetObject("C:\Documents and Settings\Jon\Desktop\New Microsoft Word Document.doc")

'Get data in array
        Set wks = ActiveSheet
        v1 = wks.UsedRange        

'Create table
        Set wdTable = wd.Tables.Add(Range:=wd.Application.Selection.Range, NumRows:=1, NumColumns:= _
            ubound(v1,2), DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
            wdAutoFitFixed)


        'Place data
        For i = 1 To UBound(v1)
            For j = 1 To UBound(v1, 2)
                If Len(v1(i, j)) > 0 Then
                    'Add row if not enough rows, this can be done before the j loop if
                    'you know the first column is always filled.
                    'You can also do an advanced filter in excel if you know that the first
                    'column is filled always and filter for filled cells then just
                    'do a straight copy and paste using r1.specialcells(xlCellTypeVisible).copy 
                    'If you know the rows ahead of time when you create the table you can create all the rows at once,
                     'which should save time.
                    wd.application.selection
                    If wdTable.Rows.Count < i Then wdTable.Rows.Add
                    wdTable.Cell(i, j).Range.Text = v1(i, j)
                End If
            Next j
        Next i

        Set wks = Nothing: Set wd = Nothing: Set v1 = Nothing
    End Sub

【讨论】:

  • 感谢您的评论,但这会导致 application.selection 出现错误。
  • 您是复制并粘贴我的代码还是将其与您的代码一起使用?如果您将它与您的一起使用,您可能会将 wd 作为 word.application,在这种情况下,您不需要 wd.application.selection,而只需要 wd.selection。
  • 我复制了你的整个代码,但仍然报错。但我认为这是因为我没有选择或复制任何东西?我想你所有的 cmets 在哪里,我需要添加一些选择或复制?
  • 您引用了这个“C:\Documents and Settings\Jon\Desktop\New Microsoft Word Document.doc”还是您自己的文档?
  • 工作表中的范围只是抓取活动工作表(您打开的最后一个工作表。必须打开 Excel 文档。word 文档由 getobject 程序打开或抓取。我不'不经常使用 word,所以我不太确定为什么它不能在那边正常工作,但它确实对我有用。桌子放置的范围是从选择的任何内容中获取的。你可以让你的文件已经打开并测试,看看你是否需要只选择单词的一部分。不过我认为你不需要这样做。
【解决方案2】:

不太确定我是否理解这个问题......但这里有一个尝试:

dim rg200x3 as range: set rg200x3 = range("a1:c200")

dim Col1 as new collection
dim Col2 as new collection
dim Col3 as new collection

dim rgRow as new range
dim sText as string
for each rgRow in rg200x3
    sText = trim(rgRow.cells(1,1)): if (sText <> "") call Col1.Add(sText)
    sText = trim(rgRow.cells(1,2)): if (sText <> "") call Col2.Add(sText)
    sText = trim(rgRow.cells(1,3)): if (sText <> "") call Col3.Add(sText)
next rgRow

此时,Col1、Col2 和 Col3 包含您的文本,其中空白单元格被分解出来,所以现在循环这些以打印出来

dim i as long
for i = 1 to 200
    on error resume next  ' (cheap way to avoid checking if index > collection sz)
    debug.print Col1(i) + " | " Col2(i) + " | " + Col3(i)
    on error goto 0
next i

(注意:手写代码没有检查...)

【讨论】:

  • 但是如何将其复制到 Word 中?
【解决方案3】:

如何替代您的第一个解决方案:

iMaxRow = 200

" Loop through columns and rows"
For iRow = 1 To iMaxRow
  For iCol = 1 To 3

    With Worksheets("GreatIdea").Cells(iRow, iCol)
      " Check that cell is not empty."
      If .Value = "" Then
          "Nothing in this cell."
          "Do nothing."
      Else
           "Copy the cell to the destination"
          .Copy appWD.Selection.PasteSpecial
      End If
    End With

  Next iCol
Next iRow

【讨论】:

  • @Tom,不,这只是格式化。我所做的只是将 Row 切换为外部循环,将 Column 切换为内部循环。
猜你喜欢
  • 2014-10-01
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
  • 2013-10-14
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 2022-01-28
相关资源
最近更新 更多