【问题标题】:String to abbreviation字符串到缩写
【发布时间】:2014-03-20 14:56:36
【问题描述】:

我是一名图形艺术家,刚接触 Excel 和 VBA,但我试图用它来处理 Excel 中的大量数据,以便在 Illustrator 中用作可变数据。

如果我想将带有产品名称的单元格转换为“Budwieser、Bud Light 和 Bud Black Crown”等标志的缩写形式,格式为“Budweiser_BL_BBC”

我编写了一个我认为可以完成任务的函数,但它返回 #VALUE!

编辑

为了解释逻辑:我的想法是获取字符串,将其拆分为“&”,然后将结果数组的第一个位置拆分为“,”,然后将“&”之后的内容添加到末尾第二个数组 - 这个数组 sProd 将产品分隔到数组的不同位置。

然后循环遍历该数组并在空格处拆分每个产品,从而创建一个锯齿状数组。

然后再次循环遍历该数组,创建一个字符串,该字符串仅包含每个产品中每个单词的第一个字母,并用下划线分隔产品。例外情况是第一个产品的第一个单词被拼写并以适当的大小写设置。 (刚刚在我的逻辑中看到一个错误并添加了第一个单词异常的代码。

编辑#2

该函数应返回一个字符串,其中原始字符串的第一个单词以正确的大小写设置,所有其他单词缩写为它们的第一个字母,产品由下划线分隔。因此,“Budweiser, Bud Light & Bud Light Lime”返回“Budweiser_BL_BLL”,“All Coke & Dr Pepper Products”返回“AllC_DPP”,“Gatorade”返回“Gatorade”。

这是我第一次使用 Excel 和 VBA。

Function Abbrev(p As String) As String

Dim sAmpersand() As Variant
Dim sProd() As Variant

sAmpersand = Split(p, " & ")
sProd = Split(sAmpersand(0), ", ")

sProd(UBound(sProd)) = sAmpersand(1)

Dim ProductCount As Integer
Dim ProductEnd As Integer
ProductEnd = UBound(sProd) - 1

For ProductCount = 0 To ProductEnd
    sProd(ProductCount) = Split(sProd(ProductCount), " ")
    ProductCount = ProductCount + 1
    Next ProductCount

Dim WordCount As Integer
Dim WordEnd As Integer
WordEnd = UBound(sProd(ProductCount)) - 1
Abbrev = StrConv(sProd(0)(0), vbProperCase)
For ProductCount = 0 To ProductEnd
    For WordCount = 0 To WordEnd
            If ProductCount = 0 Then
              WordCount = 1
              End If
        Abbrev = Abbrev & Left(sProd(ProductCount)(WordCount), 1)
        WordCount = WordCount + 1
        Next WordCount
    If ProductCount + 1 < ProductEnd Then
        Abbrev = Abbrev & "_"
        End If
        ProductCount = ProductCount + 1
    Next ProductCount

End Function

【问题讨论】:

  • 你能解释一下逻辑吗?你需要找到第一个逗号,,第一个逗号之前的单词是“main”,其他单词应该只取第一个字母?
  • 在函数中设置调试并单步执行,并在循环时检查变量值。
  • @simoco 编辑了解释我的逻辑的帖子。谢谢
  • 目前还不清楚(实际上你已经解释了你将如何获得结果,但没有解释结果应该是什么样子)。您能否添加更多示例并向我们展示您的初始字符串是如何组织的?
  • @simoco 再次编辑,希望更清晰。

标签: vba excel excel-formula


【解决方案1】:

工作代码:

Function Abbrev(p As String) As String
    Dim res As String, w1, w2

    res = Split(Split(p, ",")(0), " ")(0)
    If res = Split(p, ",")(0) Then res = res & "_"

    For Each w1 In Split(Mid(Replace(p, " &", ","), Len(res) + 1), ",")
        For Each w2 In Split(w1, " ")
            res = res & Left(w2, 1)
        Next w2
        res = res & "_"
    Next w1

    Abbrev = IIf(Right(res, 1) <> "_", res, Left(res, Len(res) - 1))
End Function

【讨论】:

  • 缺少的一件事是将第一个产品放在一起。你可以看到在“All Coke”中出现了“All_C”。有没有办法让输出成为“AllC_DPP”?非常感谢您的帮助
  • @simoco 它有效,但不适用于我没有给你的情况。使用您的函数“Canada Dry、Hawaiian Punch & Sunkist”返回“Canada_DHP_S”。我对其进行了一些调整以使其正常工作。 If res = Split(p, ",")(0) Then res = res &amp; "_" 非常感谢您的帮助!和For Each w1 In Split(Mid(Replace(p, " &amp;", ","), Len(res) + 1), ",")
  • 是的,我在更改之前为我给你的案例工作过,但发现另一个案例没有。我更改了上面提到的行,现在它可以用于我的目的,再次感谢!
  • 我们如何概括这个函数?用下划线替换任何给定的正则表达式。因为我有像“企业(1/2)管理”这样的名字,我想用 '_' 替换这些字符 '[ 0-9]/()' ?
【解决方案2】:

这是一个更好的缩写函数:

Function Abbreviate(Name As String) As String
Dim I As Integer
Dim sResult As String
Dim sTemp As String

I = InStr(Name, " ")
If I < 1 Then
    Abbreviate = Name
    Exit Function
End If

sResult = Left$(Name, I)
sTemp = Name
Do While I > 0
    sTemp = Right$(sTemp, Len(sTemp) - I)
    If Left$(sTemp, 1) = "(" Then
        If Mid$(sTemp & "***", 3, 1) = ")" Then
            sResult = sResult & " " & Left$(sTemp, 3)
        Else
            sResult = sResult & " " & Left$(sTemp, 1)
        End If
    Else
        sResult = sResult & " " & Left(sTemp, 1)
    End If
    I = InStr(sTemp, " ")
Loop
Abbreviate = sResult

End Function

这是来自mrexcel.com上的用户al_b_cnu

这是一个修改后的版本,以缩短结果:

Function Abbreviate(Name As String) As String
Dim I As Integer
Dim sResult As String
Dim sTemp As String

I = InStr(Name, " ")
If I < 1 Then
    Abbreviate = Name
    Exit Function
End If

sResult = Left$(Name, I)
sTemp = Name
Do While I > 0
    sTemp = Right$(sTemp, Len(sTemp) - I)
    If Left$(sTemp, 1) = "(" Then
        If Mid$(sTemp & "***", 3, 1) = ")" Then
            sResult = sResult & Left$(sTemp, 3)
        Else
            sResult = sResult & Left$(sTemp, 1)
        End If
    Else
        sResult = sResult & Left(sTemp, 1)
    End If
    I = InStr(sTemp, " ")
Loop
Abbreviate = sResult

End Function

【讨论】:

    猜你喜欢
    • 2015-01-15
    • 1970-01-01
    • 2016-01-05
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 2023-04-09
    • 2019-03-11
    相关资源
    最近更新 更多