2016-11-05 68 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