VBA:编写CopyAndPaste函数

时间:2016-09-08 02:05:25

标签: vba excel-vba excel

我编写了一个CopyAndPaste函数,并尝试从Main调用该函数。但是,在以下位置出现错误:

CopyAndPaste(ThisWS,FromRange,ThisWS,ToRange,False)
  

编译错误
  预期:=

我可以知道为什么会这样吗?

Sub Main()

Dim ThisWS As Worksheet, FromRange As Range, ToRange As Range

Set ThisWS = ActiveSheet
Set FromRange = Range("I6")
Set ToRange = Range("M6")

CopyAndPaste(ThisWS,FromRange,ThisWS,ToRange,False)

End Sub    


Function CopyAndPaste(RefSheet As Worksheet, RefRange As Range, ToSheet As Worksheet, ToRange As Range, _
                      Optional HLink As Boolean)

RefSheet.RefRange.Copy Destination:=ToSheet.ToRange

If HLink = True Then
    ActiveSheet.Hyperlinks.Add _
        Anchor:=ToSheet.ToRange, _
        Address:="", _
        SubAddress:=RefSheet.Name & "!" & RefRange.Address, _
        ScreenTip:="Click to view details", _
        TextToDisplay:=""
End If

End Function

4 个答案:

答案 0 :(得分:3)

其他答案似乎将括号视为仅仅是化妆品细节。他们不是。

我无法重现您的确切编译错误,但您的代码无效。这是一个Minimal, Complete, Verifiable Example,它解释了发生了什么:

有效代码

Option Explicit

Public Sub DoSomething()
    Test Nothing
End Sub

Function Test(foo As Object)
End Function

无效代码

Option Explicit

Public Sub DoSomething()
    Test (Nothing) ' compile error: invalid use of object
End Sub

Function Test(foo As Object)
End Function

唯一的区别是括号。那么这些括号究竟做了什么?

  

这很令人困惑,为什么不使用括号?

     

括号强制VBA评估括号中的表达式的值,并将结果ByVal传递给被调用的过程。

括号基本上是指“将此表达式计算为值” - 我们尝试使用在编译时已知的对象引用来执行此操作:VBA拒绝继续,并抱怨。

使用多个参数更加明显 - VBA应该将此表达式评估为什么?

(Sheet1, Thisworkbook, Nothing)
  • 调用Sub过程时,绝不能提供括号。
  • 调用Function过程时,只要不丢弃函数的返回值,就必须提供括号。

换句话说,禁止不具有Function过程Sub过程语义(即没有返回值,副作用)。

语义正确代码

Option Explicit

Public Sub DoSomething()
    Debug.Print Test(Nothing) 'parentheses required because we're using the returned value
End Sub

Function Test(foo As Object) As String
    'compute something using foo, return a value
End Function

答案 1 :(得分:2)

你传递了一些变量(但并不是真的需要)。

1.一旦您从 ThisWS 工作表中定义并设置 FromRange ,以后就无需使用RefSheet.RefRange,您只需使用RefRange }。

2.由于你没有从 CopyAndPaste 返回任何内容,它应该是一个普通的Sub(不一定是一个函数)。

3.确定您有1张或2张,因为 RefSheet ToSheet 是相同的,因为他们都得到了传递的参数 ThisWS (工作表)。

Sub Main()

Dim ThisWS As Worksheet, FromRange As range, ToRange As range

' it's better if you used instead something like Set ThisWS = Sheets("YourSheetName")
Set ThisWS = ActiveSheet
Set FromRange = ThisWS.range("I6")
Set ToRange = ThisWS.range("M6")

CopyAndPaste FromRange, ThisWS, ToRange, False

End Sub


Sub CopyAndPaste(RefRange As range, ToSheet As Worksheet, ToRange As range, _
                      Optional HLink As Boolean)

RefRange.Copy ToRange

If HLink = True Then
    ToSheet.Hyperlinks.Add _
        Anchor:=ToRange, _
        Address:="", _
        SubAddress:=RefRange.Parent.Name & "!" & RefRange.Address, _
        ScreenTip:="Click to view details", _
        TextToDisplay:=""
End If

End Sub

答案 2 :(得分:1)

函数不应该用于更改其他单元格,而是用于计算和返回值。

使你的例程成为一个子,而不是一个函数。然后在没有括号的情况下调用它。

答案 3 :(得分:0)

由于每个人的帮助,我设法完成了我的计划。这是我的代码。随意使用它。

Sub Main()

Dim FromSheet As Worksheet, ToSheet As Worksheet
Dim FromRange As Range, ToRange As Range

Set FromSheet = Worksheets(1)
Set ToSheet = Worksheets(2)
Set FromRange = FromSheet.Range("E10:E15")
Set ToCell = ToSheet.Range("N2")

CopyAndPaste FromRange, ToCell, True

End Sub

Public Sub CopyAndPaste(FromRange As Range, ToCell As Range, Optional HLink As Boolean)

If HLink = True Then

Dim FromCell As Range, R As Long, C As Long

R = FromRange.Rows.count
C = FromRange.Columns.count

    For C = 0 To C - 1
    For R = 0 To R - 1

        ToCell.Parent.Hyperlinks.Add _
            Anchor:=ToCell.Offset(R, C), _
            Address:="", _
            SubAddress:="'" & FromRange.Parent.Name & "'!" & FromRange.Rows(R + 1).Columns(C + 1).Address, _
            ScreenTip:="Click to view Sheet: " & FromRange.Parent.Name, _
            TextToDisplay:=FromRange.Rows(R + 1).Columns(C + 1).Value
    Next R
    Next C

Else

FromRange.Copy ToCell

End If

End Sub