VBA将Excel单元格中的多行文本拆分为单独的行并保留相邻的单元格值

2023-12-30

请参阅附加图像,其中显示了运行宏后我的数据和预期数据,

  • 我想拆分 B 列中的多行单元格并在单独的行中列出,并从第一个空格中删除文本。该值将称为 SESE_ID,并且应具有 C 列中同一行中每个 SESE_ID 的规则。
  • 如果 A 列中有多个由逗号或空格逗号分隔的前缀,则对每个前缀重复上述值。

请有人在宏观上帮助我...

  1. 所附第一张图片是示例来源:
  1. 以下是宏:



    Sub Complete_sepy_load_macro()
    Dim ws, s1, s2 As Worksheet
    Dim rw, rw2, rw3, col1, count1, w, x, y, z, cw As Integer
    Dim text1 As String
    Dim xwalk As String
    Dim TOSes As Variant

    Application.DisplayAlerts = False
    For Each ws In Sheets
        If ws.Name = "CMC_SEPY_SE_PYMT" Then Sheets("CMC_SEPY_SE_PYMT").Delete
    Next
    Application.DisplayAlerts = True

    Set s2 = ActiveSheet
    g = s2.Name
    Sheets.Add.Name = "CMC_SEPY_SE_PYMT"

    Set s1 = Sheets("CMC_SEPY_SE_PYMT")

    s1.Cells(1, 1) = "SEPY_PFX"
    s1.Cells(1, 2) = "SEPY_EFF_DT"
    s1.Cells(1, 3) = "SESE_ID"
    s1.Cells(1, 4) = "SEPY_TERM_DT"
    s1.Cells(1, 5) = "SESE_RULE"
    s1.Cells(1, 6) = "SEPY_EXP_CAT"
    s1.Cells(1, 7) = "SEPY_ACCT_CAT"
    s1.Cells(1, 8) = "SEPY_OPTS"
    s1.Cells(1, 9) = "SESE_RULE_ALT"
    s1.Cells(1, 10) = "SESE_RULE_ALT_COND"
    s1.Cells(1, 11) = "SEPY_LOCK_TOKEN"
    s1.Cells(1, 12) = "ATXR_SOURCE_ID"
    s1.Range("A:A").NumberFormat = "@"
    s1.Range("B:B").NumberFormat = "m/d/yyyy"
    s1.Range("C:C").NumberFormat = "@"
    s1.Range("D:D").NumberFormat = "m/d/yyyy"
    s1.Range("E:E").NumberFormat = "@"
    s1.Range("F:F").NumberFormat = "@"
    s1.Range("G:G").NumberFormat = "@"
    s1.Range("H:H").NumberFormat = "@"
    s1.Range("I:I").NumberFormat = "@"
    s1.Range("J:J").NumberFormat = "@"
    s1.Range("K:K").NumberFormat = "0"
    s1.Range("L:L").NumberFormat = "m/d/yyyy"


    rw2 = 2

    x = 1
    y = 1
    z = 1
    'service id column
    Do
        y = y + 1
    Loop Until s2.Cells(1, y) = "Service ID"

    'Rule column
    Do
        w = w + 1
    Loop Until Left(s2.Cells(1, w), 4) = "Rule"

    'Crosswalk column
    Do
        cw = cw + 1
    Loop Until Left(s2.Cells(1, cw).Value, 9) = "Crosswalk"

    'Alt rule column (location derived from rule column)
    'counts # of cells between "rule" and "alt rule", used as precedent for rest of "alt rule" cells
    ar = w
    Do
        ar = ar + 1
    Loop Until Left(s2.Cells(1, ar).Value, 3) = "Alt"
    ar = ar - w

    'prefix row
    Do
        x = x + 1
    Loop Until s2.Cells(x, w)  ""

    'first service id row
    Do
        z = z + 1
    Loop Until s2.Cells(z, y)  ""

            'change rw = z + 2 to rw = z, was skipping first two rows
            For rw = z To s2.Range("a65536").End(xlUp).Row
                If s2.Cells(rw, y)  "" Then

                    If InStr(1, s2.Cells(rw, y), Chr(10))  0 Then
                        TOSes = Split(s2.Cells(rw, y).Value, Chr(10)) 'Chr(10) is the "new line" character
                        count1 = 0
                        Do
                            If Trim(TOSes(count1))  "" Then
                                For col1 = w To s2.UsedRange.Columns.Count
                                    If Left(s2.Cells(1, col1), 4) = "Rule" Then
                                        If InStr(1, TOSes(count1), " ") > 0 Then
                                            s1.Cells(rw2, 3) = Trim(Left(TOSes(count1), InStr(1, TOSes(count1), " ")))  'sese
                                        Else
                                            s1.Cells(rw2, 3) = TOSes(count1)
                                        End If

                                        s1.Cells(rw2, 1) = s2.Cells(x, col1) 'prefix
                                        s1.Cells(rw2, 5) = s2.Cells(rw, col1) 'rule
                                        'use crosswalk service id to populate alt rule
                                        If s2.Cells(rw, cw).Value  "" Then
                                            If xwalk = "" Then
                                                Match = False
                                                xwalk = Trim(s2.Cells(rw, cw)) & " "
                                                rwcw = z
                                                Do
                                                    If InStr(1, s2.Cells(rwcw, y).Value, xwalk, vbTextCompare) > 0 Then
                                                        'obtain rule and write to alt rule column of current row
                                                        s2.Cells(rw, col1).Offset(0, ar).Value = s2.Cells(rwcw, w).Value
                                                        Match = True
                                                    End If
                                                    rwcw = rwcw + 1
                                                Loop Until Match = True
                                            End If
                                        End If
                                        s1.Cells(rw2, 9) = s2.Cells(rw, col1).Offset(0, ar) 'alt rule
                                        s1.Cells(rw2, 7) = "TBD" 'cac
                                        s1.Cells(rw2, 13) = s2.Name 'file

                                         rw2 = rw2 + 1
                                    End If
                                    xwalk = ""
                                Next col1
                            End If
                            count1 = count1 + 1
                        Loop Until count1 = UBound(TOSes) + 1
                    Else
                        For col1 = w To s2.UsedRange.Columns.Count
                            If Left(s2.Cells(1, col1), 4) = "Rule" Then
                                If InStr(1, s2.Cells(rw, y), " ") > 0 Then
                                    s1.Cells(rw2, 3) = Trim(Left(s2.Cells(rw, y), 4))  'sese
                                Else
                                    s1.Cells(rw2, 3) = s2.Cells(rw, y)
                                End If

                                s1.Cells(rw2, 1) = s2.Cells(x, col1) 'prefix
                                s1.Cells(rw2, 5) = s2.Cells(rw, col1) 'rule
                                s1.Cells(rw2, 9) = s2.Cells(rw, col1).Offset(0, ar) 'alt rule
                                s1.Cells(rw2, 7) = "TBD" 'cac
                                s1.Cells(rw2, 13) = s2.Name 'file

                                rw2 = rw2 + 1
                            End If
                        Next col1
                    End If
                ElseIf s2.Cells(rw, y) = "" And Trim(s2.Cells(rw, w))  "" Then
                    If Len(s2.Cells(rw, 1)) >= 10 Then
                        text1 = Left(s2.Cells(rw, 1), 10) & " |row: " & rw 'sese
                    Else
                        text1 = s2.Cells(rw, 1) & " row: " & rw 'sese
                    End If
                        For col1 = w To s2.UsedRange.Columns.Count
                            If Left(s2.Cells(1, col1), 4) = "Rule" Then
                                s1.Cells(rw2, 3) = text1 'sese
                                s1.Cells(rw2, 3).Interior.ColorIndex = 6
                                s1.Cells(rw2, 1) = s2.Cells(x, col1) 'prefix
                                s1.Cells(rw2, 5) = s2.Cells(rw, col1) 'rule
                                s1.Cells(rw2, 9) = s2.Cells(rw, col1).Offset(0, ar) 'alt rule
                                s1.Cells(rw2, 7) = "TBD" 'cac
                                s1.Cells(rw2, 13) = s2.Name 'file

                                rw2 = rw2 + 1
                            End If
                        Next col1
                End If
            Next


        For rw3 = 2 To s1.UsedRange.Rows.Count
            s1.Cells(rw3, 2) = "1/1/2009"
            s1.Cells(rw3, 4) = "12/31/9999"
            s1.Cells(rw3, 11) = 1
            s1.Cells(rw3, 12) = "1/1/1753"
        Next rw3
        Dim wb As Workbook
        Dim wss, wsSepy, wsSID As Worksheet 'SID = Serivce ID Spreadsheet
        Dim sepyRow, sepyCol, acctCol, sidSeseCol, sidAcctCol, j As Long
        Dim cell As Range
        Dim cellRange As Range
        Dim topRow As Range
        Dim sepySese As String

        MsgBox "All set, make sure there is no #N/A in SESE_RULE column"
        End Sub

  
  1. Below image is the output I got: enter image description here

  2. 问题:如果您看到源数据,我在 A 列中有 SEPY_PFX。我希望每个 SEPY 重复每一行。目前,我的代码给了我 RULE 作为 SEPY_PFX,我仍在努力,但如果有人快速帮助我,我会很高兴,它已经超出了我的能力范围。


此代码将适用于您发布的第一个示例,以提供您想要的输出:

原始来源:

原始结果:

它的工作原理是使用Class and 收藏,一次创建一个条目,然后将其组合在一起以获得结果。

我使用数组来收集和输出数据,因为这样会更快。在你的原作中,你有一些字体颜色,我已经继承了。

您应该能够使其适应您的真实数据,但是,如果您不能,我建议您在某些文件共享网站(例如 DropBox)上发布原始数据的“经过净化的”副本,其中包含正确的列等, OneDrive等;并在此处发布链接,以便我们可以看到“真实的东西”

关于类的使用,请参见奇普·皮尔森的网站 http://www.cpearson.com/Excel/Classes.aspx

另外,请阅读代码中的注释以获取解释和建议。

首先插入一个类模块,重命名它cOfcCode并将以下代码粘贴到其中:

'Will need to add properties for the additional columns

Option Explicit

Private pSEPY As String
Private pFontColor As Long
Private pSESE As String
Private pRule As String

Public Property Get SEPY() As String
    SEPY = pSEPY
End Property
Public Property Let SEPY(Value As String)
    pSEPY = Value
End Property

Public Property Get FontColor() As Long
    FontColor = pFontColor
End Property
Public Property Let FontColor(Value As Long)
    pFontColor = Value
End Property

Public Property Get Rule() As String
    Rule = pRule
End Property
Public Property Let Rule(Value As String)
    pRule = Value
End Property

Public Property Get SESE() As String
    SESE = pSESE
End Property
Public Property Let SESE(Value As String)
    pSESE = Value
End Property

然后,在常规模块中:

Option Explicit
Sub ReformatData()
    Dim wsSrc As Worksheet, wsRes As Worksheet
    Dim rSrc As Range, rRes As Range
    Dim vSrc As Variant, vRes As Variant
    Dim vSEPY As Variant, vSESE As Variant
    Dim cOC As cOfcCode
    Dim colOC As Collection
    Dim lRGB As Long
    Dim I As Long, J As Long, K As Long

'Change Sheet references as needed
Set wsSrc = Worksheets("Sheet2")
Set wsRes = Worksheets("Sheet3")

'Assuming Data is in Columns A:C
With wsSrc
    Set rSrc = .Range("A1", .Cells(.Rows.Count, "C").End(xlUp))
End With
Set rRes = wsRes.Range("A1")

vSrc = rSrc
Set colOC = New Collection  'Collection of each "to be" row
For I = 2 To UBound(vSrc, 1)

    'Split SEPY_PFX into relevant parts
    vSEPY = Split(vSrc(I, 1), ",")
    For J = 0 To UBound(vSEPY)

        'Get the font color from the original cell
        With rSrc(I, 1)
            lRGB = .Characters(InStr(1, .Value, vSEPY(J), vbTextCompare), 1).Font.Color
        End With

        'Split SESE_ID into relevant parts
        vSESE = Split(vSrc(I, 2), vbLf)

        'Iterate through each SESE_ID, picking up the SEPY_PFX, and RULE
        For K = 0 To UBound(vSESE)
            Set cOC = New cOfcCode

            'Will need to adjust for the extra columns
            With cOC
                .FontColor = lRGB
                .Rule = vSrc(I, 3)
                .SEPY = vSEPY(J)
                .SESE = vSESE(K)
                colOC.Add cOC '<-- ADD to the collection
            End With
        Next K
    Next J
Next I

'Put together the Results
ReDim vRes(0 To colOC.Count, 1 To UBound(vSrc, 2))

'Copy the column headings from the source
For I = 1 To UBound(vRes, 2)
    vRes(0, I) = vSrc(1, I)
Next I

'Will need to add entries for the other columns
For I = 1 To colOC.Count
    With colOC(I)
        vRes(I, 1) = .SEPY
        vRes(I, 2) = .SESE
        vRes(I, 3) = .Rule
    End With
Next I

'Clear the results worksheet and write the results
wsRes.Cells.Clear
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
rRes = vRes

'Add the correct font color and format
For I = 1 To colOC.Count
    rRes.Rows(I + 1).Font.Color = colOC(I).FontColor
Next I

With rRes.Rows(1)
    .Font.Bold = True
    .HorizontalAlignment = xlCenter
End With

rRes.EntireColumn.AutoFit

End Sub

对代码中的工作表引用进行更改(只需在常规模块的开头执行此操作)。

首先在您的原始示例上尝试此操作,以便您可以了解它是如何工作的,然后添加额外的列并处理类和集合,或者在此处发回更多详细信息

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VBA将Excel单元格中的多行文本拆分为单独的行并保留相邻的单元格值 的相关文章

  • MS Office SaveAs 类型 FileDialog 在 vb 中带有过滤器

    我想创建一个带有过滤器的 另存为 文件对话框 但这似乎无法使用 FileDialog 类 Microsoft Office 12 0 对象库 实现 文档实际上提到了这一点here http msdn microsoft com en us
  • VBA按空格分割字符串

    我想要一个 Excel 函数 我可以调用该函数并将单元格传递到其中 输入 Firstname Lastname email protected cdn cgi l email protection Firstname midname Las
  • 如何用线条在一个Excel散点图中绘制多个分组数据

    我在 Excel 中的一张图表 带线的散点图 中绘制分组数据 按索引 时遇到一些困难 我将非常感谢您的帮助 我的数据分为三列 第一列是数据或组的索引 即每组数据的唯一编号 第二列是时间 第三列是数据 Group Time Data 1 1
  • Excel 公式或 VBA:在具有 2 列条件的单独表中查找匹配的地址 - 无辅助列

    我需要公式结构方面的帮助 我有2张桌子 我想找到 a 列和 b 列相等的匹配项并获取表 2 中的地址 它们将是唯一的条目 例如 项目信息表 A B C 1 Name Company Project 2 Chris Evans Apple I
  • 将 Excel 文件导入 Access 时更改数据类型

    将 Excel 文件导入 Access 时 有什么方法可以更改默认数据类型吗 顺便说一下 我使用的是 Access 2003 我知道有时我可以自由地将任何数据类型分配给正在导入的每个列 但这只能在我导入非 Excel 文件时进行 EDIT
  • 通过 VBA MS_Access 将 MS Access 表导出为 dBase 5

    如何通过 VBA 将单个表导出为 dBase 5 文件 目前我正在使用这个VBA代码 DoCmd TransferDatabase acExport dBase IV DB Total acTable DB Total C Data Fal
  • Excel宏-将逗号分隔的条目拆分为新行[重复]

    这个问题在这里已经有答案了 我目前在一张纸上有这些数据 Col A Col B Col C 1 A angry birds gaming 2 B nirvana rock band 我想要做的是将第三列中的逗号分隔条目拆分并插入新行 如下所
  • 使用 UiPath 循环 Excel 文件中的 URL

    我尝试了几种方法 但不知怎的 它们看起来不干净 我有一个 Excel 格式的 URL 文件 一列中有 400 多个 URL 我希望 UiPath 从该文件中读取并一一浏览这些 URL 我尝试让 导航到 从从 Excel 读取的变量中读取 但
  • 在 Excel 工作簿中找不到链接

    我编写了一个宏来打开多个受密码保护的工作簿 这些工作簿彼此之间都有链接 因此为了方便起见 我设置了UpdateLinks 0这样在其他书籍打开之前 我就不会收到所有链接更新的密码提示 所有工作簿打开后 我尝试使用以下命令更新链接 Workb
  • Excel动态数组运行重复项计数

    我一直在重新设计一些旧的电子表格工具 以便使用 Excel 的较新工具来过滤和格式化动态数据输出动态数组公式 https support microsoft com en us office dynamic array formulas a
  • 求除某些列之外的 SUM

    以下是我所拥有的 A B C D E F G H I J K 1 2 3 4 5 6 7 8 9 10 50 为了找到SUM
  • WebAPI 和 Angular JS Excel 文件下载 - 文件损坏

    我正在 WebAPI 中生成 Excel 文件 我将其 存储 在内存流中 然后放入响应 如下所示 var result new HttpResponseMessage HttpStatusCode OK Content new Stream
  • 从嵌入的谷歌地图中提取标记坐标

    对此还很陌生 所以请耐心等待 我需要从嵌入的谷歌地图中提取标记坐标 示例链接是http www picknpay co za store search http www picknpay co za store search我想提取搜索时地
  • 如何将多个 Excel 工作表转换为 csv python

    我想转换所有的excel文档 xls 将工作表转换为 csv 如果 excel 文档只有一张工作表 那么我将进行如下转换 wb open workbook path1 sh wb sheet by name Sheet1 csv file
  • java.exe 以非零退出值 1 结束

    只是为了开始 我并不是真正尝试从 Android 中的 xlsx 文件中读取单元格 我已经尝试了几乎所有我在 Google 上搜索到的内容 但是每次 在两台不同的 PC 上 都是 Java 1 7 0 79 当我尝试构建 运行 这个应用程序
  • Excel VBA:排序,然后复制和粘贴

    所有 我需要编写一个执行以下操作的宏 将数据输入到 E 列的最后一个空白单元格后 按 E 列对整个工作表进行降序排序 工作表排序后 2a 将单元格复制到紧邻首次输入数据的单元格左侧的相邻单元格 2b 将复制的数据粘贴到最初输入数据的同一行的
  • 获取给定日期的周数

    例子 DD MM YYYY 1 1 2009 should give 1 31 1 2009 should give 5 1 2 2009 should also give 5 Format 1 2 2009 ww 回报6 那么 怎样才能得
  • 如何使用 C# 在 MS Excel 单元格中添加数字验证

    我的目标是限制用户在 MS Excel 单元格中仅输入 1 到 100 范围内的值 我正在以编程方式生成 Excel 文件 但是当我添加上述验证时 抛出异常Exception from HRESULT 0x800A03EC 我写的代码如下
  • 参考上一个问题:为什么 VBA 没有加载所有发票详细信息

    除了上一个问题之外 我们在销售发票上仍然存在相同的加载失败问题 下面的 VBA Json 仍然仅加载一行或第一个产品详细信息行 而不是与表中该销售发票合作的所有产品行详细信息 我们希望下面的 VBA 能够根据参数加载发票详细信息 例如 如果
  • 索引匹配不起作用

    对于下表 如果 A 列和 B 列都匹配 如何检索 C 列A 列 B 列 C 列城市 1 城市 10 本地城市 2 城市 21 远程城市 3 城市 1 远程城市 4 城市 2 本地 我尝试使用索引和匹配 但得到 N A Enter as an

随机推荐