基于固定宽度

时间:2016-10-11 13:16:06

标签: excel vba excel-vba

我很抱歉,如果在其他地方已经有同样的问题得到答案,但是我一直无法找到它,所以我去了。

我还要提到我是VBA的初学者,主要是玩其他人获得的代码以获得我想要的东西。

我目前在列A-D中有数据,C列中的信息是重要的列。其他一切都应该被忽略。

我在sheet1的单元格C1中有一行文本。它长25个字符,类似于以下内容:

4760-000004598700000000000

我有超过约970,000行数据,需要将每个单元格中的信息提取到另一张表格中的两个不同单元格中。

由于记录的数量,我不能简单地使用公式(当我尝试时,excel崩溃)。

如果使用C1的mid函数,我会输入类似(C1,2,3)和(C1,5,11)的内容。 (除了C列中的每个单元格外)

+或 - 之间的前导零和第一个非零值的开头没有任何后果,但如果需要,我可以自己修复那个部分。

理想情况下,信息将被拉入我准备的现有工作表中,在A和B列中。 (IE:Sheet 2中)

例如,使用上面提供的文本,工作表将如下所示:

A | B

760 | -0000045987 -45987

我已经研究了数组,分组和中间代码,但是由于我对VBA的了解有限,我遇到了麻烦。我相信有一种方法可以做到这一点,我很感激任何帮助来提出解决方案。

提前感谢您的帮助,如果您需要任何其他信息,请与我们联系。

3 个答案:

答案 0 :(得分:1)

听起来就像你可以通过Text to Columns工具实现的那样。我不确定你是否试图将其作为现有宏中的一个步骤,或者如果这就是你想要的宏,那么我会给你两个答案。

如果您只想在指定点分割文本,可以使用“文本到列”工具。突出显示要修改的单元格,然后转到“数据”选项卡,并从“数据工具”组中选择“文本到列”。 enter image description here

在Text to Columns向导中,选择“Fixed Width”单选按钮,然后单击Next。在步骤2中,单击数据预览以添加要分割数据的中断 - 因此,在上面给出的示例中,单击“760”和“ - ”之间。再次单击“下一步”。

在步骤3中,您可以选择操作产生的每列的格式。这对您提到的前导零有用 - 您可以将每列设置为“文本”。准备好后,单击“完成”,数据将被拆分。

您可以使用相当简单的代码对VBA执行相同的操作,这些代码可以是独立的,也可以集成到更大的宏中。

Sub RunTextToColumns()
    Dim rngAll As Range

    Set rngAll = Range("A1", "A970000")
    rngAll.TextToColumns _
        DataType:=xlFixedWidth, _
        FieldInfo:=Array(Array(0, 2), Array(3, 2))

    With Sheets("Sheet4").Range("A1", "A970000")
        .Value = Range("A1", "A970000").Value
        .Offset(0, 1).Value = Range("B1", "B970000").Value
    End With
End Sub

这需要大约一秒钟才能运行,包括拆分和复制数据。当然,对范围和工作表的硬编码引用是不好的做法,应该用变量或常量替换,但为了清楚起见,我这样做了。

答案 1 :(得分:0)

我认为有一个数组公式可以做到这一点,但我更喜欢蛮力方法。有两种方法可以使用过程或函数填充字段。我已经做了两件事,为你说明一下。同样,我故意使用多种方式来引用单元格和分离文本,以说明实现目标的各种方法。

Sub SetFields()
Dim rowcounter As Long, lastrow As Long
lastrow = ActiveSheet.Cells(Rows.Count, 3).End(xlUp).Row 'get the last row in column "C"

For rowcounter = 1 To lastrow 'for each row in the range of values
    'put the left part in column "D"
    ActiveSheet.Range("D" & rowcounter) = FieldSplitter(ActiveSheet.Cells(rowcounter, 3).Text, True)
    'and the right part in the column two over from colum "C"
    ActiveSheet.Cells(rowcounter, 3).Offset(0, 2) = FieldSplitter(ActiveSheet.Cells(rowcounter, 3).Text, False)
Next rowcounter
End Sub
Function FieldSplitter(FieldText As String, boolLeft As Boolean) As String
If boolLeft Then
    FieldSplitter = Mid(FieldText, 2, 3) 'one way of getting text from a string
Else
    FieldSplitter = Left(Right(FieldText, 16), 5) ' another way
End If
  'Another useful function is Split, as in myString = Split (fieldtext, "-")(0) This would return "4760"

End Function

答案 2 :(得分:0)

这个怎么样:

Sub GetNumbers()
Dim Cel As Range, Rng As Range, sCode As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False

Set Rng = Sheets("Sheet1").Range("C1:C" & Sheets("Sheet1").Range("C1048576").End(xlUp).Row)

For Each Cel In Rng
    Sheets("Sheet2").Cells(Cel.Row, 1).Value = Mid(Cel.Value, 2, 3)
    sCode = Mid(Cel.Value, 5, 11)
    'Internale loop to get rid of the Zeros, reducing one-by-one
    Do Until Mid(sCode, 2, 1) <> "0" And Mid(sCode, 2, 1) <> 0
        sCode = Left(sCode, 1) & Right(sCode, Len(sCode) - 2)
    Loop
    Sheets("Sheet2").Cells(Cel.Row, 2).Value = sCode
Next

Application.ScreenUpdating = True
Application.DisplayAlerts = True

End Sub