A UDF (a user defined function, called from a worksheet) cannot directly modify other cells, it can only return a value. There are, however, workarounds.
One such workaround is to construct a call to a Sub
as a string, and use Evaluate
to execute it.
Something like this:
Function copyToNewRange(rSrc As Range, rDst As Range)
Dim sSub As String
If rSrc.Columns.Count > 1 Or rDst.Columns.Count > 1 Then
copyToNewRange = CVErr(xlErrValue)
ElseIf rSrc.Rows.Count <> rDst.Rows.Count Then
copyToNewRange = CVErr(xlErrValue)
Else
sSub = "copyToNewRangeSub(" & _
rSrc.Address(True, True, xlA1, True) & "," & _
rDst.Address(True, True, xlA1, True) & ")"
rSrc.Worksheet.Evaluate sSub
copyToNewRange = vbNullString
End If
End Function
Sub copyToNewRangeSub(rSrc As Range, rDst As Range)
rDst.Value = rSrc.Value
End Sub
Note, there are several other issues in your code I have addressed
- When you want your function to return an err, return an ... Error
- To ensure the ranges are shaped correctly, counting cells alone is not enough
- Don't loop over a range, copy it in one go.
- Your function should return something
- You should
Dim
all your variables (use Option Explicit to force this)
- Use meaningfull parameter names
Thanks to Tim Willaims for the concept