简体   繁体   English

宏将数据从x列数重新排列为x列数,然后向下复制A和B行中的数据

[英]Macro to re-arrange data from x number of columns into x number of rows then copy down data in rows A and B

I have a rather significant amount of data in a spreadsheet that is poorly arranged. 电子表格中的数据排列不当,数量相当可观。 The current format has a company, a product name, and the ingredients listed afterwards. 当前格式具有公司,产品名称和随后列出的成分。 The ingredients all have their own column without a header. 所有成分都有自己的没有标题的列。 For instance, and I apologize this is not reflected below since I'm terrible at markup language, Column A would be labeled Manufacturer , Column B would be labeled as Product Name , Column C would be labeled Ingredients but then the rest of the columns are unlabeled. 例如,我很抱歉,这在下面没有反映出来,因为我对标记语言很不好,A列将被标记为Manufacturer ,B列将被标记为Product Name ,C列将被标记为Ingredients,但是其余的列为未贴标签。

Ultimately, I need to move the data to a new sheet, where data only appears in columns A, B, and C. The number of ingredients each product has varies. 最终,我需要将数据移动到新表中,其中数据仅出现在A,B和C列中。每种产品所含成分的数量各不相同。

I hope that the desired format helps. 我希望所需的格式有帮助。

Current Format: 当前格式:

1| Acme Inc.    | ABC123       | Water       | Sugar     | Eggs    | Salt
2| Acme Inc.    | BCD456       | Cornmeal    | Salt
3| JJ Baking    | JJ4567       | Flour       | Nuts      | Fruit

Desired Format: 所需格式:

1| Acme Inc. | ABC123 | Water
2| Acme Inc. | ABC123 | Sugar
3| Acme Inc. | ABC123 | Eggs
4| Acme Inc. | ABC123 | Salt
5| Acme Inc. | BCD456 | Cornmeal
6| Acme Inc. | BCD456 | Salt
7| JJ Baking | JJ4567 | Flour
8| JJ Baking | JJ4567 | Nuts
9| JJ Baking | JJ4567 | Fruit

Here's a short one that should work: 这是一个应该起作用的简短示例:

Sub test()
Dim lastRow&, lastCol&, noItems&
Dim i&, k&
' This macro will assume your column A and B are constant, and your items will start in column C
lastRow = Cells(Rows.Count, 1).End(xlUp).Row

For i = lastRow To 1 Step -1
    lastCol = Cells(i, Columns.Count).End(xlToLeft).Column
    noItems = WorksheetFunction.CountA(Range(Cells(i, 3), Cells(i, lastCol)))

    ' Now we know how many items, so add the info to the new rows.
    ' Start with the name and col B
    Range(Cells(i + 1, 1), Cells(i + noItems - 1, 1)).EntireRow.Insert
    Range(Cells(i, 1), Cells(i + noItems - 1, 2)).FillDown
    For k = 1 To noItems - 1
        Cells(i + k, 3).Value = Cells(i, 3 + k).Value
        Cells(i, 3 + k).Value = ""
    Next k

Next i

End Sub

It will look in column C through [whatever column in that row is the last one, going right], then create new rows to fit the amount of items in there. 它将在[C列]中查找[该行的最后一列,右移],然后创建新行以适应其中的项目数量。

This should do the trick, i put my many assumptions in the code comments. 这应该可以解决问题,我在代码注释中加入了许多假设。

My main one is that there are no gaps between columns with data. 我的主要观点是,数据列之间没有间隙。 EG: Column D is filled out, Column E is blank, Column F is filled out. EG:D列已填写,E列为空白,F列已填写。

Also that there are no 'blank' rows for entries for Column A, and that when we do see a blank row the function stops. 另外,列A的条目没有“空白”行,并且当我们看到空白行时,该函数停止。 Please fill in your 'Worksheet Name' where it says 'Customize to your sheet name'. 请在“工作表名称”中填写“自定义工作表名称”。

Public Sub ReOrder()
    Dim sheet As Worksheet
    Dim row As Integer
    Dim col As Integer
    Dim offset As Integer
    row = 2

    'Customize to your sheet name
    Set sheet = ThisWorkbook.Worksheets("Sheet1")

    'I am assuming there are no 'blanks' between rows or columns
    'If there are such 'blanks' use UsedRange.Rows or UsedRange.Columns
    'Then skip over the blanks with an if statement

    'Keep processing while we see data in the first column
    While (sheet.Cells(row, 1).Value <> "")
        'We only need to make a new row if anything past column C is filled out with something
        col = 4
        offset = 1
        While (sheet.Cells(row, col).Value <> "")
            'Insert new row
            sheet.Rows(row + offset).EntireRow.Insert shift:=xlDown

            'Assign Column values to the new row
            sheet.Cells(row + offset, 1).Value = sheet.Cells(row, 1).Value
            sheet.Cells(row + offset, 2).Value = sheet.Cells(row, 2).Value
            sheet.Cells(row + offset, 3).Value = sheet.Cells(row, col).Value

            'Remove Column value from the source row
            sheet.Cells(row, col).Value = ""

            col = col + 1
            offset = offset + 1
        Wend
        row = row + 1
    Wend
End Sub

I'm guessing the 3a3n codes are company specific. 我猜3a3n代码是公司特定的。 Assuming ABC1231 is in B1 of Sheet1, insert a new Row1 and apply the technique detailed here , selecting Range in “Step 2b of 3” to be B1: to the end of your data. 假设ABC1231位于Sheet1的B1中,插入新的Row1并应用此处详述的技术,在“ 3的第2b步”中选择Range为B1:到数据末尾。 When you get to the Table you may filter to select and delete the rows blank in Column Value . 进入表格后,您可以进行过滤以选择和删除列Value空白的行。

In B2 enter: 在B2中输入:

=INDEX(Sheet3!A:A,MATCH(A4,Sheet3!B:B,0))  

Select and Copy Table then Paste Special…, Values over the top and switch the order of Columns A and B. 选择并复制表格,然后粘贴特殊...,将值放在顶部,并切换列A和B的顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM