【问题标题】:VBA, Code runs fine in excel 2010, slow and not responding error in 2013VBA,代码在 excel 2010 中运行良好,在 2013 年运行缓慢且无响应错误
【发布时间】:2018-07-11 01:58:16
【问题描述】:

以前在 2010 excel 版本(版本 14.0.7165.5000)中运行我的代码时,它在 4 分钟内运行。 (但是,如果我第二次运行它,它就不起作用) 切换到 2013 时,我得到“excel 没有响应”或者它只是 excel 挂起。 该代码从目录中打开一个文件,将它们加载到我的 Excel 工作表中并编译和转换一些数据。

我浏览了代码,似乎已经过了这部分,现在 excel 没有响应我给定的 sub sub ,特别是在这部分,

   'write
    For i = 1 To WorksheetFunction.Min(nRows, UBound(arr, 1))
        For j = 1 To nCols
            If fromTop Then writeVal = arr(i, j) Else writeVal = arr(UBound(arr, 1) - i + 1, j)
            thisWS.Cells(startRow + i - 1, startCol + j - 1).value = writeVal
        Next j
    Next i

有人知道这是为什么吗?是否有一些我正在使用的功能在 2010 年有效,但在 2013 年无效?

【问题讨论】:

  • 你可以分解代码(断点/什么),看看问题出在哪里。您还可以优化 writeArrToWS 子以在整个工作表范围内调用 ClearContents,并且还可以一键将数组写入工作表
  • @MacroMarc ,当excel表格停止响应时,通常在这一行,thisCurveDataRow = findInArrCol(curveNameToMarketData(thisCurveMapRow, 2), 2, curveData)
  • “停止”是什么意思?它会崩溃、返回错误还是其他?
  • 对不起,我的意思是我的 excel 没有响应,我现在刚刚通过它,当我到达 writeArrtoWS 子时出现此错误
  • 根据代码的大小/复杂性很难知道,而且 Excel 无响应也很难追踪。我要尝试的前两件事是:1)将 generateIRandCRshocks 末尾的块更改为“With ActiveWorkbook.Sheets("IR_CR_Shocks")”块,以及 2),将 writeArrToWS 的“清除”部分更改为循环遍历数组,生成范围对象并在其上使用 .ClearContents 方法。

标签: vba excel


【解决方案1】:

这不是真正的答案。但是,我不确定代码是否会在 cmets 部分中格式化。如果有人愿意告诉我将来如何处理这种情况,请告诉我!

无论如何,优秀的家伙,我的意思是:

'clear
startCell.Resize(nRows, nCols).ClearContents

代替:

'clear
For i = 1 To nRows
    For j = 1 To nCols
        thisWS.Cells(startRow + i - 1, startCol + j - 1).value = ""
    Next j
Next i

好的...接下来将更改 writeArrToWS 子程序以使用数组一次写入整个范围。我重写了 sub,并从我上面的答案中加入了修改后的变化。我想你会想要:

Public Sub writeArrToWS(arr() As Variant, startCell As Range, fromTop As Boolean, nRows As Long, nCols As Long)

    Dim i As Long, j As Long, startRow As Long, startCol As Long
    Dim thisWS As Worksheet, totalRange As Range

    Set thisWS = startCell.Worksheet

    'set the write range
    Set totalRange = startCell.Resize(nRows, nCols)

    'clear
    totalRange.ClearContents

    'write
    If fromTop Then
        totalRange.Value2 = arr
    Else
        Dim reversedArr() As Variant, swappedRow As Long
        ReDim reversedArr(1 To nRows, 1 To nCols)
        For i = 1 To nRows
            swappedRow = nRows - i + 1
            For j = 1 To nCols
                reversedArr(swappedRow, j) = arr(i, j)
            Next j
        Next i
        totalRange.Value2 = reversedArr
    End If

End Sub

一些事情:

  • 似乎如果 fromTop 为真,您只是将数组粘贴到范围...我误解了吗?如果是这样,这几乎就像你只想要一个“reverseArray”函数/子例程......
  • 我们基本上只是生成一个新数组“reversedArr”,它颠倒了行的顺序,但保留了列
  • 是否有任何特殊原因将 nRows 和 nCols 传递给函数?当 nRows 和 nCols 不仅仅是传递数组的行数和列数时,您是否想使用该函数?如果不是,那么我认为没有理由传递这些变量,而是从传递的数组在函数内部生成它们。

【讨论】:

  • Clear 实际上效果很好,只是下一个 write 部分导致 excel 没有响应。
  • @excelguy。 nRows 和 nCols 有多大?
  • 行大约 10k ,大约 18 cols (你需要精确吗)。无论如何,您可以帮助处理数组吗?
  • Nrows = 7440 , ncols = 18
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多