Excel VBA:转置字符串的不同部分



我的值水平位于彼此相邻的单元格中。在每个单元格中,我正在提取单元格的某个子字符串,并希望在某些列中垂直转置每个部分。

例:

    ColA                         ColB                       ColC
First.Second<Third>     Fourth.Fifth<Sixth>           Seventh.Eighth<Ninth>

应类似于新工作表 (ws2):

    ColA          ColB      ColC
    First        Second     Third
    Fourth       Fifth      Sixth
    Seventh      Eighth     Ninth

我尝试遍历行和列,但随机跳过

For i = 2 to lastRow
   lastCol = ws.Cells(i, ws.Columns.Count).End(xlToLeft).Column
       For j = 2 to lastCol
           cellVal = ws.Cells(i, j).Value
            firstVal = Split(cellVal, ".")
            secondVal = 'extract second val
            thirdVal = 'extract third val
             ws2.Cells(i,1).Value = firstVal
             ws2.Cells(i,2).Value = secondVal
             ws3.Cells(i,4).Value = thirdVal

编辑:更新了以下几乎有效的代码:

Sub transPose()
  Dim used As Range
  Set used = Sheet1.UsedRange   'make better constraint if necessary
  Dim cell As Range
  Dim arr(0 To 3) As String
  Dim str As String
  Dim pointStr As Variant, arrowSplit As Variant
  Dim rowCount As Long
  rowCount = 0
  For Each cell In used      'This goes across rows and then down columns
        str = Trim(cell.Value2)
        If str <> "" Then    'Use better qualification if necessary
              spaceStr = Split(str, " ")
              arr(0) = spaceStr(0)
              arr(1) = spaceStr(1)
              arrowSplit = Split(spaceStr(1), "<")
              arr(2) = LCase(Mid(str, Application.Find("<", str) + 1, 1)) & LCase(arrowSplit(0))
              openEmail = InStr(str, "<")
              closeEmail = InStr(str, ">")
              arr(3) = Mid(str, openEmail + 1, closeEmail - openEmail - 1)
              rowCount = rowCount + 1
              Sheet2.Cells(1 + rowCount, 1).Resize(1, 4).Value = arr
        End If
  Next cell
End Sub

编辑2:数据实际上看起来像

           ColA                                  ColB                    etc...
  John Smith<John.Smith@google.com>         Jane Doe<Jane.Doe@google.com>

并且应该看起来像:

ColA     ColB      ColC           ColD
John     Smith    jsmith     john.smith@google.com
Jane     Doe      jdoe       jane.doe@google.com

试试这个:

Sub transPose()
  Dim used As Range
  Set used = Sheet1.UsedRange   'make better constraint if necessary
  Dim cell As Range
  Dim arr(0 To 2) As String
  Dim str As String
  Dim pointStr As Variant, arrowSplit As Variant
  Dim rowCount As Long
  rowCount = 0
  For Each cell In used      'This goes across rows and then down columns
        str = cell.Value2
        If str <> "" Then    'Use better qualification if necessary
              pointStr = Split(str, ".")
              arr(0) = pointStr(0)
              arrowSplit = Split(pointStr(1), "<")
              arr(1) = arrowSplit(0)
              arr(2) = Split(arrowSplit(1), ">")(0)
              rowCount = rowCount + 1
              Sheet2.Cells(1 + rowCount, 1).Resize(1, 3).Value = arr
        End If
  Next cell
End Sub

对于每个输入行,您将有 3 个输出行,这意味着您将每个输入行的输出行递增 3。此外,单元格函数采用(行、列)参数。

如果您将 i 和 j 从起始行/col 迭代到最后一行/col,数学就会变得愚蠢,所以我建议改为迭代行/列的计数并使用起点作为参考,无论是存储为 Range 对象的单元格还是起始行/列。

For i = 0 to ws.Rows.Count
   For j = 0 to ws.Columns.Count
           cellVal = ws.Cells(i + startRow, j + startCol).Value
            firstVal = Split(cellVal, ".")
            secondVal = 'extract second val
            thirdVal = 'extract third val
             ws2.Cells((i*3) + startRow, j + startCol).Value = firstVal
             ws2.Cells((i*3) + 1 + startRow, j + startCol).Value = secondVal
             ws3.Cells((i*3) + 2 + startRow, j + startCol).Value = thirdVal

等。。。

事实上,如果我这样做,我可能只会制作函数的inputRangeoutputRange参数,然后迭代这些参数。它将简化迭代(不需要混乱的startRow或startCol)和索引。如果您正在寻找这种解决方案,请发表评论,我可以添加它。

OP编辑的问题之后编辑

你可以试试这个:

Sub main2()
    Dim cell As Range, row As Range
    Dim arr As Variant
    Dim finalValues(1 To 4) As String
    Dim iRow As Long
    Dim ws As Worksheet, ws2 As Worksheet
    Set ws = Worksheets("originalData") '<--| change "originalData" to your actual sheet name with starting data
    Set ws2 = Worksheets("results") '<--| change "results" to your actual sheet name with starting data
    For Each row In ws.UsedRange.Rows
        For Each cell In row.SpecialCells(xlCellTypeConstants)
            arr = Split(Replace(Replace(cell.Value, "<", " "), ">", ""), " ")
            finalValues(1) = arr(0): finalValues(2) = arr(1): finalValues(3) = Left(arr(0), 1) & arr(1): finalValues(4) = arr(2)
            iRow = iRow + 1
            ws2.Cells(iRow, 1).Resize(, UBound(finalValues)).Value = finalValues
        Next
    Next
End Sub

最新更新