繁体   English   中英

VBA打开将继续运行程序的新工作簿

[英]VBA to open new workbook that will continue to run programme

我有大量数据,是从一个非常旧的系统中提取的。 客户端的每条记录都不会出现在列中,而是行和列的混合。 我可以拆分数据的唯一方法是使用空行将每条记录分隔到新工作表(在同一个工作簿中),然后我将以这种方式处理数据。 我的 vba 正在为此工作,但是我的记录太多,工作簿中的工作表容量达到了极限(大约 1400,另存为 sheet1,sheet2..)。 无论如何我可以合并到我的vba中以将当前工作簿保存为可能的record1,打开一个新的工作簿可能名为record2并且当这个工作簿也完全保存时,并继续处理直到所有数据都被相应地分开。

这是我的vba

        Private Sub excelsplit()
Dim wbk As Workbook
Dim l_str, l_end, l_row As Long

Set wbk = ThisWorkbook


Application.DisplayAlerts = False
Do Until wbk.Sheets.Count = 1
wbk.Sheets(wbk.Sheets.Count).Delete
Loop
Application.DisplayAlerts = True


l_str = 2
l_row = 2
Do While l_row <= wbk.Sheets(1).Range("A1000000").End(xlUp).Row + 1
If wbk.Sheets(1).Range("A" & l_row).Value = "" And _
wbk.Sheets(1).Range("B" & l_row).Value = "" And _
wbk.Sheets(1).Range("c" & l_row).Value = "" And _
wbk.Sheets(1).Range("d" & l_row).Value = "" And _
wbk.Sheets(1).Range("e" & l_row).Value = "" And _
wbk.Sheets(1).Range("f" & l_row).Value = "" And _
wbk.Sheets(1).Range("g" & l_row).Value = "" And _
wbk.Sheets(1).Range("h" & l_row).Value = "" And _
wbk.Sheets(1).Range("i" & l_row).Value = "" And _
wbk.Sheets(1).Range("j" & l_row).Value = "" And _
wbk.Sheets(1).Range("k" & l_row).Value = "" And _
wbk.Sheets(1).Range("l" & l_row).Value = "" Then
wbk.Sheets.Add after:=wbk.Sheets(wbk.Sheets.Count)
wbk.Sheets(wbk.Sheets.Count).Range("A2:l" & l_row - l_str + 1).Value = wbk.Sheets(1).Range("A" & l_str & ":l" & l_row).Value
l_str = l_row + 1
End If
l_row = l_row + 1
Loop

End Sub

我有 52000 行数据,因此必须执行大约 35 次打开和关闭场景。 任何帮助将非常感激。

附件是我的数据的屏幕截图....问题是不同的行,有些单元格在此处输入相关的图像描述数据,但有些则没有。 (我想解析它)

这是我的最终结果在此处输入图像描述

如果您知道 Sheet1 中的数据没有一致的模式,请忽略此答案。

下面的代码基于第一张图像 (Sheet1) 中数据的外观。

Sub test()
Dim rg As Range: Dim cell As Range
Dim oFill As Range: Dim cnt As Long
Dim regID
Dim mil
Dim custBname
Dim custPHnum
Dim ref
Dim dt
Dim vat
Dim tot
Dim amt

With Sheets("Sheet1")
Set rg = .Range("i2", .Range("i" & Rows.Count).End(xlUp))
End With

Set oFill = Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)

cnt = 0

For Each cell In rg.SpecialCells(xlConstants)

    If IsNumeric(cell.Value) Then

        If cell.Offset(-1, -2).Value <> "" Then
            cnt = cnt + 1
            regID = "id-" & Format(cnt, "000")
            mil = cell.Offset(-2, -1).Value 'value for mileage
            custBname = cell.Offset(-2, 1).Value 'value for customer business name
            custPHnum = cell.Offset(-2, 2).Value 'value for customer phone number
        End If
    
        ref = cell.Value 'value for column Ref
        dt = cell.Offset(0, -1).Value 'value for column Date
        vat = Split(cell.Offset(0, 2).Value, " ")(0) 'value for VAT
        tot = Split(cell.Offset(0, 2).Value, " ")(Application.CountA(Split(cell.Offset(0, 2).Value, " ")) - 1) 'value for total
        amt = tot - vat 'value for amount
    
        oFill.Value = regID
        oFill.Offset(0, 1).Value = mil
        oFill.Offset(0, 2).Value = custBname
        oFill.Offset(0, 3).Value = custPHnum
        oFill.Offset(0, 4).Value = ref
        oFill.Offset(0, 5).Value = dt
        oFill.Offset(0, 6).Value = vat
        oFill.Offset(0, 7).Value = tot
        oFill.Offset(0, 8).Value = amt
    
        Set oFill = oFill.Offset(1, 0)
    
    End If
    
Next

End Sub

子假设在 Sheet1 第 i 列中,如果该行包含一个数字,则该行的值(肯定)是参考编号。 例如,基于您的 Sheet1 图像、单元格 i16、i17、i22、i27 等。

sub 还假设 G 列中始终存在一个值,其中该行正好位于包含参考编号的行的正上方。 对不起,我很难用英语解释它。 无论如何,例如:
单元格 i16.offset(-1,-2) ---> 是单元格 G15 ---> 所以单元格 G15 必须有一个值(根据您的图像,该值为 710)。
单元格 i22.offset(-1,-2) ---> 是单元格 G21 ---> 所以单元格 G21 必须有一个值(根据您的图像,该值为 avav)。
等等。

过程:
它使用来自第 i 列 Sheet1 的数据创建一个范围到变量 rg
它将Sheet2填充到变量oFill中
使 cnt 变量值为零

然后它循环到 rg 中的每个单元格(具有值)。
在单元格的每个循环中,它检查单元格值是否为数字。
如果单元格值是数字,则检查此 cell.offset(-1,-2) 是否有值
如果它有一个值,那么这意味着这个循环的单元格有一个新的 regID,
然后它创建一个变量,其中包含来自循环单元格行之外的所需信息。 因此,代码创建了一个 regID、mil、custBname 和 custPHnum,其中具有它们值的行是循环单元格行上方的两行。

然后它创建另一个变量(ref,dt,vat,tot,amt),其中具有它们值的行与循环单元格行相同。

为了得到 vat 和 tot 变量,它将循环的 cell.offset(0,2) 用 " " 拆分成一个数组,其中 vat 值是数组中的第一项,tot 值是数组中的最后一项.
然后用vat 减去tot 得到amt 变量的值。

最后,它用所有需要的信息填充 Sheet2 的 A 列中的最后一个空行。

根据样本图像数据,具有数字值的第二个循环单元格为 4552(单元格 i17)。 由于它不会在单元格 i17.offset(-1,-2) ---> 单元格 G16 上找到值,因此当它填充 Sheet2 的 A 列中的最后一个空行时,regID、mil、custBname 的信息相同并且 custPHnum ---来自上一个循环,它在 cell.offset(-1,-2) 中找到一个值--- 将被使用。

Sheet1 中的数据“模式”必须一致才能使所有这些变量都具有正确的值。

很抱歉,我无法测试 sub,因为我很难制作与 Sheet1 图像中相同的数据模式。 所以上面的子没有经过测试,但也许可以给你一个开始的想法。

上面的代码是用这种数据模式测试的:
在此处输入图像描述

运行 sub 后,结果如下:
在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM