Excel VBA - 将多个列中的数据移动到单个列

时间:2017-07-26 19:33:09

标签: excel vba excel-vba multiple-columns

我现在有一个宏,它将来自不同工作表的数据拉入新工作表,然后将数据格式化为我可以使用的形式。我遇到的问题是,我从另一张表中提取的一些PN位于不同的单元格中以便于查看。 (例如,顶级PN在单元格C2中,而C2中部件的任何部分可能会在D3中列出,以显示它是一个子部分。)

我需要能够将不同列中的所有PN转换为单列的代码。移动所有PN后,应删除其他列(D到F)。数据范围从C列到F.根据宏从中提取数据的表,数据的长度会有所不同。宏需要能够处理这个问题。

以下是我的工作表在宏运行后的样子的示例:

Example_Data

我正在尝试检查C列是否有空行。如果说C3为空,那么我想检查D3的文字。如果有文字,我希望D3中的文字移动到C3。如果没有文字,请检查E3。重复相同的过程。从我在网上找到的,到目前为止我有这个代码(但是,它在我的宏中运行不正常)......

var obj = { "name":"John", "age":30, "city":"New York"};
var myJSON = JSON.stringify(obj);

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

正如Tehscript所说,你不需要宏。如果您仍想使用宏(也许您的实际情况比示例更复杂),这里是您的起点。

以下示例仅将细胞移位一次。所以你可能想要多次执行循环。 (您也可以遍历rowIndex并为每一行使用while循环。)

代码可以进一步重构,但我希望这种方式很容易阅读。

Sub ShiftCells()


Dim myWorkSheet As Worksheet
Set myWorkSheet = Worksheets("Tabelle1")

Dim maxRowIndex As Long
maxRowIndex = GetMaxRowIndex(myWorkSheet)

Dim rowIndex As Long
Dim columnIndex As Long

Dim leftCell As Range
Dim rightCell As Range

For Each Cell In Range("C2:F" & maxRowIndex)
    If Cell.Value = "" Then
       shiftedCell = True
       rowIndex = Cell.Row
       columnIndex = Cell.Column

       Set leftCell = myWorkSheet.Cells(rowIndex, columnIndex)
       Set rightCell = myWorkSheet.Cells(rowIndex, columnIndex + 1)

       leftCell.Value = rightCell.Value
       rightCell.Value = ""

    End If


Next Cell


End Sub

Function GetMaxRowIndex(ByVal myWorkSheet As Worksheet) As Long
    Dim numberofRowsInColumnC As Long
    numberofRowsInColumnC = myWorkSheet.Cells(Rows.Count, "C").End(xlUp).Row

    Dim numberofRowsInColumnD As Long
    numberofRowsInColumnD = myWorkSheet.Cells(Rows.Count, "D").End(xlUp).Row

    Dim numberofRowsInColumnE As Long
    numberofRowsInColumnE = myWorkSheet.Cells(Rows.Count, "E").End(xlUp).Row

    Dim numberofRowsInColumnF As Long
    numberofRowsInColumnF = myWorkSheet.Cells(Rows.Count, "F").End(xlUp).Row

    Dim maxNumberOfRows As Long
    maxNumberOfRows = WorksheetFunction.Max(numberofRowsInColumnC, _
                                                numberofRowsInColumnD, _
                                                numberofRowsInColumnE, _
                                                numberofRowsInColumnF _
                                                )
    GetMaxRowIndex = maxNumberOfRows
End Function

答案 1 :(得分:0)

更改你的" For"阻止:

With ws1.UsedRange
    lastRow = .Rows(.Rows.Count).Row
End With
For Each cell In Range("C2:C" & lastRow)
    If cell.Value = "" Then
       thisRow = cell.Row
       For Each horCell In Range(Cells(thisRow, "D"), Cells(thisRow, "F"))
            If Not horCell.Value = "" Then
                cell.Value = horCell.Value
                Exit For
            End If
       Next horCell

    End If


Next cell
Range("D:F").EntireColumn.Delete

只能通过C列循环,只有当C为空时才能循环显示D-F,当你找到带数据的那个时,它会把它放在C中。

如果您还需要列数的动态范围,请执行以下操作:

With ws1.UsedRange
    lastRow = .Rows(.Rows.Count).Row
    lastColumn = .Columns(.Columns.Count).Column
End With
For Each cell In Range("C2:C" & lastRow)
    If cell.Value = "" Then
       thisRow = cell.Row
       For Each horCell In Range(Cells(thisRow, "D"), Cells(thisRow, lastColumn))
            If Not horCell.Value = "" Then
                cell.Value = horCell.Value
                Exit For
            End If
       Next horCell

    End If


Next cell
Range(Cells(2, "D"), Cells(2, lastColumn)).EntireColumn.Delete

或者在for循环中使用正确的lastRow"到"范围,将您的代码更改为

If Not cell = "" then
     ws1.range ("C" & cell.Row).Value = cell.Value
 End if

你正在循环列D-F,所以" cell"是一个范围内的单元格,而不是C列中的单元格。因此,您需要测试那些非空的单元格,然后将它们的值放在C列的相应单元格中。: - )