Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 使用VBA删除每第2行和第3行_Excel_Dataset_Vba - Fatal编程技术网

Excel 使用VBA删除每第2行和第3行

Excel 使用VBA删除每第2行和第3行,excel,dataset,vba,Excel,Dataset,Vba,我正在寻找有关快速删除三分之二中等大小数据集的见解。目前,我正在将以空格分隔的数据从文本文件导入Excel,并使用循环逐行删除数据。循环从数据最底层的行开始,并删除向上的行。数据是按时间顺序排列的,我不能简单地删掉数据的前三分之二或后三分之二。从本质上讲,发生的情况是数据被过度采样,太多的数据点彼此过于接近。这是一个极其缓慢的过程,我只是在寻找另一种方法 Sub Delete() Dim n As Long n = Application.WorksheetFunction.Count(Ra

我正在寻找有关快速删除三分之二中等大小数据集的见解。目前,我正在将以空格分隔的数据从文本文件导入Excel,并使用循环逐行删除数据。循环从数据最底层的行开始,并删除向上的行。数据是按时间顺序排列的,我不能简单地删掉数据的前三分之二或后三分之二。从本质上讲,发生的情况是数据被过度采样,太多的数据点彼此过于接近。这是一个极其缓慢的过程,我只是在寻找另一种方法

Sub Delete()

Dim n As Long

n = Application.WorksheetFunction.Count(Range("A:A"))

Application.Calculation = xlCalculationManual

Do While n > 5

n = n - 1
Rows(n).Delete
n = n - 1
Rows(n).Delete
n = n - 1

Loop

   Application.Calculation = xlCalculationAutomatic

End Sub

使用允许按特定数字步进的for循环:

对于i=8到n步骤3

使用Union创建存储在范围变量中的不相交范围

Set rng=Union(rng,.Range(.Cells(i+1,1),.Cells(i+2,1))

然后一次删除所有内容

rng.EntireRow.Delete

鼓励的另一个好习惯是使用始终声明任何范围对象的父对象。随着代码变得越来越复杂,不声明父级可能会导致问题

通过将
块一起使用

带有工作表(“表1”)

我们可以在所有范围对象前面加上
,以表示指向该父对象的链接

Set rng=.Range(“A6:A7”)


您可以使用数组并将三分之一的行写入新数组。然后在清除原稿后打印到屏幕上

如果有公式,您将丢失公式。如果您只有一个基本的数据集,这可能适合您。应该很快

Sub MyDelete()
    Dim r As Range
    Set r = Sheet1.Range("A1").CurrentRegion  'perhaps define better
    Set r = r.Offset(1, 0).Resize(r.Rows.Count - 1)  ' I assume row 1 is header row.

Application.ScreenUpdating = False

    Dim arr As Variant
    arr = r.Value

    Dim newArr() As Variant
    ReDim newArr(1 To UBound(arr), 1 To UBound(arr, 2))
    Dim i As Long, j As Long, newCounter As Long
    i = 1
    newCounter = 1

    Do
        For j = 1 To UBound(arr, 2)
            newArr(newCounter, j) = arr(i, j)
        Next j

        newCounter = newCounter + 1
        i = i + 3
    Loop While i <= UBound(arr)

    r.ClearContents
    Sheet1.Range("A2").Resize(newCounter - 1, UBound(arr, 2)).Value = newArr

Application.ScreenUpdating = True

End Sub
Sub MyDelete()
调光范围
设置r=Sheet1。范围(“A1”)。CurrentRegion'可能定义得更好
设置r=r.Offset(1,0)。调整大小(r.Rows.Count-1)’我假设第1行是标题行。
Application.ScreenUpdating=False
作为变体的Dim-arr
arr=r.值
Dim newArr()作为变量
ReDim newArr(1至UBound(arr),1至UBound(arr,2))
暗i长,j长,newCounter长
i=1
newCounter=1
做
对于j=1至UBound(arr,2)
newArr(newCounter,j)=arr(i,j)
下一个j
newCounter=newCounter+1
i=i+3

循环同时,我还研究了多重选择循环中所有感兴趣的行,并在选择了所有行之后使用一行代码执行删除,但没有找到一种方法。我想这可能会增加总体计算时间。谢谢,我明天会试试。你认为使用这种方法会大大减少计算时间吗?@Jesse是的,因为它只删除一次。我将你的方法与使用小数据集的原始方法进行了比较,大约快225%。使用相同的数据集,循环需要519和231执行。这两组代码都在一个.xlsm中,它有许多其他的工作表、模块等。然后我把我的原始代码插入一个空的.xlsm中,并再次计时,执行耗时71秒。我假设您的方法在一个空的.xlsm中需要大约30秒。因此,我的下一个问题是:在循环过程中,是否有其他属性可以禁用以加快速度?@Jesse Yes,禁用所有事件和屏幕更新。请确保在离开宏之前重新启用它们。请记住通过单击答案旁边的复选标记将答案标记为正确。能否更具体地说明禁用所有事件?我尝试过禁用屏幕更新以及应用程序。Calculation=xlCalculationManual。我的代码在更大的电子表格中要慢得多,而且我似乎无法让它像在空电子表格中那样快速执行。
Sub MyDelete()
    Dim r As Range
    Set r = Sheet1.Range("A1").CurrentRegion  'perhaps define better
    Set r = r.Offset(1, 0).Resize(r.Rows.Count - 1)  ' I assume row 1 is header row.

Application.ScreenUpdating = False

    Dim arr As Variant
    arr = r.Value

    Dim newArr() As Variant
    ReDim newArr(1 To UBound(arr), 1 To UBound(arr, 2))
    Dim i As Long, j As Long, newCounter As Long
    i = 1
    newCounter = 1

    Do
        For j = 1 To UBound(arr, 2)
            newArr(newCounter, j) = arr(i, j)
        Next j

        newCounter = newCounter + 1
        i = i + 3
    Loop While i <= UBound(arr)

    r.ClearContents
    Sheet1.Range("A2").Resize(newCounter - 1, UBound(arr, 2)).Value = newArr

Application.ScreenUpdating = True

End Sub