0

我有一个电子表格,它使用字符串约定来传达有关各个“案例”的详细程度。

约定如下: 字符串中的数据有 5 个主要类别。1=类别,2=工具,3=文档,4=过程,5=工作帮助。

每个类别可以有多个子类别,每 5 个类别按 1a、1b、1c 或 2a、2b、2c 等细分。

主类与子类用“:”分隔,子类与子类用“,”分隔,而子类与新的主类用“;”分隔

字符串示例:“1:1i;2:2a;3:3a,3d,3l;4:4a”

以下是值类别的示例细分:

CATEGORY    1
Incorrect:VG:QOC    1i

TOOLS   2
Macro:Used  2a

DOCUMENTATION   3
TAT:Missing 3a
ROUTING:Missing 3d
STORY:Missing Impact to Health  3i

PROCESS 4
CNX Checklist Not Used  4a

我希望能够以文本形式提取标记了主要类别和子类别的内容。

示例查询:
在所有字符串中,主类别 4 被标记了多少次?在所有 4 个标记中,4a 标记了多少次?在一个“案例”或字符串上标记的所有元素是什么?

我可以构建字符串,但我无法解析它们。请帮忙... :)

4

1 回答 1

1

您正在寻找的功能是拆分(此链接适用于 VB 功能,但在 VBA 中的行为几乎相同)。您可以将特定字符串传递给它并指定分隔符,它将返回每个值的数组。

在您的情况下,由于您的字符串有多个分隔符,您需要多次执行。

第一个潜在问题是如果您没有给定类别的子类别怎么办?如果您的字符串中的每个类别始终至少有子类别,那很好,但如果可能存在没有子类别的情况,那么您需要确保您的最高级别分组仍然由;.

由于您没有说明如何将信息呈现给用户,因此下面的示例将在 Excel 的中间窗口中打印出与您所期望的内容相近的内容。

Option Explicit

Sub SplitExample()
Dim inputString As String
Dim categories() As String
Dim subCategories() As String
Dim individualSubCat() As String
Dim cat As Variant
Dim subCat As Variant
Dim cnt As Integer

    inputString = "1:1i;2:2a;3:3a,3d,3l;4:4a"

    categories = Split(inputString, ";")

    For Each cat In categories

        subCategories = Split(cat, ":")

        If UBound(subCategories) >= 0 Then
            Debug.Print ("Category " & subCategories(0))

            If UBound(subCategories) > 0 Then
                individualSubCat = Split(subCategories(1), ",")
                Debug.Print (vbTab & "Has " & UBound(individualSubCat) - LBound(individualSubCat) + 1 & " flag(s)")

                For Each subCat In individualSubCat
                    Debug.Print (vbTab & subCat & " was flagged " & CountSubCategory(individualSubCat, subCat) & " time(s)")
                Next

            Else
                Debug.Print (vbTab & "No Subcategories flagged")
            End If

            Debug.Print ("")

        End If

        Erase subCategories
        Erase individualSubCat

    Next

End Sub

这是一个可以轻松计算子类别的功能

Private Function CountSubCategory(individualSubCategories() As String, ByVal subCat As String) As Integer
Dim cnt As Integer
Dim value As Variant

    cnt = 0

    For Each value In individualSubCategories
        If value = subCat Then cnt = cnt + 1
    Next

    CountSubCategory = cnt

End Function

并使用您的示例字符串作为输入,上面的代码将打印:

Category 1
    Has 1 flag(s)
    1i was flagged 1 time(s)

Category 2
    Has 1 flag(s)
    2a was flagged 1 time(s)

Category 3
    Has 3 flag(s)
    3a was flagged 1 time(s)
    3d was flagged 1 time(s)
    3l was flagged 1 time(s)

Category 4
    Has 1 flag(s)
    4a was flagged 1 time(s)

上面的代码将打印每个标志,即使有重复。你没有说这是否是理想的行为。从数组中过滤或分组重复项并不简单,但最好使用 VBA 中的 Collection 或 Dictionary 类来完成。(查看这个问题以帮助过滤数组中的重复项)。

上面的代码只是一个示例,展示了需要做什么以及如何完成解析(因为那是您的特定要求)。要真正将其变成工作代码,您需要做两件事:

  1. 在 VBA 中创建一个 Function 或 Sub 代码以在上面解析它(基本上是上面的内容SplitExample())并给它一个名称(如ParseErrorCodes),并让它接受一个名为inputString. 然后,您将从构建字符串的方法中调用它(您说您已经可以这样做)并将该字符串传递给该方法。
  2. 决定如何输出结果。实际上,您可以用Debug.Print可以在某处输出结果的东西替换这些行(大概是另一个 Excel 电子表格,这样您就可以创建您正在寻找的图表)。

基本思想是:

Sub OutputErrorCodes()
Dim inputString as String

    ' You code to read your string values from where-ever you keep them
    '  and build the inputString
    ' this source could be a file, or a worksheet in the Excel Workbook
    '  or could be an external datasource like a database or even an internet 
    '  location
    ' once you build your inputString, you just need to call ParseErrorCodes 

    ParseErrorCodes inputString

End Sub

Sub ParseErrorCodes(input as String)

    ' MyCode from above with some modifications
    '  - You need to remove the Dim for inputString and the assignment for 
    '     inputString
    '  - You need to replace the Debug.Print lines with your method of 
    '     defining the output
    '    *  this can be via outputing directly to an excel spreadsheet or 
    '        maybe a global variable
    '    *  outputing to an excel spreadsheet would probably be the best 
    '        option and allow for more dynamic flags, but you need to decide 
    '        where to output it in the code

End Sub

Private Function CountSubCategory(individualSubCategories() As String, 
                                  ByVal subCat As String) As Integer)

    ' this code can probably be taken directly from my example

End Function
于 2012-09-18T07:44:01.313 回答