【问题标题】:Trying to improve quality and efficiency of my VBA code试图提高我的 VBA 代码的质量和效率
【发布时间】:2019-09-23 17:16:06
【问题描述】:

我有 50,000 个姓名和地址字符串,每个字符串占用一个单元格。为了将单元格拆分为不同的名称、街道编号、街道、城市等,我试图将单元格拆分为与街道编号和街道名称匹配的列。

  • E列中的所有单元格示例:

    行列:E

    1. 分开。 56 Johnston Terrace Keyham 路
    2. 沃尔斯利路 90 号和 92 号
    3. 2 安斯利露台
    4. Dyer & Cleaner 10 & 12 Mount Gold Road
    5. 亚历山大路 48b 号
    6. 奶农斯特拉瑟姆修道院路
  • NewCell 列中的结果;

    行。 Col.F |上校 | Col.H

    1. 分开。| 56 | Johnston Terrace Keyham 路
    2. '*' | 90 & 92 |沃尔斯利路
    3. '*' | 2 |安斯利露台
    4. 染色剂和清洁剂 | 10 & 12 |金山路
    5. '*' | 48b |亚历山大路
    6. 奶农 | '*' |斯特拉瑟姆修道院路

目前我的Excel Sheet没有具体的列名,只有A;乙; C 等。我有将每个单元格分开的 VBA 代码。但是,街道编号和/或街道名称将根据每个单元格中的“textnumbertext”字符串进行不同的拆分。
我有单独的 VBA 代码,可以在任何以街道号开头的条目前添加一个星号(请参阅代码)。然后将每个单元格放在正确的列中(我可以稍后删除星号)。但是,我觉得这段代码效率低下,如果我使用 Case 函数,可能会不那么冗长。

更复杂的是,一些街道编号将是 14A 或 12B 或 10c 或 12a。如果我将这些选项添加到下面的代码中,那么一切都会变得冗长且效率低下。请问有什么想法吗?

Sub ReplaceFirstNumber()
'If the first character in the string starts with a number between 1-9 THEN 
'ADD a * to the string
Dim r As Range
Dim c As Range
On Error Resume Next
Set r = Range(Range("E1"), Range("E" & Rows.Count).End(xlDown))
    For Each c In r
     If Left(c.Value, 1) = "1" _
     Or Left(c.Value, 1) = "2" _
     Or Left(c.Value, 1) = "3" _
     Or Left(c.Value, 1) = "4" _
     Or Left(c.Value, 1) = "5" _
     Or Left(c.Value, 1) = "6" _
     Or Left(c.Value, 1) = "7" _
     Or Left(c.Value, 1) = "8" _
     Or Left(c.Value, 1) = "9" Then
     c.Value = " * " & c.Value
    End If
   Next c
End Sub

【问题讨论】:

  • 在处理此类数据时,您应该考虑使用数组,您的代码会大大加快速度。我会给你举个例子,但是因为你只展示了蒂姆写的地址部分是好的。
  • 嗨 Damian 感谢 cmets。正如您从我对 Tim 的评论中看到的那样,我使用他的代码得到了一个编译错误。我将编辑我的帖子以包含我正在处理的典型单元格条目。
  • 我已经处理过此类数据,我认为实际上,如果您可以编写一个可以提取所需数据的代码,那么单独的代码将足够复杂,让您感到困难,您的优先级应该是实际的逻辑,而不是效率,因为我相信你只需要运行几次
  • 好吧@usmanhaq OP 说他的代码可以工作,但是太慢了,所以现在他的逻辑至少没问题,他可以专注于优化。
  • @DJP2019 与您提供的示例一样,您无法做到这一点......您的输入没有模式。您真的设法通过这些输入获得输出吗?如果至少总是有街道号码,你可以做到一半(取城市会有点复杂),但有些情况下你没有号码......你如何检测它是街道名称还是名称?

标签: excel vba switch-statement excel-2007


【解决方案1】:

希望下面的功能可以帮助您使这项任务变得更容易一些。它会从地址字符串中去除所有数字字符,并将包括任何尾随的单个字母。

Function getnumbersfromstring(address As String) As String
    For i = 1 To Len(address)
        If IsNumeric(Mid(address, i, 1)) Then getnumbersfromstring = getnumbersfromstring & Mid(address, i, 1) 
    Next i

    CharAfterNumber = Mid(address, Instr(1, address, getnumbersfromstring) + Len(getnumbersfromstring), 1)
    If IsNumeric(CharAfterNumber) = False And Not CharAfterNumber = " " And Not CharAfterNumber = "" Then
        getnumbersfromstring = getnumbersfromstring & CharAfterNumber
    End If
End Function

这个函数可以像这样在普通的 Sub 中调用

Sub breakupaddress()

Dim r As Range
Dim c As Range
Dim addressnr As String

On Error Resume Next
Set r = Range(Range("E1"), Range("E" & Rows.Count).End(xlDown))
    For Each c In r
        addressnr = getnumbersfromstring(c.Value)
        MsgBox "The address number is '" & addressnr & "'.", vbInformation, "Information"
    Next c
End Sub 

【讨论】:

  • 嗨 Tim Stack 感谢您抽出宝贵时间帮助我。我尝试运行 Sub 例程,但在“addressnr = getnumbersfromstring(c)”行出现错误。Visual Basic 说编译错误:ByRef 参数类型不匹配。
  • c 应该是 c.Value 因为 c 是一个范围,而函数需要一个字符串。修改了代码!
  • 嗨 Tim Stack 我是这个网站和发布信息格式的新手。我刚刚尝试给出我的单元格值和所需结果的示例。当我在这里输入时,它被格式化以便于理解,即像之前和之后一样。但是,当我输入问题的更新时,所有新的文本格式都丢失了!我显然需要学习如何正确发帖。
  • 无法确保地址更加...结构化?如果你问我,这是一个不稳定的混乱
  • 嗨 Tim Slack 是的,这是一团糟,我不喜欢它 - 我试图改进结果布局以显示哪些列将有条目,哪些没有。我是这个网站的新手,我正在学习如何发帖。感谢您的帮助和帮助。顺便说一句,在 Sub 例程中,我在 Megbox 行上遇到语法错误,我现在将尝试解决。
【解决方案2】:

我很好奇您将如何编写所有代码,但关于您的问题,可能可行的方法是:

Sub ReplaceFirstNumber()
'If the first character in the string starts with a number between 1-9 THEN 
'ADD a * to the string
Dim r As Range
Dim c As Range
Set r = Range("E1:E" & Range("E" & Rows.Count).End(xlUp).Row)
    For Each c In r
     If IsNumeric(Left(c.Value, 1))=True Then c.Value = "*" & c.Value
   Next c
End Sub

在您的代码中使用Range(Range("E1"), Range("E" & Rows.Count).End(xlDown))。这意味着E 列中的所有单元格!。这就像 Excel 2007 或更高版本中的一百万个单元格。在我的代码中,范围是 Set r = Range("E1:E" & Range("E" & Rows.Count).End(xlUp).Row) 这将只选择 E1 和 E 列中最后一个非空白单元格之间的所有单元格,因此如果您只有 50.000 行数据。

另外,如果您正在学习 VBA,我强烈建议您不要使用 On Error Resume Next 语句,因为它隐藏了错误,但它们仍然会发生。

希望您最终可以编写此代码,或者至少觉得此答案很有帮助。

但不管怎样,你还有很多代码要写。

【讨论】:

  • Foxfire 和 Burns 和 Burns Brilliant!我心里知道我的代码有改进,但你的代码工作得更好。是的!这有助于我学习 VBA 并尽量保持简单。您的 Range 评论非常有用,我以前使用过,但在我的示例中忽略了它,所以再次感谢您。注意到关于错误。
猜你喜欢
  • 2010-09-14
  • 2015-12-23
  • 2017-04-21
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 2022-06-15
  • 1970-01-01
  • 2010-10-27
相关资源
最近更新 更多