Search code examples
excelvbaworksheet-function

Using the LinEst function and return values in a column of variable length


I am trying to use the LinEst function to take values from a range of rows of data and input them into a new sheet under some headings. I only want to do this for a particular number of rows (up to row number defined as "c". My VBA skills are very basic.

Sub Button7_Click()

Sheets.Add.Name = "Down Sweep Power Law"

 Dim xrng As Range, yrng As Range
    Dim i As Long
    Dim Rng As Range
    Dim l As Long
    Dim k As Long
    Dim i2 As Long
    Dim c As Long
    Dim j As Long
    Dim drop As Range
    Dim drop2 As Range
    Dim DownSweep As Chart, UpSweep As Chart, cht As Chart
    Dim ws As Worksheet, smallest
    Dim dsws As Worksheet

    Set ws = Worksheets("Template") '<< use variables for worksheets!

    Set dsws = Worksheets("Down Sweep Power Law")

    Set Rng = ws.Range(ws.Range("B11"), ws.Range("B11").End(xlDown))

    smallest = WorksheetFunction.Small(Rng, 1)
    l = Rng.Find(what:=smallest, LookIn:=xlValues, lookat:=xlWhole).Row
    k = Rng.Rows.Count

    c = l - 10

    Set xrng = ws.Range("C11:CP11")
    Set yrng = ws.Range("C201:CP201")
    Set drop = dsws.Range("A2")
    Set x2rng = xrng.Offset(1, 0)
    Set y2rng = yrng.Offset(1, 0)
    Set drop2 = drop.Offset(1, 0)

dsws.Range("A1").Value = "(n-1) Value"
dsws.Range("B1").Value = "log(k) Value"
dsws.Range("C1").Value = "(n-1) Value"
dsws.Range("D1").Value = "n Value"
dsws.Range("E1").Value = "R Value"

If i < c Then

Set drop = Application.LinEst(Log10(yrng), Log10(xrng), True, False)

i = i + 1

End If

ITERATE:

If i < c Then

Set drop2 = Application.LinEst(Log10(y2rng), Log10(x2rng), True, False)

x2rng = x2rng.Offset(1, 0)
y2rng = y2rng.Offset(1, 0)
drop2 = drop2.Offset(1, 0)
i = i + 1
GoTo ITERATE

End If


End Sub


the code runs but when I go on the created sheet, there is a #NAME error (2029) and no values are present.

Is there a way to fix this?

Any help would be appreciated.


Solution

  • I think you have omitted a step from your plan. LinEst returns an array and you want to assign the values in that array to the range Drop. You can't assign the array directly to the range. Please try this code.

    Option Explicit
    
    Sub Button7_Click()
    
        Dim xrng As Range, yrng As Range
        Dim Drop As Range
        Dim Arr As Variant                          ' LinEst result array
        Dim Rng As Range
        Dim R As Long
        Dim l As Long
        Dim k As Long
        Dim i2 As Long
        Dim c As Long
        Dim j As Long
        Dim DownSweep As Chart, UpSweep As Chart, cht As Chart
        Dim ws As Worksheet, Smallest As Variant
        Dim dsws As Worksheet
    
        Set ws = Worksheets("Template") '<< use variables for worksheets!
        Sheets.Add.Name = "Down Sweep Power Law"
        Set dsws = Worksheets("Down Sweep Power Law")
        Set Rng = ws.Range(ws.Range("B11"), ws.Range("B11").End(xlDown))
    
        Smallest = WorksheetFunction.Small(Rng, 1)
        l = Rng.Find(what:=Smallest, LookIn:=xlValues, LookAt:=xlWhole).Row
        k = Rng.Rows.Count
        c = l - 10
    
        Set xrng = ws.Range("C11:CP11")
        Set yrng = ws.Range("C201:CP201")
        Set Drop = dsws.Range("C2:CP2").Offset(0, -2)
    
        dsws.Range("A1").Value = "(n-1) Value"
        dsws.Range("B1").Value = "log(k) Value"
        dsws.Range("C1").Value = "(n-1) Value"
        dsws.Range("D1").Value = "n Value"
        dsws.Range("E1").Value = "R Value"
    
        Do While R < c
            Arr = Application.LinEst(Log10(yrng), Log10(xrng), True, False)
            Drop.Value = Arr    ' or perhaps: = Application.Transpose(Arr)
            Set xrng = xrng.Offset(1, 0)
            Set yrng = yrng.Offset(1, 0)
            Set Drop = Drop.Offset(1, 0)
            R = R + 1
        Loop
    End Sub
    

    I don't know what kind of array LinEst will return. You may have to transpose the result.

    I also tried to improve your management of ranges. However, the code is entirely untried, for lack of data. There may be logical errors in my code as well as typos but the syntax should be sound. It may not take you all the way over the finish line but I hope it will help you in your quest.