2016-11-05 69 views
0

我想从用户定义函数返回值,但返回的值都是0。我觉得我分配给变量wk1和wk2的值没有在函数中使用。子程序返回全0 0

该子程序的目标是计算股票的每周回报,给定工作表“价格”中提供的价格。

我不是很精明与VBA所以任何帮助表示赞赏

感谢您的帮助!

Public Sub wklyrtn() 
Dim wk1, wk2 As Long 
Dim row As Long, column As Long 
Dim matrix1(2 To 261, 2 To 11) As Integer 



Sheets("Prices").Select 
Selection.Activate 

For row = 2 To 261 
    For column = 2 To 11 
     wk2 = Cells(row, column).Value 
     wk1 = Cells(row + 1, column).Value 
     matrix1(row, column) = Rtrn(wk1, wk2) 
    Next column 
Next row 

Sheets("Returns").Select 
Selection.Activate 

For row = 2 To 261 
    For column = 2 To 11 
     Cells(row, column) = matrix1(row, column) 
    Next column 
Next row 


End Sub 

Public Function Rtrn(wk1, wk2) 
Dim delt As Long 
Application.Volatile True 

delt = wk2 - wk1 
Rtrn = delt/wk1 

End Function 
+1

也许你值都被截断为0,因为你宣布'matrix'到是'Integer'。用'Variant'和s替换'Integer' ee会发生什么。 –

+1

这里有几个错误。首先,你不能声明'Dim wk1,wk2 As Long',它只会声明wk2很长,你必须做'Dim wk1 long,wk2 as long'。但这不是它会失败的原因。同时避免使用'select'。您可能需要使用'set'来引用对象引用(您的工作表) – Niclas

+1

抱歉,错误地指出它。我删除了评论,并在此处发布了正确的信息: John的建议将使您的代码正常工作。如果一个数组被声明为某种类型(例如整型),所有到这个数组的值都必须具有相同的类型。通过将其声明为Variant,所有类型的值都可以正确传输到该数组中。永远不要将任何东西声明为Integer,如果需要的话使用Long。在32位和64位系统上,整数转换为长整型,所以没有性能增益。 –

回答

1

试试这个。不知道你想用Matrix做什么。但是这会给你你需要的价值。你需要引用一个对象(工作表)而不是使用select(总是避免一般和尝试,而不是使用set引用的对象。

Option Explicit 

Public Sub wklyrtn() 
Dim wk1 As Long, wk2 As Long 
Dim row As Long, column As Long 
Dim matrix1(2 To 261, 2 To 11) As variant 
Dim wks As Worksheet, wks2 As Worksheet 

Set wks = ThisWorkbook.Sheets("Prices") 

With wks 
For row = 2 To 261 
    For column = 2 To 11 
     wk2 = wks.Cells(row, column).Value 
     wk1 = wks.Cells(row + 1, column).Value 
     matrix1(row, column) = Rtrn(wk1, wk2) 
    Next column 
Next row 
End With 

Set wks2 = ThisWorkbook.Sheets("Returns") 

With wks2 
For row = 2 To 261 
    For column = 2 To 11 
     wks2.Cells(row, column) = matrix1(row, column) 
    Next column 
Next row 
End With 


End Sub 
+0

非常感谢帮助,这工作! – willshep

0
Public Sub Get_Price_Index_Var() 
Dim lRow As Long, bCol As Byte    'Avoid naming varaibles same as VBA objects, properties, etc 
Dim vResults(2 To 261, 2 To 11) As Variant 'Using variant datatype gives flexibility to hold the result of the operations perform 
Dim aResults As Variant      'Used get resulting array to be enter in Returns Worksheet 
Dim vVal1 As Variant, vVal2 As Variant 

    With ThisWorkbook.Sheets("Prices") 
     For lRow = 2 To 261 
      For bCol = 2 To 11 
       vVal1 = .Cells(lRow, bCol).Value 
       vVal2 = .Cells(1 + lRow, bCol).Value 
       vResults(lRow, bCol) = fReturns(vVal1, vVal2) 
    Next: Next: End With 
    aResults = WorksheetFunction.Index(vResults, 0, 0) 

    With ThisWorkbook.Sheets("Returns") 
     .Cells(2, 2).Resize(UBound(aResults), UBound(aResults, 2)).Value = aResults 
    End With 

    End Sub 


Public Function fReturns(vVal1 As Variant, vVal2 As Variant) As Variant 
    fReturns = (vVal2 - vVal1)/vVal1 
    End Function 
0
其他

比Variant变量工作(因为你已经被告知),您可以使用数组既加快宏执行的优势,缩短了你的代码:

Option Explicit 

Public Sub wklyrtn() 
    Const ROWMIN As Long = 2 
    Const ROWMAX As Long = 261 
    Const COLMIN As Long = 2 
    Const COLMAX As Long = 11 

    Dim row As Long, column As Long 
    Dim data As Variant, matrix1 As Variant 

    With Sheets("Prices") 
     data = .Range(.Cells(ROWMIN, COLMIN), .Cells(ROWMAX + 1, COLMAX)).Value '<--| read all needed values into 'data' array (it needs one row more at the bottom) 
    End With 

    ReDim matrix1(1 To ROWMAX - ROWMIN + 1, 1 To COLMAX - COLMIN + 1) As Double '<--| size returned valuse array accordingly to chosen rows and column indexes ranges 
    For row = 1 To ROWMAX - ROWMIN + 1 
     For column = 1 To COLMAX - COLMIN + 1 
      matrix1(row, column) = Rtrn(data(row + 1, column), data(row, column)) '<-- store returned values into 'matrix1' array 
     Next column 
    Next row 

    Sheets("Returns").Cells(2, 2).Resize(ROWMAX - ROWMIN + 1, COLMAX - COLMIN + 1 + 1).Value = matrix1 '<--| write returned values from 'matrix1' array into cells 
End Sub 

Public Function Rtrn(wk1, wk2) 
    Dim delt As Long 
    Application.Volatile True 

    delt = wk2 - wk1 
    Rtrn = delt/wk1 
End Function