为什么我的下标在vba中超出范围?

为什么我的下标在vba中超出范围?,vba,excel,cells,Vba,Excel,Cells,我希望excel遍历一列的每个单元格,对其执行操作,然后将结果复制到另一列。 这是我最初的代码: For i = 2 To dataRows ' Cells(i, aStampCol) = Cells(i, stampCol) - stim1TimeStamp 'Next i 这段代码确实有效,但运行速度非常慢。我看了另一段代码,他们说最好将列复制到数组中,对其进行操作,然后将其复制回列 因此,我编写了以下代码: cellsAStamp = Range(Cells(2,

我希望excel遍历一列的每个单元格,对其执行操作,然后将结果复制到另一列。 这是我最初的代码:

For i = 2 To dataRows
    '    Cells(i, aStampCol) = Cells(i, stampCol) - stim1TimeStamp 
    'Next i
这段代码确实有效,但运行速度非常慢。我看了另一段代码,他们说最好将列复制到数组中,对其进行操作,然后将其复制回列

因此,我编写了以下代码:

cellsAStamp = Range(Cells(2, stampCol), Cells(datarows, stampCol)) 
For i = 0 To datarows - 2
    cellsAStamp(i) = cellsAStamp(i) - stim1TimeStamp
Next i

Range(Cells(2, aStampCol), Cells(endRow, aStampCol)) = cellsAStamp
问题是,一旦for循环启动,就会出现“下标超出范围”错误。我的印象是cellsAsStamp没有正确存储数据,但我不知道如何解决这个问题,也不知道问题出在哪里

我已将完整代码粘贴到下面,以便您可以查看我是如何初始化变量的:

Sub WM()
Dim col As Integer
Dim spanCol As Integer
Dim msgCol As Integer
Dim stampCol As Integer   'The column containing the timestamp
Dim aStampCol As Integer 'The column containing the adjusted timestamp
Dim row As Long
Dim startRow As Long
Dim stimRow As Long 'the row on the Sample_Message column that says "stim1"
Dim endRow As Long  'the row on the Sample_Message column that says "participant_trial_end"
Dim triNum() As String 'a string array that will hold "Trial: x" after it has been split
Dim stim1TimeStamp As Long
Dim cellsAStamp() As Variant 'will contain the names of all the NoBlink sheets to allow for

'Identifies Timestamp column, adds ADJUSTED_TIMESTAMP column
For stampCol = 1 To 10
    If Cells(1, stampCol) = "TIMESTAMP" Then
            aStampCol = stampCol
            colLetter = ConvertToLetter(stampCol)
            Columns(colLetter & ":" & colLetter).Select
            Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
            stampCol = stampCol + 1
            Cells(1, aStampCol) = "ADJUSTED_TIMESTAMP"
        GoTo out
    End If
Next stampCol

out:

'Identifies Trial Label column
For col = 1 To 10
    If Cells(1, col) = "TRIAL_LABEL" Then
        GoTo out1
    End If
Next col

out1:

'Identifies Span column
For spanCol = 1 To 10
    If Cells(1, spanCol) = "span" Then
        GoTo out2
    End If
Next spanCol

out2:

'Identifies Message column
For msgCol = 1 To 10
    If Cells(1, msgCol) = "SAMPLE_MESSAGE" Then
        GoTo out3
    End If
Next msgCol

out3:

'Goes through Trial_Label column and deletes trials 1 and 2
row = 2
While Cells(row, col) Like "Trial: [12]"
    row = row + 1
 Wend
 row = row - 1

    If row = 1 Then 'in case the trials weren't there, it wont start at the header
        row = 2
        GoTo skipDelete
    End If

 Rows("2:" & CStr(row)).Delete

skipDelete:

'Goes through Trial_Label column and stops once the trial changes
row = 2
GoTo stillMoreLeft
stillMoreLeft:
 startRow = row
 currTrial = Cells(row, col) 'did not initialize currSpan and currTrial as strings
 currSpan = Cells(row, spanCol)

    While currTrial = Cells(row, col)
        'highlights any row that has a message
        If Cells(row, msgCol) <> "." Then
            Rows(CStr(row) & ":" & CStr(row)).Interior.Color = vbYellow
        End If

        'Identifies the row that contains "stim1" in Sample_Message
        If Cells(row, msgCol) = "stim1" Then
            stimRow = row
        End If

        'Identifies the row that contains "participant_trial_end" in Sample_Message
        If Cells(row, msgCol) = "participant_trial_end" Then
            endRow = row
        End If

        row = row + 1
    Wend
    row = row - 1
'Copies all of the rows containted in a trial
Rows(CStr(stimRow) & ":" & CStr(endRow)).Select
Selection.Copy

'Creates new sheet that will be named appropriately
Worksheets.Add
triNum = Split(currTrial)
currSheetName = "Trial" & triNum(1) & "Span" & currSpan
ActiveSheet.Name = currSheetName

'Pastes all the rows contained in at trial
Rows("2:2").Select
ActiveSheet.Paste

'Gets timestamp for stim1
stim1TimeStamp = Cells(2, stampCol)

'Puts the whole timestamp column in an array/ Does the appropriate calculations to each value
datarows = endRow - stimRow + 2
cellsAStamp = Range(Cells(2, stampCol), Cells(datarows, stampCol)) 'looks like a legit way to use range
For i = 0 To datarows - 2
    cellsAStamp(i) = cellsAStamp(i) - stim1TimeStamp
Next i

Range(Cells(2, aStampCol), Cells(endRow, aStampCol)) = cellsAStamp

'Fills the Adjusted_TimeStamp column
'dataRows = endRow - stimRow + 2
'For i = 2 To dataRows
'    Cells(i, aStampCol) = Cells(i, stampCol) - stim1TimeStamp 'This equation says: the Adjusted_Time_Stamp=TimeStamp-TimeStamp of Stim1
'Next i

'Copies header row and pastes it to first row of most recent trial sheet
Sheets(ActiveWorkbook.Name).Select
Rows("1:1").Select
Selection.Copy
Sheets(currSheetName).Select
Rows("1:1").Select
ActiveSheet.Paste

row = row + 1 'we increment the row so that on the next line, when they check for whether the cell is empty or not, we aren't looking at the last cell of our current trial, but the first cell of our following trial
Sheets(ActiveWorkbook.Name).Select

'Looks to see if there is still a trial left, if so, it goes through all of it
If Cells(row, col) <> "" Then
    GoTo stillMoreLeft
Else
    bob = 1 + 1
End If

End Sub

Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int(iCol / 27)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
  ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
  ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
Sub-WM()
作为整数的Dim col
Dim spanCol作为整数
Dim msgCol作为整数
Dim stampCol As Integer'包含时间戳的列
Dim aStampCol As Integer'包含调整后时间戳的列
暗排一样长
黯淡的星空如长
Dim stimRow As Long“示例消息列上显示“stim1”的行”
Dim endRow As Long“示例消息列上显示“参与者试验结束”的行”
Dim triNum()作为字符串“一个字符串数组,在拆分后将保留“Trial:x”
时间戳的长度与时间戳的长度相同
Dim CellsStamp()作为变量“将包含所有允许
'标识时间戳列,添加调整的\u时间戳列
对于stampCol=1到10
如果单元格(1,stampCol)=“时间戳”,则
阿斯坦普利=stampCol
夹头=转换器夹头(stampCol)
列(colLetter&“:”&colLetter)。选择
选择。插入Shift:=xlToRight,CopyOrigin:=xlFormatFromLeftOrAbove
stampCol=stampCol+1
单元格(1,aStampCol)=“调整的时间戳”
出去
如果结束
下一个stampCol
输出:
'标识试用标签列
对于col=1到10
如果单元格(1,col)=“试验标签”,则
出去
如果结束
下一列
输出1:
'标识跨度列
对于spanCol=1到10
如果单元格(1,spanCol)=“span”,则
跳出去2
如果结束
下一个斯潘科尔
输出2:
'标识消息列
对于msgCol=1到10
如果单元格(1,msgCol)=“样本消息”,则
出去
如果结束
下一个msgCol
输出3:
'通过试用标签列并删除试用1和试用2
行=2
而单元格(行、列)则类似于“试验:[12]”
行=行+1
温德
行=行-1
如果row=1,则“如果没有试验,则不会从页眉开始”
行=2
后藤斯基普德莱特酒店
如果结束
行(“2:&CStr(行))。删除
skipDelete:
'通过试用标签列,并在试用更改后停止
行=2
转到斯蒂尔摩左
左:
startRow=行
currTrial=单元格(行,列)“”未将currSpan和currTrial初始化为字符串
currSpan=单元格(行,跨栏)
而currTrial=单元格(行、列)
'突出显示包含消息的任何行
如果单元格(行,msgCol)“.”则
行(CStr(行)&“&CStr(行)).Interior.Color=vbYellow
如果结束
'标识示例_消息中包含“stim1”的行
如果单元格(行,msgCol)=“stim1”,则
行
如果结束
'标识示例消息中包含“参与者\u试用\u结束”的行
如果单元格(行,msgCol)=“参与者试验结束”,则
endRow=行
如果结束
行=行+1
温德
行=行-1
'复制试用中包含的所有行
行(CStr(stimRow)和“&CStr(endRow))。选择
选择,复制
'创建将被适当命名的新工作表
工作表。添加
triNum=分割(当前试验)
currSheetName=“试用版”和triNum(1)以及“Span”和currSpan
ActiveSheet.Name=currSheetName
'粘贴中包含的所有行
行(“2:2”)。选择
活动表。粘贴
'获取stim1的时间戳
stim1TimeStamp=单元格(2,stampCol)
'将整个时间戳列放入数组/对每个值进行适当的计算
datarows=endRow-stimRow+2
cellsAStamp=Range(Cells(2,stampCol),Cells(datarows,stampCol))'看起来是使用Range的合法方法
对于i=0到数据行-2
CellsStamp(i)=CellsStamp(i)-Stim1时间戳
接下来我
范围(单元格(2,aStampCol),单元格(endRow,aStampCol))=cellsAStamp
'填充调整后的_时间戳列
'dataRows=endRow-stimRow+2
'对于i=2到数据行
“Cells(i,aStampCol)=Cells(i,stampCol)-stim1TimeStamp”该等式表示:调整后的时间戳=Stim1的时间戳
“接下来我
'复制标题行并将其粘贴到最新试用表的第一行
工作表(ActiveWorkbook.Name)。选择
行(“1:1”)。选择
选择,复制
工作表(currSheetName)。选择
行(“1:1”)。选择
活动表。粘贴
row=row+1'我们增加行数,以便在下一行,当他们检查单元格是否为空时,我们不是查看当前试验的最后一个单元格,而是查看下一次试验的第一个单元格
工作表(ActiveWorkbook.Name)。选择
“看看是否还有审判,如果是的话,它会经历所有的审判
如果单元格(行、列)“,则
转到斯蒂尔摩左
其他的
鲍勃=1+1
如果结束
端接头
函数转换器(iCol为整数)为字符串
Dim iAlpha作为整数
Dim iMainder作为整数
iAlpha=Int(iCol/27)
iMainder=iCol-(iAlpha*26)
如果iAlpha>0,则
转换器=Chr(iAlpha+64)
如果结束
如果iMainder>0,则
ConvertToLetter=ConvertToLetter&Chr(iMainder+64)
如果结束
端函数

将范围读入数组时,它将是一个二维数组(基于1)——维度1是行,维度2是列——即使只有一列。因此,请尝试:

cellsAStamp(i,1) = cellsAStamp(i,1) - stim1TimeStamp