如何将值传递给数组然后循环遍历数据集

时间:2018-04-18 04:10:23

标签: arrays excel vba loops dynamic

我尝试构建一个循环,将来自E列的200个连续行(或从输入框确定的行数)相加,然后将范围向下移动一个单元格并重新计算(循环)直到它消失通过命名工作表中的所有已使用单元格。

为了循环的目的,Array的长度/大小是静态的,它是通过输入框从用户请求的,并且在循环完成之前保持不变。

到目前为止,我已经使用静态单元格引用完成了计算,例如。 " E2:E201"如下所示:

ClosingPrice200Array = Range("E2:E201").Value

所以我知道代码可以计算范围之和并除以变量。

我遇到的问题包括:

  1. 我想将E3中接下来的200行连续:E202,然后是E4:E203等,直到最后一次使用的行,而不是命名每个范围的变化。
  2. 为了做到这一点,我已经声明了行变量,确认我已经计算了正确的行数并尝试使用行变量将第一个范围(E2:E201)传递给指定的数组但是我得到了一个"编译错误:无法分配给数组"从我的代码:

    Sub Calculate200DMA()
    
        Dim Dma200current As Double
        Dim SumLast200Days As Long
        Dim MovingAverageLength As Integer
        MovingAverageLength = Application.InputBox("Input Required", "Moving Average Length", 200, , , , , 1)
        Dim ClosingPrice200Array(MovingAverageLength) as Variant 
    

    &#39>不能记住数组大小是否需要是常量但是我可以创建其他数组变量以满足需要的数量,所以请告知我每次都不能动态调整数组大小运行宏。

    Dim FirstRow As Integer
    Dim Lastrow As Integer
    Dim CurrentRow As Integer
    Dim NumberOfRows As Long
    
    'count number of rows to be used in the For loop
    Sheets("Data processing").Select
    NumberOfRows = ActiveSheet.UsedRange.Rows.Count
    
    FirstRow = 2
    CurrentRow = FirstRow + (MovingAverageLength - 1)
    Lastrow = CurrentRow
    

    '这是导致编译错误的行:

    ClosingPrice200Array = Sheets("Data processing").Range(Cells(FirstRow, 5), Cells(Lastrow, 5)).Value
    

    '其余的似乎在计算我想要的数字方面正常工作:

    SumLast200Days = Excel.WorksheetFunction.Sum(ClosingPrice200Array)
    Dma200current = SumLast200Days / MovingAverageLength
    Sheets("Data processing").Cells(CurrentRow, 10).Value = Dma200current
    
    'then i want to increment to the For loop but i have not written the start nor end loop yet because not sure exactly how to write (have been googling how to populate the array first)
    FirstRow = FirstRow + 1
    Lastrow = Lastrow + 1
    CurrentRow = CurrentRow + 1
    
    1. 此外,输入框似乎没有提示输入范围的长度(行数)。这是输入框的代码:

      Dim MovingAverageLength As Integer MovingAverageLength = Application.InputBox("Input Required", "MovingAverageLength", 200, , , , , 1)

    2. 提前感谢您的帮助。到目前为止,无法找到解决我谷歌搜索(此处或其他地方)问题的确切内容。

      约翰

2 个答案:

答案 0 :(得分:0)

在设置阵列的范围时,您需要将所有对象限定为工作表。

所以替换这一行:

$dom = new domDocument();
$dom->loadHTML($html);
$xpath = new DomXPath($this->dom);
$links = $xpath->query("//a/@href");
foreach($links as $link){
     echo $dom->saveHTML($link);
     echo "<br />";
}

使用

ClosingPrice200Array = Sheets("Data processing").Range(Cells(FirstRow, 5), Cells(Lastrow, 5)).Value

另外,请确保按照Tim William's comment的说明将您的数组声明为变体类型。

编辑以回复OP's question

  

你可以告诉你为什么用这个而不是吗?

从不需要使用With Worksheets("Data processing") ClosingPrice200Array = .Range(.Cells(firstRow, 5), .Cells(lastRow, 5)).Value End With 语句。这个语句只是让你的代码更具可读性,也可以节省一些按键。

如果您没有使用with语句,则必须在该行中输入With...End With三次:

  1. 工作表(&#34;数据处理&#34;)。范​​围()
  2. 工作表(&#34;数据处理&#34;)。单元格(firstRow,5)
  3. 工作表(&#34;数据处理&#34;)。单元格(lastRow,5)
  4. 这会使结果变得不那么可读:

    Worksheets("Data processing")

    虽然上述方法有效,但不会输入ClosingPrice200Array = Worksheets("Data processing").Range(Worksheets("Data processing").Cells(firstRow, 5), Worksheets("Data processing").Cells(lastRow, 5)).Value 三次,但使用with语句。

    您的代码无效的原因是您只将Worksheets("Data processing")对象限定为工作表,而不是Range()中的Cells()个对象,这意味着您改为使用活动表。

    您可以使用在子对象前放置句点Range()来限定with语句中的对象。

    这是使用With语句的另一个例子:

    .

    如果您没有使用with语句,则必须输入三次工作表:

    With Worksheets("Sheet1")
        .Range("A1") = "Blah"
        .Cells(1, 1) = "Blah"
        .Range("F:F").Clear
    End With
    

    再说一遍,它是可选的但很有用。您只需要将两个Worksheets("Sheet1").Range("A1") = "Blah" Worksheets("Sheet1").Cells(1, 1) = "Blah" Worksheets("Sheet1").Range("F:F").Clear 对象限定为工作表。

答案 1 :(得分:0)

您可以直接使用WorksheetFunction.Average()功能并使用范围:

Option Explicit

Sub Calculate200DMA()
    Dim MovingAverageLength As Long, LastRow As Long
    MovingAverageLength = Application.InputBox("Input Required", "Moving Average Length", 200, , , , , 1)

    Dim FirstRow As Long, CurrentRowOffset As Long, LastRowOffset As Long

    FirstRow = 2
    With Sheets("Data processing")
        LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
        LastRowOffset = (LastRow - FirstRow + 1) - MovingAverageLength ' set the last offset from first row
        With .Cells(FirstRow, 4).Resize(MovingAverageLength) ' reference the first range to sum
            For CurrentRowOffset = 0 To LastRowOffset
                .Cells(.Rows.Count).Offset(CurrentRowOffset, 6).Value = WorksheetFunction.Average(.Offset(CurrentRowOffset))
            Next
        End With
    End With
End Sub