无法粘贴 - Excel VBA

Posted

技术标签:

【中文标题】无法粘贴 - Excel VBA【英文标题】:Cant paste - Excel VBA 【发布时间】:2017-03-16 14:11:46 【问题描述】:

我正在编写将自动化流程的代码。我希望它使用公式从各种文件复制到其他文件,计算,然后再返回。

我在尝试粘贴时遇到了一条消息“运行时错误'1004',范围类的pastespecial方法失败”。仅当我使用变量声明第一个单元格以复制一系列值时,才会出现该消息。 当我使用直接单元格描述时,一切正常。 我还使用自定义函数来获取给定字段名称的列字母。

Function ActiveColumnName(fieldname As String, fieldnames_line   As Integer) As String

Range("A" & fieldnames_line & ":AB" & fieldnames_line).NumberFormat = "@"

Cells.find(What:=fieldname, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
    :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
    False, SearchFormat:=False).Activate  

ActiveColumnNumber = ActiveCell.Column  


Dim m As Integer
Dim ActiveColumnName As String

ActiveColumnName  = ""

Do While (ActiveColumnNumber > 0)
    m = (ActiveColumnNumber - 1) Mod 26
    ActiveColumnName  = Chr(65 + m) + ActiveColumnName 
    ActiveColumnNumber = Int((ActiveColumnNumber - m) / 26)
Loop

End Function


sub main ()

Dim firstrow_data_main As Integer
Dim firstrow_fieldnames_main As Integer

firstrow_data_main = 16
firstrow_fieldnames_main = 15


Range(ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_main) & firstrow_data_main, Range(ActiveColumnName("ÄÅÔÅ", firstrow_fieldnames_main) & Rows.Count).End(xlUp).Offset(-1)).Select  
Application.CutCopyMode = False
Selection.Copy

Workbooks.Open help_file '"help_file" is any given .xls path with formulas


Dim firstrow_data_help As Integer
Dim firstrow_fieldnames_help As Integer

firstrow_data_help = 7
firstrow_fieldnames_help = 4

'NOW WHEN I USE THIS, DOESN'T WORK:

-> Range(ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_help) & firstrow_data_help).Select 

'WHEN I USE THIS, WORKS FINE:

-> Range("L7").Select 

Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
   Application.CutCopyMode = False

End Sub

当它不起作用时,它打开.xls,并且确实选择了所需的单元格,但没有pate。我知道这与剪贴板有关,但我无法弄清楚。有什么建议吗?

【问题讨论】:

1.通过直接引用单元格来删除所有选择和激活,请参阅HERE 2. 查找Cells() 而不是Range 并避免将列号转换为字母的整个需要,因为Cells() 使用数字。 3. 当值是您想要的唯一内容时避免使用剪贴板,只需将值分配给新单元格(这将要求两个范围的大小相同,因此使用 Resize()) 4. 始终表示范围的父工作表,它将减少错误。 【参考方案1】:
    通过直接引用单元格来删除所有选择和激活,有关详细信息,请参阅HERE。 查看 Cells() 而不是 Range,避免将列号转换为字母的整个需要,因为 Cells() 使用数字。 当您只需要值时避免使用剪贴板,只需将值分配给新单元格(这将要求两个范围的大小相同,因此请使用 Resize()) 始终表示范围的父工作表,这样可以减少错误。

代码重构

Sub main()

Dim firstrow_data_main As Integer
Dim firstrow_fieldnames_main As Integer
Dim rng As Range

Dim tWb As Workbook
Dim ws As Worksheet
Dim tWs As Worksheet
Dim firstrow_data_help As Integer
Dim firstrow_fieldnames_help As Integer



Set ws = ThisWorkbook.ActiveSheet
Set tWb = Workbooks.Open(help_file)
Set tWs = tWb.ActiveSheet

firstrow_data_main = 16
firstrow_fieldnames_main = 15
firstrow_data_help = 7
firstrow_fieldnames_help = 4

With ws
    Set rng = .Range(.Cells(firstrow_data_main, firstrow_fieldnames_main), .Cells(.Rows.Count, firstrow_fieldnames_main).End(xlUp).Offset(-1))
    tWs.Cells(firstrow_data_help, firstrow_fieldnames_help).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
End With

End Sub

【讨论】:

【参考方案2】:

我认为问题可能出在这里:

ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_main)

这意味着ActiveColumnName 是一个具有n x (1 to 2) 维度的矩阵。如果要将名称连接到变量,则必须使用(示例):

"YourStringHere" & YourVariableHere & "AnotherString"

在你的情况下是:

ActiveColumnName("<FIELDNAME>" & firstrow_fieldnames_main)

所以如果我理解正确(&lt;FIELDNAME&gt; 有点晦涩),整个命令应该是:

Range(ActiveColumnName("<FIELDNAME>" & firstrow_fieldnames_help) & "," & firstrow_data_help).Select 

【讨论】:

【参考方案3】:

首先,您应该在运行之前编译您的 VBA。 VBA 编译器立即发现了这一点:Dim ActiveColumnName As String 是不必要的,因为您在第 1 行定义函数时将 ActiveColumnName 分配为字符串。

您使用了大量对活动单元格和选择单元格的引用。众所周知,这会导致运行时错误。看到这个帖子:"How to avoid using Select in Excel Vba Macros"。

我怀疑该字段名不在您认为应该在您的 help_file 中的位置,即它不在第 4 行中。这意味着代码不知道将数据粘贴到哪里。一般来说,最好的调试方法是将代码拼凑成最小的动作,看看是什么导致了错误(参见SpreadSheet Guru Strategies)。可以运行下面的代码看看输出是什么吗?

Function ActiveColumnName(fieldname As String, fieldnames_line As Integer) As String

Range("A" & fieldnames_line & ":AB" & fieldnames_line).NumberFormat = "@"
Cells.Find(What:=fieldname, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
    :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
    False, SearchFormat:=False).Activate
ActiveColumnNumber = ActiveCell.Column
Dim m As Integer
ActiveColumnName = ""

Do While (ActiveColumnNumber > 0)
    m = (ActiveColumnNumber - 1) Mod 26
    ActiveColumnName = Chr(65 + m) + ActiveColumnName
    ActiveColumnNumber = Int((ActiveColumnNumber - m) / 26)
Loop

End Function
Sub main()

Workbooks.Open "help_file" '"help_file" is any given .xls path with formulas
Dim firstrow_data_help As Integer
Dim firstrow_fieldnames_help As Integer
firstrow_data_help = 7
firstrow_fieldnames_help = 4

MessageBox = ActiveColumnName("FIELDNAME", firstrow_fieldnames_help) & firstrow_data_help

End Sub

【讨论】:

【参考方案4】:

感谢大家的回复!我已经一一尝试了您的所有建议,但在此过程中遇到了各种问题。尽管如此,您的所有建议都帮助我对这个主题产生了不同的看法。我最终得到的解决方案源于您的建议,即丢弃“.select”作为参考方式并使用“rng”变量,当然还有摆脱双重参考“ActiveColumnName”。我知道我有一个很长的路要走,但目前这个东西有效!!谢谢!!

子主()

Dim firstrow_data_main As Integer
Dim firstrow_fieldnames_main As Integer
Dim firstrow_data_help As Integer
Dim firstrow_fieldnames_help As Integer



firstrow_data_main = 16
firstrow_fieldnames_main = 15
firstrow_data_help = 7
firstrow_fieldnames_help = 4


Dim rng1 As Range
Dim rng2 As Range

Set rng1 = Range(ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_main) & firstrow_data_main, Range(ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_main) & Rows.Count).End(xlUp).Offset(-1))

cells_selected = rng1.Rows.Count

Workbooks.Open <help_file>


Set rng2 = Range(ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_help) & firstrow_data_help, Range(ActiveColumnName("<FIELDNAME>", firstrow_fieldnames_help) & cells_selected + firstrow_data_help - 1))

rng1.Copy rng2  

结束子

【讨论】:

以上是关于无法粘贴 - Excel VBA的主要内容,如果未能解决你的问题,请参考以下文章

使用 Excel VBA 实现复制 粘贴 和保存,并自动运行VBA

Excel VBA在循环内复制和粘贴循环

excel vba 选择性粘贴并设置为真文本?

VBA 在 Outlook 中粘贴带有图表的特定 excel 范围

excel VBA 当有公式的单元格录入内容后,自动将内容粘贴为数值

vba粘贴不起作用